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 }