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