openssl 2.0.0.beta.1
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.
Potentially problematic release.
This version of openssl might be problematic. Click here for more details.
- checksums.yaml +7 -0
 - data/BSDL +22 -0
 - data/CONTRIBUTING.md +130 -0
 - data/History.md +118 -0
 - data/LICENSE.txt +56 -0
 - data/README.md +70 -0
 - data/ext/openssl/deprecation.rb +26 -0
 - data/ext/openssl/extconf.rb +158 -0
 - data/ext/openssl/openssl_missing.c +173 -0
 - data/ext/openssl/openssl_missing.h +244 -0
 - data/ext/openssl/ossl.c +1201 -0
 - data/ext/openssl/ossl.h +222 -0
 - data/ext/openssl/ossl_asn1.c +1992 -0
 - data/ext/openssl/ossl_asn1.h +66 -0
 - data/ext/openssl/ossl_bio.c +87 -0
 - data/ext/openssl/ossl_bio.h +19 -0
 - data/ext/openssl/ossl_bn.c +1153 -0
 - data/ext/openssl/ossl_bn.h +23 -0
 - data/ext/openssl/ossl_cipher.c +1085 -0
 - data/ext/openssl/ossl_cipher.h +20 -0
 - data/ext/openssl/ossl_config.c +89 -0
 - data/ext/openssl/ossl_config.h +19 -0
 - data/ext/openssl/ossl_digest.c +453 -0
 - data/ext/openssl/ossl_digest.h +20 -0
 - data/ext/openssl/ossl_engine.c +580 -0
 - data/ext/openssl/ossl_engine.h +19 -0
 - data/ext/openssl/ossl_hmac.c +398 -0
 - data/ext/openssl/ossl_hmac.h +18 -0
 - data/ext/openssl/ossl_ns_spki.c +406 -0
 - data/ext/openssl/ossl_ns_spki.h +19 -0
 - data/ext/openssl/ossl_ocsp.c +2013 -0
 - data/ext/openssl/ossl_ocsp.h +23 -0
 - data/ext/openssl/ossl_pkcs12.c +259 -0
 - data/ext/openssl/ossl_pkcs12.h +13 -0
 - data/ext/openssl/ossl_pkcs5.c +180 -0
 - data/ext/openssl/ossl_pkcs5.h +6 -0
 - data/ext/openssl/ossl_pkcs7.c +1125 -0
 - data/ext/openssl/ossl_pkcs7.h +20 -0
 - data/ext/openssl/ossl_pkey.c +435 -0
 - data/ext/openssl/ossl_pkey.h +245 -0
 - data/ext/openssl/ossl_pkey_dh.c +650 -0
 - data/ext/openssl/ossl_pkey_dsa.c +672 -0
 - data/ext/openssl/ossl_pkey_ec.c +1899 -0
 - data/ext/openssl/ossl_pkey_rsa.c +768 -0
 - data/ext/openssl/ossl_rand.c +238 -0
 - data/ext/openssl/ossl_rand.h +18 -0
 - data/ext/openssl/ossl_ssl.c +2679 -0
 - data/ext/openssl/ossl_ssl.h +41 -0
 - data/ext/openssl/ossl_ssl_session.c +352 -0
 - data/ext/openssl/ossl_version.h +15 -0
 - data/ext/openssl/ossl_x509.c +186 -0
 - data/ext/openssl/ossl_x509.h +119 -0
 - data/ext/openssl/ossl_x509attr.c +328 -0
 - data/ext/openssl/ossl_x509cert.c +860 -0
 - data/ext/openssl/ossl_x509crl.c +565 -0
 - data/ext/openssl/ossl_x509ext.c +480 -0
 - data/ext/openssl/ossl_x509name.c +547 -0
 - data/ext/openssl/ossl_x509req.c +492 -0
 - data/ext/openssl/ossl_x509revoked.c +279 -0
 - data/ext/openssl/ossl_x509store.c +846 -0
 - data/ext/openssl/ruby_missing.h +32 -0
 - data/lib/openssl.rb +21 -0
 - data/lib/openssl/bn.rb +39 -0
 - data/lib/openssl/buffering.rb +451 -0
 - data/lib/openssl/cipher.rb +67 -0
 - data/lib/openssl/config.rb +473 -0
 - data/lib/openssl/digest.rb +78 -0
 - data/lib/openssl/pkey.rb +44 -0
 - data/lib/openssl/ssl.rb +416 -0
 - data/lib/openssl/x509.rb +176 -0
 - metadata +178 -0
 
| 
         @@ -0,0 +1,238 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            /*
         
     | 
| 
      
 2 
     | 
    
         
            +
             * 'OpenSSL for Ruby' project
         
     | 
| 
      
 3 
     | 
    
         
            +
             * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
         
     | 
| 
      
 4 
     | 
    
         
            +
             *
         
     | 
| 
      
 5 
     | 
    
         
            +
             * All rights reserved.
         
     | 
| 
      
 6 
     | 
    
         
            +
             *
         
     | 
| 
      
 7 
     | 
    
         
            +
             * This program is licensed under the same licence as Ruby.
         
     | 
| 
      
 8 
     | 
    
         
            +
             * (See the file 'LICENCE'.)
         
     | 
| 
      
 9 
     | 
    
         
            +
             */
         
     | 
| 
      
 10 
     | 
    
         
            +
            #include "ossl.h"
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            VALUE mRandom;
         
     | 
| 
      
 13 
     | 
    
         
            +
            VALUE eRandomError;
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            /*
         
     | 
| 
      
 16 
     | 
    
         
            +
             *  call-seq:
         
     | 
| 
      
 17 
     | 
    
         
            +
             *     seed(str) -> str
         
     | 
| 
      
 18 
     | 
    
         
            +
             *
         
     | 
| 
      
 19 
     | 
    
         
            +
             * ::seed is equivalent to ::add where +entropy+ is length of +str+.
         
     | 
| 
      
 20 
     | 
    
         
            +
             */
         
     | 
| 
      
 21 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 22 
     | 
    
         
            +
            ossl_rand_seed(VALUE self, VALUE str)
         
     | 
| 
      
 23 
     | 
    
         
            +
            {
         
     | 
| 
      
 24 
     | 
    
         
            +
                StringValue(str);
         
     | 
| 
      
 25 
     | 
    
         
            +
                RAND_seed(RSTRING_PTR(str), RSTRING_LENINT(str));
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                return str;
         
     | 
| 
      
 28 
     | 
    
         
            +
            }
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            /*
         
     | 
| 
      
 31 
     | 
    
         
            +
             *  call-seq:
         
     | 
| 
      
 32 
     | 
    
         
            +
             *     add(str, entropy) -> self
         
     | 
| 
      
 33 
     | 
    
         
            +
             *
         
     | 
| 
      
 34 
     | 
    
         
            +
             * Mixes the bytes from +str+ into the Pseudo Random Number Generator(PRNG)
         
     | 
| 
      
 35 
     | 
    
         
            +
             * state.
         
     | 
| 
      
 36 
     | 
    
         
            +
             *
         
     | 
| 
      
 37 
     | 
    
         
            +
             * Thus, if the data from +str+ are unpredictable to an adversary, this
         
     | 
| 
      
 38 
     | 
    
         
            +
             * increases the uncertainty about the state and makes the PRNG output less
         
     | 
| 
      
 39 
     | 
    
         
            +
             * predictable.
         
     | 
| 
      
 40 
     | 
    
         
            +
             *
         
     | 
| 
      
 41 
     | 
    
         
            +
             * The +entropy+ argument is (the lower bound of) an estimate of how much
         
     | 
| 
      
 42 
     | 
    
         
            +
             * randomness is contained in +str+, measured in bytes.
         
     | 
| 
      
 43 
     | 
    
         
            +
             *
         
     | 
| 
      
 44 
     | 
    
         
            +
             * === Example
         
     | 
| 
      
 45 
     | 
    
         
            +
             *
         
     | 
| 
      
 46 
     | 
    
         
            +
             *    pid = $$
         
     | 
| 
      
 47 
     | 
    
         
            +
             *    now = Time.now
         
     | 
| 
      
 48 
     | 
    
         
            +
             *    ary = [now.to_i, now.nsec, 1000, pid]
         
     | 
| 
      
 49 
     | 
    
         
            +
             *    OpenSSL::Random.add(ary.join, 0.0)
         
     | 
| 
      
 50 
     | 
    
         
            +
             *    OpenSSL::Random.seed(ary.join)
         
     | 
| 
      
 51 
     | 
    
         
            +
             */
         
     | 
| 
      
 52 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 53 
     | 
    
         
            +
            ossl_rand_add(VALUE self, VALUE str, VALUE entropy)
         
     | 
| 
      
 54 
     | 
    
         
            +
            {
         
     | 
| 
      
 55 
     | 
    
         
            +
                StringValue(str);
         
     | 
| 
      
 56 
     | 
    
         
            +
                RAND_add(RSTRING_PTR(str), RSTRING_LENINT(str), NUM2DBL(entropy));
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                return self;
         
     | 
| 
      
 59 
     | 
    
         
            +
            }
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
            /*
         
     | 
| 
      
 62 
     | 
    
         
            +
             *  call-seq:
         
     | 
| 
      
 63 
     | 
    
         
            +
             *     load_random_file(filename) -> true
         
     | 
| 
      
 64 
     | 
    
         
            +
             *
         
     | 
| 
      
 65 
     | 
    
         
            +
             * Reads bytes from +filename+ and adds them to the PRNG.
         
     | 
| 
      
 66 
     | 
    
         
            +
             */
         
     | 
| 
      
 67 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 68 
     | 
    
         
            +
            ossl_rand_load_file(VALUE self, VALUE filename)
         
     | 
| 
      
 69 
     | 
    
         
            +
            {
         
     | 
| 
      
 70 
     | 
    
         
            +
                rb_check_safe_obj(filename);
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                if(!RAND_load_file(StringValueCStr(filename), -1)) {
         
     | 
| 
      
 73 
     | 
    
         
            +
            	ossl_raise(eRandomError, NULL);
         
     | 
| 
      
 74 
     | 
    
         
            +
                }
         
     | 
| 
      
 75 
     | 
    
         
            +
                return Qtrue;
         
     | 
| 
      
 76 
     | 
    
         
            +
            }
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            /*
         
     | 
| 
      
 79 
     | 
    
         
            +
             *  call-seq:
         
     | 
| 
      
 80 
     | 
    
         
            +
             *     write_random_file(filename) -> true
         
     | 
| 
      
 81 
     | 
    
         
            +
             *
         
     | 
| 
      
 82 
     | 
    
         
            +
             * Writes a number of random generated bytes (currently 1024) to +filename+
         
     | 
| 
      
 83 
     | 
    
         
            +
             * which can be used to initialize the PRNG by calling ::load_random_file in a
         
     | 
| 
      
 84 
     | 
    
         
            +
             * later session.
         
     | 
| 
      
 85 
     | 
    
         
            +
             */
         
     | 
| 
      
 86 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 87 
     | 
    
         
            +
            ossl_rand_write_file(VALUE self, VALUE filename)
         
     | 
| 
      
 88 
     | 
    
         
            +
            {
         
     | 
| 
      
 89 
     | 
    
         
            +
                rb_check_safe_obj(filename);
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                if (RAND_write_file(StringValueCStr(filename)) == -1) {
         
     | 
| 
      
 92 
     | 
    
         
            +
            	ossl_raise(eRandomError, NULL);
         
     | 
| 
      
 93 
     | 
    
         
            +
                }
         
     | 
| 
      
 94 
     | 
    
         
            +
                return Qtrue;
         
     | 
| 
      
 95 
     | 
    
         
            +
            }
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
            /*
         
     | 
| 
      
 98 
     | 
    
         
            +
             *  call-seq:
         
     | 
| 
      
 99 
     | 
    
         
            +
             *	random_bytes(length) -> string
         
     | 
| 
      
 100 
     | 
    
         
            +
             *
         
     | 
| 
      
 101 
     | 
    
         
            +
             * Generates +string+ with +length+ number of cryptographically strong
         
     | 
| 
      
 102 
     | 
    
         
            +
             * pseudo-random bytes.
         
     | 
| 
      
 103 
     | 
    
         
            +
             *
         
     | 
| 
      
 104 
     | 
    
         
            +
             * === Example
         
     | 
| 
      
 105 
     | 
    
         
            +
             *
         
     | 
| 
      
 106 
     | 
    
         
            +
             *    OpenSSL::Random.random_bytes(12)
         
     | 
| 
      
 107 
     | 
    
         
            +
             *    #=> "..."
         
     | 
| 
      
 108 
     | 
    
         
            +
             */
         
     | 
| 
      
 109 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 110 
     | 
    
         
            +
            ossl_rand_bytes(VALUE self, VALUE len)
         
     | 
| 
      
 111 
     | 
    
         
            +
            {
         
     | 
| 
      
 112 
     | 
    
         
            +
                VALUE str;
         
     | 
| 
      
 113 
     | 
    
         
            +
                int n = NUM2INT(len);
         
     | 
| 
      
 114 
     | 
    
         
            +
                int ret;
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                str = rb_str_new(0, n);
         
     | 
| 
      
 117 
     | 
    
         
            +
                ret = RAND_bytes((unsigned char *)RSTRING_PTR(str), n);
         
     | 
| 
      
 118 
     | 
    
         
            +
                if (ret == 0) {
         
     | 
| 
      
 119 
     | 
    
         
            +
            	ossl_raise(eRandomError, "RAND_bytes");
         
     | 
| 
      
 120 
     | 
    
         
            +
                } else if (ret == -1) {
         
     | 
| 
      
 121 
     | 
    
         
            +
            	ossl_raise(eRandomError, "RAND_bytes is not supported");
         
     | 
| 
      
 122 
     | 
    
         
            +
                }
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
                return str;
         
     | 
| 
      
 125 
     | 
    
         
            +
            }
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
            #if defined(HAVE_RAND_PSEUDO_BYTES)
         
     | 
| 
      
 128 
     | 
    
         
            +
            /*
         
     | 
| 
      
 129 
     | 
    
         
            +
             *  call-seq:
         
     | 
| 
      
 130 
     | 
    
         
            +
             *	pseudo_bytes(length) -> string
         
     | 
| 
      
 131 
     | 
    
         
            +
             *
         
     | 
| 
      
 132 
     | 
    
         
            +
             * Generates +string+ with +length+ number of pseudo-random bytes.
         
     | 
| 
      
 133 
     | 
    
         
            +
             *
         
     | 
| 
      
 134 
     | 
    
         
            +
             * Pseudo-random byte sequences generated by ::pseudo_bytes will be unique if
         
     | 
| 
      
 135 
     | 
    
         
            +
             * they are of sufficient length, but are not necessarily unpredictable.
         
     | 
| 
      
 136 
     | 
    
         
            +
             *
         
     | 
| 
      
 137 
     | 
    
         
            +
             * === Example
         
     | 
| 
      
 138 
     | 
    
         
            +
             *
         
     | 
| 
      
 139 
     | 
    
         
            +
             *    OpenSSL::Random.pseudo_bytes(12)
         
     | 
| 
      
 140 
     | 
    
         
            +
             *    #=> "..."
         
     | 
| 
      
 141 
     | 
    
         
            +
             */
         
     | 
| 
      
 142 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 143 
     | 
    
         
            +
            ossl_rand_pseudo_bytes(VALUE self, VALUE len)
         
     | 
| 
      
 144 
     | 
    
         
            +
            {
         
     | 
| 
      
 145 
     | 
    
         
            +
                VALUE str;
         
     | 
| 
      
 146 
     | 
    
         
            +
                int n = NUM2INT(len);
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                str = rb_str_new(0, n);
         
     | 
| 
      
 149 
     | 
    
         
            +
                if (RAND_pseudo_bytes((unsigned char *)RSTRING_PTR(str), n) < 1) {
         
     | 
| 
      
 150 
     | 
    
         
            +
            	ossl_raise(eRandomError, NULL);
         
     | 
| 
      
 151 
     | 
    
         
            +
                }
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
                return str;
         
     | 
| 
      
 154 
     | 
    
         
            +
            }
         
     | 
| 
      
 155 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
            #ifdef HAVE_RAND_EGD
         
     | 
| 
      
 158 
     | 
    
         
            +
            /*
         
     | 
| 
      
 159 
     | 
    
         
            +
             *  call-seq:
         
     | 
| 
      
 160 
     | 
    
         
            +
             *     egd(filename) -> true
         
     | 
| 
      
 161 
     | 
    
         
            +
             *
         
     | 
| 
      
 162 
     | 
    
         
            +
             * Same as ::egd_bytes but queries 255 bytes by default.
         
     | 
| 
      
 163 
     | 
    
         
            +
             */
         
     | 
| 
      
 164 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 165 
     | 
    
         
            +
            ossl_rand_egd(VALUE self, VALUE filename)
         
     | 
| 
      
 166 
     | 
    
         
            +
            {
         
     | 
| 
      
 167 
     | 
    
         
            +
                rb_check_safe_obj(filename);
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
      
 169 
     | 
    
         
            +
                if (RAND_egd(StringValueCStr(filename)) == -1) {
         
     | 
| 
      
 170 
     | 
    
         
            +
            	ossl_raise(eRandomError, NULL);
         
     | 
| 
      
 171 
     | 
    
         
            +
                }
         
     | 
| 
      
 172 
     | 
    
         
            +
                return Qtrue;
         
     | 
| 
      
 173 
     | 
    
         
            +
            }
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
      
 175 
     | 
    
         
            +
            /*
         
     | 
| 
      
 176 
     | 
    
         
            +
             *  call-seq:
         
     | 
| 
      
 177 
     | 
    
         
            +
             *     egd_bytes(filename, length) -> true
         
     | 
| 
      
 178 
     | 
    
         
            +
             *
         
     | 
| 
      
 179 
     | 
    
         
            +
             * Queries the entropy gathering daemon EGD on socket path given by +filename+.
         
     | 
| 
      
 180 
     | 
    
         
            +
             *
         
     | 
| 
      
 181 
     | 
    
         
            +
             * Fetches +length+ number of bytes and uses ::add to seed the OpenSSL built-in
         
     | 
| 
      
 182 
     | 
    
         
            +
             * PRNG.
         
     | 
| 
      
 183 
     | 
    
         
            +
             */
         
     | 
| 
      
 184 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 185 
     | 
    
         
            +
            ossl_rand_egd_bytes(VALUE self, VALUE filename, VALUE len)
         
     | 
| 
      
 186 
     | 
    
         
            +
            {
         
     | 
| 
      
 187 
     | 
    
         
            +
                int n = NUM2INT(len);
         
     | 
| 
      
 188 
     | 
    
         
            +
             
     | 
| 
      
 189 
     | 
    
         
            +
                rb_check_safe_obj(filename);
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
                if (RAND_egd_bytes(StringValueCStr(filename), n) == -1) {
         
     | 
| 
      
 192 
     | 
    
         
            +
            	ossl_raise(eRandomError, NULL);
         
     | 
| 
      
 193 
     | 
    
         
            +
                }
         
     | 
| 
      
 194 
     | 
    
         
            +
                return Qtrue;
         
     | 
| 
      
 195 
     | 
    
         
            +
            }
         
     | 
| 
      
 196 
     | 
    
         
            +
            #endif /* HAVE_RAND_EGD */
         
     | 
| 
      
 197 
     | 
    
         
            +
             
     | 
| 
      
 198 
     | 
    
         
            +
            /*
         
     | 
| 
      
 199 
     | 
    
         
            +
             *  call-seq:
         
     | 
| 
      
 200 
     | 
    
         
            +
             *     status? => true | false
         
     | 
| 
      
 201 
     | 
    
         
            +
             *
         
     | 
| 
      
 202 
     | 
    
         
            +
             * Return true if the PRNG has been seeded with enough data, false otherwise.
         
     | 
| 
      
 203 
     | 
    
         
            +
             */
         
     | 
| 
      
 204 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 205 
     | 
    
         
            +
            ossl_rand_status(VALUE self)
         
     | 
| 
      
 206 
     | 
    
         
            +
            {
         
     | 
| 
      
 207 
     | 
    
         
            +
                return RAND_status() ? Qtrue : Qfalse;
         
     | 
| 
      
 208 
     | 
    
         
            +
            }
         
     | 
| 
      
 209 
     | 
    
         
            +
             
     | 
| 
      
 210 
     | 
    
         
            +
            /*
         
     | 
| 
      
 211 
     | 
    
         
            +
             * INIT
         
     | 
| 
      
 212 
     | 
    
         
            +
             */
         
     | 
| 
      
 213 
     | 
    
         
            +
            void
         
     | 
| 
      
 214 
     | 
    
         
            +
            Init_ossl_rand(void)
         
     | 
| 
      
 215 
     | 
    
         
            +
            {
         
     | 
| 
      
 216 
     | 
    
         
            +
            #if 0
         
     | 
| 
      
 217 
     | 
    
         
            +
                mOSSL = rb_define_module("OpenSSL");
         
     | 
| 
      
 218 
     | 
    
         
            +
                eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
         
     | 
| 
      
 219 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 220 
     | 
    
         
            +
             
     | 
| 
      
 221 
     | 
    
         
            +
                mRandom = rb_define_module_under(mOSSL, "Random");
         
     | 
| 
      
 222 
     | 
    
         
            +
             
     | 
| 
      
 223 
     | 
    
         
            +
                eRandomError = rb_define_class_under(mRandom, "RandomError", eOSSLError);
         
     | 
| 
      
 224 
     | 
    
         
            +
             
     | 
| 
      
 225 
     | 
    
         
            +
                rb_define_module_function(mRandom, "seed", ossl_rand_seed, 1);
         
     | 
| 
      
 226 
     | 
    
         
            +
                rb_define_module_function(mRandom, "random_add", ossl_rand_add, 2);
         
     | 
| 
      
 227 
     | 
    
         
            +
                rb_define_module_function(mRandom, "load_random_file", ossl_rand_load_file, 1);
         
     | 
| 
      
 228 
     | 
    
         
            +
                rb_define_module_function(mRandom, "write_random_file", ossl_rand_write_file, 1);
         
     | 
| 
      
 229 
     | 
    
         
            +
                rb_define_module_function(mRandom, "random_bytes", ossl_rand_bytes, 1);
         
     | 
| 
      
 230 
     | 
    
         
            +
            #if defined(HAVE_RAND_PSEUDO_BYTES)
         
     | 
| 
      
 231 
     | 
    
         
            +
                rb_define_module_function(mRandom, "pseudo_bytes", ossl_rand_pseudo_bytes, 1);
         
     | 
| 
      
 232 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 233 
     | 
    
         
            +
            #ifdef HAVE_RAND_EGD
         
     | 
| 
      
 234 
     | 
    
         
            +
                rb_define_module_function(mRandom, "egd", ossl_rand_egd, 1);
         
     | 
| 
      
 235 
     | 
    
         
            +
                rb_define_module_function(mRandom, "egd_bytes", ossl_rand_egd_bytes, 2);
         
     | 
| 
      
 236 
     | 
    
         
            +
            #endif /* HAVE_RAND_EGD */
         
     | 
| 
      
 237 
     | 
    
         
            +
                rb_define_module_function(mRandom, "status?", ossl_rand_status, 0);
         
     | 
| 
      
 238 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -0,0 +1,18 @@ 
     | 
|
| 
      
 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 
     | 
    
         
            +
            #if !defined(_OSSL_RAND_H_)
         
     | 
| 
      
 11 
     | 
    
         
            +
            #define _OSSL_RAND_H_
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            extern VALUE mRandom;
         
     | 
| 
      
 14 
     | 
    
         
            +
            extern VALUE eRandomError;
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            void Init_ossl_rand(void);
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            #endif /* _OSSL_RAND_H_ */
         
     | 
| 
         @@ -0,0 +1,2679 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            /*
         
     | 
| 
      
 2 
     | 
    
         
            +
             * 'OpenSSL for Ruby' project
         
     | 
| 
      
 3 
     | 
    
         
            +
             * Copyright (C) 2000-2002  GOTOU Yuuzou <gotoyuzo@notwork.org>
         
     | 
| 
      
 4 
     | 
    
         
            +
             * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
         
     | 
| 
      
 5 
     | 
    
         
            +
             * Copyright (C) 2001-2007  Technorama Ltd. <oss-ruby@technorama.net>
         
     | 
| 
      
 6 
     | 
    
         
            +
             * All rights reserved.
         
     | 
| 
      
 7 
     | 
    
         
            +
             */
         
     | 
| 
      
 8 
     | 
    
         
            +
            /*
         
     | 
| 
      
 9 
     | 
    
         
            +
             * This program is licensed under the same licence as Ruby.
         
     | 
| 
      
 10 
     | 
    
         
            +
             * (See the file 'LICENCE'.)
         
     | 
| 
      
 11 
     | 
    
         
            +
             */
         
     | 
| 
      
 12 
     | 
    
         
            +
            #include "ossl.h"
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            #if defined(HAVE_UNISTD_H)
         
     | 
| 
      
 15 
     | 
    
         
            +
            #  include <unistd.h> /* for read(), and write() */
         
     | 
| 
      
 16 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            #define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0]))
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            #ifdef _WIN32
         
     | 
| 
      
 21 
     | 
    
         
            +
            #  define TO_SOCKET(s) _get_osfhandle(s)
         
     | 
| 
      
 22 
     | 
    
         
            +
            #else
         
     | 
| 
      
 23 
     | 
    
         
            +
            #  define TO_SOCKET(s) (s)
         
     | 
| 
      
 24 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            #define GetSSLCTX(obj, ctx) do { \
         
     | 
| 
      
 27 
     | 
    
         
            +
            	TypedData_Get_Struct((obj), SSL_CTX, &ossl_sslctx_type, (ctx));	\
         
     | 
| 
      
 28 
     | 
    
         
            +
            } while (0)
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            VALUE mSSL;
         
     | 
| 
      
 31 
     | 
    
         
            +
            static VALUE mSSLExtConfig;
         
     | 
| 
      
 32 
     | 
    
         
            +
            static VALUE eSSLError;
         
     | 
| 
      
 33 
     | 
    
         
            +
            VALUE cSSLContext;
         
     | 
| 
      
 34 
     | 
    
         
            +
            VALUE cSSLSocket;
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            static VALUE eSSLErrorWaitReadable;
         
     | 
| 
      
 37 
     | 
    
         
            +
            static VALUE eSSLErrorWaitWritable;
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            #define ossl_sslctx_set_cert(o,v)        	rb_iv_set((o),"@cert",(v))
         
     | 
| 
      
 40 
     | 
    
         
            +
            #define ossl_sslctx_set_key(o,v)         	rb_iv_set((o),"@key",(v))
         
     | 
| 
      
 41 
     | 
    
         
            +
            #define ossl_sslctx_set_client_ca(o,v)   	rb_iv_set((o),"@client_ca",(v))
         
     | 
| 
      
 42 
     | 
    
         
            +
            #define ossl_sslctx_set_ca_file(o,v)     	rb_iv_set((o),"@ca_file",(v))
         
     | 
| 
      
 43 
     | 
    
         
            +
            #define ossl_sslctx_set_ca_path(o,v)     	rb_iv_set((o),"@ca_path",(v))
         
     | 
| 
      
 44 
     | 
    
         
            +
            #define ossl_sslctx_set_timeout(o,v)     	rb_iv_set((o),"@timeout",(v))
         
     | 
| 
      
 45 
     | 
    
         
            +
            #define ossl_sslctx_set_verify_mode(o,v) 	rb_iv_set((o),"@verify_mode",(v))
         
     | 
| 
      
 46 
     | 
    
         
            +
            #define ossl_sslctx_set_verify_dep(o,v)  	rb_iv_set((o),"@verify_depth",(v))
         
     | 
| 
      
 47 
     | 
    
         
            +
            #define ossl_sslctx_set_verify_cb(o,v)   	rb_iv_set((o),"@verify_callback",(v))
         
     | 
| 
      
 48 
     | 
    
         
            +
            #define ossl_sslctx_set_cert_store(o,v)  	rb_iv_set((o),"@cert_store",(v))
         
     | 
| 
      
 49 
     | 
    
         
            +
            #define ossl_sslctx_set_extra_cert(o,v)  	rb_iv_set((o),"@extra_chain_cert",(v))
         
     | 
| 
      
 50 
     | 
    
         
            +
            #define ossl_sslctx_set_client_cert_cb(o,v) 	rb_iv_set((o),"@client_cert_cb",(v))
         
     | 
| 
      
 51 
     | 
    
         
            +
            #define ossl_sslctx_set_sess_id_ctx(o, v) 	rb_iv_set((o),"@session_id_context",(v))
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            #define ossl_sslctx_get_cert(o)          	rb_iv_get((o),"@cert")
         
     | 
| 
      
 54 
     | 
    
         
            +
            #define ossl_sslctx_get_key(o)           	rb_iv_get((o),"@key")
         
     | 
| 
      
 55 
     | 
    
         
            +
            #define ossl_sslctx_get_client_ca(o)     	rb_iv_get((o),"@client_ca")
         
     | 
| 
      
 56 
     | 
    
         
            +
            #define ossl_sslctx_get_ca_file(o)       	rb_iv_get((o),"@ca_file")
         
     | 
| 
      
 57 
     | 
    
         
            +
            #define ossl_sslctx_get_ca_path(o)       	rb_iv_get((o),"@ca_path")
         
     | 
| 
      
 58 
     | 
    
         
            +
            #define ossl_sslctx_get_timeout(o)       	rb_iv_get((o),"@timeout")
         
     | 
| 
      
 59 
     | 
    
         
            +
            #define ossl_sslctx_get_verify_mode(o)   	rb_iv_get((o),"@verify_mode")
         
     | 
| 
      
 60 
     | 
    
         
            +
            #define ossl_sslctx_get_verify_dep(o)    	rb_iv_get((o),"@verify_depth")
         
     | 
| 
      
 61 
     | 
    
         
            +
            #define ossl_sslctx_get_verify_cb(o)     	rb_iv_get((o),"@verify_callback")
         
     | 
| 
      
 62 
     | 
    
         
            +
            #define ossl_sslctx_get_cert_store(o)    	rb_iv_get((o),"@cert_store")
         
     | 
| 
      
 63 
     | 
    
         
            +
            #define ossl_sslctx_get_extra_cert(o)    	rb_iv_get((o),"@extra_chain_cert")
         
     | 
| 
      
 64 
     | 
    
         
            +
            #define ossl_sslctx_get_client_cert_cb(o) 	rb_iv_get((o),"@client_cert_cb")
         
     | 
| 
      
 65 
     | 
    
         
            +
            #define ossl_sslctx_get_tmp_ecdh_cb(o)          rb_iv_get((o),"@tmp_ecdh_callback")
         
     | 
| 
      
 66 
     | 
    
         
            +
            #define ossl_sslctx_get_sess_id_ctx(o)   	rb_iv_get((o),"@session_id_context")
         
     | 
| 
      
 67 
     | 
    
         
            +
            #define ossl_sslctx_get_verify_hostname(o)	rb_iv_get((o),"@verify_hostname")
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
            #define ossl_ssl_get_io(o)           rb_iv_get((o),"@io")
         
     | 
| 
      
 70 
     | 
    
         
            +
            #define ossl_ssl_get_ctx(o)          rb_iv_get((o),"@context")
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            #define ossl_ssl_set_io(o,v)         rb_iv_set((o),"@io",(v))
         
     | 
| 
      
 73 
     | 
    
         
            +
            #define ossl_ssl_set_ctx(o,v)        rb_iv_set((o),"@context",(v))
         
     | 
| 
      
 74 
     | 
    
         
            +
            #define ossl_ssl_set_sync_close(o,v) rb_iv_set((o),"@sync_close",(v))
         
     | 
| 
      
 75 
     | 
    
         
            +
            #define ossl_ssl_set_hostname_v(o,v) rb_iv_set((o),"@hostname",(v))
         
     | 
| 
      
 76 
     | 
    
         
            +
            #define ossl_ssl_set_tmp_dh(o,v)     rb_iv_set((o),"@tmp_dh",(v))
         
     | 
| 
      
 77 
     | 
    
         
            +
            #define ossl_ssl_set_tmp_ecdh(o,v)   rb_iv_set((o),"@tmp_ecdh",(v))
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
            static ID ID_callback_state;
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
            static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
            /*
         
     | 
| 
      
 84 
     | 
    
         
            +
             * SSLContext class
         
     | 
| 
      
 85 
     | 
    
         
            +
             */
         
     | 
| 
      
 86 
     | 
    
         
            +
            static const struct {
         
     | 
| 
      
 87 
     | 
    
         
            +
                const char *name;
         
     | 
| 
      
 88 
     | 
    
         
            +
                SSL_METHOD *(*func)(void); /* FIXME: constify when dropping 0.9.8 */
         
     | 
| 
      
 89 
     | 
    
         
            +
                int version;
         
     | 
| 
      
 90 
     | 
    
         
            +
            } ossl_ssl_method_tab[] = {
         
     | 
| 
      
 91 
     | 
    
         
            +
            #if defined(HAVE_SSL_CTX_SET_MIN_PROTO_VERSION)
         
     | 
| 
      
 92 
     | 
    
         
            +
            #define OSSL_SSL_METHOD_ENTRY(name, version) \
         
     | 
| 
      
 93 
     | 
    
         
            +
                { #name,          (SSL_METHOD *(*)(void))TLS_method, version }, \
         
     | 
| 
      
 94 
     | 
    
         
            +
                { #name"_server", (SSL_METHOD *(*)(void))TLS_server_method, version }, \
         
     | 
| 
      
 95 
     | 
    
         
            +
                { #name"_client", (SSL_METHOD *(*)(void))TLS_client_method, version }
         
     | 
| 
      
 96 
     | 
    
         
            +
            #else
         
     | 
| 
      
 97 
     | 
    
         
            +
            #define OSSL_SSL_METHOD_ENTRY(name, version) \
         
     | 
| 
      
 98 
     | 
    
         
            +
                { #name,          (SSL_METHOD *(*)(void))name##_method, version }, \
         
     | 
| 
      
 99 
     | 
    
         
            +
                { #name"_server", (SSL_METHOD *(*)(void))name##_server_method, version }, \
         
     | 
| 
      
 100 
     | 
    
         
            +
                { #name"_client", (SSL_METHOD *(*)(void))name##_client_method, version }
         
     | 
| 
      
 101 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 102 
     | 
    
         
            +
            #if defined(HAVE_SSLV2_METHOD)
         
     | 
| 
      
 103 
     | 
    
         
            +
                OSSL_SSL_METHOD_ENTRY(SSLv2, SSL2_VERSION),
         
     | 
| 
      
 104 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 105 
     | 
    
         
            +
            #if defined(HAVE_SSLV3_METHOD)
         
     | 
| 
      
 106 
     | 
    
         
            +
                OSSL_SSL_METHOD_ENTRY(SSLv3, SSL3_VERSION),
         
     | 
| 
      
 107 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 108 
     | 
    
         
            +
                OSSL_SSL_METHOD_ENTRY(TLSv1, TLS1_VERSION),
         
     | 
| 
      
 109 
     | 
    
         
            +
            #if defined(HAVE_TLSV1_1_METHOD)
         
     | 
| 
      
 110 
     | 
    
         
            +
                OSSL_SSL_METHOD_ENTRY(TLSv1_1, TLS1_1_VERSION),
         
     | 
| 
      
 111 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 112 
     | 
    
         
            +
            #if defined(HAVE_TLSV1_2_METHOD)
         
     | 
| 
      
 113 
     | 
    
         
            +
                OSSL_SSL_METHOD_ENTRY(TLSv1_2, TLS1_2_VERSION),
         
     | 
| 
      
 114 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 115 
     | 
    
         
            +
                OSSL_SSL_METHOD_ENTRY(SSLv23, 0),
         
     | 
| 
      
 116 
     | 
    
         
            +
            #undef OSSL_SSL_METHOD_ENTRY
         
     | 
| 
      
 117 
     | 
    
         
            +
            };
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
            static int ossl_ssl_ex_vcb_idx;
         
     | 
| 
      
 120 
     | 
    
         
            +
            static int ossl_ssl_ex_store_p;
         
     | 
| 
      
 121 
     | 
    
         
            +
            static int ossl_ssl_ex_ptr_idx;
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
            static void
         
     | 
| 
      
 124 
     | 
    
         
            +
            ossl_sslctx_free(void *ptr)
         
     | 
| 
      
 125 
     | 
    
         
            +
            {
         
     | 
| 
      
 126 
     | 
    
         
            +
                SSL_CTX *ctx = ptr;
         
     | 
| 
      
 127 
     | 
    
         
            +
            #if !defined(HAVE_X509_STORE_UP_REF)
         
     | 
| 
      
 128 
     | 
    
         
            +
                if(ctx && SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_store_p)== (void*)1)
         
     | 
| 
      
 129 
     | 
    
         
            +
            	ctx->cert_store = NULL;
         
     | 
| 
      
 130 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 131 
     | 
    
         
            +
                SSL_CTX_free(ctx);
         
     | 
| 
      
 132 
     | 
    
         
            +
            }
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
            static const rb_data_type_t ossl_sslctx_type = {
         
     | 
| 
      
 135 
     | 
    
         
            +
                "OpenSSL/SSL/CTX",
         
     | 
| 
      
 136 
     | 
    
         
            +
                {
         
     | 
| 
      
 137 
     | 
    
         
            +
            	0, ossl_sslctx_free,
         
     | 
| 
      
 138 
     | 
    
         
            +
                },
         
     | 
| 
      
 139 
     | 
    
         
            +
                0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
         
     | 
| 
      
 140 
     | 
    
         
            +
            };
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 143 
     | 
    
         
            +
            ossl_sslctx_s_alloc(VALUE klass)
         
     | 
| 
      
 144 
     | 
    
         
            +
            {
         
     | 
| 
      
 145 
     | 
    
         
            +
                SSL_CTX *ctx;
         
     | 
| 
      
 146 
     | 
    
         
            +
                long mode = SSL_MODE_ENABLE_PARTIAL_WRITE |
         
     | 
| 
      
 147 
     | 
    
         
            +
            	SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER;
         
     | 
| 
      
 148 
     | 
    
         
            +
                VALUE obj;
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
            #ifdef SSL_MODE_RELEASE_BUFFERS
         
     | 
| 
      
 151 
     | 
    
         
            +
                mode |= SSL_MODE_RELEASE_BUFFERS;
         
     | 
| 
      
 152 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                obj = TypedData_Wrap_Struct(klass, &ossl_sslctx_type, 0);
         
     | 
| 
      
 155 
     | 
    
         
            +
                ctx = SSL_CTX_new(SSLv23_method());
         
     | 
| 
      
 156 
     | 
    
         
            +
                if (!ctx) {
         
     | 
| 
      
 157 
     | 
    
         
            +
                    ossl_raise(eSSLError, "SSL_CTX_new");
         
     | 
| 
      
 158 
     | 
    
         
            +
                }
         
     | 
| 
      
 159 
     | 
    
         
            +
                SSL_CTX_set_mode(ctx, mode);
         
     | 
| 
      
 160 
     | 
    
         
            +
                RTYPEDDATA_DATA(obj) = ctx;
         
     | 
| 
      
 161 
     | 
    
         
            +
                SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_ptr_idx, (void*)obj);
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
            #if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
         
     | 
| 
      
 164 
     | 
    
         
            +
                /* We use SSL_CTX_set1_curves_list() to specify the curve used in ECDH. It
         
     | 
| 
      
 165 
     | 
    
         
            +
                 * allows to specify multiple curve names and OpenSSL will select
         
     | 
| 
      
 166 
     | 
    
         
            +
                 * automatically from them. In OpenSSL 1.0.2, the automatic selection has to
         
     | 
| 
      
 167 
     | 
    
         
            +
                 * be enabled explicitly. But OpenSSL 1.1.0 removed the knob and it is
         
     | 
| 
      
 168 
     | 
    
         
            +
                 * always enabled. To uniform the behavior, we enable the automatic
         
     | 
| 
      
 169 
     | 
    
         
            +
                 * selection also in 1.0.2. Users can still disable ECDH by removing ECDH
         
     | 
| 
      
 170 
     | 
    
         
            +
                 * cipher suites by SSLContext#ciphers=. */
         
     | 
| 
      
 171 
     | 
    
         
            +
                if (!SSL_CTX_set_ecdh_auto(ctx, 1))
         
     | 
| 
      
 172 
     | 
    
         
            +
            	ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
         
     | 
| 
      
 173 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
      
 175 
     | 
    
         
            +
                return obj;
         
     | 
| 
      
 176 
     | 
    
         
            +
            }
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
            /*
         
     | 
| 
      
 179 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 180 
     | 
    
         
            +
             *    ctx.ssl_version = :TLSv1
         
     | 
| 
      
 181 
     | 
    
         
            +
             *    ctx.ssl_version = "SSLv23_client"
         
     | 
| 
      
 182 
     | 
    
         
            +
             *
         
     | 
| 
      
 183 
     | 
    
         
            +
             * Sets the SSL/TLS protocol version for the context. This forces connections to
         
     | 
| 
      
 184 
     | 
    
         
            +
             * use only the specified protocol version.
         
     | 
| 
      
 185 
     | 
    
         
            +
             *
         
     | 
| 
      
 186 
     | 
    
         
            +
             * You can get a list of valid versions with OpenSSL::SSL::SSLContext::METHODS
         
     | 
| 
      
 187 
     | 
    
         
            +
             */
         
     | 
| 
      
 188 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 189 
     | 
    
         
            +
            ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method)
         
     | 
| 
      
 190 
     | 
    
         
            +
            {
         
     | 
| 
      
 191 
     | 
    
         
            +
                SSL_CTX *ctx;
         
     | 
| 
      
 192 
     | 
    
         
            +
                const char *s;
         
     | 
| 
      
 193 
     | 
    
         
            +
                VALUE m = ssl_method;
         
     | 
| 
      
 194 
     | 
    
         
            +
                int i;
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
                GetSSLCTX(self, ctx);
         
     | 
| 
      
 197 
     | 
    
         
            +
                if (RB_TYPE_P(ssl_method, T_SYMBOL))
         
     | 
| 
      
 198 
     | 
    
         
            +
            	m = rb_sym2str(ssl_method);
         
     | 
| 
      
 199 
     | 
    
         
            +
                s = StringValueCStr(m);
         
     | 
| 
      
 200 
     | 
    
         
            +
                for (i = 0; i < numberof(ossl_ssl_method_tab); i++) {
         
     | 
| 
      
 201 
     | 
    
         
            +
                    if (strcmp(ossl_ssl_method_tab[i].name, s) == 0) {
         
     | 
| 
      
 202 
     | 
    
         
            +
            #if defined(HAVE_SSL_CTX_SET_MIN_PROTO_VERSION)
         
     | 
| 
      
 203 
     | 
    
         
            +
            	    int version = ossl_ssl_method_tab[i].version;
         
     | 
| 
      
 204 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 205 
     | 
    
         
            +
            	    SSL_METHOD *method = ossl_ssl_method_tab[i].func();
         
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
      
 207 
     | 
    
         
            +
            	    if (SSL_CTX_set_ssl_version(ctx, method) != 1)
         
     | 
| 
      
 208 
     | 
    
         
            +
            		ossl_raise(eSSLError, "SSL_CTX_set_ssl_version");
         
     | 
| 
      
 209 
     | 
    
         
            +
             
     | 
| 
      
 210 
     | 
    
         
            +
            #if defined(HAVE_SSL_CTX_SET_MIN_PROTO_VERSION)
         
     | 
| 
      
 211 
     | 
    
         
            +
            	    if (!SSL_CTX_set_min_proto_version(ctx, version))
         
     | 
| 
      
 212 
     | 
    
         
            +
            		ossl_raise(eSSLError, "SSL_CTX_set_min_proto_version");
         
     | 
| 
      
 213 
     | 
    
         
            +
            	    if (!SSL_CTX_set_max_proto_version(ctx, version))
         
     | 
| 
      
 214 
     | 
    
         
            +
            		ossl_raise(eSSLError, "SSL_CTX_set_max_proto_version");
         
     | 
| 
      
 215 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 216 
     | 
    
         
            +
            	    return ssl_method;
         
     | 
| 
      
 217 
     | 
    
         
            +
                    }
         
     | 
| 
      
 218 
     | 
    
         
            +
                }
         
     | 
| 
      
 219 
     | 
    
         
            +
             
     | 
| 
      
 220 
     | 
    
         
            +
                ossl_raise(rb_eArgError, "unknown SSL method `%"PRIsVALUE"'.", m);
         
     | 
| 
      
 221 
     | 
    
         
            +
            }
         
     | 
| 
      
 222 
     | 
    
         
            +
             
     | 
| 
      
 223 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 224 
     | 
    
         
            +
            ossl_call_client_cert_cb(VALUE obj)
         
     | 
| 
      
 225 
     | 
    
         
            +
            {
         
     | 
| 
      
 226 
     | 
    
         
            +
                VALUE cb, ary, cert, key;
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
      
 228 
     | 
    
         
            +
                cb = ossl_sslctx_get_client_cert_cb(ossl_ssl_get_ctx(obj));
         
     | 
| 
      
 229 
     | 
    
         
            +
                if (NIL_P(cb))
         
     | 
| 
      
 230 
     | 
    
         
            +
            	return Qnil;
         
     | 
| 
      
 231 
     | 
    
         
            +
             
     | 
| 
      
 232 
     | 
    
         
            +
                ary = rb_funcall(cb, rb_intern("call"), 1, obj);
         
     | 
| 
      
 233 
     | 
    
         
            +
                Check_Type(ary, T_ARRAY);
         
     | 
| 
      
 234 
     | 
    
         
            +
                GetX509CertPtr(cert = rb_ary_entry(ary, 0));
         
     | 
| 
      
 235 
     | 
    
         
            +
                GetPrivPKeyPtr(key = rb_ary_entry(ary, 1));
         
     | 
| 
      
 236 
     | 
    
         
            +
             
     | 
| 
      
 237 
     | 
    
         
            +
                return rb_ary_new3(2, cert, key);
         
     | 
| 
      
 238 
     | 
    
         
            +
            }
         
     | 
| 
      
 239 
     | 
    
         
            +
             
     | 
| 
      
 240 
     | 
    
         
            +
            static int
         
     | 
| 
      
 241 
     | 
    
         
            +
            ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
         
     | 
| 
      
 242 
     | 
    
         
            +
            {
         
     | 
| 
      
 243 
     | 
    
         
            +
                VALUE obj, ret;
         
     | 
| 
      
 244 
     | 
    
         
            +
             
     | 
| 
      
 245 
     | 
    
         
            +
                obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
         
     | 
| 
      
 246 
     | 
    
         
            +
                ret = rb_protect(ossl_call_client_cert_cb, obj, NULL);
         
     | 
| 
      
 247 
     | 
    
         
            +
                if (NIL_P(ret))
         
     | 
| 
      
 248 
     | 
    
         
            +
            	return 0;
         
     | 
| 
      
 249 
     | 
    
         
            +
             
     | 
| 
      
 250 
     | 
    
         
            +
                *x509 = DupX509CertPtr(RARRAY_AREF(ret, 0));
         
     | 
| 
      
 251 
     | 
    
         
            +
                *pkey = DupPKeyPtr(RARRAY_AREF(ret, 1));
         
     | 
| 
      
 252 
     | 
    
         
            +
             
     | 
| 
      
 253 
     | 
    
         
            +
                return 1;
         
     | 
| 
      
 254 
     | 
    
         
            +
            }
         
     | 
| 
      
 255 
     | 
    
         
            +
             
     | 
| 
      
 256 
     | 
    
         
            +
            #if !defined(OPENSSL_NO_DH)
         
     | 
| 
      
 257 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 258 
     | 
    
         
            +
            ossl_call_tmp_dh_callback(VALUE args)
         
     | 
| 
      
 259 
     | 
    
         
            +
            {
         
     | 
| 
      
 260 
     | 
    
         
            +
                VALUE cb, dh;
         
     | 
| 
      
 261 
     | 
    
         
            +
                EVP_PKEY *pkey;
         
     | 
| 
      
 262 
     | 
    
         
            +
             
     | 
| 
      
 263 
     | 
    
         
            +
                cb = rb_funcall(rb_ary_entry(args, 0), rb_intern("tmp_dh_callback"), 0);
         
     | 
| 
      
 264 
     | 
    
         
            +
             
     | 
| 
      
 265 
     | 
    
         
            +
                if (NIL_P(cb)) return Qfalse;
         
     | 
| 
      
 266 
     | 
    
         
            +
                dh = rb_apply(cb, rb_intern("call"), args);
         
     | 
| 
      
 267 
     | 
    
         
            +
                pkey = GetPKeyPtr(dh);
         
     | 
| 
      
 268 
     | 
    
         
            +
                if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) return Qfalse;
         
     | 
| 
      
 269 
     | 
    
         
            +
             
     | 
| 
      
 270 
     | 
    
         
            +
                return dh;
         
     | 
| 
      
 271 
     | 
    
         
            +
            }
         
     | 
| 
      
 272 
     | 
    
         
            +
             
     | 
| 
      
 273 
     | 
    
         
            +
            static DH*
         
     | 
| 
      
 274 
     | 
    
         
            +
            ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
         
     | 
| 
      
 275 
     | 
    
         
            +
            {
         
     | 
| 
      
 276 
     | 
    
         
            +
                VALUE args, dh, rb_ssl;
         
     | 
| 
      
 277 
     | 
    
         
            +
             
     | 
| 
      
 278 
     | 
    
         
            +
                rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
         
     | 
| 
      
 279 
     | 
    
         
            +
             
     | 
| 
      
 280 
     | 
    
         
            +
                args = rb_ary_new_from_args(3, rb_ssl, INT2NUM(is_export), INT2NUM(keylength));
         
     | 
| 
      
 281 
     | 
    
         
            +
             
     | 
| 
      
 282 
     | 
    
         
            +
                dh = rb_protect(ossl_call_tmp_dh_callback, args, NULL);
         
     | 
| 
      
 283 
     | 
    
         
            +
                if (!RTEST(dh)) return NULL;
         
     | 
| 
      
 284 
     | 
    
         
            +
                ossl_ssl_set_tmp_dh(rb_ssl, dh);
         
     | 
| 
      
 285 
     | 
    
         
            +
             
     | 
| 
      
 286 
     | 
    
         
            +
                return EVP_PKEY_get0_DH(GetPKeyPtr(dh));
         
     | 
| 
      
 287 
     | 
    
         
            +
            }
         
     | 
| 
      
 288 
     | 
    
         
            +
            #endif /* OPENSSL_NO_DH */
         
     | 
| 
      
 289 
     | 
    
         
            +
             
     | 
| 
      
 290 
     | 
    
         
            +
            #if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
         
     | 
| 
      
 291 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 292 
     | 
    
         
            +
            ossl_call_tmp_ecdh_callback(VALUE args)
         
     | 
| 
      
 293 
     | 
    
         
            +
            {
         
     | 
| 
      
 294 
     | 
    
         
            +
                VALUE cb, ecdh;
         
     | 
| 
      
 295 
     | 
    
         
            +
                EVP_PKEY *pkey;
         
     | 
| 
      
 296 
     | 
    
         
            +
             
     | 
| 
      
 297 
     | 
    
         
            +
                cb = rb_funcall(rb_ary_entry(args, 0), rb_intern("tmp_ecdh_callback"), 0);
         
     | 
| 
      
 298 
     | 
    
         
            +
             
     | 
| 
      
 299 
     | 
    
         
            +
                if (NIL_P(cb)) return Qfalse;
         
     | 
| 
      
 300 
     | 
    
         
            +
                ecdh = rb_apply(cb, rb_intern("call"), args);
         
     | 
| 
      
 301 
     | 
    
         
            +
                pkey = GetPKeyPtr(ecdh);
         
     | 
| 
      
 302 
     | 
    
         
            +
                if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) return Qfalse;
         
     | 
| 
      
 303 
     | 
    
         
            +
             
     | 
| 
      
 304 
     | 
    
         
            +
                return ecdh;
         
     | 
| 
      
 305 
     | 
    
         
            +
            }
         
     | 
| 
      
 306 
     | 
    
         
            +
             
     | 
| 
      
 307 
     | 
    
         
            +
            static EC_KEY*
         
     | 
| 
      
 308 
     | 
    
         
            +
            ossl_tmp_ecdh_callback(SSL *ssl, int is_export, int keylength)
         
     | 
| 
      
 309 
     | 
    
         
            +
            {
         
     | 
| 
      
 310 
     | 
    
         
            +
                VALUE args, ecdh, rb_ssl;
         
     | 
| 
      
 311 
     | 
    
         
            +
             
     | 
| 
      
 312 
     | 
    
         
            +
                rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
         
     | 
| 
      
 313 
     | 
    
         
            +
             
     | 
| 
      
 314 
     | 
    
         
            +
                args = rb_ary_new_from_args(3, rb_ssl, INT2NUM(is_export), INT2NUM(keylength));
         
     | 
| 
      
 315 
     | 
    
         
            +
             
     | 
| 
      
 316 
     | 
    
         
            +
                ecdh = rb_protect(ossl_call_tmp_ecdh_callback, args, NULL);
         
     | 
| 
      
 317 
     | 
    
         
            +
                if (!RTEST(ecdh)) return NULL;
         
     | 
| 
      
 318 
     | 
    
         
            +
                ossl_ssl_set_tmp_ecdh(rb_ssl, ecdh);
         
     | 
| 
      
 319 
     | 
    
         
            +
             
     | 
| 
      
 320 
     | 
    
         
            +
                return EVP_PKEY_get0_EC_KEY(GetPKeyPtr(ecdh));
         
     | 
| 
      
 321 
     | 
    
         
            +
            }
         
     | 
| 
      
 322 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 323 
     | 
    
         
            +
             
     | 
| 
      
 324 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 325 
     | 
    
         
            +
            call_verify_certificate_identity(VALUE ctx_v)
         
     | 
| 
      
 326 
     | 
    
         
            +
            {
         
     | 
| 
      
 327 
     | 
    
         
            +
                X509_STORE_CTX *ctx = (X509_STORE_CTX *)ctx_v;
         
     | 
| 
      
 328 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 329 
     | 
    
         
            +
                VALUE ssl_obj, hostname, cert_obj;
         
     | 
| 
      
 330 
     | 
    
         
            +
             
     | 
| 
      
 331 
     | 
    
         
            +
                ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
         
     | 
| 
      
 332 
     | 
    
         
            +
                ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
         
     | 
| 
      
 333 
     | 
    
         
            +
                hostname = rb_attr_get(ssl_obj, rb_intern("@hostname"));
         
     | 
| 
      
 334 
     | 
    
         
            +
             
     | 
| 
      
 335 
     | 
    
         
            +
                if (!RTEST(hostname)) {
         
     | 
| 
      
 336 
     | 
    
         
            +
            	rb_warning("verify_hostname requires hostname to be set");
         
     | 
| 
      
 337 
     | 
    
         
            +
            	return Qtrue;
         
     | 
| 
      
 338 
     | 
    
         
            +
                }
         
     | 
| 
      
 339 
     | 
    
         
            +
             
     | 
| 
      
 340 
     | 
    
         
            +
                cert_obj = ossl_x509_new(X509_STORE_CTX_get_current_cert(ctx));
         
     | 
| 
      
 341 
     | 
    
         
            +
                return rb_funcall(mSSL, rb_intern("verify_certificate_identity"), 2,
         
     | 
| 
      
 342 
     | 
    
         
            +
            		      cert_obj, hostname);
         
     | 
| 
      
 343 
     | 
    
         
            +
            }
         
     | 
| 
      
 344 
     | 
    
         
            +
             
     | 
| 
      
 345 
     | 
    
         
            +
            static int
         
     | 
| 
      
 346 
     | 
    
         
            +
            ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
         
     | 
| 
      
 347 
     | 
    
         
            +
            {
         
     | 
| 
      
 348 
     | 
    
         
            +
                VALUE cb, ssl_obj, verify_hostname, ret;
         
     | 
| 
      
 349 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 350 
     | 
    
         
            +
                int status;
         
     | 
| 
      
 351 
     | 
    
         
            +
             
     | 
| 
      
 352 
     | 
    
         
            +
                ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
         
     | 
| 
      
 353 
     | 
    
         
            +
                cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx);
         
     | 
| 
      
 354 
     | 
    
         
            +
                ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
         
     | 
| 
      
 355 
     | 
    
         
            +
                verify_hostname = ossl_sslctx_get_verify_hostname(ossl_ssl_get_ctx(ssl_obj));
         
     | 
| 
      
 356 
     | 
    
         
            +
             
     | 
| 
      
 357 
     | 
    
         
            +
                if (preverify_ok && RTEST(verify_hostname) && !SSL_is_server(ssl) &&
         
     | 
| 
      
 358 
     | 
    
         
            +
            	!X509_STORE_CTX_get_error_depth(ctx)) {
         
     | 
| 
      
 359 
     | 
    
         
            +
            	ret = rb_protect(call_verify_certificate_identity, (VALUE)ctx, &status);
         
     | 
| 
      
 360 
     | 
    
         
            +
            	if (status) {
         
     | 
| 
      
 361 
     | 
    
         
            +
            	    rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status));
         
     | 
| 
      
 362 
     | 
    
         
            +
            	    return 0;
         
     | 
| 
      
 363 
     | 
    
         
            +
            	}
         
     | 
| 
      
 364 
     | 
    
         
            +
            	preverify_ok = ret == Qtrue;
         
     | 
| 
      
 365 
     | 
    
         
            +
                }
         
     | 
| 
      
 366 
     | 
    
         
            +
             
     | 
| 
      
 367 
     | 
    
         
            +
                return ossl_verify_cb_call(cb, preverify_ok, ctx);
         
     | 
| 
      
 368 
     | 
    
         
            +
            }
         
     | 
| 
      
 369 
     | 
    
         
            +
             
     | 
| 
      
 370 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 371 
     | 
    
         
            +
            ossl_call_session_get_cb(VALUE ary)
         
     | 
| 
      
 372 
     | 
    
         
            +
            {
         
     | 
| 
      
 373 
     | 
    
         
            +
                VALUE ssl_obj, cb;
         
     | 
| 
      
 374 
     | 
    
         
            +
             
     | 
| 
      
 375 
     | 
    
         
            +
                Check_Type(ary, T_ARRAY);
         
     | 
| 
      
 376 
     | 
    
         
            +
                ssl_obj = rb_ary_entry(ary, 0);
         
     | 
| 
      
 377 
     | 
    
         
            +
             
     | 
| 
      
 378 
     | 
    
         
            +
                cb = rb_funcall(ssl_obj, rb_intern("session_get_cb"), 0);
         
     | 
| 
      
 379 
     | 
    
         
            +
                if (NIL_P(cb)) return Qnil;
         
     | 
| 
      
 380 
     | 
    
         
            +
             
     | 
| 
      
 381 
     | 
    
         
            +
                return rb_funcall(cb, rb_intern("call"), 1, ary);
         
     | 
| 
      
 382 
     | 
    
         
            +
            }
         
     | 
| 
      
 383 
     | 
    
         
            +
             
     | 
| 
      
 384 
     | 
    
         
            +
            /* this method is currently only called for servers (in OpenSSL <= 0.9.8e) */
         
     | 
| 
      
 385 
     | 
    
         
            +
            static SSL_SESSION *
         
     | 
| 
      
 386 
     | 
    
         
            +
            #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
         
     | 
| 
      
 387 
     | 
    
         
            +
            ossl_sslctx_session_get_cb(SSL *ssl, const unsigned char *buf, int len, int *copy)
         
     | 
| 
      
 388 
     | 
    
         
            +
            #else
         
     | 
| 
      
 389 
     | 
    
         
            +
            ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
         
     | 
| 
      
 390 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 391 
     | 
    
         
            +
            {
         
     | 
| 
      
 392 
     | 
    
         
            +
                VALUE ary, ssl_obj, ret_obj;
         
     | 
| 
      
 393 
     | 
    
         
            +
                SSL_SESSION *sess;
         
     | 
| 
      
 394 
     | 
    
         
            +
                void *ptr;
         
     | 
| 
      
 395 
     | 
    
         
            +
                int state = 0;
         
     | 
| 
      
 396 
     | 
    
         
            +
             
     | 
| 
      
 397 
     | 
    
         
            +
                OSSL_Debug("SSL SESSION get callback entered");
         
     | 
| 
      
 398 
     | 
    
         
            +
                if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)
         
     | 
| 
      
 399 
     | 
    
         
            +
                	return NULL;
         
     | 
| 
      
 400 
     | 
    
         
            +
                ssl_obj = (VALUE)ptr;
         
     | 
| 
      
 401 
     | 
    
         
            +
                ary = rb_ary_new2(2);
         
     | 
| 
      
 402 
     | 
    
         
            +
                rb_ary_push(ary, ssl_obj);
         
     | 
| 
      
 403 
     | 
    
         
            +
                rb_ary_push(ary, rb_str_new((const char *)buf, len));
         
     | 
| 
      
 404 
     | 
    
         
            +
             
     | 
| 
      
 405 
     | 
    
         
            +
                ret_obj = rb_protect(ossl_call_session_get_cb, ary, &state);
         
     | 
| 
      
 406 
     | 
    
         
            +
                if (state) {
         
     | 
| 
      
 407 
     | 
    
         
            +
                    rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));
         
     | 
| 
      
 408 
     | 
    
         
            +
                    return NULL;
         
     | 
| 
      
 409 
     | 
    
         
            +
                }
         
     | 
| 
      
 410 
     | 
    
         
            +
                if (!rb_obj_is_instance_of(ret_obj, cSSLSession))
         
     | 
| 
      
 411 
     | 
    
         
            +
                    return NULL;
         
     | 
| 
      
 412 
     | 
    
         
            +
             
     | 
| 
      
 413 
     | 
    
         
            +
                SafeGetSSLSession(ret_obj, sess);
         
     | 
| 
      
 414 
     | 
    
         
            +
                *copy = 1;
         
     | 
| 
      
 415 
     | 
    
         
            +
             
     | 
| 
      
 416 
     | 
    
         
            +
                return sess;
         
     | 
| 
      
 417 
     | 
    
         
            +
            }
         
     | 
| 
      
 418 
     | 
    
         
            +
             
     | 
| 
      
 419 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 420 
     | 
    
         
            +
            ossl_call_session_new_cb(VALUE ary)
         
     | 
| 
      
 421 
     | 
    
         
            +
            {
         
     | 
| 
      
 422 
     | 
    
         
            +
                VALUE ssl_obj, cb;
         
     | 
| 
      
 423 
     | 
    
         
            +
             
     | 
| 
      
 424 
     | 
    
         
            +
                Check_Type(ary, T_ARRAY);
         
     | 
| 
      
 425 
     | 
    
         
            +
                ssl_obj = rb_ary_entry(ary, 0);
         
     | 
| 
      
 426 
     | 
    
         
            +
             
     | 
| 
      
 427 
     | 
    
         
            +
                cb = rb_funcall(ssl_obj, rb_intern("session_new_cb"), 0);
         
     | 
| 
      
 428 
     | 
    
         
            +
                if (NIL_P(cb)) return Qnil;
         
     | 
| 
      
 429 
     | 
    
         
            +
             
     | 
| 
      
 430 
     | 
    
         
            +
                return rb_funcall(cb, rb_intern("call"), 1, ary);
         
     | 
| 
      
 431 
     | 
    
         
            +
            }
         
     | 
| 
      
 432 
     | 
    
         
            +
             
     | 
| 
      
 433 
     | 
    
         
            +
            /* return 1 normal.  return 0 removes the session */
         
     | 
| 
      
 434 
     | 
    
         
            +
            static int
         
     | 
| 
      
 435 
     | 
    
         
            +
            ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
         
     | 
| 
      
 436 
     | 
    
         
            +
            {
         
     | 
| 
      
 437 
     | 
    
         
            +
                VALUE ary, ssl_obj, sess_obj;
         
     | 
| 
      
 438 
     | 
    
         
            +
                void *ptr;
         
     | 
| 
      
 439 
     | 
    
         
            +
                int state = 0;
         
     | 
| 
      
 440 
     | 
    
         
            +
             
     | 
| 
      
 441 
     | 
    
         
            +
                OSSL_Debug("SSL SESSION new callback entered");
         
     | 
| 
      
 442 
     | 
    
         
            +
             
     | 
| 
      
 443 
     | 
    
         
            +
                if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)
         
     | 
| 
      
 444 
     | 
    
         
            +
                	return 1;
         
     | 
| 
      
 445 
     | 
    
         
            +
                ssl_obj = (VALUE)ptr;
         
     | 
| 
      
 446 
     | 
    
         
            +
                sess_obj = rb_obj_alloc(cSSLSession);
         
     | 
| 
      
 447 
     | 
    
         
            +
                SSL_SESSION_up_ref(sess);
         
     | 
| 
      
 448 
     | 
    
         
            +
                DATA_PTR(sess_obj) = sess;
         
     | 
| 
      
 449 
     | 
    
         
            +
             
     | 
| 
      
 450 
     | 
    
         
            +
                ary = rb_ary_new2(2);
         
     | 
| 
      
 451 
     | 
    
         
            +
                rb_ary_push(ary, ssl_obj);
         
     | 
| 
      
 452 
     | 
    
         
            +
                rb_ary_push(ary, sess_obj);
         
     | 
| 
      
 453 
     | 
    
         
            +
             
     | 
| 
      
 454 
     | 
    
         
            +
                rb_protect(ossl_call_session_new_cb, ary, &state);
         
     | 
| 
      
 455 
     | 
    
         
            +
                if (state) {
         
     | 
| 
      
 456 
     | 
    
         
            +
                    rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));
         
     | 
| 
      
 457 
     | 
    
         
            +
                }
         
     | 
| 
      
 458 
     | 
    
         
            +
             
     | 
| 
      
 459 
     | 
    
         
            +
                /*
         
     | 
| 
      
 460 
     | 
    
         
            +
                 * return 0 which means to OpenSSL that the session is still
         
     | 
| 
      
 461 
     | 
    
         
            +
                 * valid (since we created Ruby Session object) and was not freed by us
         
     | 
| 
      
 462 
     | 
    
         
            +
                 * with SSL_SESSION_free(). Call SSLContext#remove_session(sess) in
         
     | 
| 
      
 463 
     | 
    
         
            +
                 * session_get_cb block if you don't want OpenSSL to cache the session
         
     | 
| 
      
 464 
     | 
    
         
            +
                 * internally.
         
     | 
| 
      
 465 
     | 
    
         
            +
                 */
         
     | 
| 
      
 466 
     | 
    
         
            +
                return 0;
         
     | 
| 
      
 467 
     | 
    
         
            +
            }
         
     | 
| 
      
 468 
     | 
    
         
            +
             
     | 
| 
      
 469 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 470 
     | 
    
         
            +
            ossl_call_session_remove_cb(VALUE ary)
         
     | 
| 
      
 471 
     | 
    
         
            +
            {
         
     | 
| 
      
 472 
     | 
    
         
            +
                VALUE sslctx_obj, cb;
         
     | 
| 
      
 473 
     | 
    
         
            +
             
     | 
| 
      
 474 
     | 
    
         
            +
                Check_Type(ary, T_ARRAY);
         
     | 
| 
      
 475 
     | 
    
         
            +
                sslctx_obj = rb_ary_entry(ary, 0);
         
     | 
| 
      
 476 
     | 
    
         
            +
             
     | 
| 
      
 477 
     | 
    
         
            +
                cb = rb_iv_get(sslctx_obj, "@session_remove_cb");
         
     | 
| 
      
 478 
     | 
    
         
            +
                if (NIL_P(cb)) return Qnil;
         
     | 
| 
      
 479 
     | 
    
         
            +
             
     | 
| 
      
 480 
     | 
    
         
            +
                return rb_funcall(cb, rb_intern("call"), 1, ary);
         
     | 
| 
      
 481 
     | 
    
         
            +
            }
         
     | 
| 
      
 482 
     | 
    
         
            +
             
     | 
| 
      
 483 
     | 
    
         
            +
            static void
         
     | 
| 
      
 484 
     | 
    
         
            +
            ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess)
         
     | 
| 
      
 485 
     | 
    
         
            +
            {
         
     | 
| 
      
 486 
     | 
    
         
            +
                VALUE ary, sslctx_obj, sess_obj;
         
     | 
| 
      
 487 
     | 
    
         
            +
                void *ptr;
         
     | 
| 
      
 488 
     | 
    
         
            +
                int state = 0;
         
     | 
| 
      
 489 
     | 
    
         
            +
             
     | 
| 
      
 490 
     | 
    
         
            +
                OSSL_Debug("SSL SESSION remove callback entered");
         
     | 
| 
      
 491 
     | 
    
         
            +
             
     | 
| 
      
 492 
     | 
    
         
            +
                if ((ptr = SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_ptr_idx)) == NULL)
         
     | 
| 
      
 493 
     | 
    
         
            +
                	return;
         
     | 
| 
      
 494 
     | 
    
         
            +
                sslctx_obj = (VALUE)ptr;
         
     | 
| 
      
 495 
     | 
    
         
            +
                sess_obj = rb_obj_alloc(cSSLSession);
         
     | 
| 
      
 496 
     | 
    
         
            +
                SSL_SESSION_up_ref(sess);
         
     | 
| 
      
 497 
     | 
    
         
            +
                DATA_PTR(sess_obj) = sess;
         
     | 
| 
      
 498 
     | 
    
         
            +
             
     | 
| 
      
 499 
     | 
    
         
            +
                ary = rb_ary_new2(2);
         
     | 
| 
      
 500 
     | 
    
         
            +
                rb_ary_push(ary, sslctx_obj);
         
     | 
| 
      
 501 
     | 
    
         
            +
                rb_ary_push(ary, sess_obj);
         
     | 
| 
      
 502 
     | 
    
         
            +
             
     | 
| 
      
 503 
     | 
    
         
            +
                rb_protect(ossl_call_session_remove_cb, ary, &state);
         
     | 
| 
      
 504 
     | 
    
         
            +
                if (state) {
         
     | 
| 
      
 505 
     | 
    
         
            +
            /*
         
     | 
| 
      
 506 
     | 
    
         
            +
              the SSL_CTX is frozen, nowhere to save state.
         
     | 
| 
      
 507 
     | 
    
         
            +
              there is no common accessor method to check it either.
         
     | 
| 
      
 508 
     | 
    
         
            +
                    rb_ivar_set(sslctx_obj, ID_callback_state, INT2NUM(state));
         
     | 
| 
      
 509 
     | 
    
         
            +
            */
         
     | 
| 
      
 510 
     | 
    
         
            +
                }
         
     | 
| 
      
 511 
     | 
    
         
            +
            }
         
     | 
| 
      
 512 
     | 
    
         
            +
             
     | 
| 
      
 513 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 514 
     | 
    
         
            +
            ossl_sslctx_add_extra_chain_cert_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, arg))
         
     | 
| 
      
 515 
     | 
    
         
            +
            {
         
     | 
| 
      
 516 
     | 
    
         
            +
                X509 *x509;
         
     | 
| 
      
 517 
     | 
    
         
            +
                SSL_CTX *ctx;
         
     | 
| 
      
 518 
     | 
    
         
            +
             
     | 
| 
      
 519 
     | 
    
         
            +
                GetSSLCTX(arg, ctx);
         
     | 
| 
      
 520 
     | 
    
         
            +
                x509 = DupX509CertPtr(i);
         
     | 
| 
      
 521 
     | 
    
         
            +
                if(!SSL_CTX_add_extra_chain_cert(ctx, x509)){
         
     | 
| 
      
 522 
     | 
    
         
            +
            	ossl_raise(eSSLError, NULL);
         
     | 
| 
      
 523 
     | 
    
         
            +
                }
         
     | 
| 
      
 524 
     | 
    
         
            +
             
     | 
| 
      
 525 
     | 
    
         
            +
                return i;
         
     | 
| 
      
 526 
     | 
    
         
            +
            }
         
     | 
| 
      
 527 
     | 
    
         
            +
             
     | 
| 
      
 528 
     | 
    
         
            +
            static VALUE ossl_sslctx_setup(VALUE self);
         
     | 
| 
      
 529 
     | 
    
         
            +
             
     | 
| 
      
 530 
     | 
    
         
            +
            #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
         
     | 
| 
      
 531 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 532 
     | 
    
         
            +
            ossl_call_servername_cb(VALUE ary)
         
     | 
| 
      
 533 
     | 
    
         
            +
            {
         
     | 
| 
      
 534 
     | 
    
         
            +
                VALUE ssl_obj, sslctx_obj, cb, ret_obj;
         
     | 
| 
      
 535 
     | 
    
         
            +
             
     | 
| 
      
 536 
     | 
    
         
            +
                Check_Type(ary, T_ARRAY);
         
     | 
| 
      
 537 
     | 
    
         
            +
                ssl_obj = rb_ary_entry(ary, 0);
         
     | 
| 
      
 538 
     | 
    
         
            +
             
     | 
| 
      
 539 
     | 
    
         
            +
                sslctx_obj = rb_iv_get(ssl_obj, "@context");
         
     | 
| 
      
 540 
     | 
    
         
            +
                if (NIL_P(sslctx_obj)) return Qnil;
         
     | 
| 
      
 541 
     | 
    
         
            +
                cb = rb_iv_get(sslctx_obj, "@servername_cb");
         
     | 
| 
      
 542 
     | 
    
         
            +
                if (NIL_P(cb)) return Qnil;
         
     | 
| 
      
 543 
     | 
    
         
            +
             
     | 
| 
      
 544 
     | 
    
         
            +
                ret_obj = rb_funcall(cb, rb_intern("call"), 1, ary);
         
     | 
| 
      
 545 
     | 
    
         
            +
                if (rb_obj_is_kind_of(ret_obj, cSSLContext)) {
         
     | 
| 
      
 546 
     | 
    
         
            +
                    SSL *ssl;
         
     | 
| 
      
 547 
     | 
    
         
            +
                    SSL_CTX *ctx2;
         
     | 
| 
      
 548 
     | 
    
         
            +
             
     | 
| 
      
 549 
     | 
    
         
            +
                    ossl_sslctx_setup(ret_obj);
         
     | 
| 
      
 550 
     | 
    
         
            +
                    GetSSL(ssl_obj, ssl);
         
     | 
| 
      
 551 
     | 
    
         
            +
                    GetSSLCTX(ret_obj, ctx2);
         
     | 
| 
      
 552 
     | 
    
         
            +
                    SSL_set_SSL_CTX(ssl, ctx2);
         
     | 
| 
      
 553 
     | 
    
         
            +
                    rb_iv_set(ssl_obj, "@context", ret_obj);
         
     | 
| 
      
 554 
     | 
    
         
            +
                } else if (!NIL_P(ret_obj)) {
         
     | 
| 
      
 555 
     | 
    
         
            +
                        ossl_raise(rb_eArgError, "servername_cb must return an OpenSSL::SSL::SSLContext object or nil");
         
     | 
| 
      
 556 
     | 
    
         
            +
                }
         
     | 
| 
      
 557 
     | 
    
         
            +
             
     | 
| 
      
 558 
     | 
    
         
            +
                return ret_obj;
         
     | 
| 
      
 559 
     | 
    
         
            +
            }
         
     | 
| 
      
 560 
     | 
    
         
            +
             
     | 
| 
      
 561 
     | 
    
         
            +
            static int
         
     | 
| 
      
 562 
     | 
    
         
            +
            ssl_servername_cb(SSL *ssl, int *ad, void *arg)
         
     | 
| 
      
 563 
     | 
    
         
            +
            {
         
     | 
| 
      
 564 
     | 
    
         
            +
                VALUE ary, ssl_obj;
         
     | 
| 
      
 565 
     | 
    
         
            +
                void *ptr;
         
     | 
| 
      
 566 
     | 
    
         
            +
                int state = 0;
         
     | 
| 
      
 567 
     | 
    
         
            +
                const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
         
     | 
| 
      
 568 
     | 
    
         
            +
             
     | 
| 
      
 569 
     | 
    
         
            +
                if (!servername)
         
     | 
| 
      
 570 
     | 
    
         
            +
                    return SSL_TLSEXT_ERR_OK;
         
     | 
| 
      
 571 
     | 
    
         
            +
             
     | 
| 
      
 572 
     | 
    
         
            +
                if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)
         
     | 
| 
      
 573 
     | 
    
         
            +
                	return SSL_TLSEXT_ERR_ALERT_FATAL;
         
     | 
| 
      
 574 
     | 
    
         
            +
                ssl_obj = (VALUE)ptr;
         
     | 
| 
      
 575 
     | 
    
         
            +
                ary = rb_ary_new2(2);
         
     | 
| 
      
 576 
     | 
    
         
            +
                rb_ary_push(ary, ssl_obj);
         
     | 
| 
      
 577 
     | 
    
         
            +
                rb_ary_push(ary, rb_str_new2(servername));
         
     | 
| 
      
 578 
     | 
    
         
            +
             
     | 
| 
      
 579 
     | 
    
         
            +
                rb_protect(ossl_call_servername_cb, ary, &state);
         
     | 
| 
      
 580 
     | 
    
         
            +
                if (state) {
         
     | 
| 
      
 581 
     | 
    
         
            +
                    rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));
         
     | 
| 
      
 582 
     | 
    
         
            +
                    return SSL_TLSEXT_ERR_ALERT_FATAL;
         
     | 
| 
      
 583 
     | 
    
         
            +
                }
         
     | 
| 
      
 584 
     | 
    
         
            +
             
     | 
| 
      
 585 
     | 
    
         
            +
                return SSL_TLSEXT_ERR_OK;
         
     | 
| 
      
 586 
     | 
    
         
            +
            }
         
     | 
| 
      
 587 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 588 
     | 
    
         
            +
             
     | 
| 
      
 589 
     | 
    
         
            +
            static void
         
     | 
| 
      
 590 
     | 
    
         
            +
            ssl_renegotiation_cb(const SSL *ssl)
         
     | 
| 
      
 591 
     | 
    
         
            +
            {
         
     | 
| 
      
 592 
     | 
    
         
            +
                VALUE ssl_obj, sslctx_obj, cb;
         
     | 
| 
      
 593 
     | 
    
         
            +
                void *ptr;
         
     | 
| 
      
 594 
     | 
    
         
            +
             
     | 
| 
      
 595 
     | 
    
         
            +
                if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)
         
     | 
| 
      
 596 
     | 
    
         
            +
            	ossl_raise(eSSLError, "SSL object could not be retrieved");
         
     | 
| 
      
 597 
     | 
    
         
            +
                ssl_obj = (VALUE)ptr;
         
     | 
| 
      
 598 
     | 
    
         
            +
             
     | 
| 
      
 599 
     | 
    
         
            +
                sslctx_obj = rb_iv_get(ssl_obj, "@context");
         
     | 
| 
      
 600 
     | 
    
         
            +
                if (NIL_P(sslctx_obj)) return;
         
     | 
| 
      
 601 
     | 
    
         
            +
                cb = rb_iv_get(sslctx_obj, "@renegotiation_cb");
         
     | 
| 
      
 602 
     | 
    
         
            +
                if (NIL_P(cb)) return;
         
     | 
| 
      
 603 
     | 
    
         
            +
             
     | 
| 
      
 604 
     | 
    
         
            +
                (void) rb_funcall(cb, rb_intern("call"), 1, ssl_obj);
         
     | 
| 
      
 605 
     | 
    
         
            +
            }
         
     | 
| 
      
 606 
     | 
    
         
            +
             
     | 
| 
      
 607 
     | 
    
         
            +
            #if defined(HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB) || defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB)
         
     | 
| 
      
 608 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 609 
     | 
    
         
            +
            ssl_npn_encode_protocol_i(VALUE cur, VALUE encoded)
         
     | 
| 
      
 610 
     | 
    
         
            +
            {
         
     | 
| 
      
 611 
     | 
    
         
            +
                int len = RSTRING_LENINT(cur);
         
     | 
| 
      
 612 
     | 
    
         
            +
                char len_byte;
         
     | 
| 
      
 613 
     | 
    
         
            +
                if (len < 1 || len > 255)
         
     | 
| 
      
 614 
     | 
    
         
            +
            	ossl_raise(eSSLError, "Advertised protocol must have length 1..255");
         
     | 
| 
      
 615 
     | 
    
         
            +
                /* Encode the length byte */
         
     | 
| 
      
 616 
     | 
    
         
            +
                len_byte = len;
         
     | 
| 
      
 617 
     | 
    
         
            +
                rb_str_buf_cat(encoded, &len_byte, 1);
         
     | 
| 
      
 618 
     | 
    
         
            +
                rb_str_buf_cat(encoded, RSTRING_PTR(cur), len);
         
     | 
| 
      
 619 
     | 
    
         
            +
                return Qnil;
         
     | 
| 
      
 620 
     | 
    
         
            +
            }
         
     | 
| 
      
 621 
     | 
    
         
            +
             
     | 
| 
      
 622 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 623 
     | 
    
         
            +
            ssl_encode_npn_protocols(VALUE protocols)
         
     | 
| 
      
 624 
     | 
    
         
            +
            {
         
     | 
| 
      
 625 
     | 
    
         
            +
                VALUE encoded = rb_str_new(NULL, 0);
         
     | 
| 
      
 626 
     | 
    
         
            +
                rb_iterate(rb_each, protocols, ssl_npn_encode_protocol_i, encoded);
         
     | 
| 
      
 627 
     | 
    
         
            +
                return encoded;
         
     | 
| 
      
 628 
     | 
    
         
            +
            }
         
     | 
| 
      
 629 
     | 
    
         
            +
             
     | 
| 
      
 630 
     | 
    
         
            +
            static int
         
     | 
| 
      
 631 
     | 
    
         
            +
            ssl_npn_select_cb_common(VALUE cb, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen)
         
     | 
| 
      
 632 
     | 
    
         
            +
            {
         
     | 
| 
      
 633 
     | 
    
         
            +
                VALUE selected;
         
     | 
| 
      
 634 
     | 
    
         
            +
                long len;
         
     | 
| 
      
 635 
     | 
    
         
            +
                VALUE protocols = rb_ary_new();
         
     | 
| 
      
 636 
     | 
    
         
            +
                unsigned char l;
         
     | 
| 
      
 637 
     | 
    
         
            +
                const unsigned char *in_end = in + inlen;
         
     | 
| 
      
 638 
     | 
    
         
            +
             
     | 
| 
      
 639 
     | 
    
         
            +
                /* assume OpenSSL verifies this format */
         
     | 
| 
      
 640 
     | 
    
         
            +
                /* The format is len_1|proto_1|...|len_n|proto_n */
         
     | 
| 
      
 641 
     | 
    
         
            +
                while (in < in_end) {
         
     | 
| 
      
 642 
     | 
    
         
            +
            	l = *in++;
         
     | 
| 
      
 643 
     | 
    
         
            +
            	rb_ary_push(protocols, rb_str_new((const char *)in, l));
         
     | 
| 
      
 644 
     | 
    
         
            +
            	in += l;
         
     | 
| 
      
 645 
     | 
    
         
            +
                }
         
     | 
| 
      
 646 
     | 
    
         
            +
             
     | 
| 
      
 647 
     | 
    
         
            +
                selected = rb_funcall(cb, rb_intern("call"), 1, protocols);
         
     | 
| 
      
 648 
     | 
    
         
            +
                StringValue(selected);
         
     | 
| 
      
 649 
     | 
    
         
            +
                len = RSTRING_LEN(selected);
         
     | 
| 
      
 650 
     | 
    
         
            +
                if (len < 1 || len >= 256) {
         
     | 
| 
      
 651 
     | 
    
         
            +
            	ossl_raise(eSSLError, "Selected protocol name must have length 1..255");
         
     | 
| 
      
 652 
     | 
    
         
            +
                }
         
     | 
| 
      
 653 
     | 
    
         
            +
                *out = (unsigned char *)RSTRING_PTR(selected);
         
     | 
| 
      
 654 
     | 
    
         
            +
                *outlen = (unsigned char)len;
         
     | 
| 
      
 655 
     | 
    
         
            +
             
     | 
| 
      
 656 
     | 
    
         
            +
                return SSL_TLSEXT_ERR_OK;
         
     | 
| 
      
 657 
     | 
    
         
            +
            }
         
     | 
| 
      
 658 
     | 
    
         
            +
             
     | 
| 
      
 659 
     | 
    
         
            +
            #ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
         
     | 
| 
      
 660 
     | 
    
         
            +
            static int
         
     | 
| 
      
 661 
     | 
    
         
            +
            ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen, void *arg)
         
     | 
| 
      
 662 
     | 
    
         
            +
            {
         
     | 
| 
      
 663 
     | 
    
         
            +
                VALUE protocols = (VALUE)arg;
         
     | 
| 
      
 664 
     | 
    
         
            +
             
     | 
| 
      
 665 
     | 
    
         
            +
                *out = (const unsigned char *) RSTRING_PTR(protocols);
         
     | 
| 
      
 666 
     | 
    
         
            +
                *outlen = RSTRING_LENINT(protocols);
         
     | 
| 
      
 667 
     | 
    
         
            +
             
     | 
| 
      
 668 
     | 
    
         
            +
                return SSL_TLSEXT_ERR_OK;
         
     | 
| 
      
 669 
     | 
    
         
            +
            }
         
     | 
| 
      
 670 
     | 
    
         
            +
             
     | 
| 
      
 671 
     | 
    
         
            +
            static int
         
     | 
| 
      
 672 
     | 
    
         
            +
            ssl_npn_select_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
         
     | 
| 
      
 673 
     | 
    
         
            +
            {
         
     | 
| 
      
 674 
     | 
    
         
            +
                VALUE sslctx_obj, cb;
         
     | 
| 
      
 675 
     | 
    
         
            +
             
     | 
| 
      
 676 
     | 
    
         
            +
                sslctx_obj = (VALUE) arg;
         
     | 
| 
      
 677 
     | 
    
         
            +
                cb = rb_iv_get(sslctx_obj, "@npn_select_cb");
         
     | 
| 
      
 678 
     | 
    
         
            +
             
     | 
| 
      
 679 
     | 
    
         
            +
                return ssl_npn_select_cb_common(cb, (const unsigned char **)out, outlen, in, inlen);
         
     | 
| 
      
 680 
     | 
    
         
            +
            }
         
     | 
| 
      
 681 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 682 
     | 
    
         
            +
             
     | 
| 
      
 683 
     | 
    
         
            +
            #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
         
     | 
| 
      
 684 
     | 
    
         
            +
            static int
         
     | 
| 
      
 685 
     | 
    
         
            +
            ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
         
     | 
| 
      
 686 
     | 
    
         
            +
            {
         
     | 
| 
      
 687 
     | 
    
         
            +
                VALUE sslctx_obj, cb;
         
     | 
| 
      
 688 
     | 
    
         
            +
             
     | 
| 
      
 689 
     | 
    
         
            +
                sslctx_obj = (VALUE) arg;
         
     | 
| 
      
 690 
     | 
    
         
            +
                cb = rb_iv_get(sslctx_obj, "@alpn_select_cb");
         
     | 
| 
      
 691 
     | 
    
         
            +
             
     | 
| 
      
 692 
     | 
    
         
            +
                return ssl_npn_select_cb_common(cb, out, outlen, in, inlen);
         
     | 
| 
      
 693 
     | 
    
         
            +
            }
         
     | 
| 
      
 694 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 695 
     | 
    
         
            +
            #endif /* HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB || HAVE_SSL_CTX_SET_ALPN_SELECT_CB */
         
     | 
| 
      
 696 
     | 
    
         
            +
             
     | 
| 
      
 697 
     | 
    
         
            +
            /* This function may serve as the entry point to support further callbacks. */
         
     | 
| 
      
 698 
     | 
    
         
            +
            static void
         
     | 
| 
      
 699 
     | 
    
         
            +
            ssl_info_cb(const SSL *ssl, int where, int val)
         
     | 
| 
      
 700 
     | 
    
         
            +
            {
         
     | 
| 
      
 701 
     | 
    
         
            +
                int is_server = SSL_is_server((SSL *)ssl);
         
     | 
| 
      
 702 
     | 
    
         
            +
             
     | 
| 
      
 703 
     | 
    
         
            +
                if (is_server && where & SSL_CB_HANDSHAKE_START) {
         
     | 
| 
      
 704 
     | 
    
         
            +
            	ssl_renegotiation_cb(ssl);
         
     | 
| 
      
 705 
     | 
    
         
            +
                }
         
     | 
| 
      
 706 
     | 
    
         
            +
            }
         
     | 
| 
      
 707 
     | 
    
         
            +
             
     | 
| 
      
 708 
     | 
    
         
            +
            /*
         
     | 
| 
      
 709 
     | 
    
         
            +
             * Gets various OpenSSL options.
         
     | 
| 
      
 710 
     | 
    
         
            +
             */
         
     | 
| 
      
 711 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 712 
     | 
    
         
            +
            ossl_sslctx_get_options(VALUE self)
         
     | 
| 
      
 713 
     | 
    
         
            +
            {
         
     | 
| 
      
 714 
     | 
    
         
            +
                SSL_CTX *ctx;
         
     | 
| 
      
 715 
     | 
    
         
            +
                GetSSLCTX(self, ctx);
         
     | 
| 
      
 716 
     | 
    
         
            +
                return LONG2NUM(SSL_CTX_get_options(ctx));
         
     | 
| 
      
 717 
     | 
    
         
            +
            }
         
     | 
| 
      
 718 
     | 
    
         
            +
             
     | 
| 
      
 719 
     | 
    
         
            +
            /*
         
     | 
| 
      
 720 
     | 
    
         
            +
             * Sets various OpenSSL options.
         
     | 
| 
      
 721 
     | 
    
         
            +
             */
         
     | 
| 
      
 722 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 723 
     | 
    
         
            +
            ossl_sslctx_set_options(VALUE self, VALUE options)
         
     | 
| 
      
 724 
     | 
    
         
            +
            {
         
     | 
| 
      
 725 
     | 
    
         
            +
                SSL_CTX *ctx;
         
     | 
| 
      
 726 
     | 
    
         
            +
             
     | 
| 
      
 727 
     | 
    
         
            +
                rb_check_frozen(self);
         
     | 
| 
      
 728 
     | 
    
         
            +
                GetSSLCTX(self, ctx);
         
     | 
| 
      
 729 
     | 
    
         
            +
             
     | 
| 
      
 730 
     | 
    
         
            +
                SSL_CTX_clear_options(ctx, SSL_CTX_get_options(ctx));
         
     | 
| 
      
 731 
     | 
    
         
            +
             
     | 
| 
      
 732 
     | 
    
         
            +
                if (NIL_P(options)) {
         
     | 
| 
      
 733 
     | 
    
         
            +
            	SSL_CTX_set_options(ctx, SSL_OP_ALL);
         
     | 
| 
      
 734 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 735 
     | 
    
         
            +
            	SSL_CTX_set_options(ctx, NUM2LONG(options));
         
     | 
| 
      
 736 
     | 
    
         
            +
                }
         
     | 
| 
      
 737 
     | 
    
         
            +
             
     | 
| 
      
 738 
     | 
    
         
            +
                return self;
         
     | 
| 
      
 739 
     | 
    
         
            +
            }
         
     | 
| 
      
 740 
     | 
    
         
            +
             
     | 
| 
      
 741 
     | 
    
         
            +
            /*
         
     | 
| 
      
 742 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 743 
     | 
    
         
            +
             *    ctx.setup => Qtrue # first time
         
     | 
| 
      
 744 
     | 
    
         
            +
             *    ctx.setup => nil # thereafter
         
     | 
| 
      
 745 
     | 
    
         
            +
             *
         
     | 
| 
      
 746 
     | 
    
         
            +
             * This method is called automatically when a new SSLSocket is created.
         
     | 
| 
      
 747 
     | 
    
         
            +
             * However, it is not thread-safe and must be called before creating
         
     | 
| 
      
 748 
     | 
    
         
            +
             * SSLSocket objects in a multi-threaded program.
         
     | 
| 
      
 749 
     | 
    
         
            +
             */
         
     | 
| 
      
 750 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 751 
     | 
    
         
            +
            ossl_sslctx_setup(VALUE self)
         
     | 
| 
      
 752 
     | 
    
         
            +
            {
         
     | 
| 
      
 753 
     | 
    
         
            +
                SSL_CTX *ctx;
         
     | 
| 
      
 754 
     | 
    
         
            +
                X509 *cert = NULL, *client_ca = NULL;
         
     | 
| 
      
 755 
     | 
    
         
            +
                EVP_PKEY *key = NULL;
         
     | 
| 
      
 756 
     | 
    
         
            +
                char *ca_path = NULL, *ca_file = NULL;
         
     | 
| 
      
 757 
     | 
    
         
            +
                int verify_mode;
         
     | 
| 
      
 758 
     | 
    
         
            +
                long i;
         
     | 
| 
      
 759 
     | 
    
         
            +
                VALUE val;
         
     | 
| 
      
 760 
     | 
    
         
            +
             
     | 
| 
      
 761 
     | 
    
         
            +
                if(OBJ_FROZEN(self)) return Qnil;
         
     | 
| 
      
 762 
     | 
    
         
            +
                GetSSLCTX(self, ctx);
         
     | 
| 
      
 763 
     | 
    
         
            +
             
     | 
| 
      
 764 
     | 
    
         
            +
            #if !defined(OPENSSL_NO_DH)
         
     | 
| 
      
 765 
     | 
    
         
            +
                SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
         
     | 
| 
      
 766 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 767 
     | 
    
         
            +
             
     | 
| 
      
 768 
     | 
    
         
            +
            #if !defined(OPENSSL_NO_EC)
         
     | 
| 
      
 769 
     | 
    
         
            +
                /* We added SSLContext#tmp_ecdh_callback= in Ruby 2.3.0,
         
     | 
| 
      
 770 
     | 
    
         
            +
                 * but SSL_CTX_set_tmp_ecdh_callback() was removed in OpenSSL 1.1.0. */
         
     | 
| 
      
 771 
     | 
    
         
            +
                if (RTEST(ossl_sslctx_get_tmp_ecdh_cb(self))) {
         
     | 
| 
      
 772 
     | 
    
         
            +
            # if defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
         
     | 
| 
      
 773 
     | 
    
         
            +
            	rb_warn("#tmp_ecdh_callback= is deprecated; use #ecdh_curves= instead");
         
     | 
| 
      
 774 
     | 
    
         
            +
            	SSL_CTX_set_tmp_ecdh_callback(ctx, ossl_tmp_ecdh_callback);
         
     | 
| 
      
 775 
     | 
    
         
            +
            #  if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
         
     | 
| 
      
 776 
     | 
    
         
            +
            	/* tmp_ecdh_callback and ecdh_auto conflict; OpenSSL ignores
         
     | 
| 
      
 777 
     | 
    
         
            +
            	 * tmp_ecdh_callback. So disable ecdh_auto. */
         
     | 
| 
      
 778 
     | 
    
         
            +
            	if (!SSL_CTX_set_ecdh_auto(ctx, 0))
         
     | 
| 
      
 779 
     | 
    
         
            +
            	    ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
         
     | 
| 
      
 780 
     | 
    
         
            +
            #  endif
         
     | 
| 
      
 781 
     | 
    
         
            +
            # else
         
     | 
| 
      
 782 
     | 
    
         
            +
            	ossl_raise(eSSLError, "OpenSSL does not support tmp_ecdh_callback; "
         
     | 
| 
      
 783 
     | 
    
         
            +
            		   "use #ecdh_curves= instead");
         
     | 
| 
      
 784 
     | 
    
         
            +
            # endif
         
     | 
| 
      
 785 
     | 
    
         
            +
                }
         
     | 
| 
      
 786 
     | 
    
         
            +
            #endif /* OPENSSL_NO_EC */
         
     | 
| 
      
 787 
     | 
    
         
            +
             
     | 
| 
      
 788 
     | 
    
         
            +
                val = ossl_sslctx_get_cert_store(self);
         
     | 
| 
      
 789 
     | 
    
         
            +
                if (!NIL_P(val)) {
         
     | 
| 
      
 790 
     | 
    
         
            +
            	X509_STORE *store = GetX509StorePtr(val); /* NO NEED TO DUP */
         
     | 
| 
      
 791 
     | 
    
         
            +
            	SSL_CTX_set_cert_store(ctx, store);
         
     | 
| 
      
 792 
     | 
    
         
            +
            #if !defined(HAVE_X509_STORE_UP_REF)
         
     | 
| 
      
 793 
     | 
    
         
            +
            	/*
         
     | 
| 
      
 794 
     | 
    
         
            +
                     * WORKAROUND:
         
     | 
| 
      
 795 
     | 
    
         
            +
            	 *   X509_STORE can count references, but
         
     | 
| 
      
 796 
     | 
    
         
            +
            	 *   X509_STORE_free() doesn't care it.
         
     | 
| 
      
 797 
     | 
    
         
            +
            	 *   So we won't increment it but mark it by ex_data.
         
     | 
| 
      
 798 
     | 
    
         
            +
            	 */
         
     | 
| 
      
 799 
     | 
    
         
            +
                    SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_store_p, (void *)1);
         
     | 
| 
      
 800 
     | 
    
         
            +
            #else /* Fixed in OpenSSL 1.0.2; bff9ce4db38b (master), 5b4b9ce976fc (1.0.2) */
         
     | 
| 
      
 801 
     | 
    
         
            +
            	X509_STORE_up_ref(store);
         
     | 
| 
      
 802 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 803 
     | 
    
         
            +
                }
         
     | 
| 
      
 804 
     | 
    
         
            +
             
     | 
| 
      
 805 
     | 
    
         
            +
                val = ossl_sslctx_get_extra_cert(self);
         
     | 
| 
      
 806 
     | 
    
         
            +
                if(!NIL_P(val)){
         
     | 
| 
      
 807 
     | 
    
         
            +
            	rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self);
         
     | 
| 
      
 808 
     | 
    
         
            +
                }
         
     | 
| 
      
 809 
     | 
    
         
            +
             
     | 
| 
      
 810 
     | 
    
         
            +
                /* private key may be bundled in certificate file. */
         
     | 
| 
      
 811 
     | 
    
         
            +
                val = ossl_sslctx_get_cert(self);
         
     | 
| 
      
 812 
     | 
    
         
            +
                cert = NIL_P(val) ? NULL : GetX509CertPtr(val); /* NO DUP NEEDED */
         
     | 
| 
      
 813 
     | 
    
         
            +
                val = ossl_sslctx_get_key(self);
         
     | 
| 
      
 814 
     | 
    
         
            +
                key = NIL_P(val) ? NULL : GetPrivPKeyPtr(val); /* NO DUP NEEDED */
         
     | 
| 
      
 815 
     | 
    
         
            +
                if (cert && key) {
         
     | 
| 
      
 816 
     | 
    
         
            +
                    if (!SSL_CTX_use_certificate(ctx, cert)) {
         
     | 
| 
      
 817 
     | 
    
         
            +
                        /* Adds a ref => Safe to FREE */
         
     | 
| 
      
 818 
     | 
    
         
            +
                        ossl_raise(eSSLError, "SSL_CTX_use_certificate");
         
     | 
| 
      
 819 
     | 
    
         
            +
                    }
         
     | 
| 
      
 820 
     | 
    
         
            +
                    if (!SSL_CTX_use_PrivateKey(ctx, key)) {
         
     | 
| 
      
 821 
     | 
    
         
            +
                        /* Adds a ref => Safe to FREE */
         
     | 
| 
      
 822 
     | 
    
         
            +
                        ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey");
         
     | 
| 
      
 823 
     | 
    
         
            +
                    }
         
     | 
| 
      
 824 
     | 
    
         
            +
                    if (!SSL_CTX_check_private_key(ctx)) {
         
     | 
| 
      
 825 
     | 
    
         
            +
                        ossl_raise(eSSLError, "SSL_CTX_check_private_key");
         
     | 
| 
      
 826 
     | 
    
         
            +
                    }
         
     | 
| 
      
 827 
     | 
    
         
            +
                }
         
     | 
| 
      
 828 
     | 
    
         
            +
             
     | 
| 
      
 829 
     | 
    
         
            +
                val = ossl_sslctx_get_client_ca(self);
         
     | 
| 
      
 830 
     | 
    
         
            +
                if(!NIL_P(val)){
         
     | 
| 
      
 831 
     | 
    
         
            +
            	if (RB_TYPE_P(val, T_ARRAY)) {
         
     | 
| 
      
 832 
     | 
    
         
            +
            	    for(i = 0; i < RARRAY_LEN(val); i++){
         
     | 
| 
      
 833 
     | 
    
         
            +
            		client_ca = GetX509CertPtr(RARRAY_AREF(val, i));
         
     | 
| 
      
 834 
     | 
    
         
            +
                    	if (!SSL_CTX_add_client_CA(ctx, client_ca)){
         
     | 
| 
      
 835 
     | 
    
         
            +
            		    /* Copies X509_NAME => FREE it. */
         
     | 
| 
      
 836 
     | 
    
         
            +
                    	    ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
         
     | 
| 
      
 837 
     | 
    
         
            +
                    	}
         
     | 
| 
      
 838 
     | 
    
         
            +
            	    }
         
     | 
| 
      
 839 
     | 
    
         
            +
                    }
         
     | 
| 
      
 840 
     | 
    
         
            +
            	else{
         
     | 
| 
      
 841 
     | 
    
         
            +
            	    client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */
         
     | 
| 
      
 842 
     | 
    
         
            +
                        if (!SSL_CTX_add_client_CA(ctx, client_ca)){
         
     | 
| 
      
 843 
     | 
    
         
            +
            		/* Copies X509_NAME => FREE it. */
         
     | 
| 
      
 844 
     | 
    
         
            +
                    	ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
         
     | 
| 
      
 845 
     | 
    
         
            +
                        }
         
     | 
| 
      
 846 
     | 
    
         
            +
            	}
         
     | 
| 
      
 847 
     | 
    
         
            +
                }
         
     | 
| 
      
 848 
     | 
    
         
            +
             
     | 
| 
      
 849 
     | 
    
         
            +
                val = ossl_sslctx_get_ca_file(self);
         
     | 
| 
      
 850 
     | 
    
         
            +
                ca_file = NIL_P(val) ? NULL : StringValueCStr(val);
         
     | 
| 
      
 851 
     | 
    
         
            +
                val = ossl_sslctx_get_ca_path(self);
         
     | 
| 
      
 852 
     | 
    
         
            +
                ca_path = NIL_P(val) ? NULL : StringValueCStr(val);
         
     | 
| 
      
 853 
     | 
    
         
            +
                if(ca_file || ca_path){
         
     | 
| 
      
 854 
     | 
    
         
            +
            	if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
         
     | 
| 
      
 855 
     | 
    
         
            +
            	    rb_warning("can't set verify locations");
         
     | 
| 
      
 856 
     | 
    
         
            +
                }
         
     | 
| 
      
 857 
     | 
    
         
            +
             
     | 
| 
      
 858 
     | 
    
         
            +
                val = ossl_sslctx_get_verify_mode(self);
         
     | 
| 
      
 859 
     | 
    
         
            +
                verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);
         
     | 
| 
      
 860 
     | 
    
         
            +
                SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback);
         
     | 
| 
      
 861 
     | 
    
         
            +
                if (RTEST(ossl_sslctx_get_client_cert_cb(self)))
         
     | 
| 
      
 862 
     | 
    
         
            +
            	SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb);
         
     | 
| 
      
 863 
     | 
    
         
            +
             
     | 
| 
      
 864 
     | 
    
         
            +
                val = ossl_sslctx_get_timeout(self);
         
     | 
| 
      
 865 
     | 
    
         
            +
                if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val));
         
     | 
| 
      
 866 
     | 
    
         
            +
             
     | 
| 
      
 867 
     | 
    
         
            +
                val = ossl_sslctx_get_verify_dep(self);
         
     | 
| 
      
 868 
     | 
    
         
            +
                if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val));
         
     | 
| 
      
 869 
     | 
    
         
            +
             
     | 
| 
      
 870 
     | 
    
         
            +
            #ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
         
     | 
| 
      
 871 
     | 
    
         
            +
                val = rb_iv_get(self, "@npn_protocols");
         
     | 
| 
      
 872 
     | 
    
         
            +
                if (!NIL_P(val)) {
         
     | 
| 
      
 873 
     | 
    
         
            +
            	VALUE encoded = ssl_encode_npn_protocols(val);
         
     | 
| 
      
 874 
     | 
    
         
            +
            	SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)encoded);
         
     | 
| 
      
 875 
     | 
    
         
            +
            	OSSL_Debug("SSL NPN advertise callback added");
         
     | 
| 
      
 876 
     | 
    
         
            +
                }
         
     | 
| 
      
 877 
     | 
    
         
            +
                if (RTEST(rb_iv_get(self, "@npn_select_cb"))) {
         
     | 
| 
      
 878 
     | 
    
         
            +
            	SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (void *) self);
         
     | 
| 
      
 879 
     | 
    
         
            +
            	OSSL_Debug("SSL NPN select callback added");
         
     | 
| 
      
 880 
     | 
    
         
            +
                }
         
     | 
| 
      
 881 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 882 
     | 
    
         
            +
             
     | 
| 
      
 883 
     | 
    
         
            +
            #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
         
     | 
| 
      
 884 
     | 
    
         
            +
                val = rb_iv_get(self, "@alpn_protocols");
         
     | 
| 
      
 885 
     | 
    
         
            +
                if (!NIL_P(val)) {
         
     | 
| 
      
 886 
     | 
    
         
            +
            	VALUE rprotos = ssl_encode_npn_protocols(val);
         
     | 
| 
      
 887 
     | 
    
         
            +
            	SSL_CTX_set_alpn_protos(ctx, (unsigned char *)RSTRING_PTR(rprotos), RSTRING_LENINT(rprotos));
         
     | 
| 
      
 888 
     | 
    
         
            +
            	OSSL_Debug("SSL ALPN values added");
         
     | 
| 
      
 889 
     | 
    
         
            +
                }
         
     | 
| 
      
 890 
     | 
    
         
            +
                if (RTEST(rb_iv_get(self, "@alpn_select_cb"))) {
         
     | 
| 
      
 891 
     | 
    
         
            +
            	SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self);
         
     | 
| 
      
 892 
     | 
    
         
            +
            	OSSL_Debug("SSL ALPN select callback added");
         
     | 
| 
      
 893 
     | 
    
         
            +
                }
         
     | 
| 
      
 894 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 895 
     | 
    
         
            +
             
     | 
| 
      
 896 
     | 
    
         
            +
                rb_obj_freeze(self);
         
     | 
| 
      
 897 
     | 
    
         
            +
             
     | 
| 
      
 898 
     | 
    
         
            +
                val = ossl_sslctx_get_sess_id_ctx(self);
         
     | 
| 
      
 899 
     | 
    
         
            +
                if (!NIL_P(val)){
         
     | 
| 
      
 900 
     | 
    
         
            +
            	StringValue(val);
         
     | 
| 
      
 901 
     | 
    
         
            +
            	if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val),
         
     | 
| 
      
 902 
     | 
    
         
            +
            					    RSTRING_LENINT(val))){
         
     | 
| 
      
 903 
     | 
    
         
            +
            	    ossl_raise(eSSLError, "SSL_CTX_set_session_id_context");
         
     | 
| 
      
 904 
     | 
    
         
            +
            	}
         
     | 
| 
      
 905 
     | 
    
         
            +
                }
         
     | 
| 
      
 906 
     | 
    
         
            +
             
     | 
| 
      
 907 
     | 
    
         
            +
                if (RTEST(rb_iv_get(self, "@session_get_cb"))) {
         
     | 
| 
      
 908 
     | 
    
         
            +
            	SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb);
         
     | 
| 
      
 909 
     | 
    
         
            +
            	OSSL_Debug("SSL SESSION get callback added");
         
     | 
| 
      
 910 
     | 
    
         
            +
                }
         
     | 
| 
      
 911 
     | 
    
         
            +
                if (RTEST(rb_iv_get(self, "@session_new_cb"))) {
         
     | 
| 
      
 912 
     | 
    
         
            +
            	SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb);
         
     | 
| 
      
 913 
     | 
    
         
            +
            	OSSL_Debug("SSL SESSION new callback added");
         
     | 
| 
      
 914 
     | 
    
         
            +
                }
         
     | 
| 
      
 915 
     | 
    
         
            +
                if (RTEST(rb_iv_get(self, "@session_remove_cb"))) {
         
     | 
| 
      
 916 
     | 
    
         
            +
            	SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb);
         
     | 
| 
      
 917 
     | 
    
         
            +
            	OSSL_Debug("SSL SESSION remove callback added");
         
     | 
| 
      
 918 
     | 
    
         
            +
                }
         
     | 
| 
      
 919 
     | 
    
         
            +
             
     | 
| 
      
 920 
     | 
    
         
            +
            #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
         
     | 
| 
      
 921 
     | 
    
         
            +
                val = rb_iv_get(self, "@servername_cb");
         
     | 
| 
      
 922 
     | 
    
         
            +
                if (!NIL_P(val)) {
         
     | 
| 
      
 923 
     | 
    
         
            +
                    SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
         
     | 
| 
      
 924 
     | 
    
         
            +
            	OSSL_Debug("SSL TLSEXT servername callback added");
         
     | 
| 
      
 925 
     | 
    
         
            +
                }
         
     | 
| 
      
 926 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 927 
     | 
    
         
            +
             
     | 
| 
      
 928 
     | 
    
         
            +
                return Qtrue;
         
     | 
| 
      
 929 
     | 
    
         
            +
            }
         
     | 
| 
      
 930 
     | 
    
         
            +
             
     | 
| 
      
 931 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 932 
     | 
    
         
            +
            ossl_ssl_cipher_to_ary(const SSL_CIPHER *cipher)
         
     | 
| 
      
 933 
     | 
    
         
            +
            {
         
     | 
| 
      
 934 
     | 
    
         
            +
                VALUE ary;
         
     | 
| 
      
 935 
     | 
    
         
            +
                int bits, alg_bits;
         
     | 
| 
      
 936 
     | 
    
         
            +
             
     | 
| 
      
 937 
     | 
    
         
            +
                ary = rb_ary_new2(4);
         
     | 
| 
      
 938 
     | 
    
         
            +
                rb_ary_push(ary, rb_str_new2(SSL_CIPHER_get_name(cipher)));
         
     | 
| 
      
 939 
     | 
    
         
            +
                rb_ary_push(ary, rb_str_new2(SSL_CIPHER_get_version(cipher)));
         
     | 
| 
      
 940 
     | 
    
         
            +
                bits = SSL_CIPHER_get_bits(cipher, &alg_bits);
         
     | 
| 
      
 941 
     | 
    
         
            +
                rb_ary_push(ary, INT2NUM(bits));
         
     | 
| 
      
 942 
     | 
    
         
            +
                rb_ary_push(ary, INT2NUM(alg_bits));
         
     | 
| 
      
 943 
     | 
    
         
            +
             
     | 
| 
      
 944 
     | 
    
         
            +
                return ary;
         
     | 
| 
      
 945 
     | 
    
         
            +
            }
         
     | 
| 
      
 946 
     | 
    
         
            +
             
     | 
| 
      
 947 
     | 
    
         
            +
            /*
         
     | 
| 
      
 948 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 949 
     | 
    
         
            +
             *    ctx.ciphers => [[name, version, bits, alg_bits], ...]
         
     | 
| 
      
 950 
     | 
    
         
            +
             *
         
     | 
| 
      
 951 
     | 
    
         
            +
             * The list of cipher suites configured for this context.
         
     | 
| 
      
 952 
     | 
    
         
            +
             */
         
     | 
| 
      
 953 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 954 
     | 
    
         
            +
            ossl_sslctx_get_ciphers(VALUE self)
         
     | 
| 
      
 955 
     | 
    
         
            +
            {
         
     | 
| 
      
 956 
     | 
    
         
            +
                SSL_CTX *ctx;
         
     | 
| 
      
 957 
     | 
    
         
            +
                STACK_OF(SSL_CIPHER) *ciphers;
         
     | 
| 
      
 958 
     | 
    
         
            +
                const SSL_CIPHER *cipher;
         
     | 
| 
      
 959 
     | 
    
         
            +
                VALUE ary;
         
     | 
| 
      
 960 
     | 
    
         
            +
                int i, num;
         
     | 
| 
      
 961 
     | 
    
         
            +
             
     | 
| 
      
 962 
     | 
    
         
            +
                GetSSLCTX(self, ctx);
         
     | 
| 
      
 963 
     | 
    
         
            +
                if(!ctx){
         
     | 
| 
      
 964 
     | 
    
         
            +
                    rb_warning("SSL_CTX is not initialized.");
         
     | 
| 
      
 965 
     | 
    
         
            +
                    return Qnil;
         
     | 
| 
      
 966 
     | 
    
         
            +
                }
         
     | 
| 
      
 967 
     | 
    
         
            +
                ciphers = SSL_CTX_get_ciphers(ctx);
         
     | 
| 
      
 968 
     | 
    
         
            +
             
     | 
| 
      
 969 
     | 
    
         
            +
                if (!ciphers)
         
     | 
| 
      
 970 
     | 
    
         
            +
                    return rb_ary_new();
         
     | 
| 
      
 971 
     | 
    
         
            +
             
     | 
| 
      
 972 
     | 
    
         
            +
                num = sk_SSL_CIPHER_num(ciphers);
         
     | 
| 
      
 973 
     | 
    
         
            +
                ary = rb_ary_new2(num);
         
     | 
| 
      
 974 
     | 
    
         
            +
                for(i = 0; i < num; i++){
         
     | 
| 
      
 975 
     | 
    
         
            +
                    cipher = sk_SSL_CIPHER_value(ciphers, i);
         
     | 
| 
      
 976 
     | 
    
         
            +
                    rb_ary_push(ary, ossl_ssl_cipher_to_ary(cipher));
         
     | 
| 
      
 977 
     | 
    
         
            +
                }
         
     | 
| 
      
 978 
     | 
    
         
            +
                return ary;
         
     | 
| 
      
 979 
     | 
    
         
            +
            }
         
     | 
| 
      
 980 
     | 
    
         
            +
             
     | 
| 
      
 981 
     | 
    
         
            +
            /*
         
     | 
| 
      
 982 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 983 
     | 
    
         
            +
             *    ctx.ciphers = "cipher1:cipher2:..."
         
     | 
| 
      
 984 
     | 
    
         
            +
             *    ctx.ciphers = [name, ...]
         
     | 
| 
      
 985 
     | 
    
         
            +
             *    ctx.ciphers = [[name, version, bits, alg_bits], ...]
         
     | 
| 
      
 986 
     | 
    
         
            +
             *
         
     | 
| 
      
 987 
     | 
    
         
            +
             * Sets the list of available cipher suites for this context.  Note in a server
         
     | 
| 
      
 988 
     | 
    
         
            +
             * context some ciphers require the appropriate certificates.  For example, an
         
     | 
| 
      
 989 
     | 
    
         
            +
             * RSA cipher suite can only be chosen when an RSA certificate is available.
         
     | 
| 
      
 990 
     | 
    
         
            +
             */
         
     | 
| 
      
 991 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 992 
     | 
    
         
            +
            ossl_sslctx_set_ciphers(VALUE self, VALUE v)
         
     | 
| 
      
 993 
     | 
    
         
            +
            {
         
     | 
| 
      
 994 
     | 
    
         
            +
                SSL_CTX *ctx;
         
     | 
| 
      
 995 
     | 
    
         
            +
                VALUE str, elem;
         
     | 
| 
      
 996 
     | 
    
         
            +
                int i;
         
     | 
| 
      
 997 
     | 
    
         
            +
             
     | 
| 
      
 998 
     | 
    
         
            +
                rb_check_frozen(self);
         
     | 
| 
      
 999 
     | 
    
         
            +
                if (NIL_P(v))
         
     | 
| 
      
 1000 
     | 
    
         
            +
            	return v;
         
     | 
| 
      
 1001 
     | 
    
         
            +
                else if (RB_TYPE_P(v, T_ARRAY)) {
         
     | 
| 
      
 1002 
     | 
    
         
            +
                    str = rb_str_new(0, 0);
         
     | 
| 
      
 1003 
     | 
    
         
            +
                    for (i = 0; i < RARRAY_LEN(v); i++) {
         
     | 
| 
      
 1004 
     | 
    
         
            +
                        elem = rb_ary_entry(v, i);
         
     | 
| 
      
 1005 
     | 
    
         
            +
                        if (RB_TYPE_P(elem, T_ARRAY)) elem = rb_ary_entry(elem, 0);
         
     | 
| 
      
 1006 
     | 
    
         
            +
                        elem = rb_String(elem);
         
     | 
| 
      
 1007 
     | 
    
         
            +
                        rb_str_append(str, elem);
         
     | 
| 
      
 1008 
     | 
    
         
            +
                        if (i < RARRAY_LEN(v)-1) rb_str_cat2(str, ":");
         
     | 
| 
      
 1009 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1010 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 1011 
     | 
    
         
            +
                    str = v;
         
     | 
| 
      
 1012 
     | 
    
         
            +
                    StringValue(str);
         
     | 
| 
      
 1013 
     | 
    
         
            +
                }
         
     | 
| 
      
 1014 
     | 
    
         
            +
             
     | 
| 
      
 1015 
     | 
    
         
            +
                GetSSLCTX(self, ctx);
         
     | 
| 
      
 1016 
     | 
    
         
            +
                if(!ctx){
         
     | 
| 
      
 1017 
     | 
    
         
            +
                    ossl_raise(eSSLError, "SSL_CTX is not initialized.");
         
     | 
| 
      
 1018 
     | 
    
         
            +
                    return Qnil;
         
     | 
| 
      
 1019 
     | 
    
         
            +
                }
         
     | 
| 
      
 1020 
     | 
    
         
            +
                if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str))) {
         
     | 
| 
      
 1021 
     | 
    
         
            +
                    ossl_raise(eSSLError, "SSL_CTX_set_cipher_list");
         
     | 
| 
      
 1022 
     | 
    
         
            +
                }
         
     | 
| 
      
 1023 
     | 
    
         
            +
             
     | 
| 
      
 1024 
     | 
    
         
            +
                return v;
         
     | 
| 
      
 1025 
     | 
    
         
            +
            }
         
     | 
| 
      
 1026 
     | 
    
         
            +
             
     | 
| 
      
 1027 
     | 
    
         
            +
            #if !defined(OPENSSL_NO_EC)
         
     | 
| 
      
 1028 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1029 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 1030 
     | 
    
         
            +
             *    ctx.ecdh_curves = curve_list -> curve_list
         
     | 
| 
      
 1031 
     | 
    
         
            +
             *
         
     | 
| 
      
 1032 
     | 
    
         
            +
             * Sets the list of "supported elliptic curves" for this context.
         
     | 
| 
      
 1033 
     | 
    
         
            +
             *
         
     | 
| 
      
 1034 
     | 
    
         
            +
             * For a TLS client, the list is directly used in the Supported Elliptic Curves
         
     | 
| 
      
 1035 
     | 
    
         
            +
             * Extension. For a server, the list is used by OpenSSL to determine the set of
         
     | 
| 
      
 1036 
     | 
    
         
            +
             * shared curves. OpenSSL will pick the most appropriate one from it.
         
     | 
| 
      
 1037 
     | 
    
         
            +
             *
         
     | 
| 
      
 1038 
     | 
    
         
            +
             * Note that this works differently with old OpenSSL (<= 1.0.1). Only one curve
         
     | 
| 
      
 1039 
     | 
    
         
            +
             * can be set, and this has no effect for TLS clients.
         
     | 
| 
      
 1040 
     | 
    
         
            +
             *
         
     | 
| 
      
 1041 
     | 
    
         
            +
             * === Example
         
     | 
| 
      
 1042 
     | 
    
         
            +
             *   ctx1 = OpenSSL::SSL::SSLContext.new
         
     | 
| 
      
 1043 
     | 
    
         
            +
             *   ctx1.ecdh_curves = "X25519:P-256:P-224"
         
     | 
| 
      
 1044 
     | 
    
         
            +
             *   svr = OpenSSL::SSL::SSLServer.new(tcp_svr, ctx1)
         
     | 
| 
      
 1045 
     | 
    
         
            +
             *   Thread.new { svr.accept }
         
     | 
| 
      
 1046 
     | 
    
         
            +
             *
         
     | 
| 
      
 1047 
     | 
    
         
            +
             *   ctx2 = OpenSSL::SSL::SSLContext.new
         
     | 
| 
      
 1048 
     | 
    
         
            +
             *   ctx2.ecdh_curves = "P-256"
         
     | 
| 
      
 1049 
     | 
    
         
            +
             *   cli = OpenSSL::SSL::SSLSocket.new(tcp_sock, ctx2)
         
     | 
| 
      
 1050 
     | 
    
         
            +
             *   cli.connect
         
     | 
| 
      
 1051 
     | 
    
         
            +
             *
         
     | 
| 
      
 1052 
     | 
    
         
            +
             *   p cli.tmp_key.group.curve_name
         
     | 
| 
      
 1053 
     | 
    
         
            +
             *   # => "prime256v1" (is an alias for NIST P-256)
         
     | 
| 
      
 1054 
     | 
    
         
            +
             */
         
     | 
| 
      
 1055 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1056 
     | 
    
         
            +
            ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg)
         
     | 
| 
      
 1057 
     | 
    
         
            +
            {
         
     | 
| 
      
 1058 
     | 
    
         
            +
                SSL_CTX *ctx;
         
     | 
| 
      
 1059 
     | 
    
         
            +
             
     | 
| 
      
 1060 
     | 
    
         
            +
                rb_check_frozen(self);
         
     | 
| 
      
 1061 
     | 
    
         
            +
                GetSSLCTX(self, ctx);
         
     | 
| 
      
 1062 
     | 
    
         
            +
                StringValueCStr(arg);
         
     | 
| 
      
 1063 
     | 
    
         
            +
             
     | 
| 
      
 1064 
     | 
    
         
            +
            #if defined(HAVE_SSL_CTX_SET1_CURVES_LIST)
         
     | 
| 
      
 1065 
     | 
    
         
            +
                if (!SSL_CTX_set1_curves_list(ctx, RSTRING_PTR(arg)))
         
     | 
| 
      
 1066 
     | 
    
         
            +
            	ossl_raise(eSSLError, NULL);
         
     | 
| 
      
 1067 
     | 
    
         
            +
            #else
         
     | 
| 
      
 1068 
     | 
    
         
            +
                /* OpenSSL does not have SSL_CTX_set1_curves_list()... Fallback to
         
     | 
| 
      
 1069 
     | 
    
         
            +
                 * SSL_CTX_set_tmp_ecdh(). So only the first curve is used. */
         
     | 
| 
      
 1070 
     | 
    
         
            +
                {
         
     | 
| 
      
 1071 
     | 
    
         
            +
            	VALUE curve, splitted;
         
     | 
| 
      
 1072 
     | 
    
         
            +
            	EC_KEY *ec;
         
     | 
| 
      
 1073 
     | 
    
         
            +
            	int nid;
         
     | 
| 
      
 1074 
     | 
    
         
            +
             
     | 
| 
      
 1075 
     | 
    
         
            +
            	splitted = rb_str_split(arg, ":");
         
     | 
| 
      
 1076 
     | 
    
         
            +
            	if (!RARRAY_LEN(splitted))
         
     | 
| 
      
 1077 
     | 
    
         
            +
            	    ossl_raise(eSSLError, "invalid input format");
         
     | 
| 
      
 1078 
     | 
    
         
            +
            	curve = RARRAY_AREF(splitted, 0);
         
     | 
| 
      
 1079 
     | 
    
         
            +
            	StringValueCStr(curve);
         
     | 
| 
      
 1080 
     | 
    
         
            +
             
     | 
| 
      
 1081 
     | 
    
         
            +
            	/* SSL_CTX_set1_curves_list() accepts NIST names */
         
     | 
| 
      
 1082 
     | 
    
         
            +
            	nid = EC_curve_nist2nid(RSTRING_PTR(curve));
         
     | 
| 
      
 1083 
     | 
    
         
            +
            	if (nid == NID_undef)
         
     | 
| 
      
 1084 
     | 
    
         
            +
            	    nid = OBJ_txt2nid(RSTRING_PTR(curve));
         
     | 
| 
      
 1085 
     | 
    
         
            +
            	if (nid == NID_undef)
         
     | 
| 
      
 1086 
     | 
    
         
            +
            	    ossl_raise(eSSLError, "unknown curve name");
         
     | 
| 
      
 1087 
     | 
    
         
            +
             
     | 
| 
      
 1088 
     | 
    
         
            +
            	ec = EC_KEY_new_by_curve_name(nid);
         
     | 
| 
      
 1089 
     | 
    
         
            +
            	if (!ec)
         
     | 
| 
      
 1090 
     | 
    
         
            +
            	    ossl_raise(eSSLError, NULL);
         
     | 
| 
      
 1091 
     | 
    
         
            +
            	EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
         
     | 
| 
      
 1092 
     | 
    
         
            +
            	if (!SSL_CTX_set_tmp_ecdh(ctx, ec)) {
         
     | 
| 
      
 1093 
     | 
    
         
            +
            	    EC_KEY_free(ec);
         
     | 
| 
      
 1094 
     | 
    
         
            +
            	    ossl_raise(eSSLError, "SSL_CTX_set_tmp_ecdh");
         
     | 
| 
      
 1095 
     | 
    
         
            +
            	}
         
     | 
| 
      
 1096 
     | 
    
         
            +
            	EC_KEY_free(ec);
         
     | 
| 
      
 1097 
     | 
    
         
            +
            # if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
         
     | 
| 
      
 1098 
     | 
    
         
            +
            	/* tmp_ecdh and ecdh_auto conflict. tmp_ecdh is ignored when ecdh_auto
         
     | 
| 
      
 1099 
     | 
    
         
            +
            	 * is enabled. So disable ecdh_auto. */
         
     | 
| 
      
 1100 
     | 
    
         
            +
            	if (!SSL_CTX_set_ecdh_auto(ctx, 0))
         
     | 
| 
      
 1101 
     | 
    
         
            +
            	    ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
         
     | 
| 
      
 1102 
     | 
    
         
            +
            # endif
         
     | 
| 
      
 1103 
     | 
    
         
            +
                }
         
     | 
| 
      
 1104 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 1105 
     | 
    
         
            +
             
     | 
| 
      
 1106 
     | 
    
         
            +
                return arg;
         
     | 
| 
      
 1107 
     | 
    
         
            +
            }
         
     | 
| 
      
 1108 
     | 
    
         
            +
            #else
         
     | 
| 
      
 1109 
     | 
    
         
            +
            #define ossl_sslctx_set_ecdh_curves rb_f_notimplement
         
     | 
| 
      
 1110 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 1111 
     | 
    
         
            +
             
     | 
| 
      
 1112 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1113 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 1114 
     | 
    
         
            +
             *    ctx.security_level -> Integer
         
     | 
| 
      
 1115 
     | 
    
         
            +
             *
         
     | 
| 
      
 1116 
     | 
    
         
            +
             * Returns the security level for the context.
         
     | 
| 
      
 1117 
     | 
    
         
            +
             *
         
     | 
| 
      
 1118 
     | 
    
         
            +
             * See also OpenSSL::SSL::SSLContext#security_level=.
         
     | 
| 
      
 1119 
     | 
    
         
            +
             */
         
     | 
| 
      
 1120 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1121 
     | 
    
         
            +
            ossl_sslctx_get_security_level(VALUE self)
         
     | 
| 
      
 1122 
     | 
    
         
            +
            {
         
     | 
| 
      
 1123 
     | 
    
         
            +
                SSL_CTX *ctx;
         
     | 
| 
      
 1124 
     | 
    
         
            +
             
     | 
| 
      
 1125 
     | 
    
         
            +
                GetSSLCTX(self, ctx);
         
     | 
| 
      
 1126 
     | 
    
         
            +
             
     | 
| 
      
 1127 
     | 
    
         
            +
            #if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
         
     | 
| 
      
 1128 
     | 
    
         
            +
                return INT2NUM(SSL_CTX_get_security_level(ctx));
         
     | 
| 
      
 1129 
     | 
    
         
            +
            #else
         
     | 
| 
      
 1130 
     | 
    
         
            +
                (void)ctx;
         
     | 
| 
      
 1131 
     | 
    
         
            +
                return INT2FIX(0);
         
     | 
| 
      
 1132 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 1133 
     | 
    
         
            +
            }
         
     | 
| 
      
 1134 
     | 
    
         
            +
             
     | 
| 
      
 1135 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1136 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 1137 
     | 
    
         
            +
             *    ctx.security_level = integer
         
     | 
| 
      
 1138 
     | 
    
         
            +
             *
         
     | 
| 
      
 1139 
     | 
    
         
            +
             * Sets the security level for the context. OpenSSL limits parameters according
         
     | 
| 
      
 1140 
     | 
    
         
            +
             * to the level. The "parameters" include: ciphersuites, curves, key sizes,
         
     | 
| 
      
 1141 
     | 
    
         
            +
             * certificate signature algorithms, protocol version and so on. For example,
         
     | 
| 
      
 1142 
     | 
    
         
            +
             * level 1 rejects parameters offering below 80 bits of security, such as
         
     | 
| 
      
 1143 
     | 
    
         
            +
             * ciphersuites using MD5 for the MAC or RSA keys shorter than 1024 bits.
         
     | 
| 
      
 1144 
     | 
    
         
            +
             *
         
     | 
| 
      
 1145 
     | 
    
         
            +
             * Note that attempts to set such parameters with insufficient security are
         
     | 
| 
      
 1146 
     | 
    
         
            +
             * also blocked. You need to lower the level first.
         
     | 
| 
      
 1147 
     | 
    
         
            +
             *
         
     | 
| 
      
 1148 
     | 
    
         
            +
             * This feature is not supported in OpenSSL < 1.1.0, and setting the level to
         
     | 
| 
      
 1149 
     | 
    
         
            +
             * other than 0 will raise NotImplementedError. Level 0 means everything is
         
     | 
| 
      
 1150 
     | 
    
         
            +
             * permitted, the same behavior as previous versions of OpenSSL.
         
     | 
| 
      
 1151 
     | 
    
         
            +
             *
         
     | 
| 
      
 1152 
     | 
    
         
            +
             * See the manpage of SSL_CTX_set_security_level(3) for details.
         
     | 
| 
      
 1153 
     | 
    
         
            +
             */
         
     | 
| 
      
 1154 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1155 
     | 
    
         
            +
            ossl_sslctx_set_security_level(VALUE self, VALUE value)
         
     | 
| 
      
 1156 
     | 
    
         
            +
            {
         
     | 
| 
      
 1157 
     | 
    
         
            +
                SSL_CTX *ctx;
         
     | 
| 
      
 1158 
     | 
    
         
            +
             
     | 
| 
      
 1159 
     | 
    
         
            +
                rb_check_frozen(self);
         
     | 
| 
      
 1160 
     | 
    
         
            +
                GetSSLCTX(self, ctx);
         
     | 
| 
      
 1161 
     | 
    
         
            +
             
     | 
| 
      
 1162 
     | 
    
         
            +
            #if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
         
     | 
| 
      
 1163 
     | 
    
         
            +
                SSL_CTX_set_security_level(ctx, NUM2INT(value));
         
     | 
| 
      
 1164 
     | 
    
         
            +
            #else
         
     | 
| 
      
 1165 
     | 
    
         
            +
                (void)ctx;
         
     | 
| 
      
 1166 
     | 
    
         
            +
                if (NUM2INT(value) != 0)
         
     | 
| 
      
 1167 
     | 
    
         
            +
            	ossl_raise(rb_eNotImpError, "setting security level to other than 0 is "
         
     | 
| 
      
 1168 
     | 
    
         
            +
            		   "not supported in this version of OpenSSL");
         
     | 
| 
      
 1169 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 1170 
     | 
    
         
            +
             
     | 
| 
      
 1171 
     | 
    
         
            +
                return value;
         
     | 
| 
      
 1172 
     | 
    
         
            +
            }
         
     | 
| 
      
 1173 
     | 
    
         
            +
             
     | 
| 
      
 1174 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1175 
     | 
    
         
            +
             *  call-seq:
         
     | 
| 
      
 1176 
     | 
    
         
            +
             *     ctx.session_add(session) -> true | false
         
     | 
| 
      
 1177 
     | 
    
         
            +
             *
         
     | 
| 
      
 1178 
     | 
    
         
            +
             * Adds +session+ to the session cache.
         
     | 
| 
      
 1179 
     | 
    
         
            +
             */
         
     | 
| 
      
 1180 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1181 
     | 
    
         
            +
            ossl_sslctx_session_add(VALUE self, VALUE arg)
         
     | 
| 
      
 1182 
     | 
    
         
            +
            {
         
     | 
| 
      
 1183 
     | 
    
         
            +
                SSL_CTX *ctx;
         
     | 
| 
      
 1184 
     | 
    
         
            +
                SSL_SESSION *sess;
         
     | 
| 
      
 1185 
     | 
    
         
            +
             
     | 
| 
      
 1186 
     | 
    
         
            +
                GetSSLCTX(self, ctx);
         
     | 
| 
      
 1187 
     | 
    
         
            +
                SafeGetSSLSession(arg, sess);
         
     | 
| 
      
 1188 
     | 
    
         
            +
             
     | 
| 
      
 1189 
     | 
    
         
            +
                return SSL_CTX_add_session(ctx, sess) == 1 ? Qtrue : Qfalse;
         
     | 
| 
      
 1190 
     | 
    
         
            +
            }
         
     | 
| 
      
 1191 
     | 
    
         
            +
             
     | 
| 
      
 1192 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1193 
     | 
    
         
            +
             *  call-seq:
         
     | 
| 
      
 1194 
     | 
    
         
            +
             *     ctx.session_remove(session) -> true | false
         
     | 
| 
      
 1195 
     | 
    
         
            +
             *
         
     | 
| 
      
 1196 
     | 
    
         
            +
             * Removes +session+ from the session cache.
         
     | 
| 
      
 1197 
     | 
    
         
            +
             */
         
     | 
| 
      
 1198 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1199 
     | 
    
         
            +
            ossl_sslctx_session_remove(VALUE self, VALUE arg)
         
     | 
| 
      
 1200 
     | 
    
         
            +
            {
         
     | 
| 
      
 1201 
     | 
    
         
            +
                SSL_CTX *ctx;
         
     | 
| 
      
 1202 
     | 
    
         
            +
                SSL_SESSION *sess;
         
     | 
| 
      
 1203 
     | 
    
         
            +
             
     | 
| 
      
 1204 
     | 
    
         
            +
                GetSSLCTX(self, ctx);
         
     | 
| 
      
 1205 
     | 
    
         
            +
                SafeGetSSLSession(arg, sess);
         
     | 
| 
      
 1206 
     | 
    
         
            +
             
     | 
| 
      
 1207 
     | 
    
         
            +
                return SSL_CTX_remove_session(ctx, sess) == 1 ? Qtrue : Qfalse;
         
     | 
| 
      
 1208 
     | 
    
         
            +
            }
         
     | 
| 
      
 1209 
     | 
    
         
            +
             
     | 
| 
      
 1210 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1211 
     | 
    
         
            +
             *  call-seq:
         
     | 
| 
      
 1212 
     | 
    
         
            +
             *     ctx.session_cache_mode -> Integer
         
     | 
| 
      
 1213 
     | 
    
         
            +
             *
         
     | 
| 
      
 1214 
     | 
    
         
            +
             * The current session cache mode.
         
     | 
| 
      
 1215 
     | 
    
         
            +
             */
         
     | 
| 
      
 1216 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1217 
     | 
    
         
            +
            ossl_sslctx_get_session_cache_mode(VALUE self)
         
     | 
| 
      
 1218 
     | 
    
         
            +
            {
         
     | 
| 
      
 1219 
     | 
    
         
            +
                SSL_CTX *ctx;
         
     | 
| 
      
 1220 
     | 
    
         
            +
             
     | 
| 
      
 1221 
     | 
    
         
            +
                GetSSLCTX(self, ctx);
         
     | 
| 
      
 1222 
     | 
    
         
            +
             
     | 
| 
      
 1223 
     | 
    
         
            +
                return LONG2NUM(SSL_CTX_get_session_cache_mode(ctx));
         
     | 
| 
      
 1224 
     | 
    
         
            +
            }
         
     | 
| 
      
 1225 
     | 
    
         
            +
             
     | 
| 
      
 1226 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1227 
     | 
    
         
            +
             *  call-seq:
         
     | 
| 
      
 1228 
     | 
    
         
            +
             *     ctx.session_cache_mode=(integer) -> Integer
         
     | 
| 
      
 1229 
     | 
    
         
            +
             *
         
     | 
| 
      
 1230 
     | 
    
         
            +
             * Sets the SSL session cache mode.  Bitwise-or together the desired
         
     | 
| 
      
 1231 
     | 
    
         
            +
             * SESSION_CACHE_* constants to set.  See SSL_CTX_set_session_cache_mode(3) for
         
     | 
| 
      
 1232 
     | 
    
         
            +
             * details.
         
     | 
| 
      
 1233 
     | 
    
         
            +
             */
         
     | 
| 
      
 1234 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1235 
     | 
    
         
            +
            ossl_sslctx_set_session_cache_mode(VALUE self, VALUE arg)
         
     | 
| 
      
 1236 
     | 
    
         
            +
            {
         
     | 
| 
      
 1237 
     | 
    
         
            +
                SSL_CTX *ctx;
         
     | 
| 
      
 1238 
     | 
    
         
            +
             
     | 
| 
      
 1239 
     | 
    
         
            +
                GetSSLCTX(self, ctx);
         
     | 
| 
      
 1240 
     | 
    
         
            +
             
     | 
| 
      
 1241 
     | 
    
         
            +
                SSL_CTX_set_session_cache_mode(ctx, NUM2LONG(arg));
         
     | 
| 
      
 1242 
     | 
    
         
            +
             
     | 
| 
      
 1243 
     | 
    
         
            +
                return arg;
         
     | 
| 
      
 1244 
     | 
    
         
            +
            }
         
     | 
| 
      
 1245 
     | 
    
         
            +
             
     | 
| 
      
 1246 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1247 
     | 
    
         
            +
             *  call-seq:
         
     | 
| 
      
 1248 
     | 
    
         
            +
             *     ctx.session_cache_size -> Integer
         
     | 
| 
      
 1249 
     | 
    
         
            +
             *
         
     | 
| 
      
 1250 
     | 
    
         
            +
             * Returns the current session cache size.  Zero is used to represent an
         
     | 
| 
      
 1251 
     | 
    
         
            +
             * unlimited cache size.
         
     | 
| 
      
 1252 
     | 
    
         
            +
             */
         
     | 
| 
      
 1253 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1254 
     | 
    
         
            +
            ossl_sslctx_get_session_cache_size(VALUE self)
         
     | 
| 
      
 1255 
     | 
    
         
            +
            {
         
     | 
| 
      
 1256 
     | 
    
         
            +
                SSL_CTX *ctx;
         
     | 
| 
      
 1257 
     | 
    
         
            +
             
     | 
| 
      
 1258 
     | 
    
         
            +
                GetSSLCTX(self, ctx);
         
     | 
| 
      
 1259 
     | 
    
         
            +
             
     | 
| 
      
 1260 
     | 
    
         
            +
                return LONG2NUM(SSL_CTX_sess_get_cache_size(ctx));
         
     | 
| 
      
 1261 
     | 
    
         
            +
            }
         
     | 
| 
      
 1262 
     | 
    
         
            +
             
     | 
| 
      
 1263 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1264 
     | 
    
         
            +
             *  call-seq:
         
     | 
| 
      
 1265 
     | 
    
         
            +
             *     ctx.session_cache_size=(integer) -> Integer
         
     | 
| 
      
 1266 
     | 
    
         
            +
             *
         
     | 
| 
      
 1267 
     | 
    
         
            +
             * Sets the session cache size.  Returns the previously valid session cache
         
     | 
| 
      
 1268 
     | 
    
         
            +
             * size.  Zero is used to represent an unlimited session cache size.
         
     | 
| 
      
 1269 
     | 
    
         
            +
             */
         
     | 
| 
      
 1270 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1271 
     | 
    
         
            +
            ossl_sslctx_set_session_cache_size(VALUE self, VALUE arg)
         
     | 
| 
      
 1272 
     | 
    
         
            +
            {
         
     | 
| 
      
 1273 
     | 
    
         
            +
                SSL_CTX *ctx;
         
     | 
| 
      
 1274 
     | 
    
         
            +
             
     | 
| 
      
 1275 
     | 
    
         
            +
                GetSSLCTX(self, ctx);
         
     | 
| 
      
 1276 
     | 
    
         
            +
             
     | 
| 
      
 1277 
     | 
    
         
            +
                SSL_CTX_sess_set_cache_size(ctx, NUM2LONG(arg));
         
     | 
| 
      
 1278 
     | 
    
         
            +
             
     | 
| 
      
 1279 
     | 
    
         
            +
                return arg;
         
     | 
| 
      
 1280 
     | 
    
         
            +
            }
         
     | 
| 
      
 1281 
     | 
    
         
            +
             
     | 
| 
      
 1282 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1283 
     | 
    
         
            +
             *  call-seq:
         
     | 
| 
      
 1284 
     | 
    
         
            +
             *     ctx.session_cache_stats -> Hash
         
     | 
| 
      
 1285 
     | 
    
         
            +
             *
         
     | 
| 
      
 1286 
     | 
    
         
            +
             * Returns a Hash containing the following keys:
         
     | 
| 
      
 1287 
     | 
    
         
            +
             *
         
     | 
| 
      
 1288 
     | 
    
         
            +
             * :accept:: Number of started SSL/TLS handshakes in server mode
         
     | 
| 
      
 1289 
     | 
    
         
            +
             * :accept_good:: Number of established SSL/TLS sessions in server mode
         
     | 
| 
      
 1290 
     | 
    
         
            +
             * :accept_renegotiate:: Number of start renegotiations in server mode
         
     | 
| 
      
 1291 
     | 
    
         
            +
             * :cache_full:: Number of sessions that were removed due to cache overflow
         
     | 
| 
      
 1292 
     | 
    
         
            +
             * :cache_hits:: Number of successfully reused connections
         
     | 
| 
      
 1293 
     | 
    
         
            +
             * :cache_misses:: Number of sessions proposed by clients that were not found
         
     | 
| 
      
 1294 
     | 
    
         
            +
             *                 in the cache
         
     | 
| 
      
 1295 
     | 
    
         
            +
             * :cache_num:: Number of sessions in the internal session cache
         
     | 
| 
      
 1296 
     | 
    
         
            +
             * :cb_hits:: Number of sessions retrieved from the external cache in server
         
     | 
| 
      
 1297 
     | 
    
         
            +
             *            mode
         
     | 
| 
      
 1298 
     | 
    
         
            +
             * :connect:: Number of started SSL/TLS handshakes in client mode
         
     | 
| 
      
 1299 
     | 
    
         
            +
             * :connect_good:: Number of established SSL/TLS sessions in client mode
         
     | 
| 
      
 1300 
     | 
    
         
            +
             * :connect_renegotiate:: Number of start renegotiations in client mode
         
     | 
| 
      
 1301 
     | 
    
         
            +
             * :timeouts:: Number of sessions proposed by clients that were found in the
         
     | 
| 
      
 1302 
     | 
    
         
            +
             *             cache but had expired due to timeouts
         
     | 
| 
      
 1303 
     | 
    
         
            +
             */
         
     | 
| 
      
 1304 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1305 
     | 
    
         
            +
            ossl_sslctx_get_session_cache_stats(VALUE self)
         
     | 
| 
      
 1306 
     | 
    
         
            +
            {
         
     | 
| 
      
 1307 
     | 
    
         
            +
                SSL_CTX *ctx;
         
     | 
| 
      
 1308 
     | 
    
         
            +
                VALUE hash;
         
     | 
| 
      
 1309 
     | 
    
         
            +
             
     | 
| 
      
 1310 
     | 
    
         
            +
                GetSSLCTX(self, ctx);
         
     | 
| 
      
 1311 
     | 
    
         
            +
             
     | 
| 
      
 1312 
     | 
    
         
            +
                hash = rb_hash_new();
         
     | 
| 
      
 1313 
     | 
    
         
            +
                rb_hash_aset(hash, ID2SYM(rb_intern("cache_num")), LONG2NUM(SSL_CTX_sess_number(ctx)));
         
     | 
| 
      
 1314 
     | 
    
         
            +
                rb_hash_aset(hash, ID2SYM(rb_intern("connect")), LONG2NUM(SSL_CTX_sess_connect(ctx)));
         
     | 
| 
      
 1315 
     | 
    
         
            +
                rb_hash_aset(hash, ID2SYM(rb_intern("connect_good")), LONG2NUM(SSL_CTX_sess_connect_good(ctx)));
         
     | 
| 
      
 1316 
     | 
    
         
            +
                rb_hash_aset(hash, ID2SYM(rb_intern("connect_renegotiate")), LONG2NUM(SSL_CTX_sess_connect_renegotiate(ctx)));
         
     | 
| 
      
 1317 
     | 
    
         
            +
                rb_hash_aset(hash, ID2SYM(rb_intern("accept")), LONG2NUM(SSL_CTX_sess_accept(ctx)));
         
     | 
| 
      
 1318 
     | 
    
         
            +
                rb_hash_aset(hash, ID2SYM(rb_intern("accept_good")), LONG2NUM(SSL_CTX_sess_accept_good(ctx)));
         
     | 
| 
      
 1319 
     | 
    
         
            +
                rb_hash_aset(hash, ID2SYM(rb_intern("accept_renegotiate")), LONG2NUM(SSL_CTX_sess_accept_renegotiate(ctx)));
         
     | 
| 
      
 1320 
     | 
    
         
            +
                rb_hash_aset(hash, ID2SYM(rb_intern("cache_hits")), LONG2NUM(SSL_CTX_sess_hits(ctx)));
         
     | 
| 
      
 1321 
     | 
    
         
            +
                rb_hash_aset(hash, ID2SYM(rb_intern("cb_hits")), LONG2NUM(SSL_CTX_sess_cb_hits(ctx)));
         
     | 
| 
      
 1322 
     | 
    
         
            +
                rb_hash_aset(hash, ID2SYM(rb_intern("cache_misses")), LONG2NUM(SSL_CTX_sess_misses(ctx)));
         
     | 
| 
      
 1323 
     | 
    
         
            +
                rb_hash_aset(hash, ID2SYM(rb_intern("cache_full")), LONG2NUM(SSL_CTX_sess_cache_full(ctx)));
         
     | 
| 
      
 1324 
     | 
    
         
            +
                rb_hash_aset(hash, ID2SYM(rb_intern("timeouts")), LONG2NUM(SSL_CTX_sess_timeouts(ctx)));
         
     | 
| 
      
 1325 
     | 
    
         
            +
             
     | 
| 
      
 1326 
     | 
    
         
            +
                return hash;
         
     | 
| 
      
 1327 
     | 
    
         
            +
            }
         
     | 
| 
      
 1328 
     | 
    
         
            +
             
     | 
| 
      
 1329 
     | 
    
         
            +
             
     | 
| 
      
 1330 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1331 
     | 
    
         
            +
             *  call-seq:
         
     | 
| 
      
 1332 
     | 
    
         
            +
             *     ctx.flush_sessions(time | nil) -> self
         
     | 
| 
      
 1333 
     | 
    
         
            +
             *
         
     | 
| 
      
 1334 
     | 
    
         
            +
             * Removes sessions in the internal cache that have expired at +time+.
         
     | 
| 
      
 1335 
     | 
    
         
            +
             */
         
     | 
| 
      
 1336 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1337 
     | 
    
         
            +
            ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
         
     | 
| 
      
 1338 
     | 
    
         
            +
            {
         
     | 
| 
      
 1339 
     | 
    
         
            +
                VALUE arg1;
         
     | 
| 
      
 1340 
     | 
    
         
            +
                SSL_CTX *ctx;
         
     | 
| 
      
 1341 
     | 
    
         
            +
                time_t tm = 0;
         
     | 
| 
      
 1342 
     | 
    
         
            +
             
     | 
| 
      
 1343 
     | 
    
         
            +
                rb_scan_args(argc, argv, "01", &arg1);
         
     | 
| 
      
 1344 
     | 
    
         
            +
             
     | 
| 
      
 1345 
     | 
    
         
            +
                GetSSLCTX(self, ctx);
         
     | 
| 
      
 1346 
     | 
    
         
            +
             
     | 
| 
      
 1347 
     | 
    
         
            +
                if (NIL_P(arg1)) {
         
     | 
| 
      
 1348 
     | 
    
         
            +
                    tm = time(0);
         
     | 
| 
      
 1349 
     | 
    
         
            +
                } else if (rb_obj_is_instance_of(arg1, rb_cTime)) {
         
     | 
| 
      
 1350 
     | 
    
         
            +
                    tm = NUM2LONG(rb_funcall(arg1, rb_intern("to_i"), 0));
         
     | 
| 
      
 1351 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 1352 
     | 
    
         
            +
                    ossl_raise(rb_eArgError, "arg must be Time or nil");
         
     | 
| 
      
 1353 
     | 
    
         
            +
                }
         
     | 
| 
      
 1354 
     | 
    
         
            +
             
     | 
| 
      
 1355 
     | 
    
         
            +
                SSL_CTX_flush_sessions(ctx, (long)tm);
         
     | 
| 
      
 1356 
     | 
    
         
            +
             
     | 
| 
      
 1357 
     | 
    
         
            +
                return self;
         
     | 
| 
      
 1358 
     | 
    
         
            +
            }
         
     | 
| 
      
 1359 
     | 
    
         
            +
             
     | 
| 
      
 1360 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1361 
     | 
    
         
            +
             * SSLSocket class
         
     | 
| 
      
 1362 
     | 
    
         
            +
             */
         
     | 
| 
      
 1363 
     | 
    
         
            +
            #ifndef OPENSSL_NO_SOCK
         
     | 
| 
      
 1364 
     | 
    
         
            +
            static inline int
         
     | 
| 
      
 1365 
     | 
    
         
            +
            ssl_started(SSL *ssl)
         
     | 
| 
      
 1366 
     | 
    
         
            +
            {
         
     | 
| 
      
 1367 
     | 
    
         
            +
                /* the FD is set in ossl_ssl_setup(), called by #connect or #accept */
         
     | 
| 
      
 1368 
     | 
    
         
            +
                return SSL_get_fd(ssl) >= 0;
         
     | 
| 
      
 1369 
     | 
    
         
            +
            }
         
     | 
| 
      
 1370 
     | 
    
         
            +
             
     | 
| 
      
 1371 
     | 
    
         
            +
            static void
         
     | 
| 
      
 1372 
     | 
    
         
            +
            ossl_ssl_shutdown(SSL *ssl)
         
     | 
| 
      
 1373 
     | 
    
         
            +
            {
         
     | 
| 
      
 1374 
     | 
    
         
            +
                int i;
         
     | 
| 
      
 1375 
     | 
    
         
            +
             
     | 
| 
      
 1376 
     | 
    
         
            +
                /* 4 is from SSL_smart_shutdown() of mod_ssl.c (v2.2.19) */
         
     | 
| 
      
 1377 
     | 
    
         
            +
                /* It says max 2x pending + 2x data = 4 */
         
     | 
| 
      
 1378 
     | 
    
         
            +
                for (i = 0; i < 4; ++i) {
         
     | 
| 
      
 1379 
     | 
    
         
            +
            	/*
         
     | 
| 
      
 1380 
     | 
    
         
            +
            	 * Ignore the case SSL_shutdown returns -1. Empty handshake_func
         
     | 
| 
      
 1381 
     | 
    
         
            +
            	 * must not happen.
         
     | 
| 
      
 1382 
     | 
    
         
            +
            	 */
         
     | 
| 
      
 1383 
     | 
    
         
            +
            	if (SSL_shutdown(ssl) != 0)
         
     | 
| 
      
 1384 
     | 
    
         
            +
            	    break;
         
     | 
| 
      
 1385 
     | 
    
         
            +
                }
         
     | 
| 
      
 1386 
     | 
    
         
            +
                ossl_clear_error();
         
     | 
| 
      
 1387 
     | 
    
         
            +
            }
         
     | 
| 
      
 1388 
     | 
    
         
            +
             
     | 
| 
      
 1389 
     | 
    
         
            +
            static void
         
     | 
| 
      
 1390 
     | 
    
         
            +
            ossl_ssl_free(void *ssl)
         
     | 
| 
      
 1391 
     | 
    
         
            +
            {
         
     | 
| 
      
 1392 
     | 
    
         
            +
                SSL_free(ssl);
         
     | 
| 
      
 1393 
     | 
    
         
            +
            }
         
     | 
| 
      
 1394 
     | 
    
         
            +
             
     | 
| 
      
 1395 
     | 
    
         
            +
            const rb_data_type_t ossl_ssl_type = {
         
     | 
| 
      
 1396 
     | 
    
         
            +
                "OpenSSL/SSL",
         
     | 
| 
      
 1397 
     | 
    
         
            +
                {
         
     | 
| 
      
 1398 
     | 
    
         
            +
            	0, ossl_ssl_free,
         
     | 
| 
      
 1399 
     | 
    
         
            +
                },
         
     | 
| 
      
 1400 
     | 
    
         
            +
                0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
         
     | 
| 
      
 1401 
     | 
    
         
            +
            };
         
     | 
| 
      
 1402 
     | 
    
         
            +
             
     | 
| 
      
 1403 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1404 
     | 
    
         
            +
            ossl_ssl_s_alloc(VALUE klass)
         
     | 
| 
      
 1405 
     | 
    
         
            +
            {
         
     | 
| 
      
 1406 
     | 
    
         
            +
                return TypedData_Wrap_Struct(klass, &ossl_ssl_type, NULL);
         
     | 
| 
      
 1407 
     | 
    
         
            +
            }
         
     | 
| 
      
 1408 
     | 
    
         
            +
             
     | 
| 
      
 1409 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1410 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 1411 
     | 
    
         
            +
             *    SSLSocket.new(io) => aSSLSocket
         
     | 
| 
      
 1412 
     | 
    
         
            +
             *    SSLSocket.new(io, ctx) => aSSLSocket
         
     | 
| 
      
 1413 
     | 
    
         
            +
             *
         
     | 
| 
      
 1414 
     | 
    
         
            +
             * Creates a new SSL socket from +io+ which must be a real IO object (not an
         
     | 
| 
      
 1415 
     | 
    
         
            +
             * IO-like object that responds to read/write).
         
     | 
| 
      
 1416 
     | 
    
         
            +
             *
         
     | 
| 
      
 1417 
     | 
    
         
            +
             * If +ctx+ is provided the SSL Sockets initial params will be taken from
         
     | 
| 
      
 1418 
     | 
    
         
            +
             * the context.
         
     | 
| 
      
 1419 
     | 
    
         
            +
             *
         
     | 
| 
      
 1420 
     | 
    
         
            +
             * The OpenSSL::Buffering module provides additional IO methods.
         
     | 
| 
      
 1421 
     | 
    
         
            +
             *
         
     | 
| 
      
 1422 
     | 
    
         
            +
             * This method will freeze the SSLContext if one is provided;
         
     | 
| 
      
 1423 
     | 
    
         
            +
             * however, session management is still allowed in the frozen SSLContext.
         
     | 
| 
      
 1424 
     | 
    
         
            +
             */
         
     | 
| 
      
 1425 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1426 
     | 
    
         
            +
            ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
         
     | 
| 
      
 1427 
     | 
    
         
            +
            {
         
     | 
| 
      
 1428 
     | 
    
         
            +
                VALUE io, v_ctx, verify_cb;
         
     | 
| 
      
 1429 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 1430 
     | 
    
         
            +
                SSL_CTX *ctx;
         
     | 
| 
      
 1431 
     | 
    
         
            +
             
     | 
| 
      
 1432 
     | 
    
         
            +
                TypedData_Get_Struct(self, SSL, &ossl_ssl_type, ssl);
         
     | 
| 
      
 1433 
     | 
    
         
            +
                if (ssl)
         
     | 
| 
      
 1434 
     | 
    
         
            +
            	ossl_raise(eSSLError, "SSL already initialized");
         
     | 
| 
      
 1435 
     | 
    
         
            +
             
     | 
| 
      
 1436 
     | 
    
         
            +
                if (rb_scan_args(argc, argv, "11", &io, &v_ctx) == 1)
         
     | 
| 
      
 1437 
     | 
    
         
            +
            	v_ctx = rb_funcall(cSSLContext, rb_intern("new"), 0);
         
     | 
| 
      
 1438 
     | 
    
         
            +
             
     | 
| 
      
 1439 
     | 
    
         
            +
                GetSSLCTX(v_ctx, ctx);
         
     | 
| 
      
 1440 
     | 
    
         
            +
                ossl_ssl_set_ctx(self, v_ctx);
         
     | 
| 
      
 1441 
     | 
    
         
            +
                ossl_sslctx_setup(v_ctx);
         
     | 
| 
      
 1442 
     | 
    
         
            +
             
     | 
| 
      
 1443 
     | 
    
         
            +
                if (rb_respond_to(io, rb_intern("nonblock=")))
         
     | 
| 
      
 1444 
     | 
    
         
            +
            	rb_funcall(io, rb_intern("nonblock="), 1, Qtrue);
         
     | 
| 
      
 1445 
     | 
    
         
            +
                ossl_ssl_set_io(self, io);
         
     | 
| 
      
 1446 
     | 
    
         
            +
             
     | 
| 
      
 1447 
     | 
    
         
            +
                ossl_ssl_set_sync_close(self, Qfalse);
         
     | 
| 
      
 1448 
     | 
    
         
            +
             
     | 
| 
      
 1449 
     | 
    
         
            +
                ssl = SSL_new(ctx);
         
     | 
| 
      
 1450 
     | 
    
         
            +
                if (!ssl)
         
     | 
| 
      
 1451 
     | 
    
         
            +
            	ossl_raise(eSSLError, NULL);
         
     | 
| 
      
 1452 
     | 
    
         
            +
                RTYPEDDATA_DATA(self) = ssl;
         
     | 
| 
      
 1453 
     | 
    
         
            +
             
     | 
| 
      
 1454 
     | 
    
         
            +
                SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void *)self);
         
     | 
| 
      
 1455 
     | 
    
         
            +
                SSL_set_info_callback(ssl, ssl_info_cb);
         
     | 
| 
      
 1456 
     | 
    
         
            +
                verify_cb = ossl_sslctx_get_verify_cb(v_ctx);
         
     | 
| 
      
 1457 
     | 
    
         
            +
                SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void *)verify_cb);
         
     | 
| 
      
 1458 
     | 
    
         
            +
             
     | 
| 
      
 1459 
     | 
    
         
            +
                rb_call_super(0, NULL);
         
     | 
| 
      
 1460 
     | 
    
         
            +
             
     | 
| 
      
 1461 
     | 
    
         
            +
                return self;
         
     | 
| 
      
 1462 
     | 
    
         
            +
            }
         
     | 
| 
      
 1463 
     | 
    
         
            +
             
     | 
| 
      
 1464 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1465 
     | 
    
         
            +
            ossl_ssl_setup(VALUE self)
         
     | 
| 
      
 1466 
     | 
    
         
            +
            {
         
     | 
| 
      
 1467 
     | 
    
         
            +
                VALUE io;
         
     | 
| 
      
 1468 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 1469 
     | 
    
         
            +
                rb_io_t *fptr;
         
     | 
| 
      
 1470 
     | 
    
         
            +
             
     | 
| 
      
 1471 
     | 
    
         
            +
                GetSSL(self, ssl);
         
     | 
| 
      
 1472 
     | 
    
         
            +
                if (ssl_started(ssl))
         
     | 
| 
      
 1473 
     | 
    
         
            +
            	return Qtrue;
         
     | 
| 
      
 1474 
     | 
    
         
            +
             
     | 
| 
      
 1475 
     | 
    
         
            +
                io = ossl_ssl_get_io(self);
         
     | 
| 
      
 1476 
     | 
    
         
            +
                GetOpenFile(io, fptr);
         
     | 
| 
      
 1477 
     | 
    
         
            +
                rb_io_check_readable(fptr);
         
     | 
| 
      
 1478 
     | 
    
         
            +
                rb_io_check_writable(fptr);
         
     | 
| 
      
 1479 
     | 
    
         
            +
                SSL_set_fd(ssl, TO_SOCKET(FPTR_TO_FD(fptr)));
         
     | 
| 
      
 1480 
     | 
    
         
            +
             
     | 
| 
      
 1481 
     | 
    
         
            +
                return Qtrue;
         
     | 
| 
      
 1482 
     | 
    
         
            +
            }
         
     | 
| 
      
 1483 
     | 
    
         
            +
             
     | 
| 
      
 1484 
     | 
    
         
            +
            #ifdef _WIN32
         
     | 
| 
      
 1485 
     | 
    
         
            +
            #define ssl_get_error(ssl, ret) (errno = rb_w32_map_errno(WSAGetLastError()), SSL_get_error((ssl), (ret)))
         
     | 
| 
      
 1486 
     | 
    
         
            +
            #else
         
     | 
| 
      
 1487 
     | 
    
         
            +
            #define ssl_get_error(ssl, ret) SSL_get_error((ssl), (ret))
         
     | 
| 
      
 1488 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 1489 
     | 
    
         
            +
             
     | 
| 
      
 1490 
     | 
    
         
            +
            static void
         
     | 
| 
      
 1491 
     | 
    
         
            +
            write_would_block(int nonblock)
         
     | 
| 
      
 1492 
     | 
    
         
            +
            {
         
     | 
| 
      
 1493 
     | 
    
         
            +
                if (nonblock) {
         
     | 
| 
      
 1494 
     | 
    
         
            +
                    VALUE exc = ossl_exc_new(eSSLErrorWaitWritable, "write would block");
         
     | 
| 
      
 1495 
     | 
    
         
            +
                    rb_exc_raise(exc);
         
     | 
| 
      
 1496 
     | 
    
         
            +
                }
         
     | 
| 
      
 1497 
     | 
    
         
            +
            }
         
     | 
| 
      
 1498 
     | 
    
         
            +
             
     | 
| 
      
 1499 
     | 
    
         
            +
            static void
         
     | 
| 
      
 1500 
     | 
    
         
            +
            read_would_block(int nonblock)
         
     | 
| 
      
 1501 
     | 
    
         
            +
            {
         
     | 
| 
      
 1502 
     | 
    
         
            +
                if (nonblock) {
         
     | 
| 
      
 1503 
     | 
    
         
            +
                    VALUE exc = ossl_exc_new(eSSLErrorWaitReadable, "read would block");
         
     | 
| 
      
 1504 
     | 
    
         
            +
                    rb_exc_raise(exc);
         
     | 
| 
      
 1505 
     | 
    
         
            +
                }
         
     | 
| 
      
 1506 
     | 
    
         
            +
            }
         
     | 
| 
      
 1507 
     | 
    
         
            +
             
     | 
| 
      
 1508 
     | 
    
         
            +
            static int
         
     | 
| 
      
 1509 
     | 
    
         
            +
            no_exception_p(VALUE opts)
         
     | 
| 
      
 1510 
     | 
    
         
            +
            {
         
     | 
| 
      
 1511 
     | 
    
         
            +
                if (RB_TYPE_P(opts, T_HASH) &&
         
     | 
| 
      
 1512 
     | 
    
         
            +
                      rb_hash_lookup2(opts, sym_exception, Qundef) == Qfalse)
         
     | 
| 
      
 1513 
     | 
    
         
            +
            	return 1;
         
     | 
| 
      
 1514 
     | 
    
         
            +
                return 0;
         
     | 
| 
      
 1515 
     | 
    
         
            +
            }
         
     | 
| 
      
 1516 
     | 
    
         
            +
             
     | 
| 
      
 1517 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1518 
     | 
    
         
            +
            ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
         
     | 
| 
      
 1519 
     | 
    
         
            +
            {
         
     | 
| 
      
 1520 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 1521 
     | 
    
         
            +
                rb_io_t *fptr;
         
     | 
| 
      
 1522 
     | 
    
         
            +
                int ret, ret2;
         
     | 
| 
      
 1523 
     | 
    
         
            +
                VALUE cb_state;
         
     | 
| 
      
 1524 
     | 
    
         
            +
                int nonblock = opts != Qfalse;
         
     | 
| 
      
 1525 
     | 
    
         
            +
             
     | 
| 
      
 1526 
     | 
    
         
            +
                rb_ivar_set(self, ID_callback_state, Qnil);
         
     | 
| 
      
 1527 
     | 
    
         
            +
             
     | 
| 
      
 1528 
     | 
    
         
            +
                GetSSL(self, ssl);
         
     | 
| 
      
 1529 
     | 
    
         
            +
             
     | 
| 
      
 1530 
     | 
    
         
            +
                GetOpenFile(ossl_ssl_get_io(self), fptr);
         
     | 
| 
      
 1531 
     | 
    
         
            +
                for(;;){
         
     | 
| 
      
 1532 
     | 
    
         
            +
            	ret = func(ssl);
         
     | 
| 
      
 1533 
     | 
    
         
            +
             
     | 
| 
      
 1534 
     | 
    
         
            +
                    cb_state = rb_ivar_get(self, ID_callback_state);
         
     | 
| 
      
 1535 
     | 
    
         
            +
                    if (!NIL_P(cb_state)) {
         
     | 
| 
      
 1536 
     | 
    
         
            +
            	    /* must cleanup OpenSSL error stack before re-raising */
         
     | 
| 
      
 1537 
     | 
    
         
            +
            	    ossl_clear_error();
         
     | 
| 
      
 1538 
     | 
    
         
            +
            	    rb_jump_tag(NUM2INT(cb_state));
         
     | 
| 
      
 1539 
     | 
    
         
            +
            	}
         
     | 
| 
      
 1540 
     | 
    
         
            +
             
     | 
| 
      
 1541 
     | 
    
         
            +
            	if (ret > 0)
         
     | 
| 
      
 1542 
     | 
    
         
            +
            	    break;
         
     | 
| 
      
 1543 
     | 
    
         
            +
             
     | 
| 
      
 1544 
     | 
    
         
            +
            	switch((ret2 = ssl_get_error(ssl, ret))){
         
     | 
| 
      
 1545 
     | 
    
         
            +
            	case SSL_ERROR_WANT_WRITE:
         
     | 
| 
      
 1546 
     | 
    
         
            +
                        if (no_exception_p(opts)) { return sym_wait_writable; }
         
     | 
| 
      
 1547 
     | 
    
         
            +
                        write_would_block(nonblock);
         
     | 
| 
      
 1548 
     | 
    
         
            +
                        rb_io_wait_writable(FPTR_TO_FD(fptr));
         
     | 
| 
      
 1549 
     | 
    
         
            +
                        continue;
         
     | 
| 
      
 1550 
     | 
    
         
            +
            	case SSL_ERROR_WANT_READ:
         
     | 
| 
      
 1551 
     | 
    
         
            +
                        if (no_exception_p(opts)) { return sym_wait_readable; }
         
     | 
| 
      
 1552 
     | 
    
         
            +
                        read_would_block(nonblock);
         
     | 
| 
      
 1553 
     | 
    
         
            +
                        rb_io_wait_readable(FPTR_TO_FD(fptr));
         
     | 
| 
      
 1554 
     | 
    
         
            +
                        continue;
         
     | 
| 
      
 1555 
     | 
    
         
            +
            	case SSL_ERROR_SYSCALL:
         
     | 
| 
      
 1556 
     | 
    
         
            +
            	    if (errno) rb_sys_fail(funcname);
         
     | 
| 
      
 1557 
     | 
    
         
            +
            	    ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
         
     | 
| 
      
 1558 
     | 
    
         
            +
            	default:
         
     | 
| 
      
 1559 
     | 
    
         
            +
            	    ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
         
     | 
| 
      
 1560 
     | 
    
         
            +
            	}
         
     | 
| 
      
 1561 
     | 
    
         
            +
                }
         
     | 
| 
      
 1562 
     | 
    
         
            +
             
     | 
| 
      
 1563 
     | 
    
         
            +
                return self;
         
     | 
| 
      
 1564 
     | 
    
         
            +
            }
         
     | 
| 
      
 1565 
     | 
    
         
            +
             
     | 
| 
      
 1566 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1567 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 1568 
     | 
    
         
            +
             *    ssl.connect => self
         
     | 
| 
      
 1569 
     | 
    
         
            +
             *
         
     | 
| 
      
 1570 
     | 
    
         
            +
             * Initiates an SSL/TLS handshake with a server.  The handshake may be started
         
     | 
| 
      
 1571 
     | 
    
         
            +
             * after unencrypted data has been sent over the socket.
         
     | 
| 
      
 1572 
     | 
    
         
            +
             */
         
     | 
| 
      
 1573 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1574 
     | 
    
         
            +
            ossl_ssl_connect(VALUE self)
         
     | 
| 
      
 1575 
     | 
    
         
            +
            {
         
     | 
| 
      
 1576 
     | 
    
         
            +
                ossl_ssl_setup(self);
         
     | 
| 
      
 1577 
     | 
    
         
            +
             
     | 
| 
      
 1578 
     | 
    
         
            +
                return ossl_start_ssl(self, SSL_connect, "SSL_connect", Qfalse);
         
     | 
| 
      
 1579 
     | 
    
         
            +
            }
         
     | 
| 
      
 1580 
     | 
    
         
            +
             
     | 
| 
      
 1581 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1582 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 1583 
     | 
    
         
            +
             *    ssl.connect_nonblock([options]) => self
         
     | 
| 
      
 1584 
     | 
    
         
            +
             *
         
     | 
| 
      
 1585 
     | 
    
         
            +
             * Initiates the SSL/TLS handshake as a client in non-blocking manner.
         
     | 
| 
      
 1586 
     | 
    
         
            +
             *
         
     | 
| 
      
 1587 
     | 
    
         
            +
             *   # emulates blocking connect
         
     | 
| 
      
 1588 
     | 
    
         
            +
             *   begin
         
     | 
| 
      
 1589 
     | 
    
         
            +
             *     ssl.connect_nonblock
         
     | 
| 
      
 1590 
     | 
    
         
            +
             *   rescue IO::WaitReadable
         
     | 
| 
      
 1591 
     | 
    
         
            +
             *     IO.select([s2])
         
     | 
| 
      
 1592 
     | 
    
         
            +
             *     retry
         
     | 
| 
      
 1593 
     | 
    
         
            +
             *   rescue IO::WaitWritable
         
     | 
| 
      
 1594 
     | 
    
         
            +
             *     IO.select(nil, [s2])
         
     | 
| 
      
 1595 
     | 
    
         
            +
             *     retry
         
     | 
| 
      
 1596 
     | 
    
         
            +
             *   end
         
     | 
| 
      
 1597 
     | 
    
         
            +
             *
         
     | 
| 
      
 1598 
     | 
    
         
            +
             * By specifying `exception: false`, the options hash allows you to indicate
         
     | 
| 
      
 1599 
     | 
    
         
            +
             * that connect_nonblock should not raise an IO::WaitReadable or
         
     | 
| 
      
 1600 
     | 
    
         
            +
             * IO::WaitWritable exception, but return the symbol :wait_readable or
         
     | 
| 
      
 1601 
     | 
    
         
            +
             * :wait_writable instead.
         
     | 
| 
      
 1602 
     | 
    
         
            +
             */
         
     | 
| 
      
 1603 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1604 
     | 
    
         
            +
            ossl_ssl_connect_nonblock(int argc, VALUE *argv, VALUE self)
         
     | 
| 
      
 1605 
     | 
    
         
            +
            {
         
     | 
| 
      
 1606 
     | 
    
         
            +
                VALUE opts;
         
     | 
| 
      
 1607 
     | 
    
         
            +
                rb_scan_args(argc, argv, "0:", &opts);
         
     | 
| 
      
 1608 
     | 
    
         
            +
             
     | 
| 
      
 1609 
     | 
    
         
            +
                ossl_ssl_setup(self);
         
     | 
| 
      
 1610 
     | 
    
         
            +
             
     | 
| 
      
 1611 
     | 
    
         
            +
                return ossl_start_ssl(self, SSL_connect, "SSL_connect", opts);
         
     | 
| 
      
 1612 
     | 
    
         
            +
            }
         
     | 
| 
      
 1613 
     | 
    
         
            +
             
     | 
| 
      
 1614 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1615 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 1616 
     | 
    
         
            +
             *    ssl.accept => self
         
     | 
| 
      
 1617 
     | 
    
         
            +
             *
         
     | 
| 
      
 1618 
     | 
    
         
            +
             * Waits for a SSL/TLS client to initiate a handshake.  The handshake may be
         
     | 
| 
      
 1619 
     | 
    
         
            +
             * started after unencrypted data has been sent over the socket.
         
     | 
| 
      
 1620 
     | 
    
         
            +
             */
         
     | 
| 
      
 1621 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1622 
     | 
    
         
            +
            ossl_ssl_accept(VALUE self)
         
     | 
| 
      
 1623 
     | 
    
         
            +
            {
         
     | 
| 
      
 1624 
     | 
    
         
            +
                ossl_ssl_setup(self);
         
     | 
| 
      
 1625 
     | 
    
         
            +
             
     | 
| 
      
 1626 
     | 
    
         
            +
                return ossl_start_ssl(self, SSL_accept, "SSL_accept", Qfalse);
         
     | 
| 
      
 1627 
     | 
    
         
            +
            }
         
     | 
| 
      
 1628 
     | 
    
         
            +
             
     | 
| 
      
 1629 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1630 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 1631 
     | 
    
         
            +
             *    ssl.accept_nonblock([options]) => self
         
     | 
| 
      
 1632 
     | 
    
         
            +
             *
         
     | 
| 
      
 1633 
     | 
    
         
            +
             * Initiates the SSL/TLS handshake as a server in non-blocking manner.
         
     | 
| 
      
 1634 
     | 
    
         
            +
             *
         
     | 
| 
      
 1635 
     | 
    
         
            +
             *   # emulates blocking accept
         
     | 
| 
      
 1636 
     | 
    
         
            +
             *   begin
         
     | 
| 
      
 1637 
     | 
    
         
            +
             *     ssl.accept_nonblock
         
     | 
| 
      
 1638 
     | 
    
         
            +
             *   rescue IO::WaitReadable
         
     | 
| 
      
 1639 
     | 
    
         
            +
             *     IO.select([s2])
         
     | 
| 
      
 1640 
     | 
    
         
            +
             *     retry
         
     | 
| 
      
 1641 
     | 
    
         
            +
             *   rescue IO::WaitWritable
         
     | 
| 
      
 1642 
     | 
    
         
            +
             *     IO.select(nil, [s2])
         
     | 
| 
      
 1643 
     | 
    
         
            +
             *     retry
         
     | 
| 
      
 1644 
     | 
    
         
            +
             *   end
         
     | 
| 
      
 1645 
     | 
    
         
            +
             *
         
     | 
| 
      
 1646 
     | 
    
         
            +
             * By specifying `exception: false`, the options hash allows you to indicate
         
     | 
| 
      
 1647 
     | 
    
         
            +
             * that accept_nonblock should not raise an IO::WaitReadable or
         
     | 
| 
      
 1648 
     | 
    
         
            +
             * IO::WaitWritable exception, but return the symbol :wait_readable or
         
     | 
| 
      
 1649 
     | 
    
         
            +
             * :wait_writable instead.
         
     | 
| 
      
 1650 
     | 
    
         
            +
             */
         
     | 
| 
      
 1651 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1652 
     | 
    
         
            +
            ossl_ssl_accept_nonblock(int argc, VALUE *argv, VALUE self)
         
     | 
| 
      
 1653 
     | 
    
         
            +
            {
         
     | 
| 
      
 1654 
     | 
    
         
            +
                VALUE opts;
         
     | 
| 
      
 1655 
     | 
    
         
            +
             
     | 
| 
      
 1656 
     | 
    
         
            +
                rb_scan_args(argc, argv, "0:", &opts);
         
     | 
| 
      
 1657 
     | 
    
         
            +
                ossl_ssl_setup(self);
         
     | 
| 
      
 1658 
     | 
    
         
            +
             
     | 
| 
      
 1659 
     | 
    
         
            +
                return ossl_start_ssl(self, SSL_accept, "SSL_accept", opts);
         
     | 
| 
      
 1660 
     | 
    
         
            +
            }
         
     | 
| 
      
 1661 
     | 
    
         
            +
             
     | 
| 
      
 1662 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1663 
     | 
    
         
            +
            ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
         
     | 
| 
      
 1664 
     | 
    
         
            +
            {
         
     | 
| 
      
 1665 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 1666 
     | 
    
         
            +
                int ilen, nread = 0;
         
     | 
| 
      
 1667 
     | 
    
         
            +
                VALUE len, str;
         
     | 
| 
      
 1668 
     | 
    
         
            +
                rb_io_t *fptr;
         
     | 
| 
      
 1669 
     | 
    
         
            +
                VALUE opts = Qnil;
         
     | 
| 
      
 1670 
     | 
    
         
            +
             
     | 
| 
      
 1671 
     | 
    
         
            +
                if (nonblock) {
         
     | 
| 
      
 1672 
     | 
    
         
            +
            	rb_scan_args(argc, argv, "11:", &len, &str, &opts);
         
     | 
| 
      
 1673 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 1674 
     | 
    
         
            +
            	rb_scan_args(argc, argv, "11", &len, &str);
         
     | 
| 
      
 1675 
     | 
    
         
            +
                }
         
     | 
| 
      
 1676 
     | 
    
         
            +
             
     | 
| 
      
 1677 
     | 
    
         
            +
                ilen = NUM2INT(len);
         
     | 
| 
      
 1678 
     | 
    
         
            +
                if(NIL_P(str)) str = rb_str_new(0, ilen);
         
     | 
| 
      
 1679 
     | 
    
         
            +
                else{
         
     | 
| 
      
 1680 
     | 
    
         
            +
                    StringValue(str);
         
     | 
| 
      
 1681 
     | 
    
         
            +
                    rb_str_modify(str);
         
     | 
| 
      
 1682 
     | 
    
         
            +
                    rb_str_resize(str, ilen);
         
     | 
| 
      
 1683 
     | 
    
         
            +
                }
         
     | 
| 
      
 1684 
     | 
    
         
            +
                if(ilen == 0) return str;
         
     | 
| 
      
 1685 
     | 
    
         
            +
             
     | 
| 
      
 1686 
     | 
    
         
            +
                GetSSL(self, ssl);
         
     | 
| 
      
 1687 
     | 
    
         
            +
                GetOpenFile(ossl_ssl_get_io(self), fptr);
         
     | 
| 
      
 1688 
     | 
    
         
            +
                if (ssl_started(ssl)) {
         
     | 
| 
      
 1689 
     | 
    
         
            +
            	if(!nonblock && SSL_pending(ssl) <= 0)
         
     | 
| 
      
 1690 
     | 
    
         
            +
            	    rb_thread_wait_fd(FPTR_TO_FD(fptr));
         
     | 
| 
      
 1691 
     | 
    
         
            +
            	for (;;){
         
     | 
| 
      
 1692 
     | 
    
         
            +
            	    nread = SSL_read(ssl, RSTRING_PTR(str), RSTRING_LENINT(str));
         
     | 
| 
      
 1693 
     | 
    
         
            +
            	    switch(ssl_get_error(ssl, nread)){
         
     | 
| 
      
 1694 
     | 
    
         
            +
            	    case SSL_ERROR_NONE:
         
     | 
| 
      
 1695 
     | 
    
         
            +
            		goto end;
         
     | 
| 
      
 1696 
     | 
    
         
            +
            	    case SSL_ERROR_ZERO_RETURN:
         
     | 
| 
      
 1697 
     | 
    
         
            +
            		if (no_exception_p(opts)) { return Qnil; }
         
     | 
| 
      
 1698 
     | 
    
         
            +
            		rb_eof_error();
         
     | 
| 
      
 1699 
     | 
    
         
            +
            	    case SSL_ERROR_WANT_WRITE:
         
     | 
| 
      
 1700 
     | 
    
         
            +
            		if (no_exception_p(opts)) { return sym_wait_writable; }
         
     | 
| 
      
 1701 
     | 
    
         
            +
                            write_would_block(nonblock);
         
     | 
| 
      
 1702 
     | 
    
         
            +
                            rb_io_wait_writable(FPTR_TO_FD(fptr));
         
     | 
| 
      
 1703 
     | 
    
         
            +
                            continue;
         
     | 
| 
      
 1704 
     | 
    
         
            +
            	    case SSL_ERROR_WANT_READ:
         
     | 
| 
      
 1705 
     | 
    
         
            +
            		if (no_exception_p(opts)) { return sym_wait_readable; }
         
     | 
| 
      
 1706 
     | 
    
         
            +
                            read_would_block(nonblock);
         
     | 
| 
      
 1707 
     | 
    
         
            +
                            rb_io_wait_readable(FPTR_TO_FD(fptr));
         
     | 
| 
      
 1708 
     | 
    
         
            +
            		continue;
         
     | 
| 
      
 1709 
     | 
    
         
            +
            	    case SSL_ERROR_SYSCALL:
         
     | 
| 
      
 1710 
     | 
    
         
            +
            		if(ERR_peek_error() == 0 && nread == 0) {
         
     | 
| 
      
 1711 
     | 
    
         
            +
            		    if (no_exception_p(opts)) { return Qnil; }
         
     | 
| 
      
 1712 
     | 
    
         
            +
            		    rb_eof_error();
         
     | 
| 
      
 1713 
     | 
    
         
            +
            		}
         
     | 
| 
      
 1714 
     | 
    
         
            +
            		rb_sys_fail(0);
         
     | 
| 
      
 1715 
     | 
    
         
            +
            	    default:
         
     | 
| 
      
 1716 
     | 
    
         
            +
            		ossl_raise(eSSLError, "SSL_read");
         
     | 
| 
      
 1717 
     | 
    
         
            +
            	    }
         
     | 
| 
      
 1718 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1719 
     | 
    
         
            +
                }
         
     | 
| 
      
 1720 
     | 
    
         
            +
                else {
         
     | 
| 
      
 1721 
     | 
    
         
            +
                    ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread");
         
     | 
| 
      
 1722 
     | 
    
         
            +
                    rb_warning("SSL session is not started yet.");
         
     | 
| 
      
 1723 
     | 
    
         
            +
                    if (nonblock) {
         
     | 
| 
      
 1724 
     | 
    
         
            +
                      return rb_funcall(ossl_ssl_get_io(self), meth, 3, len, str, opts);
         
     | 
| 
      
 1725 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 1726 
     | 
    
         
            +
                      return rb_funcall(ossl_ssl_get_io(self), meth, 2, len, str);
         
     | 
| 
      
 1727 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1728 
     | 
    
         
            +
                }
         
     | 
| 
      
 1729 
     | 
    
         
            +
             
     | 
| 
      
 1730 
     | 
    
         
            +
              end:
         
     | 
| 
      
 1731 
     | 
    
         
            +
                rb_str_set_len(str, nread);
         
     | 
| 
      
 1732 
     | 
    
         
            +
                OBJ_TAINT(str);
         
     | 
| 
      
 1733 
     | 
    
         
            +
             
     | 
| 
      
 1734 
     | 
    
         
            +
                return str;
         
     | 
| 
      
 1735 
     | 
    
         
            +
            }
         
     | 
| 
      
 1736 
     | 
    
         
            +
             
     | 
| 
      
 1737 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1738 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 1739 
     | 
    
         
            +
             *    ssl.sysread(length) => string
         
     | 
| 
      
 1740 
     | 
    
         
            +
             *    ssl.sysread(length, buffer) => buffer
         
     | 
| 
      
 1741 
     | 
    
         
            +
             *
         
     | 
| 
      
 1742 
     | 
    
         
            +
             * Reads +length+ bytes from the SSL connection.  If a pre-allocated +buffer+
         
     | 
| 
      
 1743 
     | 
    
         
            +
             * is provided the data will be written into it.
         
     | 
| 
      
 1744 
     | 
    
         
            +
             */
         
     | 
| 
      
 1745 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1746 
     | 
    
         
            +
            ossl_ssl_read(int argc, VALUE *argv, VALUE self)
         
     | 
| 
      
 1747 
     | 
    
         
            +
            {
         
     | 
| 
      
 1748 
     | 
    
         
            +
                return ossl_ssl_read_internal(argc, argv, self, 0);
         
     | 
| 
      
 1749 
     | 
    
         
            +
            }
         
     | 
| 
      
 1750 
     | 
    
         
            +
             
     | 
| 
      
 1751 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1752 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 1753 
     | 
    
         
            +
             *    ssl.sysread_nonblock(length) => string
         
     | 
| 
      
 1754 
     | 
    
         
            +
             *    ssl.sysread_nonblock(length, buffer) => buffer
         
     | 
| 
      
 1755 
     | 
    
         
            +
             *    ssl.sysread_nonblock(length[, buffer [, opts]) => buffer
         
     | 
| 
      
 1756 
     | 
    
         
            +
             *
         
     | 
| 
      
 1757 
     | 
    
         
            +
             * A non-blocking version of #sysread.  Raises an SSLError if reading would
         
     | 
| 
      
 1758 
     | 
    
         
            +
             * block.  If "exception: false" is passed, this method returns a symbol of
         
     | 
| 
      
 1759 
     | 
    
         
            +
             * :wait_readable, :wait_writable, or nil, rather than raising an exception.
         
     | 
| 
      
 1760 
     | 
    
         
            +
             *
         
     | 
| 
      
 1761 
     | 
    
         
            +
             * Reads +length+ bytes from the SSL connection.  If a pre-allocated +buffer+
         
     | 
| 
      
 1762 
     | 
    
         
            +
             * is provided the data will be written into it.
         
     | 
| 
      
 1763 
     | 
    
         
            +
             */
         
     | 
| 
      
 1764 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1765 
     | 
    
         
            +
            ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self)
         
     | 
| 
      
 1766 
     | 
    
         
            +
            {
         
     | 
| 
      
 1767 
     | 
    
         
            +
                return ossl_ssl_read_internal(argc, argv, self, 1);
         
     | 
| 
      
 1768 
     | 
    
         
            +
            }
         
     | 
| 
      
 1769 
     | 
    
         
            +
             
     | 
| 
      
 1770 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1771 
     | 
    
         
            +
            ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
         
     | 
| 
      
 1772 
     | 
    
         
            +
            {
         
     | 
| 
      
 1773 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 1774 
     | 
    
         
            +
                int nwrite = 0;
         
     | 
| 
      
 1775 
     | 
    
         
            +
                rb_io_t *fptr;
         
     | 
| 
      
 1776 
     | 
    
         
            +
                int nonblock = opts != Qfalse;
         
     | 
| 
      
 1777 
     | 
    
         
            +
             
     | 
| 
      
 1778 
     | 
    
         
            +
                StringValue(str);
         
     | 
| 
      
 1779 
     | 
    
         
            +
                GetSSL(self, ssl);
         
     | 
| 
      
 1780 
     | 
    
         
            +
                GetOpenFile(ossl_ssl_get_io(self), fptr);
         
     | 
| 
      
 1781 
     | 
    
         
            +
             
     | 
| 
      
 1782 
     | 
    
         
            +
                if (ssl_started(ssl)) {
         
     | 
| 
      
 1783 
     | 
    
         
            +
            	for (;;){
         
     | 
| 
      
 1784 
     | 
    
         
            +
            	    int num = RSTRING_LENINT(str);
         
     | 
| 
      
 1785 
     | 
    
         
            +
             
     | 
| 
      
 1786 
     | 
    
         
            +
            	    /* SSL_write(3ssl) manpage states num == 0 is undefined */
         
     | 
| 
      
 1787 
     | 
    
         
            +
            	    if (num == 0)
         
     | 
| 
      
 1788 
     | 
    
         
            +
            		goto end;
         
     | 
| 
      
 1789 
     | 
    
         
            +
             
     | 
| 
      
 1790 
     | 
    
         
            +
            	    nwrite = SSL_write(ssl, RSTRING_PTR(str), num);
         
     | 
| 
      
 1791 
     | 
    
         
            +
            	    switch(ssl_get_error(ssl, nwrite)){
         
     | 
| 
      
 1792 
     | 
    
         
            +
            	    case SSL_ERROR_NONE:
         
     | 
| 
      
 1793 
     | 
    
         
            +
            		goto end;
         
     | 
| 
      
 1794 
     | 
    
         
            +
            	    case SSL_ERROR_WANT_WRITE:
         
     | 
| 
      
 1795 
     | 
    
         
            +
            		if (no_exception_p(opts)) { return sym_wait_writable; }
         
     | 
| 
      
 1796 
     | 
    
         
            +
                            write_would_block(nonblock);
         
     | 
| 
      
 1797 
     | 
    
         
            +
                            rb_io_wait_writable(FPTR_TO_FD(fptr));
         
     | 
| 
      
 1798 
     | 
    
         
            +
                            continue;
         
     | 
| 
      
 1799 
     | 
    
         
            +
            	    case SSL_ERROR_WANT_READ:
         
     | 
| 
      
 1800 
     | 
    
         
            +
            		if (no_exception_p(opts)) { return sym_wait_readable; }
         
     | 
| 
      
 1801 
     | 
    
         
            +
                            read_would_block(nonblock);
         
     | 
| 
      
 1802 
     | 
    
         
            +
                            rb_io_wait_readable(FPTR_TO_FD(fptr));
         
     | 
| 
      
 1803 
     | 
    
         
            +
                            continue;
         
     | 
| 
      
 1804 
     | 
    
         
            +
            	    case SSL_ERROR_SYSCALL:
         
     | 
| 
      
 1805 
     | 
    
         
            +
            		if (errno) rb_sys_fail(0);
         
     | 
| 
      
 1806 
     | 
    
         
            +
            	    default:
         
     | 
| 
      
 1807 
     | 
    
         
            +
            		ossl_raise(eSSLError, "SSL_write");
         
     | 
| 
      
 1808 
     | 
    
         
            +
            	    }
         
     | 
| 
      
 1809 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1810 
     | 
    
         
            +
                }
         
     | 
| 
      
 1811 
     | 
    
         
            +
                else {
         
     | 
| 
      
 1812 
     | 
    
         
            +
                    ID id_syswrite = rb_intern("syswrite");
         
     | 
| 
      
 1813 
     | 
    
         
            +
                    rb_warning("SSL session is not started yet.");
         
     | 
| 
      
 1814 
     | 
    
         
            +
            	return rb_funcall(ossl_ssl_get_io(self), id_syswrite, 1, str);
         
     | 
| 
      
 1815 
     | 
    
         
            +
                }
         
     | 
| 
      
 1816 
     | 
    
         
            +
             
     | 
| 
      
 1817 
     | 
    
         
            +
              end:
         
     | 
| 
      
 1818 
     | 
    
         
            +
                return INT2NUM(nwrite);
         
     | 
| 
      
 1819 
     | 
    
         
            +
            }
         
     | 
| 
      
 1820 
     | 
    
         
            +
             
     | 
| 
      
 1821 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1822 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 1823 
     | 
    
         
            +
             *    ssl.syswrite(string) => Integer
         
     | 
| 
      
 1824 
     | 
    
         
            +
             *
         
     | 
| 
      
 1825 
     | 
    
         
            +
             * Writes +string+ to the SSL connection.
         
     | 
| 
      
 1826 
     | 
    
         
            +
             */
         
     | 
| 
      
 1827 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1828 
     | 
    
         
            +
            ossl_ssl_write(VALUE self, VALUE str)
         
     | 
| 
      
 1829 
     | 
    
         
            +
            {
         
     | 
| 
      
 1830 
     | 
    
         
            +
                return ossl_ssl_write_internal(self, str, Qfalse);
         
     | 
| 
      
 1831 
     | 
    
         
            +
            }
         
     | 
| 
      
 1832 
     | 
    
         
            +
             
     | 
| 
      
 1833 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1834 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 1835 
     | 
    
         
            +
             *    ssl.syswrite_nonblock(string) => Integer
         
     | 
| 
      
 1836 
     | 
    
         
            +
             *
         
     | 
| 
      
 1837 
     | 
    
         
            +
             * Writes +string+ to the SSL connection in a non-blocking manner.  Raises an
         
     | 
| 
      
 1838 
     | 
    
         
            +
             * SSLError if writing would block.
         
     | 
| 
      
 1839 
     | 
    
         
            +
             */
         
     | 
| 
      
 1840 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1841 
     | 
    
         
            +
            ossl_ssl_write_nonblock(int argc, VALUE *argv, VALUE self)
         
     | 
| 
      
 1842 
     | 
    
         
            +
            {
         
     | 
| 
      
 1843 
     | 
    
         
            +
                VALUE str, opts;
         
     | 
| 
      
 1844 
     | 
    
         
            +
             
     | 
| 
      
 1845 
     | 
    
         
            +
                rb_scan_args(argc, argv, "1:", &str, &opts);
         
     | 
| 
      
 1846 
     | 
    
         
            +
             
     | 
| 
      
 1847 
     | 
    
         
            +
                return ossl_ssl_write_internal(self, str, opts);
         
     | 
| 
      
 1848 
     | 
    
         
            +
            }
         
     | 
| 
      
 1849 
     | 
    
         
            +
             
     | 
| 
      
 1850 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1851 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 1852 
     | 
    
         
            +
             *    ssl.stop => nil
         
     | 
| 
      
 1853 
     | 
    
         
            +
             *
         
     | 
| 
      
 1854 
     | 
    
         
            +
             * Sends "close notify" to the peer and tries to shut down the SSL connection
         
     | 
| 
      
 1855 
     | 
    
         
            +
             * gracefully.
         
     | 
| 
      
 1856 
     | 
    
         
            +
             */
         
     | 
| 
      
 1857 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1858 
     | 
    
         
            +
            ossl_ssl_stop(VALUE self)
         
     | 
| 
      
 1859 
     | 
    
         
            +
            {
         
     | 
| 
      
 1860 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 1861 
     | 
    
         
            +
             
     | 
| 
      
 1862 
     | 
    
         
            +
                GetSSL(self, ssl);
         
     | 
| 
      
 1863 
     | 
    
         
            +
             
     | 
| 
      
 1864 
     | 
    
         
            +
                ossl_ssl_shutdown(ssl);
         
     | 
| 
      
 1865 
     | 
    
         
            +
             
     | 
| 
      
 1866 
     | 
    
         
            +
                return Qnil;
         
     | 
| 
      
 1867 
     | 
    
         
            +
            }
         
     | 
| 
      
 1868 
     | 
    
         
            +
             
     | 
| 
      
 1869 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1870 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 1871 
     | 
    
         
            +
             *    ssl.cert => cert or nil
         
     | 
| 
      
 1872 
     | 
    
         
            +
             *
         
     | 
| 
      
 1873 
     | 
    
         
            +
             * The X509 certificate for this socket endpoint.
         
     | 
| 
      
 1874 
     | 
    
         
            +
             */
         
     | 
| 
      
 1875 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1876 
     | 
    
         
            +
            ossl_ssl_get_cert(VALUE self)
         
     | 
| 
      
 1877 
     | 
    
         
            +
            {
         
     | 
| 
      
 1878 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 1879 
     | 
    
         
            +
                X509 *cert = NULL;
         
     | 
| 
      
 1880 
     | 
    
         
            +
             
     | 
| 
      
 1881 
     | 
    
         
            +
                GetSSL(self, ssl);
         
     | 
| 
      
 1882 
     | 
    
         
            +
             
     | 
| 
      
 1883 
     | 
    
         
            +
                /*
         
     | 
| 
      
 1884 
     | 
    
         
            +
                 * Is this OpenSSL bug? Should add a ref?
         
     | 
| 
      
 1885 
     | 
    
         
            +
                 * TODO: Ask for.
         
     | 
| 
      
 1886 
     | 
    
         
            +
                 */
         
     | 
| 
      
 1887 
     | 
    
         
            +
                cert = SSL_get_certificate(ssl); /* NO DUPs => DON'T FREE. */
         
     | 
| 
      
 1888 
     | 
    
         
            +
             
     | 
| 
      
 1889 
     | 
    
         
            +
                if (!cert) {
         
     | 
| 
      
 1890 
     | 
    
         
            +
                    return Qnil;
         
     | 
| 
      
 1891 
     | 
    
         
            +
                }
         
     | 
| 
      
 1892 
     | 
    
         
            +
                return ossl_x509_new(cert);
         
     | 
| 
      
 1893 
     | 
    
         
            +
            }
         
     | 
| 
      
 1894 
     | 
    
         
            +
             
     | 
| 
      
 1895 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1896 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 1897 
     | 
    
         
            +
             *    ssl.peer_cert => cert or nil
         
     | 
| 
      
 1898 
     | 
    
         
            +
             *
         
     | 
| 
      
 1899 
     | 
    
         
            +
             * The X509 certificate for this socket's peer.
         
     | 
| 
      
 1900 
     | 
    
         
            +
             */
         
     | 
| 
      
 1901 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1902 
     | 
    
         
            +
            ossl_ssl_get_peer_cert(VALUE self)
         
     | 
| 
      
 1903 
     | 
    
         
            +
            {
         
     | 
| 
      
 1904 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 1905 
     | 
    
         
            +
                X509 *cert = NULL;
         
     | 
| 
      
 1906 
     | 
    
         
            +
                VALUE obj;
         
     | 
| 
      
 1907 
     | 
    
         
            +
             
     | 
| 
      
 1908 
     | 
    
         
            +
                GetSSL(self, ssl);
         
     | 
| 
      
 1909 
     | 
    
         
            +
             
     | 
| 
      
 1910 
     | 
    
         
            +
                cert = SSL_get_peer_certificate(ssl); /* Adds a ref => Safe to FREE. */
         
     | 
| 
      
 1911 
     | 
    
         
            +
             
     | 
| 
      
 1912 
     | 
    
         
            +
                if (!cert) {
         
     | 
| 
      
 1913 
     | 
    
         
            +
                    return Qnil;
         
     | 
| 
      
 1914 
     | 
    
         
            +
                }
         
     | 
| 
      
 1915 
     | 
    
         
            +
                obj = ossl_x509_new(cert);
         
     | 
| 
      
 1916 
     | 
    
         
            +
                X509_free(cert);
         
     | 
| 
      
 1917 
     | 
    
         
            +
             
     | 
| 
      
 1918 
     | 
    
         
            +
                return obj;
         
     | 
| 
      
 1919 
     | 
    
         
            +
            }
         
     | 
| 
      
 1920 
     | 
    
         
            +
             
     | 
| 
      
 1921 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1922 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 1923 
     | 
    
         
            +
             *    ssl.peer_cert_chain => [cert, ...] or nil
         
     | 
| 
      
 1924 
     | 
    
         
            +
             *
         
     | 
| 
      
 1925 
     | 
    
         
            +
             * The X509 certificate chain for this socket's peer.
         
     | 
| 
      
 1926 
     | 
    
         
            +
             */
         
     | 
| 
      
 1927 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1928 
     | 
    
         
            +
            ossl_ssl_get_peer_cert_chain(VALUE self)
         
     | 
| 
      
 1929 
     | 
    
         
            +
            {
         
     | 
| 
      
 1930 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 1931 
     | 
    
         
            +
                STACK_OF(X509) *chain;
         
     | 
| 
      
 1932 
     | 
    
         
            +
                X509 *cert;
         
     | 
| 
      
 1933 
     | 
    
         
            +
                VALUE ary;
         
     | 
| 
      
 1934 
     | 
    
         
            +
                int i, num;
         
     | 
| 
      
 1935 
     | 
    
         
            +
             
     | 
| 
      
 1936 
     | 
    
         
            +
                GetSSL(self, ssl);
         
     | 
| 
      
 1937 
     | 
    
         
            +
             
     | 
| 
      
 1938 
     | 
    
         
            +
                chain = SSL_get_peer_cert_chain(ssl);
         
     | 
| 
      
 1939 
     | 
    
         
            +
                if(!chain) return Qnil;
         
     | 
| 
      
 1940 
     | 
    
         
            +
                num = sk_X509_num(chain);
         
     | 
| 
      
 1941 
     | 
    
         
            +
                ary = rb_ary_new2(num);
         
     | 
| 
      
 1942 
     | 
    
         
            +
                for (i = 0; i < num; i++){
         
     | 
| 
      
 1943 
     | 
    
         
            +
            	cert = sk_X509_value(chain, i);
         
     | 
| 
      
 1944 
     | 
    
         
            +
            	rb_ary_push(ary, ossl_x509_new(cert));
         
     | 
| 
      
 1945 
     | 
    
         
            +
                }
         
     | 
| 
      
 1946 
     | 
    
         
            +
             
     | 
| 
      
 1947 
     | 
    
         
            +
                return ary;
         
     | 
| 
      
 1948 
     | 
    
         
            +
            }
         
     | 
| 
      
 1949 
     | 
    
         
            +
             
     | 
| 
      
 1950 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1951 
     | 
    
         
            +
            * call-seq:
         
     | 
| 
      
 1952 
     | 
    
         
            +
            *    ssl.ssl_version => String
         
     | 
| 
      
 1953 
     | 
    
         
            +
            *
         
     | 
| 
      
 1954 
     | 
    
         
            +
            * Returns a String representing the SSL/TLS version that was negotiated
         
     | 
| 
      
 1955 
     | 
    
         
            +
            * for the connection, for example "TLSv1.2".
         
     | 
| 
      
 1956 
     | 
    
         
            +
            */
         
     | 
| 
      
 1957 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1958 
     | 
    
         
            +
            ossl_ssl_get_version(VALUE self)
         
     | 
| 
      
 1959 
     | 
    
         
            +
            {
         
     | 
| 
      
 1960 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 1961 
     | 
    
         
            +
             
     | 
| 
      
 1962 
     | 
    
         
            +
                GetSSL(self, ssl);
         
     | 
| 
      
 1963 
     | 
    
         
            +
             
     | 
| 
      
 1964 
     | 
    
         
            +
                return rb_str_new2(SSL_get_version(ssl));
         
     | 
| 
      
 1965 
     | 
    
         
            +
            }
         
     | 
| 
      
 1966 
     | 
    
         
            +
             
     | 
| 
      
 1967 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1968 
     | 
    
         
            +
            * call-seq:
         
     | 
| 
      
 1969 
     | 
    
         
            +
            *    ssl.cipher => [name, version, bits, alg_bits]
         
     | 
| 
      
 1970 
     | 
    
         
            +
            *
         
     | 
| 
      
 1971 
     | 
    
         
            +
            * The cipher being used for the current connection
         
     | 
| 
      
 1972 
     | 
    
         
            +
            */
         
     | 
| 
      
 1973 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1974 
     | 
    
         
            +
            ossl_ssl_get_cipher(VALUE self)
         
     | 
| 
      
 1975 
     | 
    
         
            +
            {
         
     | 
| 
      
 1976 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 1977 
     | 
    
         
            +
                SSL_CIPHER *cipher;
         
     | 
| 
      
 1978 
     | 
    
         
            +
             
     | 
| 
      
 1979 
     | 
    
         
            +
                GetSSL(self, ssl);
         
     | 
| 
      
 1980 
     | 
    
         
            +
             
     | 
| 
      
 1981 
     | 
    
         
            +
                cipher = (SSL_CIPHER *)SSL_get_current_cipher(ssl);
         
     | 
| 
      
 1982 
     | 
    
         
            +
             
     | 
| 
      
 1983 
     | 
    
         
            +
                return ossl_ssl_cipher_to_ary(cipher);
         
     | 
| 
      
 1984 
     | 
    
         
            +
            }
         
     | 
| 
      
 1985 
     | 
    
         
            +
             
     | 
| 
      
 1986 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1987 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 1988 
     | 
    
         
            +
             *    ssl.state => string
         
     | 
| 
      
 1989 
     | 
    
         
            +
             *
         
     | 
| 
      
 1990 
     | 
    
         
            +
             * A description of the current connection state. This is for diagnostic
         
     | 
| 
      
 1991 
     | 
    
         
            +
             * purposes only.
         
     | 
| 
      
 1992 
     | 
    
         
            +
             */
         
     | 
| 
      
 1993 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1994 
     | 
    
         
            +
            ossl_ssl_get_state(VALUE self)
         
     | 
| 
      
 1995 
     | 
    
         
            +
            {
         
     | 
| 
      
 1996 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 1997 
     | 
    
         
            +
                VALUE ret;
         
     | 
| 
      
 1998 
     | 
    
         
            +
             
     | 
| 
      
 1999 
     | 
    
         
            +
                GetSSL(self, ssl);
         
     | 
| 
      
 2000 
     | 
    
         
            +
             
     | 
| 
      
 2001 
     | 
    
         
            +
                ret = rb_str_new2(SSL_state_string(ssl));
         
     | 
| 
      
 2002 
     | 
    
         
            +
                if (ruby_verbose) {
         
     | 
| 
      
 2003 
     | 
    
         
            +
                    rb_str_cat2(ret, ": ");
         
     | 
| 
      
 2004 
     | 
    
         
            +
                    rb_str_cat2(ret, SSL_state_string_long(ssl));
         
     | 
| 
      
 2005 
     | 
    
         
            +
                }
         
     | 
| 
      
 2006 
     | 
    
         
            +
                return ret;
         
     | 
| 
      
 2007 
     | 
    
         
            +
            }
         
     | 
| 
      
 2008 
     | 
    
         
            +
             
     | 
| 
      
 2009 
     | 
    
         
            +
            /*
         
     | 
| 
      
 2010 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 2011 
     | 
    
         
            +
             *    ssl.pending => Integer
         
     | 
| 
      
 2012 
     | 
    
         
            +
             *
         
     | 
| 
      
 2013 
     | 
    
         
            +
             * The number of bytes that are immediately available for reading.
         
     | 
| 
      
 2014 
     | 
    
         
            +
             */
         
     | 
| 
      
 2015 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 2016 
     | 
    
         
            +
            ossl_ssl_pending(VALUE self)
         
     | 
| 
      
 2017 
     | 
    
         
            +
            {
         
     | 
| 
      
 2018 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 2019 
     | 
    
         
            +
             
     | 
| 
      
 2020 
     | 
    
         
            +
                GetSSL(self, ssl);
         
     | 
| 
      
 2021 
     | 
    
         
            +
             
     | 
| 
      
 2022 
     | 
    
         
            +
                return INT2NUM(SSL_pending(ssl));
         
     | 
| 
      
 2023 
     | 
    
         
            +
            }
         
     | 
| 
      
 2024 
     | 
    
         
            +
             
     | 
| 
      
 2025 
     | 
    
         
            +
            /*
         
     | 
| 
      
 2026 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 2027 
     | 
    
         
            +
             *    ssl.session_reused? -> true | false
         
     | 
| 
      
 2028 
     | 
    
         
            +
             *
         
     | 
| 
      
 2029 
     | 
    
         
            +
             * Returns true if a reused session was negotiated during the handshake.
         
     | 
| 
      
 2030 
     | 
    
         
            +
             */
         
     | 
| 
      
 2031 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 2032 
     | 
    
         
            +
            ossl_ssl_session_reused(VALUE self)
         
     | 
| 
      
 2033 
     | 
    
         
            +
            {
         
     | 
| 
      
 2034 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 2035 
     | 
    
         
            +
             
     | 
| 
      
 2036 
     | 
    
         
            +
                GetSSL(self, ssl);
         
     | 
| 
      
 2037 
     | 
    
         
            +
             
     | 
| 
      
 2038 
     | 
    
         
            +
                return SSL_session_reused(ssl) ? Qtrue : Qfalse;
         
     | 
| 
      
 2039 
     | 
    
         
            +
            }
         
     | 
| 
      
 2040 
     | 
    
         
            +
             
     | 
| 
      
 2041 
     | 
    
         
            +
            /*
         
     | 
| 
      
 2042 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 2043 
     | 
    
         
            +
             *    ssl.session = session -> session
         
     | 
| 
      
 2044 
     | 
    
         
            +
             *
         
     | 
| 
      
 2045 
     | 
    
         
            +
             * Sets the Session to be used when the connection is established.
         
     | 
| 
      
 2046 
     | 
    
         
            +
             */
         
     | 
| 
      
 2047 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 2048 
     | 
    
         
            +
            ossl_ssl_set_session(VALUE self, VALUE arg1)
         
     | 
| 
      
 2049 
     | 
    
         
            +
            {
         
     | 
| 
      
 2050 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 2051 
     | 
    
         
            +
                SSL_SESSION *sess;
         
     | 
| 
      
 2052 
     | 
    
         
            +
             
     | 
| 
      
 2053 
     | 
    
         
            +
                GetSSL(self, ssl);
         
     | 
| 
      
 2054 
     | 
    
         
            +
                SafeGetSSLSession(arg1, sess);
         
     | 
| 
      
 2055 
     | 
    
         
            +
             
     | 
| 
      
 2056 
     | 
    
         
            +
                if (SSL_set_session(ssl, sess) != 1)
         
     | 
| 
      
 2057 
     | 
    
         
            +
                    ossl_raise(eSSLError, "SSL_set_session");
         
     | 
| 
      
 2058 
     | 
    
         
            +
             
     | 
| 
      
 2059 
     | 
    
         
            +
                return arg1;
         
     | 
| 
      
 2060 
     | 
    
         
            +
            }
         
     | 
| 
      
 2061 
     | 
    
         
            +
             
     | 
| 
      
 2062 
     | 
    
         
            +
            #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
         
     | 
| 
      
 2063 
     | 
    
         
            +
            /*
         
     | 
| 
      
 2064 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 2065 
     | 
    
         
            +
             *    ssl.hostname = hostname -> hostname
         
     | 
| 
      
 2066 
     | 
    
         
            +
             *
         
     | 
| 
      
 2067 
     | 
    
         
            +
             * Sets the server hostname used for SNI. This needs to be set before
         
     | 
| 
      
 2068 
     | 
    
         
            +
             * SSLSocket#connect.
         
     | 
| 
      
 2069 
     | 
    
         
            +
             */
         
     | 
| 
      
 2070 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 2071 
     | 
    
         
            +
            ossl_ssl_set_hostname(VALUE self, VALUE arg)
         
     | 
| 
      
 2072 
     | 
    
         
            +
            {
         
     | 
| 
      
 2073 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 2074 
     | 
    
         
            +
                char *hostname = NULL;
         
     | 
| 
      
 2075 
     | 
    
         
            +
             
     | 
| 
      
 2076 
     | 
    
         
            +
                GetSSL(self, ssl);
         
     | 
| 
      
 2077 
     | 
    
         
            +
             
     | 
| 
      
 2078 
     | 
    
         
            +
                if (!NIL_P(arg))
         
     | 
| 
      
 2079 
     | 
    
         
            +
            	hostname = StringValueCStr(arg);
         
     | 
| 
      
 2080 
     | 
    
         
            +
             
     | 
| 
      
 2081 
     | 
    
         
            +
                if (!SSL_set_tlsext_host_name(ssl, hostname))
         
     | 
| 
      
 2082 
     | 
    
         
            +
            	ossl_raise(eSSLError, NULL);
         
     | 
| 
      
 2083 
     | 
    
         
            +
             
     | 
| 
      
 2084 
     | 
    
         
            +
                /* for SSLSocket#hostname */
         
     | 
| 
      
 2085 
     | 
    
         
            +
                ossl_ssl_set_hostname_v(self, arg);
         
     | 
| 
      
 2086 
     | 
    
         
            +
             
     | 
| 
      
 2087 
     | 
    
         
            +
                return arg;
         
     | 
| 
      
 2088 
     | 
    
         
            +
            }
         
     | 
| 
      
 2089 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 2090 
     | 
    
         
            +
             
     | 
| 
      
 2091 
     | 
    
         
            +
            /*
         
     | 
| 
      
 2092 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 2093 
     | 
    
         
            +
             *    ssl.verify_result => Integer
         
     | 
| 
      
 2094 
     | 
    
         
            +
             *
         
     | 
| 
      
 2095 
     | 
    
         
            +
             * Returns the result of the peer certificates verification.  See verify(1)
         
     | 
| 
      
 2096 
     | 
    
         
            +
             * for error values and descriptions.
         
     | 
| 
      
 2097 
     | 
    
         
            +
             *
         
     | 
| 
      
 2098 
     | 
    
         
            +
             * If no peer certificate was presented X509_V_OK is returned.
         
     | 
| 
      
 2099 
     | 
    
         
            +
             */
         
     | 
| 
      
 2100 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 2101 
     | 
    
         
            +
            ossl_ssl_get_verify_result(VALUE self)
         
     | 
| 
      
 2102 
     | 
    
         
            +
            {
         
     | 
| 
      
 2103 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 2104 
     | 
    
         
            +
             
     | 
| 
      
 2105 
     | 
    
         
            +
                GetSSL(self, ssl);
         
     | 
| 
      
 2106 
     | 
    
         
            +
             
     | 
| 
      
 2107 
     | 
    
         
            +
                return INT2NUM(SSL_get_verify_result(ssl));
         
     | 
| 
      
 2108 
     | 
    
         
            +
            }
         
     | 
| 
      
 2109 
     | 
    
         
            +
             
     | 
| 
      
 2110 
     | 
    
         
            +
            /*
         
     | 
| 
      
 2111 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 2112 
     | 
    
         
            +
             *    ssl.client_ca => [x509name, ...]
         
     | 
| 
      
 2113 
     | 
    
         
            +
             *
         
     | 
| 
      
 2114 
     | 
    
         
            +
             * Returns the list of client CAs. Please note that in contrast to
         
     | 
| 
      
 2115 
     | 
    
         
            +
             * SSLContext#client_ca= no array of X509::Certificate is returned but
         
     | 
| 
      
 2116 
     | 
    
         
            +
             * X509::Name instances of the CA's subject distinguished name.
         
     | 
| 
      
 2117 
     | 
    
         
            +
             *
         
     | 
| 
      
 2118 
     | 
    
         
            +
             * In server mode, returns the list set by SSLContext#client_ca=.
         
     | 
| 
      
 2119 
     | 
    
         
            +
             * In client mode, returns the list of client CAs sent from the server.
         
     | 
| 
      
 2120 
     | 
    
         
            +
             */
         
     | 
| 
      
 2121 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 2122 
     | 
    
         
            +
            ossl_ssl_get_client_ca_list(VALUE self)
         
     | 
| 
      
 2123 
     | 
    
         
            +
            {
         
     | 
| 
      
 2124 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 2125 
     | 
    
         
            +
                STACK_OF(X509_NAME) *ca;
         
     | 
| 
      
 2126 
     | 
    
         
            +
             
     | 
| 
      
 2127 
     | 
    
         
            +
                GetSSL(self, ssl);
         
     | 
| 
      
 2128 
     | 
    
         
            +
             
     | 
| 
      
 2129 
     | 
    
         
            +
                ca = SSL_get_client_CA_list(ssl);
         
     | 
| 
      
 2130 
     | 
    
         
            +
                return ossl_x509name_sk2ary(ca);
         
     | 
| 
      
 2131 
     | 
    
         
            +
            }
         
     | 
| 
      
 2132 
     | 
    
         
            +
             
     | 
| 
      
 2133 
     | 
    
         
            +
            # ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
         
     | 
| 
      
 2134 
     | 
    
         
            +
            /*
         
     | 
| 
      
 2135 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 2136 
     | 
    
         
            +
             *    ssl.npn_protocol => String | nil
         
     | 
| 
      
 2137 
     | 
    
         
            +
             *
         
     | 
| 
      
 2138 
     | 
    
         
            +
             * Returns the protocol string that was finally selected by the client
         
     | 
| 
      
 2139 
     | 
    
         
            +
             * during the handshake.
         
     | 
| 
      
 2140 
     | 
    
         
            +
             */
         
     | 
| 
      
 2141 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 2142 
     | 
    
         
            +
            ossl_ssl_npn_protocol(VALUE self)
         
     | 
| 
      
 2143 
     | 
    
         
            +
            {
         
     | 
| 
      
 2144 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 2145 
     | 
    
         
            +
                const unsigned char *out;
         
     | 
| 
      
 2146 
     | 
    
         
            +
                unsigned int outlen;
         
     | 
| 
      
 2147 
     | 
    
         
            +
             
     | 
| 
      
 2148 
     | 
    
         
            +
                GetSSL(self, ssl);
         
     | 
| 
      
 2149 
     | 
    
         
            +
             
     | 
| 
      
 2150 
     | 
    
         
            +
                SSL_get0_next_proto_negotiated(ssl, &out, &outlen);
         
     | 
| 
      
 2151 
     | 
    
         
            +
                if (!outlen)
         
     | 
| 
      
 2152 
     | 
    
         
            +
            	return Qnil;
         
     | 
| 
      
 2153 
     | 
    
         
            +
                else
         
     | 
| 
      
 2154 
     | 
    
         
            +
            	return rb_str_new((const char *) out, outlen);
         
     | 
| 
      
 2155 
     | 
    
         
            +
            }
         
     | 
| 
      
 2156 
     | 
    
         
            +
            # endif
         
     | 
| 
      
 2157 
     | 
    
         
            +
             
     | 
| 
      
 2158 
     | 
    
         
            +
            # ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
         
     | 
| 
      
 2159 
     | 
    
         
            +
            /*
         
     | 
| 
      
 2160 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 2161 
     | 
    
         
            +
             *    ssl.alpn_protocol => String | nil
         
     | 
| 
      
 2162 
     | 
    
         
            +
             *
         
     | 
| 
      
 2163 
     | 
    
         
            +
             * Returns the ALPN protocol string that was finally selected by the server
         
     | 
| 
      
 2164 
     | 
    
         
            +
             * during the handshake.
         
     | 
| 
      
 2165 
     | 
    
         
            +
             */
         
     | 
| 
      
 2166 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 2167 
     | 
    
         
            +
            ossl_ssl_alpn_protocol(VALUE self)
         
     | 
| 
      
 2168 
     | 
    
         
            +
            {
         
     | 
| 
      
 2169 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 2170 
     | 
    
         
            +
                const unsigned char *out;
         
     | 
| 
      
 2171 
     | 
    
         
            +
                unsigned int outlen;
         
     | 
| 
      
 2172 
     | 
    
         
            +
             
     | 
| 
      
 2173 
     | 
    
         
            +
                GetSSL(self, ssl);
         
     | 
| 
      
 2174 
     | 
    
         
            +
             
     | 
| 
      
 2175 
     | 
    
         
            +
                SSL_get0_alpn_selected(ssl, &out, &outlen);
         
     | 
| 
      
 2176 
     | 
    
         
            +
                if (!outlen)
         
     | 
| 
      
 2177 
     | 
    
         
            +
            	return Qnil;
         
     | 
| 
      
 2178 
     | 
    
         
            +
                else
         
     | 
| 
      
 2179 
     | 
    
         
            +
            	return rb_str_new((const char *) out, outlen);
         
     | 
| 
      
 2180 
     | 
    
         
            +
            }
         
     | 
| 
      
 2181 
     | 
    
         
            +
            # endif
         
     | 
| 
      
 2182 
     | 
    
         
            +
             
     | 
| 
      
 2183 
     | 
    
         
            +
            # ifdef HAVE_SSL_GET_SERVER_TMP_KEY
         
     | 
| 
      
 2184 
     | 
    
         
            +
            /*
         
     | 
| 
      
 2185 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 2186 
     | 
    
         
            +
             *    ssl.tmp_key => PKey or nil
         
     | 
| 
      
 2187 
     | 
    
         
            +
             *
         
     | 
| 
      
 2188 
     | 
    
         
            +
             * Returns the ephemeral key used in case of forward secrecy cipher.
         
     | 
| 
      
 2189 
     | 
    
         
            +
             */
         
     | 
| 
      
 2190 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 2191 
     | 
    
         
            +
            ossl_ssl_tmp_key(VALUE self)
         
     | 
| 
      
 2192 
     | 
    
         
            +
            {
         
     | 
| 
      
 2193 
     | 
    
         
            +
                SSL *ssl;
         
     | 
| 
      
 2194 
     | 
    
         
            +
                EVP_PKEY *key;
         
     | 
| 
      
 2195 
     | 
    
         
            +
             
     | 
| 
      
 2196 
     | 
    
         
            +
                GetSSL(self, ssl);
         
     | 
| 
      
 2197 
     | 
    
         
            +
                if (!SSL_get_server_tmp_key(ssl, &key))
         
     | 
| 
      
 2198 
     | 
    
         
            +
            	return Qnil;
         
     | 
| 
      
 2199 
     | 
    
         
            +
                return ossl_pkey_new(key);
         
     | 
| 
      
 2200 
     | 
    
         
            +
            }
         
     | 
| 
      
 2201 
     | 
    
         
            +
            # endif /* defined(HAVE_SSL_GET_SERVER_TMP_KEY) */
         
     | 
| 
      
 2202 
     | 
    
         
            +
            #endif /* !defined(OPENSSL_NO_SOCK) */
         
     | 
| 
      
 2203 
     | 
    
         
            +
             
     | 
| 
      
 2204 
     | 
    
         
            +
            void
         
     | 
| 
      
 2205 
     | 
    
         
            +
            Init_ossl_ssl(void)
         
     | 
| 
      
 2206 
     | 
    
         
            +
            {
         
     | 
| 
      
 2207 
     | 
    
         
            +
                int i;
         
     | 
| 
      
 2208 
     | 
    
         
            +
                VALUE ary;
         
     | 
| 
      
 2209 
     | 
    
         
            +
             
     | 
| 
      
 2210 
     | 
    
         
            +
            #if 0
         
     | 
| 
      
 2211 
     | 
    
         
            +
                mOSSL = rb_define_module("OpenSSL");
         
     | 
| 
      
 2212 
     | 
    
         
            +
                eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
         
     | 
| 
      
 2213 
     | 
    
         
            +
                rb_mWaitReadable = rb_define_module_under(rb_cIO, "WaitReadable");
         
     | 
| 
      
 2214 
     | 
    
         
            +
                rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
         
     | 
| 
      
 2215 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 2216 
     | 
    
         
            +
             
     | 
| 
      
 2217 
     | 
    
         
            +
                ID_callback_state = rb_intern("@callback_state");
         
     | 
| 
      
 2218 
     | 
    
         
            +
             
     | 
| 
      
 2219 
     | 
    
         
            +
                ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_vcb_idx",0,0,0);
         
     | 
| 
      
 2220 
     | 
    
         
            +
                ossl_ssl_ex_store_p = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_store_p",0,0,0);
         
     | 
| 
      
 2221 
     | 
    
         
            +
                ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_ptr_idx",0,0,0);
         
     | 
| 
      
 2222 
     | 
    
         
            +
             
     | 
| 
      
 2223 
     | 
    
         
            +
                /* Document-module: OpenSSL::SSL
         
     | 
| 
      
 2224 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2225 
     | 
    
         
            +
                 * Use SSLContext to set up the parameters for a TLS (former SSL)
         
     | 
| 
      
 2226 
     | 
    
         
            +
                 * connection. Both client and server TLS connections are supported,
         
     | 
| 
      
 2227 
     | 
    
         
            +
                 * SSLSocket and SSLServer may be used in conjunction with an instance
         
     | 
| 
      
 2228 
     | 
    
         
            +
                 * of SSLContext to set up connections.
         
     | 
| 
      
 2229 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2230 
     | 
    
         
            +
                mSSL = rb_define_module_under(mOSSL, "SSL");
         
     | 
| 
      
 2231 
     | 
    
         
            +
             
     | 
| 
      
 2232 
     | 
    
         
            +
                /* Document-module: OpenSSL::ExtConfig
         
     | 
| 
      
 2233 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2234 
     | 
    
         
            +
                 * This module contains configuration information about the SSL extension,
         
     | 
| 
      
 2235 
     | 
    
         
            +
                 * for example if socket support is enabled, or the host name TLS extension
         
     | 
| 
      
 2236 
     | 
    
         
            +
                 * is enabled.  Constants in this module will always be defined, but contain
         
     | 
| 
      
 2237 
     | 
    
         
            +
                 * `true` or `false` values depending on the configuration of your OpenSSL
         
     | 
| 
      
 2238 
     | 
    
         
            +
                 * installation.
         
     | 
| 
      
 2239 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2240 
     | 
    
         
            +
                mSSLExtConfig = rb_define_module_under(mOSSL, "ExtConfig");
         
     | 
| 
      
 2241 
     | 
    
         
            +
             
     | 
| 
      
 2242 
     | 
    
         
            +
                /* Document-class: OpenSSL::SSL::SSLError
         
     | 
| 
      
 2243 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2244 
     | 
    
         
            +
                 * Generic error class raised by SSLSocket and SSLContext.
         
     | 
| 
      
 2245 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2246 
     | 
    
         
            +
                eSSLError = rb_define_class_under(mSSL, "SSLError", eOSSLError);
         
     | 
| 
      
 2247 
     | 
    
         
            +
                eSSLErrorWaitReadable = rb_define_class_under(mSSL, "SSLErrorWaitReadable", eSSLError);
         
     | 
| 
      
 2248 
     | 
    
         
            +
                rb_include_module(eSSLErrorWaitReadable, rb_mWaitReadable);
         
     | 
| 
      
 2249 
     | 
    
         
            +
                eSSLErrorWaitWritable = rb_define_class_under(mSSL, "SSLErrorWaitWritable", eSSLError);
         
     | 
| 
      
 2250 
     | 
    
         
            +
                rb_include_module(eSSLErrorWaitWritable, rb_mWaitWritable);
         
     | 
| 
      
 2251 
     | 
    
         
            +
             
     | 
| 
      
 2252 
     | 
    
         
            +
                Init_ossl_ssl_session();
         
     | 
| 
      
 2253 
     | 
    
         
            +
             
     | 
| 
      
 2254 
     | 
    
         
            +
                /* Document-class: OpenSSL::SSL::SSLContext
         
     | 
| 
      
 2255 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2256 
     | 
    
         
            +
                 * An SSLContext is used to set various options regarding certificates,
         
     | 
| 
      
 2257 
     | 
    
         
            +
                 * algorithms, verification, session caching, etc.  The SSLContext is
         
     | 
| 
      
 2258 
     | 
    
         
            +
                 * used to create an SSLSocket.
         
     | 
| 
      
 2259 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2260 
     | 
    
         
            +
                 * All attributes must be set before creating an SSLSocket as the
         
     | 
| 
      
 2261 
     | 
    
         
            +
                 * SSLContext will be frozen afterward.
         
     | 
| 
      
 2262 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2263 
     | 
    
         
            +
                cSSLContext = rb_define_class_under(mSSL, "SSLContext", rb_cObject);
         
     | 
| 
      
 2264 
     | 
    
         
            +
                rb_define_alloc_func(cSSLContext, ossl_sslctx_s_alloc);
         
     | 
| 
      
 2265 
     | 
    
         
            +
                rb_undef_method(cSSLContext, "initialize_copy");
         
     | 
| 
      
 2266 
     | 
    
         
            +
             
     | 
| 
      
 2267 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2268 
     | 
    
         
            +
                 * Context certificate
         
     | 
| 
      
 2269 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2270 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("cert"), 1, 1, Qfalse);
         
     | 
| 
      
 2271 
     | 
    
         
            +
             
     | 
| 
      
 2272 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2273 
     | 
    
         
            +
                 * Context private key
         
     | 
| 
      
 2274 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2275 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("key"), 1, 1, Qfalse);
         
     | 
| 
      
 2276 
     | 
    
         
            +
             
     | 
| 
      
 2277 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2278 
     | 
    
         
            +
                 * A certificate or Array of certificates that will be sent to the client.
         
     | 
| 
      
 2279 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2280 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("client_ca"), 1, 1, Qfalse);
         
     | 
| 
      
 2281 
     | 
    
         
            +
             
     | 
| 
      
 2282 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2283 
     | 
    
         
            +
                 * The path to a file containing a PEM-format CA certificate
         
     | 
| 
      
 2284 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2285 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("ca_file"), 1, 1, Qfalse);
         
     | 
| 
      
 2286 
     | 
    
         
            +
             
     | 
| 
      
 2287 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2288 
     | 
    
         
            +
                 * The path to a directory containing CA certificates in PEM format.
         
     | 
| 
      
 2289 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2290 
     | 
    
         
            +
                 * Files are looked up by subject's X509 name's hash value.
         
     | 
| 
      
 2291 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2292 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("ca_path"), 1, 1, Qfalse);
         
     | 
| 
      
 2293 
     | 
    
         
            +
             
     | 
| 
      
 2294 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2295 
     | 
    
         
            +
                 * Maximum session lifetime in seconds.
         
     | 
| 
      
 2296 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2297 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("timeout"), 1, 1, Qfalse);
         
     | 
| 
      
 2298 
     | 
    
         
            +
             
     | 
| 
      
 2299 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2300 
     | 
    
         
            +
                 * Session verification mode.
         
     | 
| 
      
 2301 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2302 
     | 
    
         
            +
                 * Valid modes are VERIFY_NONE, VERIFY_PEER, VERIFY_CLIENT_ONCE,
         
     | 
| 
      
 2303 
     | 
    
         
            +
                 * VERIFY_FAIL_IF_NO_PEER_CERT and defined on OpenSSL::SSL
         
     | 
| 
      
 2304 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2305 
     | 
    
         
            +
                 * The default mode is VERIFY_NONE, which does not perform any verification
         
     | 
| 
      
 2306 
     | 
    
         
            +
                 * at all.
         
     | 
| 
      
 2307 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2308 
     | 
    
         
            +
                 * See SSL_CTX_set_verify(3) for details.
         
     | 
| 
      
 2309 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2310 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("verify_mode"), 1, 1, Qfalse);
         
     | 
| 
      
 2311 
     | 
    
         
            +
             
     | 
| 
      
 2312 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2313 
     | 
    
         
            +
                 * Number of CA certificates to walk when verifying a certificate chain.
         
     | 
| 
      
 2314 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2315 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("verify_depth"), 1, 1, Qfalse);
         
     | 
| 
      
 2316 
     | 
    
         
            +
             
     | 
| 
      
 2317 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2318 
     | 
    
         
            +
                 * A callback for additional certificate verification.  The callback is
         
     | 
| 
      
 2319 
     | 
    
         
            +
                 * invoked for each certificate in the chain.
         
     | 
| 
      
 2320 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2321 
     | 
    
         
            +
                 * The callback is invoked with two values.  +preverify_ok+ indicates
         
     | 
| 
      
 2322 
     | 
    
         
            +
                 * indicates if the verification was passed (true) or not (false).
         
     | 
| 
      
 2323 
     | 
    
         
            +
                 * +store_context+ is an OpenSSL::X509::StoreContext containing the
         
     | 
| 
      
 2324 
     | 
    
         
            +
                 * context used for certificate verification.
         
     | 
| 
      
 2325 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2326 
     | 
    
         
            +
                 * If the callback returns false, the chain verification is immediately
         
     | 
| 
      
 2327 
     | 
    
         
            +
                 * stopped and a bad_certificate alert is then sent.
         
     | 
| 
      
 2328 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2329 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("verify_callback"), 1, 1, Qfalse);
         
     | 
| 
      
 2330 
     | 
    
         
            +
             
     | 
| 
      
 2331 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2332 
     | 
    
         
            +
                 * Whether to check the server certificate is valid for the hostname.
         
     | 
| 
      
 2333 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2334 
     | 
    
         
            +
                 * In order to make this work, verify_mode must be set to VERIFY_PEER and
         
     | 
| 
      
 2335 
     | 
    
         
            +
                 * the server hostname must be given by OpenSSL::SSL::SSLSocket#hostname=.
         
     | 
| 
      
 2336 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2337 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("verify_hostname"), 1, 1, Qfalse);
         
     | 
| 
      
 2338 
     | 
    
         
            +
             
     | 
| 
      
 2339 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2340 
     | 
    
         
            +
                 * An OpenSSL::X509::Store used for certificate verification.
         
     | 
| 
      
 2341 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2342 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("cert_store"), 1, 1, Qfalse);
         
     | 
| 
      
 2343 
     | 
    
         
            +
             
     | 
| 
      
 2344 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2345 
     | 
    
         
            +
                 * An Array of extra X509 certificates to be added to the certificate
         
     | 
| 
      
 2346 
     | 
    
         
            +
                 * chain.
         
     | 
| 
      
 2347 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2348 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("extra_chain_cert"), 1, 1, Qfalse);
         
     | 
| 
      
 2349 
     | 
    
         
            +
             
     | 
| 
      
 2350 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2351 
     | 
    
         
            +
                 * A callback invoked when a client certificate is requested by a server
         
     | 
| 
      
 2352 
     | 
    
         
            +
                 * and no certificate has been set.
         
     | 
| 
      
 2353 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2354 
     | 
    
         
            +
                 * The callback is invoked with a Session and must return an Array
         
     | 
| 
      
 2355 
     | 
    
         
            +
                 * containing an OpenSSL::X509::Certificate and an OpenSSL::PKey.  If any
         
     | 
| 
      
 2356 
     | 
    
         
            +
                 * other value is returned the handshake is suspended.
         
     | 
| 
      
 2357 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2358 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("client_cert_cb"), 1, 1, Qfalse);
         
     | 
| 
      
 2359 
     | 
    
         
            +
             
     | 
| 
      
 2360 
     | 
    
         
            +
            #if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
         
     | 
| 
      
 2361 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2362 
     | 
    
         
            +
                 * A callback invoked when ECDH parameters are required.
         
     | 
| 
      
 2363 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2364 
     | 
    
         
            +
                 * The callback is invoked with the Session for the key exchange, an
         
     | 
| 
      
 2365 
     | 
    
         
            +
                 * flag indicating the use of an export cipher and the keylength
         
     | 
| 
      
 2366 
     | 
    
         
            +
                 * required.
         
     | 
| 
      
 2367 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2368 
     | 
    
         
            +
                 * The callback is deprecated. This does not work with recent versions of
         
     | 
| 
      
 2369 
     | 
    
         
            +
                 * OpenSSL. Use OpenSSL::SSL::SSLContext#ecdh_curves= instead.
         
     | 
| 
      
 2370 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2371 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("tmp_ecdh_callback"), 1, 1, Qfalse);
         
     | 
| 
      
 2372 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 2373 
     | 
    
         
            +
             
     | 
| 
      
 2374 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2375 
     | 
    
         
            +
                 * Sets the context in which a session can be reused.  This allows
         
     | 
| 
      
 2376 
     | 
    
         
            +
                 * sessions for multiple applications to be distinguished, for example, by
         
     | 
| 
      
 2377 
     | 
    
         
            +
                 * name.
         
     | 
| 
      
 2378 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2379 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("session_id_context"), 1, 1, Qfalse);
         
     | 
| 
      
 2380 
     | 
    
         
            +
             
     | 
| 
      
 2381 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2382 
     | 
    
         
            +
                 * A callback invoked on a server when a session is proposed by the client
         
     | 
| 
      
 2383 
     | 
    
         
            +
                 * but the session could not be found in the server's internal cache.
         
     | 
| 
      
 2384 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2385 
     | 
    
         
            +
                 * The callback is invoked with the SSLSocket and session id.  The
         
     | 
| 
      
 2386 
     | 
    
         
            +
                 * callback may return a Session from an external cache.
         
     | 
| 
      
 2387 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2388 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("session_get_cb"), 1, 1, Qfalse);
         
     | 
| 
      
 2389 
     | 
    
         
            +
             
     | 
| 
      
 2390 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2391 
     | 
    
         
            +
                 * A callback invoked when a new session was negotiated.
         
     | 
| 
      
 2392 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2393 
     | 
    
         
            +
                 * The callback is invoked with an SSLSocket.  If false is returned the
         
     | 
| 
      
 2394 
     | 
    
         
            +
                 * session will be removed from the internal cache.
         
     | 
| 
      
 2395 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2396 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("session_new_cb"), 1, 1, Qfalse);
         
     | 
| 
      
 2397 
     | 
    
         
            +
             
     | 
| 
      
 2398 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2399 
     | 
    
         
            +
                 * A callback invoked when a session is removed from the internal cache.
         
     | 
| 
      
 2400 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2401 
     | 
    
         
            +
                 * The callback is invoked with an SSLContext and a Session.
         
     | 
| 
      
 2402 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2403 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("session_remove_cb"), 1, 1, Qfalse);
         
     | 
| 
      
 2404 
     | 
    
         
            +
             
     | 
| 
      
 2405 
     | 
    
         
            +
            #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
         
     | 
| 
      
 2406 
     | 
    
         
            +
                rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qtrue);
         
     | 
| 
      
 2407 
     | 
    
         
            +
            #else
         
     | 
| 
      
 2408 
     | 
    
         
            +
                rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qfalse);
         
     | 
| 
      
 2409 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 2410 
     | 
    
         
            +
             
     | 
| 
      
 2411 
     | 
    
         
            +
            #ifdef TLS_DH_anon_WITH_AES_256_GCM_SHA384
         
     | 
| 
      
 2412 
     | 
    
         
            +
                rb_define_const(mSSLExtConfig, "TLS_DH_anon_WITH_AES_256_GCM_SHA384", Qtrue);
         
     | 
| 
      
 2413 
     | 
    
         
            +
            #else
         
     | 
| 
      
 2414 
     | 
    
         
            +
                rb_define_const(mSSLExtConfig, "TLS_DH_anon_WITH_AES_256_GCM_SHA384", Qfalse);
         
     | 
| 
      
 2415 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 2416 
     | 
    
         
            +
             
     | 
| 
      
 2417 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2418 
     | 
    
         
            +
                 * A callback invoked whenever a new handshake is initiated. May be used
         
     | 
| 
      
 2419 
     | 
    
         
            +
                 * to disable renegotiation entirely.
         
     | 
| 
      
 2420 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2421 
     | 
    
         
            +
                 * The callback is invoked with the active SSLSocket. The callback's
         
     | 
| 
      
 2422 
     | 
    
         
            +
                 * return value is irrelevant, normal return indicates "approval" of the
         
     | 
| 
      
 2423 
     | 
    
         
            +
                 * renegotiation and will continue the process. To forbid renegotiation
         
     | 
| 
      
 2424 
     | 
    
         
            +
                 * and to cancel the process, an Error may be raised within the callback.
         
     | 
| 
      
 2425 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2426 
     | 
    
         
            +
                 * === Disable client renegotiation
         
     | 
| 
      
 2427 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2428 
     | 
    
         
            +
                 * When running a server, it is often desirable to disable client
         
     | 
| 
      
 2429 
     | 
    
         
            +
                 * renegotiation entirely. You may use a callback as follows to implement
         
     | 
| 
      
 2430 
     | 
    
         
            +
                 * this feature:
         
     | 
| 
      
 2431 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2432 
     | 
    
         
            +
                 *   num_handshakes = 0
         
     | 
| 
      
 2433 
     | 
    
         
            +
                 *   ctx.renegotiation_cb = lambda do |ssl|
         
     | 
| 
      
 2434 
     | 
    
         
            +
                 *     num_handshakes += 1
         
     | 
| 
      
 2435 
     | 
    
         
            +
                 *     raise RuntimeError.new("Client renegotiation disabled") if num_handshakes > 1
         
     | 
| 
      
 2436 
     | 
    
         
            +
                 *   end
         
     | 
| 
      
 2437 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2438 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("renegotiation_cb"), 1, 1, Qfalse);
         
     | 
| 
      
 2439 
     | 
    
         
            +
            #ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
         
     | 
| 
      
 2440 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2441 
     | 
    
         
            +
                 * An Enumerable of Strings. Each String represents a protocol to be
         
     | 
| 
      
 2442 
     | 
    
         
            +
                 * advertised as the list of supported protocols for Next Protocol
         
     | 
| 
      
 2443 
     | 
    
         
            +
                 * Negotiation. Supported in OpenSSL 1.0.1 and higher. Has no effect
         
     | 
| 
      
 2444 
     | 
    
         
            +
                 * on the client side. If not set explicitly, the NPN extension will
         
     | 
| 
      
 2445 
     | 
    
         
            +
                 * not be sent by the server in the handshake.
         
     | 
| 
      
 2446 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2447 
     | 
    
         
            +
                 * === Example
         
     | 
| 
      
 2448 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2449 
     | 
    
         
            +
                 *   ctx.npn_protocols = ["http/1.1", "spdy/2"]
         
     | 
| 
      
 2450 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2451 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("npn_protocols"), 1, 1, Qfalse);
         
     | 
| 
      
 2452 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2453 
     | 
    
         
            +
                 * A callback invoked on the client side when the client needs to select
         
     | 
| 
      
 2454 
     | 
    
         
            +
                 * a protocol from the list sent by the server. Supported in OpenSSL 1.0.1
         
     | 
| 
      
 2455 
     | 
    
         
            +
                 * and higher. The client MUST select a protocol of those advertised by
         
     | 
| 
      
 2456 
     | 
    
         
            +
                 * the server. If none is acceptable, raising an error in the callback
         
     | 
| 
      
 2457 
     | 
    
         
            +
                 * will cause the handshake to fail. Not setting this callback explicitly
         
     | 
| 
      
 2458 
     | 
    
         
            +
                 * means not supporting the NPN extension on the client - any protocols
         
     | 
| 
      
 2459 
     | 
    
         
            +
                 * advertised by the server will be ignored.
         
     | 
| 
      
 2460 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2461 
     | 
    
         
            +
                 * === Example
         
     | 
| 
      
 2462 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2463 
     | 
    
         
            +
                 *   ctx.npn_select_cb = lambda do |protocols|
         
     | 
| 
      
 2464 
     | 
    
         
            +
                 *     # inspect the protocols and select one
         
     | 
| 
      
 2465 
     | 
    
         
            +
                 *     protocols.first
         
     | 
| 
      
 2466 
     | 
    
         
            +
                 *   end
         
     | 
| 
      
 2467 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2468 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("npn_select_cb"), 1, 1, Qfalse);
         
     | 
| 
      
 2469 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 2470 
     | 
    
         
            +
             
     | 
| 
      
 2471 
     | 
    
         
            +
            #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
         
     | 
| 
      
 2472 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2473 
     | 
    
         
            +
                 * An Enumerable of Strings. Each String represents a protocol to be
         
     | 
| 
      
 2474 
     | 
    
         
            +
                 * advertised as the list of supported protocols for Application-Layer
         
     | 
| 
      
 2475 
     | 
    
         
            +
                 * Protocol Negotiation. Supported in OpenSSL 1.0.2 and higher. Has no
         
     | 
| 
      
 2476 
     | 
    
         
            +
                 * effect on the server side. If not set explicitly, the ALPN extension will
         
     | 
| 
      
 2477 
     | 
    
         
            +
                 * not be included in the handshake.
         
     | 
| 
      
 2478 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2479 
     | 
    
         
            +
                 * === Example
         
     | 
| 
      
 2480 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2481 
     | 
    
         
            +
                 *   ctx.alpn_protocols = ["http/1.1", "spdy/2", "h2"]
         
     | 
| 
      
 2482 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2483 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("alpn_protocols"), 1, 1, Qfalse);
         
     | 
| 
      
 2484 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2485 
     | 
    
         
            +
                 * A callback invoked on the server side when the server needs to select
         
     | 
| 
      
 2486 
     | 
    
         
            +
                 * a protocol from the list sent by the client. Supported in OpenSSL 1.0.2
         
     | 
| 
      
 2487 
     | 
    
         
            +
                 * and higher. The callback must return a protocol of those advertised by
         
     | 
| 
      
 2488 
     | 
    
         
            +
                 * the client. If none is acceptable, raising an error in the callback
         
     | 
| 
      
 2489 
     | 
    
         
            +
                 * will cause the handshake to fail. Not setting this callback explicitly
         
     | 
| 
      
 2490 
     | 
    
         
            +
                 * means not supporting the ALPN extension on the server - any protocols
         
     | 
| 
      
 2491 
     | 
    
         
            +
                 * advertised by the client will be ignored.
         
     | 
| 
      
 2492 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2493 
     | 
    
         
            +
                 * === Example
         
     | 
| 
      
 2494 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2495 
     | 
    
         
            +
                 *   ctx.alpn_select_cb = lambda do |protocols|
         
     | 
| 
      
 2496 
     | 
    
         
            +
                 *     # inspect the protocols and select one
         
     | 
| 
      
 2497 
     | 
    
         
            +
                 *     protocols.first
         
     | 
| 
      
 2498 
     | 
    
         
            +
                 *   end
         
     | 
| 
      
 2499 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2500 
     | 
    
         
            +
                rb_attr(cSSLContext, rb_intern("alpn_select_cb"), 1, 1, Qfalse);
         
     | 
| 
      
 2501 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 2502 
     | 
    
         
            +
             
     | 
| 
      
 2503 
     | 
    
         
            +
                rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
         
     | 
| 
      
 2504 
     | 
    
         
            +
                rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
         
     | 
| 
      
 2505 
     | 
    
         
            +
                rb_define_method(cSSLContext, "ssl_version=", ossl_sslctx_set_ssl_version, 1);
         
     | 
| 
      
 2506 
     | 
    
         
            +
                rb_define_method(cSSLContext, "ciphers",     ossl_sslctx_get_ciphers, 0);
         
     | 
| 
      
 2507 
     | 
    
         
            +
                rb_define_method(cSSLContext, "ciphers=",    ossl_sslctx_set_ciphers, 1);
         
     | 
| 
      
 2508 
     | 
    
         
            +
                rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1);
         
     | 
| 
      
 2509 
     | 
    
         
            +
                rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0);
         
     | 
| 
      
 2510 
     | 
    
         
            +
                rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1);
         
     | 
| 
      
 2511 
     | 
    
         
            +
             
     | 
| 
      
 2512 
     | 
    
         
            +
                rb_define_method(cSSLContext, "setup", ossl_sslctx_setup, 0);
         
     | 
| 
      
 2513 
     | 
    
         
            +
             
     | 
| 
      
 2514 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2515 
     | 
    
         
            +
                 * No session caching for client or server
         
     | 
| 
      
 2516 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2517 
     | 
    
         
            +
                rb_define_const(cSSLContext, "SESSION_CACHE_OFF", LONG2NUM(SSL_SESS_CACHE_OFF));
         
     | 
| 
      
 2518 
     | 
    
         
            +
             
     | 
| 
      
 2519 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2520 
     | 
    
         
            +
                 * Client sessions are added to the session cache
         
     | 
| 
      
 2521 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2522 
     | 
    
         
            +
                rb_define_const(cSSLContext, "SESSION_CACHE_CLIENT", LONG2NUM(SSL_SESS_CACHE_CLIENT)); /* doesn't actually do anything in 0.9.8e */
         
     | 
| 
      
 2523 
     | 
    
         
            +
             
     | 
| 
      
 2524 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2525 
     | 
    
         
            +
                 * Server sessions are added to the session cache
         
     | 
| 
      
 2526 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2527 
     | 
    
         
            +
                rb_define_const(cSSLContext, "SESSION_CACHE_SERVER", LONG2NUM(SSL_SESS_CACHE_SERVER));
         
     | 
| 
      
 2528 
     | 
    
         
            +
             
     | 
| 
      
 2529 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2530 
     | 
    
         
            +
                 * Both client and server sessions are added to the session cache
         
     | 
| 
      
 2531 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2532 
     | 
    
         
            +
                rb_define_const(cSSLContext, "SESSION_CACHE_BOTH", LONG2NUM(SSL_SESS_CACHE_BOTH)); /* no different than CACHE_SERVER in 0.9.8e */
         
     | 
| 
      
 2533 
     | 
    
         
            +
             
     | 
| 
      
 2534 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2535 
     | 
    
         
            +
                 * Normally the session cache is checked for expired sessions every 255
         
     | 
| 
      
 2536 
     | 
    
         
            +
                 * connections.  Since this may lead to a delay that cannot be controlled,
         
     | 
| 
      
 2537 
     | 
    
         
            +
                 * the automatic flushing may be disabled and #flush_sessions can be
         
     | 
| 
      
 2538 
     | 
    
         
            +
                 * called explicitly.
         
     | 
| 
      
 2539 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2540 
     | 
    
         
            +
                rb_define_const(cSSLContext, "SESSION_CACHE_NO_AUTO_CLEAR", LONG2NUM(SSL_SESS_CACHE_NO_AUTO_CLEAR));
         
     | 
| 
      
 2541 
     | 
    
         
            +
             
     | 
| 
      
 2542 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2543 
     | 
    
         
            +
                 * Always perform external lookups of sessions even if they are in the
         
     | 
| 
      
 2544 
     | 
    
         
            +
                 * internal cache.
         
     | 
| 
      
 2545 
     | 
    
         
            +
                 *
         
     | 
| 
      
 2546 
     | 
    
         
            +
                 * This flag has no effect on clients
         
     | 
| 
      
 2547 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2548 
     | 
    
         
            +
                rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_LOOKUP", LONG2NUM(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP));
         
     | 
| 
      
 2549 
     | 
    
         
            +
             
     | 
| 
      
 2550 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2551 
     | 
    
         
            +
                 * Never automatically store sessions in the internal store.
         
     | 
| 
      
 2552 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2553 
     | 
    
         
            +
                rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_STORE", LONG2NUM(SSL_SESS_CACHE_NO_INTERNAL_STORE));
         
     | 
| 
      
 2554 
     | 
    
         
            +
             
     | 
| 
      
 2555 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2556 
     | 
    
         
            +
                 * Enables both SESSION_CACHE_NO_INTERNAL_LOOKUP and
         
     | 
| 
      
 2557 
     | 
    
         
            +
                 * SESSION_CACHE_NO_INTERNAL_STORE.
         
     | 
| 
      
 2558 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2559 
     | 
    
         
            +
                rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL", LONG2NUM(SSL_SESS_CACHE_NO_INTERNAL));
         
     | 
| 
      
 2560 
     | 
    
         
            +
             
     | 
| 
      
 2561 
     | 
    
         
            +
                rb_define_method(cSSLContext, "session_add",     ossl_sslctx_session_add, 1);
         
     | 
| 
      
 2562 
     | 
    
         
            +
                rb_define_method(cSSLContext, "session_remove",     ossl_sslctx_session_remove, 1);
         
     | 
| 
      
 2563 
     | 
    
         
            +
                rb_define_method(cSSLContext, "session_cache_mode",     ossl_sslctx_get_session_cache_mode, 0);
         
     | 
| 
      
 2564 
     | 
    
         
            +
                rb_define_method(cSSLContext, "session_cache_mode=",     ossl_sslctx_set_session_cache_mode, 1);
         
     | 
| 
      
 2565 
     | 
    
         
            +
                rb_define_method(cSSLContext, "session_cache_size",     ossl_sslctx_get_session_cache_size, 0);
         
     | 
| 
      
 2566 
     | 
    
         
            +
                rb_define_method(cSSLContext, "session_cache_size=",     ossl_sslctx_set_session_cache_size, 1);
         
     | 
| 
      
 2567 
     | 
    
         
            +
                rb_define_method(cSSLContext, "session_cache_stats",     ossl_sslctx_get_session_cache_stats, 0);
         
     | 
| 
      
 2568 
     | 
    
         
            +
                rb_define_method(cSSLContext, "flush_sessions",     ossl_sslctx_flush_sessions, -1);
         
     | 
| 
      
 2569 
     | 
    
         
            +
                rb_define_method(cSSLContext, "options",     ossl_sslctx_get_options, 0);
         
     | 
| 
      
 2570 
     | 
    
         
            +
                rb_define_method(cSSLContext, "options=",     ossl_sslctx_set_options, 1);
         
     | 
| 
      
 2571 
     | 
    
         
            +
             
     | 
| 
      
 2572 
     | 
    
         
            +
                ary = rb_ary_new2(numberof(ossl_ssl_method_tab));
         
     | 
| 
      
 2573 
     | 
    
         
            +
                for (i = 0; i < numberof(ossl_ssl_method_tab); i++) {
         
     | 
| 
      
 2574 
     | 
    
         
            +
                    rb_ary_push(ary, ID2SYM(rb_intern(ossl_ssl_method_tab[i].name)));
         
     | 
| 
      
 2575 
     | 
    
         
            +
                }
         
     | 
| 
      
 2576 
     | 
    
         
            +
                rb_obj_freeze(ary);
         
     | 
| 
      
 2577 
     | 
    
         
            +
                /* The list of available SSL/TLS methods */
         
     | 
| 
      
 2578 
     | 
    
         
            +
                rb_define_const(cSSLContext, "METHODS", ary);
         
     | 
| 
      
 2579 
     | 
    
         
            +
             
     | 
| 
      
 2580 
     | 
    
         
            +
                /*
         
     | 
| 
      
 2581 
     | 
    
         
            +
                 * Document-class: OpenSSL::SSL::SSLSocket
         
     | 
| 
      
 2582 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2583 
     | 
    
         
            +
                cSSLSocket = rb_define_class_under(mSSL, "SSLSocket", rb_cObject);
         
     | 
| 
      
 2584 
     | 
    
         
            +
            #ifdef OPENSSL_NO_SOCK
         
     | 
| 
      
 2585 
     | 
    
         
            +
                rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qtrue);
         
     | 
| 
      
 2586 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "initialize", rb_f_notimplement, -1);
         
     | 
| 
      
 2587 
     | 
    
         
            +
            #else
         
     | 
| 
      
 2588 
     | 
    
         
            +
                rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qfalse);
         
     | 
| 
      
 2589 
     | 
    
         
            +
                rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc);
         
     | 
| 
      
 2590 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1);
         
     | 
| 
      
 2591 
     | 
    
         
            +
                rb_undef_method(cSSLSocket, "initialize_copy");
         
     | 
| 
      
 2592 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "connect",    ossl_ssl_connect, 0);
         
     | 
| 
      
 2593 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "connect_nonblock",    ossl_ssl_connect_nonblock, -1);
         
     | 
| 
      
 2594 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "accept",     ossl_ssl_accept, 0);
         
     | 
| 
      
 2595 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "accept_nonblock", ossl_ssl_accept_nonblock, -1);
         
     | 
| 
      
 2596 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "sysread",    ossl_ssl_read, -1);
         
     | 
| 
      
 2597 
     | 
    
         
            +
                rb_define_private_method(cSSLSocket, "sysread_nonblock",    ossl_ssl_read_nonblock, -1);
         
     | 
| 
      
 2598 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "syswrite",   ossl_ssl_write, 1);
         
     | 
| 
      
 2599 
     | 
    
         
            +
                rb_define_private_method(cSSLSocket, "syswrite_nonblock",    ossl_ssl_write_nonblock, -1);
         
     | 
| 
      
 2600 
     | 
    
         
            +
                rb_define_private_method(cSSLSocket, "stop",   ossl_ssl_stop, 0);
         
     | 
| 
      
 2601 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "cert",       ossl_ssl_get_cert, 0);
         
     | 
| 
      
 2602 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "peer_cert",  ossl_ssl_get_peer_cert, 0);
         
     | 
| 
      
 2603 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "peer_cert_chain", ossl_ssl_get_peer_cert_chain, 0);
         
     | 
| 
      
 2604 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "ssl_version",    ossl_ssl_get_version, 0);
         
     | 
| 
      
 2605 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "cipher",     ossl_ssl_get_cipher, 0);
         
     | 
| 
      
 2606 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "state",      ossl_ssl_get_state, 0);
         
     | 
| 
      
 2607 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "pending",    ossl_ssl_pending, 0);
         
     | 
| 
      
 2608 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "session_reused?",    ossl_ssl_session_reused, 0);
         
     | 
| 
      
 2609 
     | 
    
         
            +
                /* implementation of OpenSSL::SSL::SSLSocket#session is in lib/openssl/ssl.rb */
         
     | 
| 
      
 2610 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "session=",    ossl_ssl_set_session, 1);
         
     | 
| 
      
 2611 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "verify_result", ossl_ssl_get_verify_result, 0);
         
     | 
| 
      
 2612 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0);
         
     | 
| 
      
 2613 
     | 
    
         
            +
            #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
         
     | 
| 
      
 2614 
     | 
    
         
            +
                /* #hostname is defined in lib/openssl/ssl.rb */
         
     | 
| 
      
 2615 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "hostname=", ossl_ssl_set_hostname, 1);
         
     | 
| 
      
 2616 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 2617 
     | 
    
         
            +
            # ifdef HAVE_SSL_GET_SERVER_TMP_KEY
         
     | 
| 
      
 2618 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0);
         
     | 
| 
      
 2619 
     | 
    
         
            +
            # endif
         
     | 
| 
      
 2620 
     | 
    
         
            +
            # ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
         
     | 
| 
      
 2621 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
         
     | 
| 
      
 2622 
     | 
    
         
            +
            # endif
         
     | 
| 
      
 2623 
     | 
    
         
            +
            # ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
         
     | 
| 
      
 2624 
     | 
    
         
            +
                rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
         
     | 
| 
      
 2625 
     | 
    
         
            +
            # endif
         
     | 
| 
      
 2626 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 2627 
     | 
    
         
            +
             
     | 
| 
      
 2628 
     | 
    
         
            +
            #define ossl_ssl_def_const(x) rb_define_const(mSSL, #x, LONG2NUM(SSL_##x))
         
     | 
| 
      
 2629 
     | 
    
         
            +
             
     | 
| 
      
 2630 
     | 
    
         
            +
                ossl_ssl_def_const(VERIFY_NONE);
         
     | 
| 
      
 2631 
     | 
    
         
            +
                ossl_ssl_def_const(VERIFY_PEER);
         
     | 
| 
      
 2632 
     | 
    
         
            +
                ossl_ssl_def_const(VERIFY_FAIL_IF_NO_PEER_CERT);
         
     | 
| 
      
 2633 
     | 
    
         
            +
                ossl_ssl_def_const(VERIFY_CLIENT_ONCE);
         
     | 
| 
      
 2634 
     | 
    
         
            +
                /* Introduce constants included in OP_ALL.  These constants are mostly for
         
     | 
| 
      
 2635 
     | 
    
         
            +
                 * unset some bits in OP_ALL such as;
         
     | 
| 
      
 2636 
     | 
    
         
            +
                 *   ctx.options = OP_ALL & ~OP_DONT_INSERT_EMPTY_FRAGMENTS
         
     | 
| 
      
 2637 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2638 
     | 
    
         
            +
                ossl_ssl_def_const(OP_MICROSOFT_SESS_ID_BUG);
         
     | 
| 
      
 2639 
     | 
    
         
            +
                ossl_ssl_def_const(OP_NETSCAPE_CHALLENGE_BUG);
         
     | 
| 
      
 2640 
     | 
    
         
            +
                ossl_ssl_def_const(OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG);
         
     | 
| 
      
 2641 
     | 
    
         
            +
                ossl_ssl_def_const(OP_SSLREF2_REUSE_CERT_TYPE_BUG);
         
     | 
| 
      
 2642 
     | 
    
         
            +
                ossl_ssl_def_const(OP_MICROSOFT_BIG_SSLV3_BUFFER);
         
     | 
| 
      
 2643 
     | 
    
         
            +
                ossl_ssl_def_const(OP_MSIE_SSLV2_RSA_PADDING);
         
     | 
| 
      
 2644 
     | 
    
         
            +
                ossl_ssl_def_const(OP_SSLEAY_080_CLIENT_DH_BUG);
         
     | 
| 
      
 2645 
     | 
    
         
            +
                ossl_ssl_def_const(OP_TLS_D5_BUG);
         
     | 
| 
      
 2646 
     | 
    
         
            +
                ossl_ssl_def_const(OP_TLS_BLOCK_PADDING_BUG);
         
     | 
| 
      
 2647 
     | 
    
         
            +
                ossl_ssl_def_const(OP_DONT_INSERT_EMPTY_FRAGMENTS);
         
     | 
| 
      
 2648 
     | 
    
         
            +
                ossl_ssl_def_const(OP_ALL);
         
     | 
| 
      
 2649 
     | 
    
         
            +
                ossl_ssl_def_const(OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
         
     | 
| 
      
 2650 
     | 
    
         
            +
                ossl_ssl_def_const(OP_SINGLE_ECDH_USE);
         
     | 
| 
      
 2651 
     | 
    
         
            +
                ossl_ssl_def_const(OP_SINGLE_DH_USE);
         
     | 
| 
      
 2652 
     | 
    
         
            +
                ossl_ssl_def_const(OP_EPHEMERAL_RSA);
         
     | 
| 
      
 2653 
     | 
    
         
            +
                ossl_ssl_def_const(OP_CIPHER_SERVER_PREFERENCE);
         
     | 
| 
      
 2654 
     | 
    
         
            +
                ossl_ssl_def_const(OP_TLS_ROLLBACK_BUG);
         
     | 
| 
      
 2655 
     | 
    
         
            +
                ossl_ssl_def_const(OP_NO_SSLv2);
         
     | 
| 
      
 2656 
     | 
    
         
            +
                ossl_ssl_def_const(OP_NO_SSLv3);
         
     | 
| 
      
 2657 
     | 
    
         
            +
                ossl_ssl_def_const(OP_NO_TLSv1);
         
     | 
| 
      
 2658 
     | 
    
         
            +
            #if defined(SSL_OP_NO_TLSv1_1)
         
     | 
| 
      
 2659 
     | 
    
         
            +
                ossl_ssl_def_const(OP_NO_TLSv1_1);
         
     | 
| 
      
 2660 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 2661 
     | 
    
         
            +
            #if defined(SSL_OP_NO_TLSv1_2)
         
     | 
| 
      
 2662 
     | 
    
         
            +
                ossl_ssl_def_const(OP_NO_TLSv1_2);
         
     | 
| 
      
 2663 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 2664 
     | 
    
         
            +
            #if defined(SSL_OP_NO_TICKET)
         
     | 
| 
      
 2665 
     | 
    
         
            +
                ossl_ssl_def_const(OP_NO_TICKET);
         
     | 
| 
      
 2666 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 2667 
     | 
    
         
            +
            #if defined(SSL_OP_NO_COMPRESSION)
         
     | 
| 
      
 2668 
     | 
    
         
            +
                ossl_ssl_def_const(OP_NO_COMPRESSION);
         
     | 
| 
      
 2669 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 2670 
     | 
    
         
            +
                ossl_ssl_def_const(OP_PKCS1_CHECK_1);
         
     | 
| 
      
 2671 
     | 
    
         
            +
                ossl_ssl_def_const(OP_PKCS1_CHECK_2);
         
     | 
| 
      
 2672 
     | 
    
         
            +
                ossl_ssl_def_const(OP_NETSCAPE_CA_DN_BUG);
         
     | 
| 
      
 2673 
     | 
    
         
            +
                ossl_ssl_def_const(OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
         
     | 
| 
      
 2674 
     | 
    
         
            +
             
     | 
| 
      
 2675 
     | 
    
         
            +
            #undef rb_intern
         
     | 
| 
      
 2676 
     | 
    
         
            +
                sym_exception = ID2SYM(rb_intern("exception"));
         
     | 
| 
      
 2677 
     | 
    
         
            +
                sym_wait_readable = ID2SYM(rb_intern("wait_readable"));
         
     | 
| 
      
 2678 
     | 
    
         
            +
                sym_wait_writable = ID2SYM(rb_intern("wait_writable"));
         
     | 
| 
      
 2679 
     | 
    
         
            +
            }
         
     |