Ruby: ext/openssl/ossl.c Source File

Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)

ossl.c
Go to the documentation of this file.
1/*
2 * 'OpenSSL for Ruby' project
3 * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
4 * All rights reserved.
5 */
6/*
7 * This program is licensed under the same licence as Ruby.
8 * (See the file 'LICENCE'.)
9 */
10#include "ossl.h"
11#include <stdarg.h> /* for ossl_raise */
12#include <ruby/thread_native.h> /* for OpenSSL < 1.1.0 locks */
13
14/*
15 * Data Conversion
16 */
17#define OSSL_IMPL_ARY2SK(name, type, expected_class, dup) \
18STACK_OF(type) * \
19ossl_##name##_ary2sk0(VALUE ary) \
20{ \
21 STACK_OF(type) *sk; \
22 VALUE val; \
23 type *x; \
24 int i; \
25 \
26 Check_Type(ary, T_ARRAY); \
27 sk = sk_##type##_new_null(); \
28 if (!sk) ossl_raise(eOSSLError, NULL); \
29 \
30 for (i = 0; i < RARRAY_LEN(ary); i++) { \
31 val = rb_ary_entry(ary, i); \
32 if (!rb_obj_is_kind_of(val, expected_class)) { \
33 sk_##type##_pop_free(sk, type##_free); \
34 ossl_raise(eOSSLError, "object in array not" \
35 " of class ##type##"); \
36 } \
37 x = dup(val); /* NEED TO DUP */ \
38 sk_##type##_push(sk, x); \
39 } \
40 return sk; \
41} \
42 \
43STACK_OF(type) * \
44ossl_protect_##name##_ary2sk(VALUE ary, int *status) \
45{ \
46 return (STACK_OF(type)*)rb_protect( \
47 (VALUE (*)(VALUE))ossl_##name##_ary2sk0, \
48 ary, \
49 status); \
50} \
51 \
52STACK_OF(type) * \
53ossl_##name##_ary2sk(VALUE ary) \
54{ \
55 STACK_OF(type) *sk; \
56 int status = 0; \
57 \
58 sk = ossl_protect_##name##_ary2sk(ary, &status); \
59 if (status) rb_jump_tag(status); \
60 \
61 return sk; \
62}
63 OSSL_IMPL_ARY2SK(x509, X509, cX509Cert, DupX509CertPtr)
64
65#define OSSL_IMPL_SK2ARY(name, type) \
66VALUE \
67ossl_##name##_sk2ary(const STACK_OF(type) *sk) \
68{ \
69 type *t; \
70 int i, num; \
71 VALUE ary; \
72 \
73 if (!sk) { \
74 OSSL_Debug("empty sk!"); \
75 return Qnil; \
76 } \
77 num = sk_##type##_num(sk); \
78 if (num < 0) { \
79 OSSL_Debug("items in sk < -1???"); \
80 return rb_ary_new(); \
81 } \
82 ary = rb_ary_new2(num); \
83 \
84 for (i=0; i<num; i++) { \
85 t = sk_##type##_value(sk, i); \
86 rb_ary_push(ary, ossl_##name##_new(t)); \
87 } \
88 return ary; \
89}
90 OSSL_IMPL_SK2ARY(x509, X509)
91 OSSL_IMPL_SK2ARY(x509crl, X509_CRL)
92 OSSL_IMPL_SK2ARY(x509name, X509_NAME)
93
94static VALUE
95ossl_str_new_i(VALUE size)
96{
97 return rb_str_new(NULL, (long)size);
98}
99
100 VALUE
101ossl_str_new(const char *ptr, long len, int *pstate)
102{
103 VALUE str;
104 int state;
105
106 str = rb_protect(ossl_str_new_i, len, &state);
107 if (pstate)
108 *pstate = state;
109 if (state) {
110 if (!pstate)
111 rb_set_errinfo(Qnil);
112 return Qnil;
113 }
114 if (ptr)
115 memcpy(RSTRING_PTR(str), ptr, len);
116 return str;
117}
118
119 VALUE
120ossl_buf2str(char *buf, int len)
121{
122 VALUE str;
123 int state;
124
125 str = ossl_str_new(buf, len, &state);
126 OPENSSL_free(buf);
127 if (state)
128 rb_jump_tag(state);
129 return str;
130}
131
132void
133ossl_bin2hex(unsigned char *in, char *out, size_t inlen)
134{
135 const char *hex = "0123456789abcdef";
136 size_t i;
137
138 assert(inlen <= LONG_MAX / 2);
139 for (i = 0; i < inlen; i++) {
140 unsigned char p = in[i];
141
142 out[i * 2 + 0] = hex[p >> 4];
143 out[i * 2 + 1] = hex[p & 0x0f];
144 }
145}
146
147/*
148 * our default PEM callback
149 */
150 VALUE
151ossl_pem_passwd_value(VALUE pass)
152{
153 if (NIL_P(pass))
154 return Qnil;
155
156 StringValue(pass);
157
158 /* PEM_BUFSIZE is currently used as the second argument of pem_password_cb,
159 * that is +max_len+ of ossl_pem_passwd_cb() */
160 if (RSTRING_LEN(pass) > PEM_BUFSIZE)
161 ossl_raise(eOSSLError, "password must not be longer than %d bytes", PEM_BUFSIZE);
162
163 return pass;
164}
165
166static VALUE
167ossl_pem_passwd_cb0(VALUE flag)
168{
169 VALUE pass = rb_yield(flag);
170 if (NIL_P(pass))
171 return Qnil;
172 StringValue(pass);
173 return pass;
174}
175
176int
177ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_)
178{
179 long len;
180 int status;
181 VALUE rflag, pass = (VALUE)pwd_;
182
183 if (RTEST(pass)) {
184 /* PEM_def_callback(buf, max_len, flag, StringValueCStr(pass)) does not
185 * work because it does not allow NUL characters and truncates to 1024
186 * bytes silently if the input is over 1024 bytes */
187 if (RB_TYPE_P(pass, T_STRING)) {
188 len = RSTRING_LEN(pass);
189 if (len <= max_len) {
190 memcpy(buf, RSTRING_PTR(pass), len);
191 return (int)len;
192 }
193 }
194 OSSL_Debug("passed data is not valid String???");
195 return -1;
196 }
197
198 if (!rb_block_given_p()) {
199 return PEM_def_callback(buf, max_len, flag, NULL);
200 }
201
202 while (1) {
203 /*
204 * when the flag is nonzero, this passphrase
205 * will be used to perform encryption; otherwise it will
206 * be used to perform decryption.
207 */
208 rflag = flag ? Qtrue : Qfalse;
209 pass = rb_protect(ossl_pem_passwd_cb0, rflag, &status);
210 if (status) {
211 /* ignore an exception raised. */
212 rb_set_errinfo(Qnil);
213 return -1;
214 }
215 if (NIL_P(pass))
216 return -1;
217 len = RSTRING_LEN(pass);
218 if (len > max_len) {
219 rb_warning("password must not be longer than %d bytes", max_len);
220 continue;
221 }
222 memcpy(buf, RSTRING_PTR(pass), len);
223 break;
224 }
225 return (int)len;
226}
227
228/*
229 * main module
230 */
231 VALUE mOSSL;
232
233/*
234 * OpenSSLError < StandardError
235 */
236 VALUE eOSSLError;
237
238/*
239 * Convert to DER string
240 */
241static ID ossl_s_to_der;
242
243 VALUE
244ossl_to_der(VALUE obj)
245{
246 VALUE tmp;
247
248 tmp = rb_funcall(obj, ossl_s_to_der, 0);
249 StringValue(tmp);
250
251 return tmp;
252}
253
254 VALUE
255ossl_to_der_if_possible(VALUE obj)
256{
257 if(rb_respond_to(obj, ossl_s_to_der))
258 return ossl_to_der(obj);
259 return obj;
260}
261
262/*
263 * Errors
264 */
265static VALUE
266ossl_make_error(VALUE exc, const char *fmt, va_list args)
267{
268 VALUE str = Qnil;
269 unsigned long e;
270
271 if (fmt) {
272 str = rb_vsprintf(fmt, args);
273 }
274 e = ERR_peek_last_error();
275 if (e) {
276 const char *msg = ERR_reason_error_string(e);
277
278 if (NIL_P(str)) {
279 if (msg) str = rb_str_new_cstr(msg);
280 }
281 else {
282 if (RSTRING_LEN(str)) rb_str_cat2(str, ": ");
283 rb_str_cat2(str, msg ? msg : "(null)");
284 }
285 ossl_clear_error();
286 }
287
288 if (NIL_P(str)) str = rb_str_new(0, 0);
289 return rb_exc_new3(exc, str);
290}
291
292void
293ossl_raise(VALUE exc, const char *fmt, ...)
294{
295 va_list args;
296 VALUE err;
297 va_start(args, fmt);
298 err = ossl_make_error(exc, fmt, args);
299 va_end(args);
300 rb_exc_raise(err);
301}
302
303void
304ossl_clear_error(void)
305{
306 if (dOSSL == Qtrue) {
307 unsigned long e;
308 const char *file, *data, *errstr;
309 int line, flags;
310
311 while ((e = ERR_get_error_line_data(&file, &line, &data, &flags))) {
312 errstr = ERR_error_string(e, NULL);
313 if (!errstr)
314 errstr = "(null)";
315
316 if (flags & ERR_TXT_STRING) {
317 if (!data)
318 data = "(null)";
319 rb_warn("error on stack: %s (%s)", errstr, data);
320 }
321 else {
322 rb_warn("error on stack: %s", errstr);
323 }
324 }
325 }
326 else {
327 ERR_clear_error();
328 }
329}
330
331/*
332 * call-seq:
333 * OpenSSL.errors -> [String...]
334 *
335 * See any remaining errors held in queue.
336 *
337 * Any errors you see here are probably due to a bug in Ruby's OpenSSL
338 * implementation.
339 */
340 VALUE
341ossl_get_errors(VALUE _)
342{
343 VALUE ary;
344 long e;
345
346 ary = rb_ary_new();
347 while ((e = ERR_get_error()) != 0){
348 rb_ary_push(ary, rb_str_new2(ERR_error_string(e, NULL)));
349 }
350
351 return ary;
352}
353
354/*
355 * Debug
356 */
357 VALUE dOSSL;
358
359#if !defined(HAVE_VA_ARGS_MACRO)
360void
361ossl_debug(const char *fmt, ...)
362{
363 va_list args;
364
365 if (dOSSL == Qtrue) {
366 fprintf(stderr, "OSSL_DEBUG: ");
367 va_start(args, fmt);
368 vfprintf(stderr, fmt, args);
369 va_end(args);
370 fprintf(stderr, " [CONTEXT N/A]\n");
371 }
372}
373#endif
374
375/*
376 * call-seq:
377 * OpenSSL.debug -> true | false
378 */
379static VALUE
380ossl_debug_get(VALUE self)
381{
382 return dOSSL;
383}
384
385/*
386 * call-seq:
387 * OpenSSL.debug = boolean -> boolean
388 *
389 * Turns on or off debug mode. With debug mode, all erros added to the OpenSSL
390 * error queue will be printed to stderr.
391 */
392static VALUE
393ossl_debug_set(VALUE self, VALUE val)
394{
395 dOSSL = RTEST(val) ? Qtrue : Qfalse;
396
397 return val;
398}
399
400/*
401 * call-seq:
402 * OpenSSL.fips_mode -> true | false
403 */
404static VALUE
405ossl_fips_mode_get(VALUE self)
406{
407
408#ifdef OPENSSL_FIPS
409 VALUE enabled;
410 enabled = FIPS_mode() ? Qtrue : Qfalse;
411 return enabled;
412#else
413 return Qfalse;
414#endif
415}
416
417/*
418 * call-seq:
419 * OpenSSL.fips_mode = boolean -> boolean
420 *
421 * Turns FIPS mode on or off. Turning on FIPS mode will obviously only have an
422 * effect for FIPS-capable installations of the OpenSSL library. Trying to do
423 * so otherwise will result in an error.
424 *
425 * === Examples
426 * OpenSSL.fips_mode = true # turn FIPS mode on
427 * OpenSSL.fips_mode = false # and off again
428 */
429static VALUE
430ossl_fips_mode_set(VALUE self, VALUE enabled)
431{
432
433#ifdef OPENSSL_FIPS
434 if (RTEST(enabled)) {
435 int mode = FIPS_mode();
436 if(!mode && !FIPS_mode_set(1)) /* turning on twice leads to an error */
437 ossl_raise(eOSSLError, "Turning on FIPS mode failed");
438 } else {
439 if(!FIPS_mode_set(0)) /* turning off twice is OK */
440 ossl_raise(eOSSLError, "Turning off FIPS mode failed");
441 }
442 return enabled;
443#else
444 if (RTEST(enabled))
445 ossl_raise(eOSSLError, "This version of OpenSSL does not support FIPS mode");
446 return enabled;
447#endif
448}
449
450#if defined(OSSL_DEBUG)
451#if !defined(LIBRESSL_VERSION_NUMBER) && \
452 (OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_NO_CRYPTO_MDEBUG) || \
453 defined(CRYPTO_malloc_debug_init))
454/*
455 * call-seq:
456 * OpenSSL.mem_check_start -> nil
457 *
458 * Calls CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON). Starts tracking memory
459 * allocations. See also OpenSSL.print_mem_leaks.
460 *
461 * This is available only when built with a capable OpenSSL and --enable-debug
462 * configure option.
463 */
464static VALUE
465mem_check_start(VALUE self)
466{
467 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
468 return Qnil;
469}
470
471/*
472 * call-seq:
473 * OpenSSL.print_mem_leaks -> true | false
474 *
475 * For debugging the Ruby/OpenSSL library. Calls CRYPTO_mem_leaks_fp(stderr).
476 * Prints detected memory leaks to standard error. This cleans the global state
477 * up thus you cannot use any methods of the library after calling this.
478 *
479 * Returns +true+ if leaks detected, +false+ otherwise.
480 *
481 * This is available only when built with a capable OpenSSL and --enable-debug
482 * configure option.
483 *
484 * === Example
485 * OpenSSL.mem_check_start
486 * NOT_GCED = OpenSSL::PKey::RSA.new(256)
487 *
488 * END {
489 * GC.start
490 * OpenSSL.print_mem_leaks # will print the leakage
491 * }
492 */
493static VALUE
494print_mem_leaks(VALUE self)
495{
496#if OPENSSL_VERSION_NUMBER >= 0x10100000
497 int ret;
498#endif
499
500#ifndef HAVE_RB_EXT_RACTOR_SAFE
501 // for Ruby 2.x
502 void ossl_bn_ctx_free(void); // ossl_bn.c
503 ossl_bn_ctx_free();
504#endif
505
506#if OPENSSL_VERSION_NUMBER >= 0x10100000
507 ret = CRYPTO_mem_leaks_fp(stderr);
508 if (ret < 0)
509 ossl_raise(eOSSLError, "CRYPTO_mem_leaks_fp");
510 return ret ? Qfalse : Qtrue;
511#else
512 CRYPTO_mem_leaks_fp(stderr);
513 return Qnil;
514#endif
515}
516#endif
517#endif
518
519#if !defined(HAVE_OPENSSL_110_THREADING_API)
523 struct CRYPTO_dynlock_value {
524 rb_nativethread_lock_t lock;
525 rb_nativethread_id_t owner;
526 size_t count;
527};
528
529static void
530ossl_lock_init(struct CRYPTO_dynlock_value *l)
531{
532 rb_nativethread_lock_initialize(&l->lock);
533 l->count = 0;
534}
535
536static void
537ossl_lock_unlock(int mode, struct CRYPTO_dynlock_value *l)
538{
539 if (mode & CRYPTO_LOCK) {
540 /* TODO: rb_nativethread_id_t is not necessarily compared with ==. */
541 rb_nativethread_id_t tid = rb_nativethread_self();
542 if (l->count && l->owner == tid) {
543 l->count++;
544 return;
545 }
546 rb_nativethread_lock_lock(&l->lock);
547 l->owner = tid;
548 l->count = 1;
549 } else {
550 if (!--l->count)
551 rb_nativethread_lock_unlock(&l->lock);
552 }
553}
554
555static struct CRYPTO_dynlock_value *
556ossl_dyn_create_callback(const char *file, int line)
557{
558 /* Do not use xmalloc() here, since it may raise NoMemoryError */
559 struct CRYPTO_dynlock_value *dynlock =
560 OPENSSL_malloc(sizeof(struct CRYPTO_dynlock_value));
561 if (dynlock)
562 ossl_lock_init(dynlock);
563 return dynlock;
564}
565
566static void
567ossl_dyn_lock_callback(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)
568{
569 ossl_lock_unlock(mode, l);
570}
571
572static void
573ossl_dyn_destroy_callback(struct CRYPTO_dynlock_value *l, const char *file, int line)
574{
575 rb_nativethread_lock_destroy(&l->lock);
576 OPENSSL_free(l);
577}
578
579static void ossl_threadid_func(CRYPTO_THREADID *id)
580{
581 /* register native thread id */
582 CRYPTO_THREADID_set_pointer(id, (void *)rb_nativethread_self());
583}
584
585static struct CRYPTO_dynlock_value *ossl_locks;
586
587static void
588ossl_lock_callback(int mode, int type, const char *file, int line)
589{
590 ossl_lock_unlock(mode, &ossl_locks[type]);
591}
592
593static void Init_ossl_locks(void)
594{
595 int i;
596 int num_locks = CRYPTO_num_locks();
597
598 ossl_locks = ALLOC_N(struct CRYPTO_dynlock_value, num_locks);
599 for (i = 0; i < num_locks; i++)
600 ossl_lock_init(&ossl_locks[i]);
601
602 CRYPTO_THREADID_set_callback(ossl_threadid_func);
603 CRYPTO_set_locking_callback(ossl_lock_callback);
604 CRYPTO_set_dynlock_create_callback(ossl_dyn_create_callback);
605 CRYPTO_set_dynlock_lock_callback(ossl_dyn_lock_callback);
606 CRYPTO_set_dynlock_destroy_callback(ossl_dyn_destroy_callback);
607}
608#endif /* !HAVE_OPENSSL_110_THREADING_API */
609
610/*
611 * call-seq:
612 * OpenSSL.fixed_length_secure_compare(string, string) -> boolean
613 *
614 * Constant time memory comparison for fixed length strings, such as results
615 * of HMAC calculations.
616 *
617 * Returns +true+ if the strings are identical, +false+ if they are of the same
618 * length but not identical. If the length is different, +ArgumentError+ is
619 * raised.
620 */
621static VALUE
622ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
623{
624 const unsigned char *p1 = (const unsigned char *)StringValuePtr(str1);
625 const unsigned char *p2 = (const unsigned char *)StringValuePtr(str2);
626 long len1 = RSTRING_LEN(str1);
627 long len2 = RSTRING_LEN(str2);
628
629 if (len1 != len2) {
630 ossl_raise(rb_eArgError, "inputs must be of equal length");
631 }
632
633 switch (CRYPTO_memcmp(p1, p2, len1)) {
634 case 0: return Qtrue;
635 default: return Qfalse;
636 }
637}
638
639/*
640 * OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the
641 * OpenSSL[https://www.openssl.org/] library.
642 *
643 * = Examples
644 *
645 * All examples assume you have loaded OpenSSL with:
646 *
647 * require 'openssl'
648 *
649 * These examples build atop each other. For example the key created in the
650 * next is used in throughout these examples.
651 *
652 * == Keys
653 *
654 * === Creating a Key
655 *
656 * This example creates a 2048 bit RSA keypair and writes it to the current
657 * directory.
658 *
659 * key = OpenSSL::PKey::RSA.new 2048
660 *
661 * open 'private_key.pem', 'w' do |io| io.write key.to_pem end
662 * open 'public_key.pem', 'w' do |io| io.write key.public_key.to_pem end
663 *
664 * === Exporting a Key
665 *
666 * Keys saved to disk without encryption are not secure as anyone who gets
667 * ahold of the key may use it unless it is encrypted. In order to securely
668 * export a key you may export it with a pass phrase.
669 *
670 * cipher = OpenSSL::Cipher.new 'AES-256-CBC'
671 * pass_phrase = 'my secure pass phrase goes here'
672 *
673 * key_secure = key.export cipher, pass_phrase
674 *
675 * open 'private.secure.pem', 'w' do |io|
676 * io.write key_secure
677 * end
678 *
679 * OpenSSL::Cipher.ciphers returns a list of available ciphers.
680 *
681 * === Loading a Key
682 *
683 * A key can also be loaded from a file.
684 *
685 * key2 = OpenSSL::PKey::RSA.new File.read 'private_key.pem'
686 * key2.public? # => true
687 * key2.private? # => true
688 *
689 * or
690 *
691 * key3 = OpenSSL::PKey::RSA.new File.read 'public_key.pem'
692 * key3.public? # => true
693 * key3.private? # => false
694 *
695 * === Loading an Encrypted Key
696 *
697 * OpenSSL will prompt you for your pass phrase when loading an encrypted key.
698 * If you will not be able to type in the pass phrase you may provide it when
699 * loading the key:
700 *
701 * key4_pem = File.read 'private.secure.pem'
702 * pass_phrase = 'my secure pass phrase goes here'
703 * key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase
704 *
705 * == RSA Encryption
706 *
707 * RSA provides encryption and decryption using the public and private keys.
708 * You can use a variety of padding methods depending upon the intended use of
709 * encrypted data.
710 *
711 * === Encryption & Decryption
712 *
713 * Asymmetric public/private key encryption is slow and victim to attack in
714 * cases where it is used without padding or directly to encrypt larger chunks
715 * of data. Typical use cases for RSA encryption involve "wrapping" a symmetric
716 * key with the public key of the recipient who would "unwrap" that symmetric
717 * key again using their private key.
718 * The following illustrates a simplified example of such a key transport
719 * scheme. It shouldn't be used in practice, though, standardized protocols
720 * should always be preferred.
721 *
722 * wrapped_key = key.public_encrypt key
723 *
724 * A symmetric key encrypted with the public key can only be decrypted with
725 * the corresponding private key of the recipient.
726 *
727 * original_key = key.private_decrypt wrapped_key
728 *
729 * By default PKCS#1 padding will be used, but it is also possible to use
730 * other forms of padding, see PKey::RSA for further details.
731 *
732 * === Signatures
733 *
734 * Using "private_encrypt" to encrypt some data with the private key is
735 * equivalent to applying a digital signature to the data. A verifying
736 * party may validate the signature by comparing the result of decrypting
737 * the signature with "public_decrypt" to the original data. However,
738 * OpenSSL::PKey already has methods "sign" and "verify" that handle
739 * digital signatures in a standardized way - "private_encrypt" and
740 * "public_decrypt" shouldn't be used in practice.
741 *
742 * To sign a document, a cryptographically secure hash of the document is
743 * computed first, which is then signed using the private key.
744 *
745 * signature = key.sign 'SHA256', document
746 *
747 * To validate the signature, again a hash of the document is computed and
748 * the signature is decrypted using the public key. The result is then
749 * compared to the hash just computed, if they are equal the signature was
750 * valid.
751 *
752 * if key.verify 'SHA256', signature, document
753 * puts 'Valid'
754 * else
755 * puts 'Invalid'
756 * end
757 *
758 * == PBKDF2 Password-based Encryption
759 *
760 * If supported by the underlying OpenSSL version used, Password-based
761 * Encryption should use the features of PKCS5. If not supported or if
762 * required by legacy applications, the older, less secure methods specified
763 * in RFC 2898 are also supported (see below).
764 *
765 * PKCS5 supports PBKDF2 as it was specified in PKCS#5
766 * v2.0[http://www.rsa.com/rsalabs/node.asp?id=2127]. It still uses a
767 * password, a salt, and additionally a number of iterations that will
768 * slow the key derivation process down. The slower this is, the more work
769 * it requires being able to brute-force the resulting key.
770 *
771 * === Encryption
772 *
773 * The strategy is to first instantiate a Cipher for encryption, and
774 * then to generate a random IV plus a key derived from the password
775 * using PBKDF2. PKCS #5 v2.0 recommends at least 8 bytes for the salt,
776 * the number of iterations largely depends on the hardware being used.
777 *
778 * cipher = OpenSSL::Cipher.new 'AES-256-CBC'
779 * cipher.encrypt
780 * iv = cipher.random_iv
781 *
782 * pwd = 'some hopefully not to easily guessable password'
783 * salt = OpenSSL::Random.random_bytes 16
784 * iter = 20000
785 * key_len = cipher.key_len
786 * digest = OpenSSL::Digest.new('SHA256')
787 *
788 * key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
789 * cipher.key = key
790 *
791 * Now encrypt the data:
792 *
793 * encrypted = cipher.update document
794 * encrypted << cipher.final
795 *
796 * === Decryption
797 *
798 * Use the same steps as before to derive the symmetric AES key, this time
799 * setting the Cipher up for decryption.
800 *
801 * cipher = OpenSSL::Cipher.new 'AES-256-CBC'
802 * cipher.decrypt
803 * cipher.iv = iv # the one generated with #random_iv
804 *
805 * pwd = 'some hopefully not to easily guessable password'
806 * salt = ... # the one generated above
807 * iter = 20000
808 * key_len = cipher.key_len
809 * digest = OpenSSL::Digest.new('SHA256')
810 *
811 * key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
812 * cipher.key = key
813 *
814 * Now decrypt the data:
815 *
816 * decrypted = cipher.update encrypted
817 * decrypted << cipher.final
818 *
819 * == PKCS #5 Password-based Encryption
820 *
821 * PKCS #5 is a password-based encryption standard documented at
822 * RFC2898[http://www.ietf.org/rfc/rfc2898.txt]. It allows a short password or
823 * passphrase to be used to create a secure encryption key. If possible, PBKDF2
824 * as described above should be used if the circumstances allow it.
825 *
826 * PKCS #5 uses a Cipher, a pass phrase and a salt to generate an encryption
827 * key.
828 *
829 * pass_phrase = 'my secure pass phrase goes here'
830 * salt = '8 octets'
831 *
832 * === Encryption
833 *
834 * First set up the cipher for encryption
835 *
836 * encryptor = OpenSSL::Cipher.new 'AES-256-CBC'
837 * encryptor.encrypt
838 * encryptor.pkcs5_keyivgen pass_phrase, salt
839 *
840 * Then pass the data you want to encrypt through
841 *
842 * encrypted = encryptor.update 'top secret document'
843 * encrypted << encryptor.final
844 *
845 * === Decryption
846 *
847 * Use a new Cipher instance set up for decryption
848 *
849 * decryptor = OpenSSL::Cipher.new 'AES-256-CBC'
850 * decryptor.decrypt
851 * decryptor.pkcs5_keyivgen pass_phrase, salt
852 *
853 * Then pass the data you want to decrypt through
854 *
855 * plain = decryptor.update encrypted
856 * plain << decryptor.final
857 *
858 * == X509 Certificates
859 *
860 * === Creating a Certificate
861 *
862 * This example creates a self-signed certificate using an RSA key and a SHA1
863 * signature.
864 *
865 * key = OpenSSL::PKey::RSA.new 2048
866 * name = OpenSSL::X509::Name.parse '/CN=nobody/DC=example'
867 *
868 * cert = OpenSSL::X509::Certificate.new
869 * cert.version = 2
870 * cert.serial = 0
871 * cert.not_before = Time.now
872 * cert.not_after = Time.now + 3600
873 *
874 * cert.public_key = key.public_key
875 * cert.subject = name
876 *
877 * === Certificate Extensions
878 *
879 * You can add extensions to the certificate with
880 * OpenSSL::SSL::ExtensionFactory to indicate the purpose of the certificate.
881 *
882 * extension_factory = OpenSSL::X509::ExtensionFactory.new nil, cert
883 *
884 * cert.add_extension \
885 * extension_factory.create_extension('basicConstraints', 'CA:FALSE', true)
886 *
887 * cert.add_extension \
888 * extension_factory.create_extension(
889 * 'keyUsage', 'keyEncipherment,dataEncipherment,digitalSignature')
890 *
891 * cert.add_extension \
892 * extension_factory.create_extension('subjectKeyIdentifier', 'hash')
893 *
894 * The list of supported extensions (and in some cases their possible values)
895 * can be derived from the "objects.h" file in the OpenSSL source code.
896 *
897 * === Signing a Certificate
898 *
899 * To sign a certificate set the issuer and use OpenSSL::X509::Certificate#sign
900 * with a digest algorithm. This creates a self-signed cert because we're using
901 * the same name and key to sign the certificate as was used to create the
902 * certificate.
903 *
904 * cert.issuer = name
905 * cert.sign key, OpenSSL::Digest.new('SHA1')
906 *
907 * open 'certificate.pem', 'w' do |io| io.write cert.to_pem end
908 *
909 * === Loading a Certificate
910 *
911 * Like a key, a cert can also be loaded from a file.
912 *
913 * cert2 = OpenSSL::X509::Certificate.new File.read 'certificate.pem'
914 *
915 * === Verifying a Certificate
916 *
917 * Certificate#verify will return true when a certificate was signed with the
918 * given public key.
919 *
920 * raise 'certificate can not be verified' unless cert2.verify key
921 *
922 * == Certificate Authority
923 *
924 * A certificate authority (CA) is a trusted third party that allows you to
925 * verify the ownership of unknown certificates. The CA issues key signatures
926 * that indicate it trusts the user of that key. A user encountering the key
927 * can verify the signature by using the CA's public key.
928 *
929 * === CA Key
930 *
931 * CA keys are valuable, so we encrypt and save it to disk and make sure it is
932 * not readable by other users.
933 *
934 * ca_key = OpenSSL::PKey::RSA.new 2048
935 * pass_phrase = 'my secure pass phrase goes here'
936 *
937 * cipher = OpenSSL::Cipher.new 'AES-256-CBC'
938 *
939 * open 'ca_key.pem', 'w', 0400 do |io|
940 * io.write ca_key.export(cipher, pass_phrase)
941 * end
942 *
943 * === CA Certificate
944 *
945 * A CA certificate is created the same way we created a certificate above, but
946 * with different extensions.
947 *
948 * ca_name = OpenSSL::X509::Name.parse '/CN=ca/DC=example'
949 *
950 * ca_cert = OpenSSL::X509::Certificate.new
951 * ca_cert.serial = 0
952 * ca_cert.version = 2
953 * ca_cert.not_before = Time.now
954 * ca_cert.not_after = Time.now + 86400
955 *
956 * ca_cert.public_key = ca_key.public_key
957 * ca_cert.subject = ca_name
958 * ca_cert.issuer = ca_name
959 *
960 * extension_factory = OpenSSL::X509::ExtensionFactory.new
961 * extension_factory.subject_certificate = ca_cert
962 * extension_factory.issuer_certificate = ca_cert
963 *
964 * ca_cert.add_extension \
965 * extension_factory.create_extension('subjectKeyIdentifier', 'hash')
966 *
967 * This extension indicates the CA's key may be used as a CA.
968 *
969 * ca_cert.add_extension \
970 * extension_factory.create_extension('basicConstraints', 'CA:TRUE', true)
971 *
972 * This extension indicates the CA's key may be used to verify signatures on
973 * both certificates and certificate revocations.
974 *
975 * ca_cert.add_extension \
976 * extension_factory.create_extension(
977 * 'keyUsage', 'cRLSign,keyCertSign', true)
978 *
979 * Root CA certificates are self-signed.
980 *
981 * ca_cert.sign ca_key, OpenSSL::Digest.new('SHA1')
982 *
983 * The CA certificate is saved to disk so it may be distributed to all the
984 * users of the keys this CA will sign.
985 *
986 * open 'ca_cert.pem', 'w' do |io|
987 * io.write ca_cert.to_pem
988 * end
989 *
990 * === Certificate Signing Request
991 *
992 * The CA signs keys through a Certificate Signing Request (CSR). The CSR
993 * contains the information necessary to identify the key.
994 *
995 * csr = OpenSSL::X509::Request.new
996 * csr.version = 0
997 * csr.subject = name
998 * csr.public_key = key.public_key
999 * csr.sign key, OpenSSL::Digest.new('SHA1')
1000 *
1001 * A CSR is saved to disk and sent to the CA for signing.
1002 *
1003 * open 'csr.pem', 'w' do |io|
1004 * io.write csr.to_pem
1005 * end
1006 *
1007 * === Creating a Certificate from a CSR
1008 *
1009 * Upon receiving a CSR the CA will verify it before signing it. A minimal
1010 * verification would be to check the CSR's signature.
1011 *
1012 * csr = OpenSSL::X509::Request.new File.read 'csr.pem'
1013 *
1014 * raise 'CSR can not be verified' unless csr.verify csr.public_key
1015 *
1016 * After verification a certificate is created, marked for various usages,
1017 * signed with the CA key and returned to the requester.
1018 *
1019 * csr_cert = OpenSSL::X509::Certificate.new
1020 * csr_cert.serial = 0
1021 * csr_cert.version = 2
1022 * csr_cert.not_before = Time.now
1023 * csr_cert.not_after = Time.now + 600
1024 *
1025 * csr_cert.subject = csr.subject
1026 * csr_cert.public_key = csr.public_key
1027 * csr_cert.issuer = ca_cert.subject
1028 *
1029 * extension_factory = OpenSSL::X509::ExtensionFactory.new
1030 * extension_factory.subject_certificate = csr_cert
1031 * extension_factory.issuer_certificate = ca_cert
1032 *
1033 * csr_cert.add_extension \
1034 * extension_factory.create_extension('basicConstraints', 'CA:FALSE')
1035 *
1036 * csr_cert.add_extension \
1037 * extension_factory.create_extension(
1038 * 'keyUsage', 'keyEncipherment,dataEncipherment,digitalSignature')
1039 *
1040 * csr_cert.add_extension \
1041 * extension_factory.create_extension('subjectKeyIdentifier', 'hash')
1042 *
1043 * csr_cert.sign ca_key, OpenSSL::Digest.new('SHA1')
1044 *
1045 * open 'csr_cert.pem', 'w' do |io|
1046 * io.write csr_cert.to_pem
1047 * end
1048 *
1049 * == SSL and TLS Connections
1050 *
1051 * Using our created key and certificate we can create an SSL or TLS connection.
1052 * An SSLContext is used to set up an SSL session.
1053 *
1054 * context = OpenSSL::SSL::SSLContext.new
1055 *
1056 * === SSL Server
1057 *
1058 * An SSL server requires the certificate and private key to communicate
1059 * securely with its clients:
1060 *
1061 * context.cert = cert
1062 * context.key = key
1063 *
1064 * Then create an SSLServer with a TCP server socket and the context. Use the
1065 * SSLServer like an ordinary TCP server.
1066 *
1067 * require 'socket'
1068 *
1069 * tcp_server = TCPServer.new 5000
1070 * ssl_server = OpenSSL::SSL::SSLServer.new tcp_server, context
1071 *
1072 * loop do
1073 * ssl_connection = ssl_server.accept
1074 *
1075 * data = connection.gets
1076 *
1077 * response = "I got #{data.dump}"
1078 * puts response
1079 *
1080 * connection.puts "I got #{data.dump}"
1081 * connection.close
1082 * end
1083 *
1084 * === SSL client
1085 *
1086 * An SSL client is created with a TCP socket and the context.
1087 * SSLSocket#connect must be called to initiate the SSL handshake and start
1088 * encryption. A key and certificate are not required for the client socket.
1089 *
1090 * Note that SSLSocket#close doesn't close the underlying socket by default. Set
1091 * SSLSocket#sync_close to true if you want.
1092 *
1093 * require 'socket'
1094 *
1095 * tcp_socket = TCPSocket.new 'localhost', 5000
1096 * ssl_client = OpenSSL::SSL::SSLSocket.new tcp_socket, context
1097 * ssl_client.sync_close = true
1098 * ssl_client.connect
1099 *
1100 * ssl_client.puts "hello server!"
1101 * puts ssl_client.gets
1102 *
1103 * ssl_client.close # shutdown the TLS connection and close tcp_socket
1104 *
1105 * === Peer Verification
1106 *
1107 * An unverified SSL connection does not provide much security. For enhanced
1108 * security the client or server can verify the certificate of its peer.
1109 *
1110 * The client can be modified to verify the server's certificate against the
1111 * certificate authority's certificate:
1112 *
1113 * context.ca_file = 'ca_cert.pem'
1114 * context.verify_mode = OpenSSL::SSL::VERIFY_PEER
1115 *
1116 * require 'socket'
1117 *
1118 * tcp_socket = TCPSocket.new 'localhost', 5000
1119 * ssl_client = OpenSSL::SSL::SSLSocket.new tcp_socket, context
1120 * ssl_client.connect
1121 *
1122 * ssl_client.puts "hello server!"
1123 * puts ssl_client.gets
1124 *
1125 * If the server certificate is invalid or <tt>context.ca_file</tt> is not set
1126 * when verifying peers an OpenSSL::SSL::SSLError will be raised.
1127 *
1128 */
1129void
1130Init_openssl(void)
1131{
1132#if HAVE_RB_EXT_RACTOR_SAFE
1133 rb_ext_ractor_safe(true);
1134#endif
1135
1136#undef rb_intern
1137 /*
1138 * Init timezone info
1139 */
1140#if 0
1141 tzset();
1142#endif
1143
1144 /*
1145 * Init all digests, ciphers
1146 */
1147#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
1148 if (!OPENSSL_init_ssl(0, NULL))
1149 rb_raise(rb_eRuntimeError, "OPENSSL_init_ssl");
1150#else
1151 OpenSSL_add_ssl_algorithms();
1152 OpenSSL_add_all_algorithms();
1153 ERR_load_crypto_strings();
1154 SSL_load_error_strings();
1155#endif
1156
1157 /*
1158 * Init main module
1159 */
1160 mOSSL = rb_define_module("OpenSSL");
1161 rb_global_variable(&mOSSL);
1162 rb_define_singleton_method(mOSSL, "fixed_length_secure_compare", ossl_crypto_fixed_length_secure_compare, 2);
1163
1164 /*
1165 * Version of OpenSSL the ruby OpenSSL extension was built with
1166 */
1167 rb_define_const(mOSSL, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
1168
1169 /*
1170 * Version of OpenSSL the ruby OpenSSL extension is running with
1171 */
1172#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
1173 rb_define_const(mOSSL, "OPENSSL_LIBRARY_VERSION", rb_str_new2(OpenSSL_version(OPENSSL_VERSION)));
1174#else
1175 rb_define_const(mOSSL, "OPENSSL_LIBRARY_VERSION", rb_str_new2(SSLeay_version(SSLEAY_VERSION)));
1176#endif
1177
1178 /*
1179 * Version number of OpenSSL the ruby OpenSSL extension was built with
1180 * (base 16)
1181 */
1182 rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER));
1183
1184 /*
1185 * Boolean indicating whether OpenSSL is FIPS-capable or not
1186 */
1187 rb_define_const(mOSSL, "OPENSSL_FIPS",
1188#ifdef OPENSSL_FIPS
1189 Qtrue
1190#else
1191 Qfalse
1192#endif
1193 );
1194
1195 rb_define_module_function(mOSSL, "fips_mode", ossl_fips_mode_get, 0);
1196 rb_define_module_function(mOSSL, "fips_mode=", ossl_fips_mode_set, 1);
1197
1198 /*
1199 * Generic error,
1200 * common for all classes under OpenSSL module
1201 */
1202 eOSSLError = rb_define_class_under(mOSSL,"OpenSSLError",rb_eStandardError);
1203 rb_global_variable(&eOSSLError);
1204
1205 /*
1206 * Init debug core
1207 */
1208 dOSSL = Qfalse;
1209 rb_global_variable(&dOSSL);
1210
1211 rb_define_module_function(mOSSL, "debug", ossl_debug_get, 0);
1212 rb_define_module_function(mOSSL, "debug=", ossl_debug_set, 1);
1213 rb_define_module_function(mOSSL, "errors", ossl_get_errors, 0);
1214
1215 /*
1216 * Get ID of to_der
1217 */
1218 ossl_s_to_der = rb_intern("to_der");
1219
1220#if !defined(HAVE_OPENSSL_110_THREADING_API)
1221 Init_ossl_locks();
1222#endif
1223
1224 /*
1225 * Init components
1226 */
1227 Init_ossl_bn();
1228 Init_ossl_cipher();
1229 Init_ossl_config();
1230 Init_ossl_digest();
1231 Init_ossl_hmac();
1232 Init_ossl_ns_spki();
1233 Init_ossl_pkcs12();
1234 Init_ossl_pkcs7();
1235 Init_ossl_pkey();
1236 Init_ossl_rand();
1237 Init_ossl_ssl();
1238#ifndef OPENSSL_NO_TS
1239 Init_ossl_ts();
1240#endif
1241 Init_ossl_x509();
1242 Init_ossl_ocsp();
1243 Init_ossl_engine();
1244 Init_ossl_asn1();
1245 Init_ossl_kdf();
1246
1247#if defined(OSSL_DEBUG)
1248 /*
1249 * For debugging Ruby/OpenSSL. Enable only when built with --enable-debug
1250 */
1251#if !defined(LIBRESSL_VERSION_NUMBER) && \
1252 (OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_NO_CRYPTO_MDEBUG) || \
1253 defined(CRYPTO_malloc_debug_init))
1254 rb_define_module_function(mOSSL, "mem_check_start", mem_check_start, 0);
1255 rb_define_module_function(mOSSL, "print_mem_leaks", print_mem_leaks, 0);
1256
1257#if defined(CRYPTO_malloc_debug_init) /* <= 1.0.2 */
1258 CRYPTO_malloc_debug_init();
1259#endif
1260
1261#if defined(V_CRYPTO_MDEBUG_ALL) /* <= 1.0.2 */
1262 CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
1263#endif
1264
1265#if OPENSSL_VERSION_NUMBER < 0x10100000 /* <= 1.0.2 */
1266 {
1267 int i;
1268 /*
1269 * See crypto/ex_data.c; call def_get_class() immediately to avoid
1270 * allocations. 15 is the maximum number that is used as the class index
1271 * in OpenSSL 1.0.2.
1272 */
1273 for (i = 0; i <= 15; i++) {
1274 if (CRYPTO_get_ex_new_index(i, 0, (void *)"ossl-mdebug-dummy", 0, 0, 0) < 0)
1275 rb_raise(rb_eRuntimeError, "CRYPTO_get_ex_new_index for "
1276 "class index %d failed", i);
1277 }
1278 }
1279#endif
1280#endif
1281#endif
1282}
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:1301
rb_ary_new
VALUE rb_ary_new(void)
Definition: array.c:749
rb_define_singleton_method
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
Definition: cxxanyargs.hpp:668
rb_define_module_function
#define rb_define_module_function(klass, mid, func, arity)
Defines klass#mid and makes it a module function.
Definition: cxxanyargs.hpp:672
ptr
struct RIMemo * ptr
Definition: debug.c:88
assert
#define assert(x)
Definition: dlmalloc.c:1176
out
string_t out
Definition: enough.c:230
len
uint8_t len
Definition: escape.c:17
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
RSTRING_LEN
#define RSTRING_LEN(string)
Definition: fbuffer.h:22
RSTRING_PTR
#define RSTRING_PTR(string)
Definition: fbuffer.h:19
memcpy
#define memcpy(d, s, n)
Definition: ffi_common.h:55
rb_define_class_under
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:797
rb_define_module
VALUE rb_define_module(const char *name)
Definition: class.c:871
rb_block_given_p
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:935
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2917
rb_exc_raise
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
Definition: eval.c:712
rb_eStandardError
VALUE rb_eStandardError
Definition: error.c:1054
rb_set_errinfo
void rb_set_errinfo(VALUE err)
Sets the current exception ($!) to the given value.
Definition: eval.c:1925
rb_protect
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *pstate)
Protects a function call from potential global escapes from the function.
Definition: eval.c:1105
rb_eRuntimeError
VALUE rb_eRuntimeError
Definition: error.c:1055
rb_warn
void rb_warn(const char *fmt,...)
Definition: error.c:408
rb_eArgError
VALUE rb_eArgError
Definition: error.c:1058
rb_jump_tag
void rb_jump_tag(int tag)
Continues the exception caught by rb_protect() and rb_eval_string_protect().
Definition: eval.c:921
rb_warning
void rb_warning(const char *fmt,...)
Definition: error.c:439
in
unsigned in(void *in_desc, z_const unsigned char **buf)
Definition: gun.c:89
rb_funcall
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:1077
rb_exc_new3
#define rb_exc_new3
Definition: error.h:31
rb_ext_ractor_safe
void rb_ext_ractor_safe(bool flag)
Definition: load.c:1058
rb_str_new2
#define rb_str_new2
Definition: string.h:276
rb_str_cat2
#define rb_str_cat2
Definition: string.h:285
rb_str_new
#define rb_str_new(str, len)
Definition: string.h:213
rb_str_new_cstr
#define rb_str_new_cstr(str)
Definition: string.h:219
rb_respond_to
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:2561
rb_intern
ID rb_intern(const char *)
Definition: symbol.c:785
rb_define_const
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:3150
INT2NUM
#define INT2NUM
Definition: int.h:43
size
voidpf void uLong size
Definition: ioapi.h:138
mode
const char int mode
Definition: ioapi.h:137
buf
voidpf void * buf
Definition: ioapi.h:138
rb_yield
VALUE rb_yield(VALUE)
Definition: vm_eval.c:1341
LONG_MAX
#define LONG_MAX
Definition: limits.h:36
ALLOC_N
#define ALLOC_N
Definition: memory.h:133
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:56
ossl_bin2hex
void ossl_bin2hex(unsigned char *in, char *out, size_t inlen)
Definition: ossl.c:133
mOSSL
VALUE mOSSL
Definition: ossl.c:231
ossl_pem_passwd_cb
int ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_)
Definition: ossl.c:177
ossl_get_errors
VALUE ossl_get_errors(VALUE _)
Definition: ossl.c:341
Init_openssl
void Init_openssl(void)
Definition: ossl.c:1130
OSSL_IMPL_ARY2SK
#define OSSL_IMPL_ARY2SK(name, type, expected_class, dup)
Definition: ossl.c:17
dOSSL
VALUE dOSSL
Definition: ossl.c:357
ossl_buf2str
VALUE ossl_buf2str(char *buf, int len)
Definition: ossl.c:120
ossl_str_new
VALUE ossl_str_new(const char *ptr, long len, int *pstate)
Definition: ossl.c:101
OSSL_IMPL_SK2ARY
#define OSSL_IMPL_SK2ARY(name, type)
Definition: ossl.c:65
ossl_pem_passwd_value
VALUE ossl_pem_passwd_value(VALUE pass)
Definition: ossl.c:151
ossl_to_der
VALUE ossl_to_der(VALUE obj)
Definition: ossl.c:244
ossl_to_der_if_possible
VALUE ossl_to_der_if_possible(VALUE obj)
Definition: ossl.c:255
ossl_raise
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:293
eOSSLError
VALUE eOSSLError
Definition: ossl.c:236
ossl_clear_error
void ossl_clear_error(void)
Definition: ossl.c:304
ossl.h
OSSL_Debug
#define OSSL_Debug(...)
Definition: ossl.h:140
Init_ossl_asn1
void Init_ossl_asn1(void)
Definition: ossl_asn1.c:1385
ossl_bn_ctx_free
void ossl_bn_ctx_free(void)
Definition: ossl_bn.c:203
Init_ossl_bn
void Init_ossl_bn(void)
Definition: ossl_bn.c:1148
Init_ossl_cipher
void Init_ossl_cipher(void)
Definition: ossl_cipher.c:845
Init_ossl_config
void Init_ossl_config(void)
Definition: ossl_config.c:72
Init_ossl_digest
void Init_ossl_digest(void)
Definition: ossl_digest.c:314
Init_ossl_engine
void Init_ossl_engine(void)
Definition: ossl_engine.c:519
Init_ossl_hmac
void Init_ossl_hmac(void)
Definition: ossl_hmac.c:327
Init_ossl_kdf
void Init_ossl_kdf(void)
Definition: ossl_kdf.c:236
Init_ossl_ns_spki
void Init_ossl_ns_spki(void)
Definition: ossl_ns_spki.c:379
Init_ossl_ocsp
void Init_ossl_ocsp(void)
Definition: ossl_ocsp.c:1699
Init_ossl_pkcs12
void Init_ossl_pkcs12(void)
Definition: ossl_pkcs12.c:233
Init_ossl_pkcs7
void Init_ossl_pkcs7(void)
Definition: ossl_pkcs7.c:1028
Init_ossl_pkey
void Init_ossl_pkey(void)
Definition: ossl_pkey.c:572
Init_ossl_rand
void Init_ossl_rand(void)
Definition: ossl_rand.c:176
Init_ossl_ssl
void Init_ossl_ssl(void)
Definition: ossl_ssl.c:2507
Init_ossl_ts
void Init_ossl_ts(void)
Definition: ossl_ts.c:1249
Init_ossl_x509
void Init_ossl_x509(void)
Definition: ossl_x509.c:30
DupX509CertPtr
X509 * DupX509CertPtr(VALUE)
Definition: ossl_x509cert.c:81
cX509Cert
VALUE cX509Cert
Definition: ossl_x509cert.c:30
NULL
#define NULL
Definition: regenc.h:69
StringValue
#define StringValue(v)
Definition: rstring.h:50
StringValuePtr
#define StringValuePtr(v)
Definition: rstring.h:51
Qtrue
#define Qtrue
Definition: special_consts.h:52
RTEST
#define RTEST
Definition: special_consts.h:42
Qnil
#define Qnil
Definition: special_consts.h:51
Qfalse
#define Qfalse
Definition: special_consts.h:50
NIL_P
#define NIL_P
Definition: special_consts.h:46
rb_vsprintf
VALUE rb_vsprintf(const char *, va_list)
Definition: sprintf.c:1197
stdarg.h
Defines old _.
_
#define _(args)
Definition: stdarg.h:31
CRYPTO_dynlock_value
Stores locks needed for OpenSSL thread safety.
Definition: ossl.c:523
CRYPTO_dynlock_value::count
size_t count
Definition: ossl.c:526
CRYPTO_dynlock_value::lock
rb_nativethread_lock_t lock
Definition: ossl.c:524
CRYPTO_dynlock_value::owner
rb_nativethread_id_t owner
Definition: ossl.c:525
file
Definition: gzappend.c:170
rb_global_variable
Definition: variable.c:320
state
Definition: blast.c:41
thread_native.h
rb_nativethread_self
rb_nativethread_id_t rb_nativethread_self()
rb_nativethread_lock_lock
void rb_nativethread_lock_lock(rb_nativethread_lock_t *lock)
Definition: thread.c:442
rb_nativethread_lock_unlock
void rb_nativethread_lock_unlock(rb_nativethread_lock_t *lock)
Definition: thread.c:448
rb_nativethread_lock_initialize
void rb_nativethread_lock_initialize(rb_nativethread_lock_t *lock)
Definition: thread.c:430
rb_nativethread_lock_destroy
void rb_nativethread_lock_destroy(rb_nativethread_lock_t *lock)
Definition: thread.c:436
VALUE
unsigned long VALUE
Definition: value.h:38
ID
unsigned long ID
Definition: value.h:39
T_STRING
#define T_STRING
Definition: value_type.h:77
err
int err
Definition: win32.c:142