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