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 OpenSsl10XNativeJna 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       * Cleanups before program exit, it will avoid memory leaks.
64       *
65       * @return 0 on success, 1 otherwise.
66       */
67      public static native int ENGINE_cleanup();
68  
69      /**
70       * Releases all functional references.
71       *
72       * @param e
73       *            engine reference.
74       * @return 0 on success, 1 otherwise.
75       */
76      public static native int ENGINE_finish(PointerByReference e);
77  
78      /**
79       * Frees the structural reference
80       *
81       * @param e
82       *            engine reference.
83       * @return 0 on success, 1 otherwise.
84       */
85      public static native int ENGINE_free(PointerByReference e);
86  
87      /**
88       * Obtains a functional reference from an existing structural reference.
89       *
90       * @param e
91       *            engine reference
92       * @return zero if the ENGINE was not already operational and couldn't be successfully
93       *         initialized
94       */
95      public static native int ENGINE_init(PointerByReference e);
96  
97      /**
98       * Initializes the engine.
99       */
100     public static native void ENGINE_load_rdrand();
101 
102     /**
103      * Sets the engine as the default for random number generation.
104      *
105      * @param e
106      *            engine reference
107      * @param flags
108      *            ENGINE_METHOD_RAND
109      * @return zero if failed.
110      */
111     public static native int ENGINE_set_default(PointerByReference e, int flags);
112 
113     /**
114      * Generates a human-readable string representing the error code e.
115      *
116      * @see <a href="https://www.openssl.org/docs/man1.0.2/man3/ERR_error_string.html">ERR_error_string</a>
117      *
118      * @param err
119      *            the error code
120      * @param null_
121      *            buf is NULL, the error string is placed in a static buffer
122      * @return the human-readable error messages.
123      */
124     public static native String ERR_error_string(NativeLong err, char[] null_);
125 
126     // TODO: NOT USED?
127     /**
128      * Registers the error strings for all libcrypto functions.
129      */
130     public static native void ERR_load_crypto_strings();
131 
132     /**
133      * @return the earliest error code from the thread's error queue without modifying it.
134      */
135     public static native NativeLong ERR_peek_error();
136 
137     /**
138      * @return an OpenSSL AES EVP cipher instance with a 128-bit key CBC mode
139      */
140     public static native PointerByReference EVP_aes_128_cbc();
141 
142     /**
143      * @return an OpenSSL AES EVP cipher instance with a 128-bit key CTR mode
144      */
145     public static native PointerByReference EVP_aes_128_ctr();
146 
147     /**
148      * @return an OpenSSL AES EVP cipher instance with a 192-bit key CBC mode
149      */
150     public static native PointerByReference EVP_aes_192_cbc();
151 
152     /**
153      * @return an OpenSSL AES EVP cipher instance with a 192-bit key CTR mode
154      */
155     public static native PointerByReference EVP_aes_192_ctr();
156 
157     /**
158      * @return an OpenSSL AES EVP cipher instance with a 256-bit key CBC mode
159      */
160     public static native PointerByReference EVP_aes_256_cbc();
161 
162     /**
163      * @return an OpenSSL AES EVP cipher instance with a 256-bit key CTR mode
164      */
165     public static native PointerByReference EVP_aes_256_ctr();
166 
167     /**
168      * Clears all information from a cipher context and free up any allocated * memory associate
169      * with it.
170      *
171      * @param c
172      *            openssl evp cipher
173      */
174     public static native void EVP_CIPHER_CTX_cleanup(PointerByReference c);
175 
176     /**
177      * Clears all information from a cipher context and free up any allocated memory associate with
178      * it, including ctx itself.
179      *
180      * @param c
181      *            openssl evp cipher
182      */
183     public static native void EVP_CIPHER_CTX_free(PointerByReference c);
184 
185     // TODO: NOT USED?
186     /**
187      * EVP_CIPHER_CTX_init() remains as an alias for EVP_CIPHER_CTX_reset
188      *
189      * @param p
190      *            cipher context
191      */
192     public static native void EVP_CIPHER_CTX_init(PointerByReference p);
193 
194     /**
195      * Creates a cipher context.
196      *
197      * @return a pointer to a newly created EVP_CIPHER_CTX for success and NULL for failure.
198      */
199     public static native PointerByReference EVP_CIPHER_CTX_new();
200 
201     /**
202      * Enables or disables padding
203      *
204      * @param c
205      *            cipher context
206      * @param pad
207      *            If the pad parameter is zero then no padding is performed
208      * @return always returns 1
209      */
210     public static native int EVP_CIPHER_CTX_set_padding(PointerByReference c, int pad);
211 
212     /**
213      * Finishes a multiple-part operation.
214      *
215      * @param ctx
216      *            cipher context
217      * @param bout
218      *            output byte buffer
219      * @param outl
220      *            output length
221      * @return 1 for success and 0 for failure.
222      */
223     public static native int EVP_CipherFinal_ex(PointerByReference ctx, ByteBuffer bout,
224             int[] outl);
225 
226     // ENGINE API: https://www.openssl.org/docs/man1.0.2/man3/engine.html
227 
228     /**
229      * Init a cipher.
230      *
231      * @param ctx
232      *            cipher context
233      * @param cipher
234      *            evp cipher instance
235      * @param impl
236      *            engine
237      * @param key
238      *            key
239      * @param iv
240      *            iv
241      * @param enc
242      *            1 for encryption, 0 for decryption
243      * @return 1 for success and 0 for failure.
244      */
245     public static native int EVP_CipherInit_ex(PointerByReference ctx, PointerByReference cipher,
246             PointerByReference impl, byte[] key, byte[] iv, int enc);
247 
248     /**
249      * Continues a multiple-part encryption/decryption operation.
250      *
251      * @param ctx
252      *            cipher context
253      * @param bout
254      *            output byte buffer
255      * @param outl
256      *            output length
257      * @param in
258      *            input byte buffer
259      * @param inl
260      *            input length
261      * @return 1 for success and 0 for failure.
262      */
263     public static native int EVP_CipherUpdate(PointerByReference ctx, ByteBuffer bout, int[] outl,
264             ByteBuffer in, int inl);
265 
266     /**
267      * Generates random data
268      *
269      * @param buf
270      *            the bytes for generated random.
271      * @param num
272      *            buffer length
273      * @return 1 on success, 0 otherwise.
274      */
275     public static native int RAND_bytes(ByteBuffer buf, int num);
276 
277     // Random generator
278     /**
279      * OpenSSL uses for random number generation
280      *
281      * @return pointers to the respective methods
282      */
283     public static native PointerByReference RAND_get_rand_method();
284 
285     /**
286      * OpenSSL uses for random number generation.
287      *
288      * @return pointers to the respective methods
289      */
290     public static native PointerByReference RAND_SSLeay();
291 
292     /**
293      * @see <a href="https://www.openssl.org/docs/man1.0.2/man3/SSLeay.html">Version Number</a>
294      * TODO (does not appear to be used yet)
295      * @return OPENSSL_VERSION_NUMBER which is a numeric release version identifier
296      */
297     public static native NativeLong SSLeay();
298 
299     /**
300      * Retrieves version/build information about OpenSSL library.
301      * This is returned by {@link OpenSslNativeJna#OpenSSLVersion(int)}
302      *
303      * @see <a href="https://www.openssl.org/docs/man1.0.2/man3/SSLeay_version.html">Version Info</a>
304      *
305      * @param type
306      *            type can be SSLEAY_VERSION, SSLEAY_CFLAGS, SSLEAY_BUILT_ON...
307      * @return A pointer to a constant string describing the version of the OpenSSL library or
308      *         giving information about the library build.
309      */
310     public static native String SSLeay_version(int type);
311 
312 
313     // ================== instance interface methods ==================
314 
315     @Override
316     public PointerByReference _ENGINE_by_id(final String string) {
317         return ENGINE_by_id(string);
318     }
319 
320     @Override
321     public int _ENGINE_cleanup() {
322         return ENGINE_cleanup();
323     }
324 
325     @Override
326     public int _ENGINE_finish(final PointerByReference rdrandEngine) {
327         return ENGINE_finish(rdrandEngine);
328     }
329 
330     @Override
331     public int _ENGINE_free(final PointerByReference rdrandEngine) {
332         return ENGINE_free(rdrandEngine);
333     }
334 
335     @Override
336     public int _ENGINE_init(final PointerByReference rdrandEngine) {
337         return ENGINE_init(rdrandEngine);
338     }
339 
340     @Override
341     public void _ENGINE_load_rdrand() {
342         ENGINE_load_rdrand();
343     }
344 
345     @Override
346     public int _ENGINE_set_default(final PointerByReference rdrandEngine, final int flags) {
347         return ENGINE_set_default(rdrandEngine, flags);
348     }
349 
350     @Override
351     public String _ERR_error_string(final NativeLong err, final char[] buff) {
352         return ERR_error_string(err, buff);
353     }
354 
355     @Override
356     public NativeLong _ERR_peek_error() {
357         return ERR_peek_error();
358     }
359 
360     @Override
361     public PointerByReference _EVP_aes_128_cbc() {
362         return EVP_aes_128_cbc();
363     }
364 
365     @Override
366     public PointerByReference _EVP_aes_128_ctr() {
367         return EVP_aes_128_ctr();
368     }
369 
370     @Override
371     public PointerByReference _EVP_aes_192_cbc() {
372         return EVP_aes_192_cbc();
373     }
374 
375     @Override
376     public PointerByReference _EVP_aes_192_ctr() {
377         return EVP_aes_192_ctr();
378     }
379 
380     @Override
381     public PointerByReference _EVP_aes_256_cbc() {
382         return EVP_aes_256_cbc();
383     }
384 
385     @Override
386     public PointerByReference _EVP_aes_256_ctr() {
387         return EVP_aes_256_ctr();
388     }
389 
390     @Override
391     public void _EVP_CIPHER_CTX_cleanup(final PointerByReference context) {
392         EVP_CIPHER_CTX_cleanup(context);
393     }
394 
395     @Override
396     public void _EVP_CIPHER_CTX_free(final PointerByReference context) {
397         EVP_CIPHER_CTX_free(context);
398     }
399 
400     @Override
401     public PointerByReference _EVP_CIPHER_CTX_new() {
402         return EVP_CIPHER_CTX_new();
403     }
404 
405     @Override
406     public int _EVP_CIPHER_CTX_set_padding(final PointerByReference context, final int padding) {
407         return EVP_CIPHER_CTX_set_padding(context, padding);
408     }
409 
410     @Override
411     public int _EVP_CipherFinal_ex(final PointerByReference context, final ByteBuffer outBuffer, final int[] outlen) {
412         return EVP_CipherFinal_ex(context, outBuffer, outlen);
413     }
414 
415     @Override
416     public int _EVP_CipherInit_ex(final PointerByReference context, final PointerByReference algo, final PointerByReference impl, final byte[] encoded,
417             final byte[] iv, final int cipherMode) {
418         return EVP_CipherInit_ex(context, algo, impl, encoded, iv, cipherMode);
419     }
420 
421     @Override
422     public int _EVP_CipherUpdate(final PointerByReference context, final ByteBuffer outBuffer, final int[] outlen, final ByteBuffer inBuffer,
423             final int remaining) {
424         return EVP_CipherUpdate(context, outBuffer, outlen, inBuffer, remaining);
425     }
426 
427     @Override
428     public Throwable _INIT_ERROR() {
429         return INIT_ERROR;
430     }
431 
432     @Override
433     public boolean _INIT_OK() {
434         return INIT_OK;
435     }
436 
437     @Override
438     public String _OpenSSL_version(final int i) {
439         return SSLeay_version(i);
440     }
441 
442     @Override
443     public int _RAND_bytes(final ByteBuffer buf, final int length) {
444         return RAND_bytes(buf, length) ;
445     }
446 
447     @Override
448     public PointerByReference _RAND_get_rand_method() {
449         return RAND_get_rand_method();
450     }
451 
452     @Override
453     public PointerByReference _RAND_SSLeay() {
454         return RAND_SSLeay();
455     }
456 }