From 0b309103a86d6bdfec3fecdd7e59cdedf9d140a7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marcus=20R=C3=BCckert?= <mrueckert@suse.de>
Date: Tue, 7 Mar 2017 13:10:30 +0100
Subject: [PATCH 08/24] ruby 1.8.x openssl branch update

---
 ext/openssl/extconf.rb         |   3 +
 ext/openssl/lib/net/telnets.rb |   8 +--
 ext/openssl/openssl_missing.h  |  12 ++--
 ext/openssl/ossl.c             |   6 +-
 ext/openssl/ossl.h             |   2 +-
 ext/openssl/ossl_asn1.c        |  39 +++++++------
 ext/openssl/ossl_bn.c          |   8 +--
 ext/openssl/ossl_cipher.c      |  43 ++++----------
 ext/openssl/ossl_digest.c      |   6 +-
 ext/openssl/ossl_engine.c      |   2 +-
 ext/openssl/ossl_hmac.c        |  30 +++++-----
 ext/openssl/ossl_ns_spki.c     |   8 +--
 ext/openssl/ossl_ocsp.c        |  26 +++++----
 ext/openssl/ossl_pkcs12.c      |   8 ++-
 ext/openssl/ossl_pkcs5.c       |   4 +-
 ext/openssl/ossl_pkcs7.c       |  12 ++--
 ext/openssl/ossl_pkey.c        |   6 +-
 ext/openssl/ossl_pkey_dh.c     |   6 +-
 ext/openssl/ossl_pkey_dsa.c    |  19 +++---
 ext/openssl/ossl_pkey_ec.c     |  16 ++---
 ext/openssl/ossl_pkey_rsa.c    |  28 ++++-----
 ext/openssl/ossl_rand.c        |   4 +-
 ext/openssl/ossl_ssl.c         | 129 +++++++++++++++++++++++++++++++++++------
 ext/openssl/ossl_ssl_session.c |   4 +-
 ext/openssl/ossl_x509attr.c    |  17 +++---
 ext/openssl/ossl_x509cert.c    |  14 +++--
 ext/openssl/ossl_x509crl.c     |  10 ++--
 ext/openssl/ossl_x509ext.c     |  13 +++--
 ext/openssl/ossl_x509name.c    |   8 +--
 ext/openssl/ossl_x509req.c     |  12 ++--
 ext/openssl/ossl_x509store.c   |   4 +-
 31 files changed, 301 insertions(+), 206 deletions(-)

diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
index 3f9ef511f3..51c25d467d 100644
--- a/ext/openssl/extconf.rb
+++ b/ext/openssl/extconf.rb
@@ -97,6 +97,9 @@ have_func("X509_STORE_set_ex_data")
 have_func("OBJ_NAME_do_all_sorted")
 have_func("SSL_SESSION_get_id")
 have_func("OPENSSL_cleanse")
+unless have_func("SSL_set_tlsext_host_name", ['openssl/ssl.h'])
+	have_macro("SSL_set_tlsext_host_name", ['openssl/ssl.h']) && $defs.push("-DHAVE_SSL_SET_TLSEXT_HOST_NAME")
+end
 if try_compile("#define FOO(...) foo(__VA_ARGS__)\n int x(){FOO(1);FOO(1,2);FOO(1,2,3);}\n")
   $defs.push("-DHAVE_VA_ARGS_MACRO")
 end
diff --git a/ext/openssl/lib/net/telnets.rb b/ext/openssl/lib/net/telnets.rb
index 2b69280432..bf36be0df1 100644
--- a/ext/openssl/lib/net/telnets.rb
+++ b/ext/openssl/lib/net/telnets.rb
@@ -145,7 +145,7 @@ module Net
         end
       end
     end # preprocess
-    
+
     alias waitfor_org waitfor
 
     def waitfor(options)
@@ -181,7 +181,7 @@ module Net
         begin
           c = @rest + @sock.sysread(1024 * 1024)
           @dumplog.log_dump('<', c) if @options.has_key?("Dump_log")
-          if @options["Telnetmode"]   
+          if @options["Telnetmode"]
             pos = 0
             catch(:next){
               while true
@@ -213,11 +213,11 @@ module Net
           end
           @log.print(buf) if @options.has_key?("Output_log")
           line.concat(buf)
-          yield buf if block_given?   
+          yield buf if block_given?
         rescue EOFError # End of file reached
           if line == ''
             line = nil
-            yield nil if block_given? 
+            yield nil if block_given?
           end
           break
         end
diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h
index db1630530e..619cf6fdb5 100644
--- a/ext/openssl/openssl_missing.h
+++ b/ext/openssl/openssl_missing.h
@@ -28,7 +28,7 @@ typedef int i2d_of_void();
 
 #if !defined(PEM_read_bio_DSAPublicKey)
 # define PEM_read_bio_DSAPublicKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \
-        (char *(*)())d2i_DSAPublicKey,PEM_STRING_DSA_PUBLIC,bp,(char **)x,cb,u)
+        (d2i_of_void *)d2i_DSAPublicKey,PEM_STRING_DSA_PUBLIC,bp,(void **)x,cb,u)
 #endif
 
 #if !defined(PEM_write_bio_DSAPublicKey)
@@ -40,27 +40,27 @@ typedef int i2d_of_void();
 
 #if !defined(DSAPrivateKey_dup)
 # define DSAPrivateKey_dup(dsa) (DSA *)ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey, \
-	(char *(*)())d2i_DSAPrivateKey,(char *)dsa)
+	(d2i_of_void *)d2i_DSAPrivateKey,(char *)dsa)
 #endif
 
 #if !defined(DSAPublicKey_dup)
 # define DSAPublicKey_dup(dsa) (DSA *)ASN1_dup((i2d_of_void *)i2d_DSAPublicKey, \
-	(char *(*)())d2i_DSAPublicKey,(char *)dsa)
+	(d2i_of_void *)d2i_DSAPublicKey,(char *)dsa)
 #endif
 
 #if !defined(X509_REVOKED_dup)
 # define X509_REVOKED_dup(rev) (X509_REVOKED *)ASN1_dup((i2d_of_void *)i2d_X509_REVOKED, \
-	(char *(*)())d2i_X509_REVOKED, (char *)rev)
+	(d2i_of_void *)d2i_X509_REVOKED, (char *)rev)
 #endif
 
 #if !defined(PKCS7_SIGNER_INFO_dup)
 #  define PKCS7_SIGNER_INFO_dup(si) (PKCS7_SIGNER_INFO *)ASN1_dup((i2d_of_void *)i2d_PKCS7_SIGNER_INFO, \
-	(char *(*)())d2i_PKCS7_SIGNER_INFO, (char *)si)
+	(d2i_of_void *)d2i_PKCS7_SIGNER_INFO, (char *)si)
 #endif
 
 #if !defined(PKCS7_RECIP_INFO_dup)
 #  define PKCS7_RECIP_INFO_dup(ri) (PKCS7_RECIP_INFO *)ASN1_dup((i2d_of_void *)i2d_PKCS7_RECIP_INFO, \
-	(char *(*)())d2i_PKCS7_RECIP_INFO, (char *)ri)
+	(d2i_of_void *)d2i_PKCS7_RECIP_INFO, (char *)ri)
 #endif
 
 #if !defined(HAVE_EVP_MD_CTX_INIT)
diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c
index 7aa2c0d449..85ba654061 100644
--- a/ext/openssl/ossl.c
+++ b/ext/openssl/ossl.c
@@ -15,7 +15,7 @@
  * String to HEXString conversion
  */
 int
-string2hex(char *buf, int buf_len, char **hexbuf, int *hexbuf_len)
+string2hex(const unsigned char *buf, int buf_len, char **hexbuf, int *hexbuf_len)
 {
     static const char hex[]="0123456789abcdef";
     int i, len = 2 * buf_len;
@@ -464,7 +464,7 @@ Init_openssl()
     /*
      * Verify callback Proc index for ext-data
      */
-    if ((ossl_verify_cb_idx = X509_STORE_CTX_get_ex_new_index(0, "ossl_verify_cb_idx", 0, 0, 0)) < 0)
+    if ((ossl_verify_cb_idx = X509_STORE_CTX_get_ex_new_index(0, (void *)"ossl_verify_cb_idx", 0, 0, 0)) < 0)
         ossl_raise(eOSSLError, "X509_STORE_CTX_get_ex_new_index");
 
     /*
@@ -506,7 +506,7 @@ Init_openssl()
  * Check if all symbols are OK with 'make LDSHARED=gcc all'
  */
 int
-main(int argc, char *argv[], char *env[])
+main(int argc, char *argv[])
 {
     return 0;
 }
diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h
index 9944a862e4..d0edb7d5de 100644
--- a/ext/openssl/ossl.h
+++ b/ext/openssl/ossl.h
@@ -117,7 +117,7 @@ extern VALUE eOSSLError;
 /*
  * String to HEXString conversion
  */
-int string2hex(char *, int, char **, int *);
+int string2hex(const unsigned char *, int, char **, int *);
 
 /*
  * Data Conversion
diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c
index 92f6bf77f5..e6169f96ae 100644
--- a/ext/openssl/ossl_asn1.c
+++ b/ext/openssl/ossl_asn1.c
@@ -33,7 +33,7 @@ asn1time_to_time(ASN1_TIME *time)
 	
     switch (time->type) {
     case V_ASN1_UTCTIME:
-	if (sscanf(time->data, "%2d%2d%2d%2d%2d%2dZ", &tm.tm_year, &tm.tm_mon,
+	if (sscanf((const char *)time->data, "%2d%2d%2d%2d%2d%2dZ", &tm.tm_year, &tm.tm_mon,
     		&tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
 	    ossl_raise(rb_eTypeError, "bad UTCTIME format");
 	} 
@@ -44,7 +44,7 @@ asn1time_to_time(ASN1_TIME *time)
 	}
 	break;
     case V_ASN1_GENERALIZEDTIME:
-	if (sscanf(time->data, "%4d%2d%2d%2d%2d%2dZ", &tm.tm_year, &tm.tm_mon,
+	if (sscanf((const char *)time->data, "%4d%2d%2d%2d%2d%2dZ", &tm.tm_year, &tm.tm_mon,
     		&tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
 	    ossl_raise(rb_eTypeError, "bad GENERALIZEDTIME format" );
 	} 
@@ -80,7 +80,7 @@ time_to_time_t(VALUE time)
 VALUE
 asn1str_to_str(ASN1_STRING *str)
 {
-    return rb_str_new(str->data, str->length);
+    return rb_str_new((const char *)str->data, str->length);
 }
 
 /*
@@ -218,7 +218,7 @@ obj_to_asn1bstr(VALUE obj, long unused_bits)
     StringValue(obj);
     if(!(bstr = ASN1_BIT_STRING_new()))
 	ossl_raise(eASN1Error, NULL);
-    ASN1_BIT_STRING_set(bstr, RSTRING_PTR(obj), RSTRING_LEN(obj));
+    ASN1_BIT_STRING_set(bstr, (unsigned char *)RSTRING_PTR(obj), RSTRING_LEN(obj));
     bstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
     bstr->flags |= ASN1_STRING_FLAG_BITS_LEFT|(unused_bits&0x07);
 
@@ -311,7 +311,7 @@ static VALUE
 decode_bool(unsigned char* der, int length)
 {
     int val;
-    unsigned char *p;
+    const unsigned char *p;
 
     p = der;
     if((val = d2i_ASN1_BOOLEAN(NULL, &p, length)) < 0)
@@ -324,7 +324,7 @@ static VALUE
 decode_int(unsigned char* der, int length)
 {
     ASN1_INTEGER *ai;
-    unsigned char *p;
+    const unsigned char *p;
     VALUE ret; 
     int status = 0;
 
@@ -364,7 +364,7 @@ static VALUE
 decode_enum(unsigned char* der, int length)
 {
     ASN1_ENUMERATED *ai;
-    unsigned char *p;
+    const unsigned char *p;
     VALUE ret; 
     int status = 0;
 
@@ -383,7 +383,7 @@ static VALUE
 decode_null(unsigned char* der, int length)
 {
     ASN1_NULL *null;
-    unsigned char *p;
+    const unsigned char *p;
 
     p = der;
     if(!(null = d2i_ASN1_NULL(NULL, &p, length)))
@@ -397,7 +397,7 @@ static VALUE
 decode_obj(unsigned char* der, int length)
 {
     ASN1_OBJECT *obj;
-    unsigned char *p;
+    const unsigned char *p;
     VALUE ret;
     int nid;
     BIO *bio;
@@ -426,7 +426,7 @@ static VALUE
 decode_time(unsigned char* der, int length)
 {
     ASN1_TIME *time;
-    unsigned char *p;
+    const unsigned char *p;
     VALUE ret;
     int status = 0;
 
@@ -701,7 +701,7 @@ ossl_asn1data_to_der(VALUE self)
     if((length = ASN1_object_size(1, RSTRING_LEN(value), tag)) <= 0)
 	ossl_raise(eASN1Error, NULL);
     der = rb_str_new(0, length);
-    p = RSTRING_PTR(der);
+    p = (unsigned char *)RSTRING_PTR(der);
     ASN1_put_object(&p, is_cons, RSTRING_LEN(value), tag, tag_class);
     memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value));
     p += RSTRING_LEN(value);
@@ -715,6 +715,7 @@ ossl_asn1_decode0(unsigned char **pp, long length, long *offset, long depth,
 		  int once, int yield)
 {
     unsigned char *start, *p;
+    const unsigned char *p0;
     long len, off = *offset;
     int hlen, tag, tc, j;
     VALUE ary, asn1data, value, tag_class;
@@ -723,7 +724,9 @@ ossl_asn1_decode0(unsigned char **pp, long length, long *offset, long depth,
     p = *pp;
     while(length > 0){
 	start = p;
-	j = ASN1_get_object(&p, &len, &tag, &tc, length);
+	p0 = p;
+	j = ASN1_get_object(&p0, &len, &tag, &tc, length);
+	p = (unsigned char *)p0;
 	if(j & 0x80) ossl_raise(eASN1Error, NULL);
 	hlen = p - start;
 	if(yield){
@@ -758,7 +761,7 @@ ossl_asn1_decode0(unsigned char **pp, long length, long *offset, long depth,
 	    else value = ossl_asn1_decode0(&p, len, &off, depth+1, 0, yield);
 	}
 	else{
-	    value = rb_str_new(p, len);
+	    value = rb_str_new((const char *)p, len);
 	    p += len;
 	    off += len;
 	}
@@ -823,7 +826,7 @@ ossl_asn1_traverse(VALUE self, VALUE obj)
 
     obj = ossl_to_der_if_possible(obj);
     tmp = rb_str_new4(StringValue(obj));
-    p = RSTRING_PTR(tmp);
+    p = (unsigned char *)RSTRING_PTR(tmp);
     ossl_asn1_decode0(&p, RSTRING_LEN(tmp), &offset, 0, 0, 1);
 
     return Qnil;
@@ -839,7 +842,7 @@ ossl_asn1_decode(VALUE self, VALUE obj)
 
     obj = ossl_to_der_if_possible(obj);
     tmp = rb_str_new4(StringValue(obj));
-    p = RSTRING_PTR(tmp);
+    p = (unsigned char *)RSTRING_PTR(tmp);
     ary = ossl_asn1_decode0(&p, RSTRING_LEN(tmp), &offset, 0, 1, 0);
     ret = rb_ary_entry(ary, 0);
 
@@ -856,7 +859,7 @@ ossl_asn1_decode_all(VALUE self, VALUE obj)
 
     obj = ossl_to_der_if_possible(obj);
     tmp = rb_str_new4(StringValue(obj));
-    p = RSTRING_PTR(tmp);
+    p = (unsigned char *)RSTRING_PTR(tmp);
     ret = ossl_asn1_decode0(&p, RSTRING_LEN(tmp), &offset, 0, 0, 0);
 
     return ret;
@@ -951,7 +954,7 @@ ossl_asn1prim_to_der(VALUE self)
     ossl_ASN1_TYPE_free(asn1);
     reallen = p - buf;
     assert(reallen <= len);
-    str = ossl_buf2str(buf, reallen); /* buf will be free in ossl_buf2str */
+    str = ossl_buf2str((char *)buf, reallen); /* buf will be free in ossl_buf2str */
 
     return str;
 }
@@ -973,7 +976,7 @@ ossl_asn1cons_to_der(VALUE self)
     seq_len = ASN1_object_size(1, RSTRING_LEN(value), tag);
     length = ASN1_object_size(1, seq_len, tn);
     str = rb_str_new(0, length);
-    p = RSTRING_PTR(str);
+    p = (unsigned char *)RSTRING_PTR(str);
     if(tc == V_ASN1_UNIVERSAL)
 	ASN1_put_object(&p, 1, RSTRING_LEN(value), tn, tc);
     else{
diff --git a/ext/openssl/ossl_bn.c b/ext/openssl/ossl_bn.c
index be43b0eacd..76f98d2cd1 100644
--- a/ext/openssl/ossl_bn.c
+++ b/ext/openssl/ossl_bn.c
@@ -131,12 +131,12 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
 
     switch (base) {
     case 0:
-	if (!BN_mpi2bn(RSTRING_PTR(str), RSTRING_LEN(str), bn)) {
+	if (!BN_mpi2bn((unsigned char *)RSTRING_PTR(str), RSTRING_LEN(str), bn)) {
 	    ossl_raise(eBNError, NULL);
 	}
 	break;
     case 2:
-	if (!BN_bin2bn(RSTRING_PTR(str), RSTRING_LEN(str), bn)) {
+	if (!BN_bin2bn((unsigned char *)RSTRING_PTR(str), RSTRING_LEN(str), bn)) {
 	    ossl_raise(eBNError, NULL);
 	}
 	break;
@@ -185,13 +185,13 @@ ossl_bn_to_s(int argc, VALUE *argv, VALUE self)
     case 0:
 	len = BN_bn2mpi(bn, NULL);
         str = rb_str_new(0, len);
-	if (BN_bn2mpi(bn, RSTRING_PTR(str)) != len)
+	if (BN_bn2mpi(bn, (unsigned char *)RSTRING_PTR(str)) != len)
 	    ossl_raise(eBNError, NULL);
 	break;
     case 2:
 	len = BN_num_bytes(bn);
         str = rb_str_new(0, len);
-	if (BN_bn2bin(bn, RSTRING_PTR(str)) != len)
+	if (BN_bn2bin(bn, (unsigned char *)RSTRING_PTR(str)) != len)
 	    ossl_raise(eBNError, NULL);
 	break;
     case 10:
diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c
index a2a052ca6b..3701d68300 100644
--- a/ext/openssl/ossl_cipher.c
+++ b/ext/openssl/ossl_cipher.c
@@ -188,7 +188,7 @@ ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode)
 	 * We deprecated the arguments for this method, but we decided
 	 * keeping this behaviour for backward compatibility.
 	 */
-	char *cname  = rb_class2name(rb_obj_class(self));
+	const char *cname  = rb_class2name(rb_obj_class(self));
 	rb_warn("argumtents for %s#encrypt and %s#decrypt were deprecated; "
                 "use %s#pkcs5_keyivgen to derive key and IV",
                 cname, cname, cname);
@@ -204,7 +204,7 @@ ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode)
 	    else memcpy(iv, RSTRING_PTR(init_v), sizeof(iv));
 	}
 	EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), EVP_md5(), iv,
-		       RSTRING_PTR(pass), RSTRING_LEN(pass), 1, key, NULL);
+		       (unsigned char *)RSTRING_PTR(pass), RSTRING_LEN(pass), 1, key, NULL);
 	p_key = key;
 	p_iv = iv;
     }
@@ -281,13 +281,13 @@ ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self)
 	StringValue(vsalt);
 	if(RSTRING_LEN(vsalt) != PKCS5_SALT_LEN)
 	    rb_raise(eCipherError, "salt must be an 8-octet string");
-	salt = RSTRING_PTR(vsalt);
+	salt = (unsigned char *)RSTRING_PTR(vsalt);
     }
     iter = NIL_P(viter) ? 2048 : NUM2INT(viter);
     digest = NIL_P(vdigest) ? EVP_md5() : GetDigestPtr(vdigest);
     GetCipher(self, ctx);
     EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), digest, salt,
-		   RSTRING_PTR(vpass), RSTRING_LEN(vpass), iter, key, iv); 
+		   (unsigned char *)RSTRING_PTR(vpass), RSTRING_LEN(vpass), iter, key, iv); 
     if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, -1) != 1)
 	ossl_raise(eCipherError, NULL);
     OPENSSL_cleanse(key, sizeof key);
@@ -299,26 +299,6 @@ ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self)
 
 /*
  *  call-seq:
- *     cipher << data -> string
- *
- *  === Parameters
- *  +data+ is a nonempty string.
- *
- * This method is deprecated and not available in 1.9.x or later.
- */
-static VALUE
-ossl_cipher_update_deprecated(VALUE self, VALUE data)
-{
-    char *cname;
-
-    cname = rb_class2name(rb_obj_class(self));
-    rb_warning("%s#<< is deprecated; use %s#update instead", cname, cname);
-    return rb_funcall(self, rb_intern("update"), 1, data);
-}
-
-
-/*
- *  call-seq:
  *     cipher.update(data [, buffer]) -> string or buffer
  *
  *  === Parameters
@@ -329,14 +309,14 @@ static VALUE
 ossl_cipher_update(int argc, VALUE *argv, VALUE self)
 {
     EVP_CIPHER_CTX *ctx;
-    char *in;
+    unsigned char *in;
     int in_len, out_len;
     VALUE data, str;
 
     rb_scan_args(argc, argv, "11", &data, &str);
 
     StringValue(data);
-    in = RSTRING_PTR(data);
+    in = (unsigned char *)RSTRING_PTR(data);
     if ((in_len = RSTRING_LEN(data)) == 0)
         rb_raise(rb_eArgError, "data must not be empty");
     GetCipher(self, ctx);
@@ -349,7 +329,7 @@ ossl_cipher_update(int argc, VALUE *argv, VALUE self)
         rb_str_resize(str, out_len);
     }
 
-    if (!EVP_CipherUpdate(ctx, RSTRING_PTR(str), &out_len, in, in_len))
+    if (!EVP_CipherUpdate(ctx, (unsigned char *)RSTRING_PTR(str), &out_len, in, in_len))
 	ossl_raise(eCipherError, NULL);
     assert(out_len < RSTRING_LEN(str));
     rb_str_set_len(str, out_len);
@@ -374,7 +354,7 @@ ossl_cipher_final(VALUE self)
 
     GetCipher(self, ctx);
     str = rb_str_new(0, EVP_CIPHER_CTX_block_size(ctx));
-    if (!EVP_CipherFinal_ex(ctx, RSTRING_PTR(str), &out_len))
+    if (!EVP_CipherFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), &out_len))
 	ossl_raise(eCipherError, NULL);
     assert(out_len <= RSTRING_LEN(str));
     rb_str_set_len(str, out_len);
@@ -417,7 +397,7 @@ ossl_cipher_set_key(VALUE self, VALUE key)
     if (RSTRING_LEN(key) < EVP_CIPHER_CTX_key_length(ctx))
         ossl_raise(eCipherError, "key length too short");
 
-    if (EVP_CipherInit_ex(ctx, NULL, NULL, RSTRING_PTR(key), NULL, -1) != 1)
+    if (EVP_CipherInit_ex(ctx, NULL, NULL, (unsigned char *)RSTRING_PTR(key), NULL, -1) != 1)
         ossl_raise(eCipherError, NULL);
 
     return key;
@@ -442,7 +422,7 @@ ossl_cipher_set_iv(VALUE self, VALUE iv)
     if (RSTRING_LEN(iv) < EVP_CIPHER_CTX_iv_length(ctx))
         ossl_raise(eCipherError, "iv length too short");
 
-    if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, RSTRING_PTR(iv), -1) != 1)
+    if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, (unsigned char *)RSTRING_PTR(iv), -1) != 1)
 	ossl_raise(eCipherError, NULL);
 
     return iv;
@@ -553,9 +533,6 @@ Init_ossl_cipher(void)
     rb_define_method(cCipher, "decrypt", ossl_cipher_decrypt, -1);
     rb_define_method(cCipher, "pkcs5_keyivgen", ossl_cipher_pkcs5_keyivgen, -1);
     rb_define_method(cCipher, "update", ossl_cipher_update, -1);
-#if RUBY_VERSION_CODE < 190
-    rb_define_method(cCipher, "<<", ossl_cipher_update_deprecated, 1);
-#endif
     rb_define_method(cCipher, "final", ossl_cipher_final, 0);
     rb_define_method(cCipher, "name", ossl_cipher_name, 0);
     rb_define_method(cCipher, "key=", ossl_cipher_set_key, 1);
diff --git a/ext/openssl/ossl_digest.c b/ext/openssl/ossl_digest.c
index 879d399fe7..9b8ced5233 100644
--- a/ext/openssl/ossl_digest.c
+++ b/ext/openssl/ossl_digest.c
@@ -38,7 +38,7 @@ GetDigestPtr(VALUE obj)
     const EVP_MD *md;
 
     if (TYPE(obj) == T_STRING) {
-    	const char *name = STR2CSTR(obj);
+    	const char *name = StringValueCStr(obj);
 
         md = EVP_get_digestbyname(name);
         if (!md)
@@ -96,7 +96,6 @@ ossl_digest_initialize(int argc, VALUE *argv, VALUE self)
 {
     EVP_MD_CTX *ctx;
     const EVP_MD *md;
-    char *name;
     VALUE type, data;
 
     rb_scan_args(argc, argv, "11", &type, &data);
@@ -182,7 +181,7 @@ ossl_digest_finish(int argc, VALUE *argv, VALUE self)
         rb_str_resize(str, EVP_MD_CTX_size(ctx));
     }
 
-    EVP_DigestFinal_ex(ctx, RSTRING_PTR(str), NULL);
+    EVP_DigestFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), NULL);
 
     return str;
 }
@@ -234,7 +233,6 @@ ossl_digest_block_length(VALUE self)
 void
 Init_ossl_digest()
 {
-    rb_require("openssl");
     rb_require("digest");
 
 #if 0 /* let rdoc know about mOSSL */
diff --git a/ext/openssl/ossl_engine.c b/ext/openssl/ossl_engine.c
index c6fc603a1e..6e26548909 100644
--- a/ext/openssl/ossl_engine.c
+++ b/ext/openssl/ossl_engine.c
@@ -344,7 +344,7 @@ static VALUE
 ossl_engine_inspect(VALUE self)
 {
     VALUE str;
-    char *cname = rb_class2name(rb_obj_class(self));
+    const char *cname = rb_class2name(rb_obj_class(self));
     
     str = rb_str_new2("#<");
     rb_str_cat2(str, cname);
diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c
index f8098bb9c3..aa7644aa5c 100644
--- a/ext/openssl/ossl_hmac.c
+++ b/ext/openssl/ossl_hmac.c
@@ -103,13 +103,13 @@ ossl_hmac_update(VALUE self, VALUE data)
 
     StringValue(data);
     GetHMAC(self, ctx);
-    HMAC_Update(ctx, RSTRING_PTR(data), RSTRING_LEN(data));
+    HMAC_Update(ctx, (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data));
 
     return self;
 }
 
 static void
-hmac_final(HMAC_CTX *ctx, char **buf, int *buf_len)
+hmac_final(HMAC_CTX *ctx, unsigned char **buf, unsigned int *buf_len)
 {
     HMAC_CTX final;
 
@@ -132,13 +132,13 @@ static VALUE
 ossl_hmac_digest(VALUE self)
 {
     HMAC_CTX *ctx;
-    char *buf;
-    int buf_len;
+    unsigned char *buf;
+    unsigned int buf_len;
     VALUE digest;
 	
     GetHMAC(self, ctx);
     hmac_final(ctx, &buf, &buf_len);
-    digest = ossl_buf2str(buf, buf_len);
+    digest = ossl_buf2str((char *)buf, buf_len);
     
     return digest;
 }
@@ -152,8 +152,9 @@ static VALUE
 ossl_hmac_hexdigest(VALUE self)
 {
     HMAC_CTX *ctx;
-    char *buf, *hexbuf;
-    int buf_len;
+    unsigned char *buf;
+    char *hexbuf;
+    unsigned int buf_len;
     VALUE hexdigest;
 	
     GetHMAC(self, ctx);
@@ -192,15 +193,15 @@ ossl_hmac_reset(VALUE self)
 static VALUE
 ossl_hmac_s_digest(VALUE klass, VALUE digest, VALUE key, VALUE data)
 {
-    char *buf;
-    int buf_len;
+    unsigned char *buf;
+    unsigned int buf_len;
 	
     StringValue(key);
     StringValue(data);
     buf = HMAC(GetDigestPtr(digest), RSTRING_PTR(key), RSTRING_LEN(key),
-	       RSTRING_PTR(data), RSTRING_LEN(data), NULL, &buf_len);
+	       (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data), NULL, &buf_len);
 
-    return rb_str_new(buf, buf_len);
+    return rb_str_new((const char *)buf, buf_len);
 }
 
 /*
@@ -211,15 +212,16 @@ ossl_hmac_s_digest(VALUE klass, VALUE digest, VALUE key, VALUE data)
 static VALUE
 ossl_hmac_s_hexdigest(VALUE klass, VALUE digest, VALUE key, VALUE data)
 {
-    char *buf, *hexbuf;
-    int buf_len;
+    unsigned char *buf;
+    char *hexbuf;
+    unsigned int buf_len;
     VALUE hexdigest;
 
     StringValue(key);
     StringValue(data);
 	
     buf = HMAC(GetDigestPtr(digest), RSTRING_PTR(key), RSTRING_LEN(key),
-	       RSTRING_PTR(data), RSTRING_LEN(data), NULL, &buf_len);
+	       (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data), NULL, &buf_len);
     if (string2hex(buf, buf_len, &hexbuf, NULL) != 2 * buf_len) {
 	ossl_raise(eHMACError, "Cannot convert buf to hexbuf");
     }
diff --git a/ext/openssl/ossl_ns_spki.c b/ext/openssl/ossl_ns_spki.c
index 738a203d93..5ff58c3108 100644
--- a/ext/openssl/ossl_ns_spki.c
+++ b/ext/openssl/ossl_ns_spki.c
@@ -56,14 +56,14 @@ ossl_spki_initialize(int argc, VALUE *argv, VALUE self)
 {
     NETSCAPE_SPKI *spki;
     VALUE buffer;
-    unsigned char *p;
+    const unsigned char *p;
 	
     if (rb_scan_args(argc, argv, "01", &buffer) == 0) {
 	return self;
     }
     StringValue(buffer);
     if (!(spki = NETSCAPE_SPKI_b64_decode(RSTRING_PTR(buffer), -1))) {
-	p = RSTRING_PTR(buffer);
+	p = (unsigned char *)RSTRING_PTR(buffer);
 	if (!(spki = d2i_NETSCAPE_SPKI(NULL, &p, RSTRING_LEN(buffer)))) {
 	    ossl_raise(eSPKIError, NULL);
 	}
@@ -87,7 +87,7 @@ ossl_spki_to_der(VALUE self)
     if ((len = i2d_NETSCAPE_SPKI(spki, NULL)) <= 0)
         ossl_raise(eX509CertError, NULL);
     str = rb_str_new(0, len);
-    p = RSTRING_PTR(str);
+    p = (unsigned char *)RSTRING_PTR(str);
     if (i2d_NETSCAPE_SPKI(spki, &p) <= 0)
         ossl_raise(eX509CertError, NULL);
     ossl_str_adjust(str, p);
@@ -172,7 +172,7 @@ ossl_spki_get_challenge(VALUE self)
 	return rb_str_new(0, 0);
     }
 
-    return rb_str_new(spki->spkac->challenge->data,
+    return rb_str_new((const char *)spki->spkac->challenge->data,
 		      spki->spkac->challenge->length);
 }
 
diff --git a/ext/openssl/ossl_ocsp.c b/ext/openssl/ossl_ocsp.c
index a6618ffede..898b2ad753 100644
--- a/ext/openssl/ossl_ocsp.c
+++ b/ext/openssl/ossl_ocsp.c
@@ -103,15 +103,17 @@ static VALUE
 ossl_ocspreq_initialize(int argc, VALUE *argv, VALUE self)
 {
     VALUE arg;
-    unsigned char *p;
+    const unsigned char *p;
 
     rb_scan_args(argc, argv, "01", &arg);
     if(!NIL_P(arg)){
+	OCSP_REQUEST *req = DATA_PTR(self), *x;
 	arg = ossl_to_der_if_possible(arg);
 	StringValue(arg);
 	p = (unsigned char*)RSTRING_PTR(arg);
-	if(!d2i_OCSP_REQUEST((OCSP_REQUEST**)&DATA_PTR(self), &p,
-			     RSTRING_LEN(arg))){
+	x = d2i_OCSP_REQUEST(&req, &p, RSTRING_LEN(arg));
+	DATA_PTR(self) = req;
+	if(!x){
 	    ossl_raise(eOCSPError, "cannot load DER encoded request");
 	}
     }
@@ -134,7 +136,7 @@ ossl_ocspreq_add_nonce(int argc, VALUE *argv, VALUE self)
     else{
 	StringValue(val);
 	GetOCSPReq(self, req);
-	ret = OCSP_request_add1_nonce(req, RSTRING_PTR(val), RSTRING_LEN(val));
+	ret = OCSP_request_add1_nonce(req, (unsigned char *)RSTRING_PTR(val), RSTRING_LEN(val));
     }
     if(!ret) ossl_raise(eOCSPError, NULL);
 
@@ -265,7 +267,7 @@ ossl_ocspreq_to_der(VALUE self)
     if((len = i2d_OCSP_REQUEST(req, NULL)) <= 0)
 	ossl_raise(eOCSPError, NULL);
     str = rb_str_new(0, len);
-    p = RSTRING_PTR(str);
+    p = (unsigned char *)RSTRING_PTR(str);
     if(i2d_OCSP_REQUEST(req, &p) <= 0)
 	ossl_raise(eOCSPError, NULL);
     ossl_str_adjust(str, p);
@@ -310,15 +312,17 @@ static VALUE
 ossl_ocspres_initialize(int argc, VALUE *argv, VALUE self)
 {
     VALUE arg;
-    unsigned char *p;
+    const unsigned char *p;
 
     rb_scan_args(argc, argv, "01", &arg);
     if(!NIL_P(arg)){
+	OCSP_RESPONSE *res = DATA_PTR(self), *x;
 	arg = ossl_to_der_if_possible(arg);
 	StringValue(arg);
-	p = RSTRING_PTR(arg);
-	if(!d2i_OCSP_RESPONSE((OCSP_RESPONSE**)&DATA_PTR(self), &p,
-			      RSTRING_LEN(arg))){
+	p = (unsigned char *)RSTRING_PTR(arg);
+	x = d2i_OCSP_RESPONSE(&res, &p, RSTRING_LEN(arg));
+	DATA_PTR(self) = res;
+	if(!x){
 	    ossl_raise(eOCSPError, "cannot load DER encoded response");
 	}
     }
@@ -377,7 +381,7 @@ ossl_ocspres_to_der(VALUE self)
     if((len = i2d_OCSP_RESPONSE(res, NULL)) <= 0)
 	ossl_raise(eOCSPError, NULL);
     str = rb_str_new(0, len);
-    p = RSTRING_PTR(str);
+    p = (unsigned char *)RSTRING_PTR(str);
     if(i2d_OCSP_RESPONSE(res, &p) <= 0)
 	ossl_raise(eOCSPError, NULL);
     ossl_str_adjust(str, p);
@@ -436,7 +440,7 @@ ossl_ocspbres_add_nonce(int argc, VALUE *argv, VALUE self)
     else{
 	StringValue(val);
 	GetOCSPBasicRes(self, bs);
-	ret = OCSP_basic_add1_nonce(bs, RSTRING_PTR(val), RSTRING_LEN(val));
+	ret = OCSP_basic_add1_nonce(bs, (unsigned char *)RSTRING_PTR(val), RSTRING_LEN(val));
     }
     if(!ret) ossl_raise(eOCSPError, NULL);
 
diff --git a/ext/openssl/ossl_pkcs12.c b/ext/openssl/ossl_pkcs12.c
index 2ec69ba8db..a58d5e05e8 100644
--- a/ext/openssl/ossl_pkcs12.c
+++ b/ext/openssl/ossl_pkcs12.c
@@ -137,15 +137,17 @@ ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self)
     X509 *x509;
     STACK_OF(X509) *x509s = NULL;
     int st = 0;
+    PKCS12 *pkcs = DATA_PTR(self);
 
     if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) return self;
     passphrase = NIL_P(pass) ? NULL : StringValuePtr(pass);
     in = ossl_obj2bio(arg);
-    d2i_PKCS12_bio(in, (PKCS12 **)&DATA_PTR(self));
+    d2i_PKCS12_bio(in, &pkcs);
+    DATA_PTR(self) = pkcs;
     BIO_free(in);
 
     pkey = cert = ca = Qnil;
-    if(!PKCS12_parse((PKCS12*)DATA_PTR(self), passphrase, &key, &x509, &x509s))
+    if(!PKCS12_parse(pkcs, passphrase, &key, &x509, &x509s))
 	ossl_raise(ePKCS12Error, "PKCS12_parse");
     pkey = rb_protect((VALUE(*)_((VALUE)))ossl_pkey_new, (VALUE)key,
 		      &st); /* NO DUP */
@@ -181,7 +183,7 @@ ossl_pkcs12_to_der(VALUE self)
     if((len = i2d_PKCS12(p12, NULL)) <= 0)
 	ossl_raise(ePKCS12Error, NULL);
     str = rb_str_new(0, len);
-    p = RSTRING_PTR(str);
+    p = (unsigned char *)RSTRING_PTR(str);
     if(i2d_PKCS12(p12, &p) <= 0)
 	ossl_raise(ePKCS12Error, NULL);
     ossl_str_adjust(str, p);
diff --git a/ext/openssl/ossl_pkcs5.c b/ext/openssl/ossl_pkcs5.c
index 39ba013839..ca20339adb 100644
--- a/ext/openssl/ossl_pkcs5.c
+++ b/ext/openssl/ossl_pkcs5.c
@@ -75,7 +75,9 @@ ossl_pkcs5_pbkdf2_hmac_sha1(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALU
 
     str = rb_str_new(0, len);
 
-    if (PKCS5_PBKDF2_HMAC_SHA1(RSTRING_PTR(pass), RSTRING_LEN(pass), RSTRING_PTR(salt), RSTRING_LEN(salt), NUM2INT(iter), len, RSTRING_PTR(str)) != 1)
+    if (PKCS5_PBKDF2_HMAC_SHA1(RSTRING_PTR(pass), RSTRING_LEN(pass),
+			       (const unsigned char *)RSTRING_PTR(salt), RSTRING_LEN(salt), NUM2INT(iter),
+			       len, (unsigned char *)RSTRING_PTR(str)) != 1)
         ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC_SHA1");
 
     return str;
diff --git a/ext/openssl/ossl_pkcs7.c b/ext/openssl/ossl_pkcs7.c
index 5177f5c1e5..b0cc656d4c 100644
--- a/ext/openssl/ossl_pkcs7.c
+++ b/ext/openssl/ossl_pkcs7.c
@@ -309,7 +309,7 @@ ossl_pkcs7_alloc(VALUE klass)
 static VALUE
 ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self)
 {
-    PKCS7 *p7;
+    PKCS7 *p7, *pkcs = DATA_PTR(self);
     BIO *in;
     VALUE arg;
 
@@ -317,10 +317,12 @@ ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self)
 	return self;
     arg = ossl_to_der_if_possible(arg);
     in = ossl_obj2bio(arg);
-    p7 = PEM_read_bio_PKCS7(in, (PKCS7 **)&DATA_PTR(self), NULL, NULL);
+    p7 = PEM_read_bio_PKCS7(in, &pkcs, NULL, NULL);
+    DATA_PTR(self) = pkcs;
     if (!p7) {
-	BIO_reset(in);
-        p7 = d2i_PKCS7_bio(in, (PKCS7 **)&DATA_PTR(self));
+	(void)BIO_reset(in);
+        p7 = d2i_PKCS7_bio(in, &pkcs);
+	DATA_PTR(self) = pkcs;
     }
     BIO_free(in);
     ossl_pkcs7_set_data(self, Qnil);
@@ -798,7 +800,7 @@ ossl_pkcs7_to_der(VALUE self)
     if((len = i2d_PKCS7(pkcs7, NULL)) <= 0)
 	ossl_raise(ePKCS7Error, NULL);
     str = rb_str_new(0, len);
-    p = RSTRING_PTR(str);
+    p = (unsigned char *)RSTRING_PTR(str);
     if(i2d_PKCS7(pkcs7, &p) <= 0)
 	ossl_raise(ePKCS7Error, NULL);
     ossl_str_adjust(str, p);
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
index 8f68189881..903a3bb1e5 100644
--- a/ext/openssl/ossl_pkey.c
+++ b/ext/openssl/ossl_pkey.c
@@ -164,7 +164,7 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
 {
     EVP_PKEY *pkey;
     EVP_MD_CTX ctx;
-    int buf_len;
+    unsigned int buf_len;
     VALUE str;
 
     if (rb_funcall(self, id_private_q, 0, NULL) != Qtrue) {
@@ -175,7 +175,7 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
     StringValue(data);
     EVP_SignUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data));
     str = rb_str_new(0, EVP_PKEY_size(pkey)+16);
-    if (!EVP_SignFinal(&ctx, RSTRING_PTR(str), &buf_len, pkey))
+    if (!EVP_SignFinal(&ctx, (unsigned char *)RSTRING_PTR(str), &buf_len, pkey))
 	ossl_raise(ePKeyError, NULL);
     assert((long)buf_len <= RSTRING_LEN(str));
     rb_str_set_len(str, buf_len);
@@ -194,7 +194,7 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
     StringValue(sig);
     StringValue(data);
     EVP_VerifyUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data));
-    switch (EVP_VerifyFinal(&ctx, RSTRING_PTR(sig), RSTRING_LEN(sig), pkey)) {
+    switch (EVP_VerifyFinal(&ctx, (unsigned char *)RSTRING_PTR(sig), RSTRING_LEN(sig), pkey)) {
     case 0:
 	return Qfalse;
     case 1:
diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c
index 3412305a5e..768cda86b7 100644
--- a/ext/openssl/ossl_pkey_dh.c
+++ b/ext/openssl/ossl_pkey_dh.c
@@ -169,7 +169,7 @@ ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
 	in = ossl_obj2bio(arg);
 	dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
 	if (!dh){
-	    BIO_reset(in);
+	    (void)BIO_reset(in);
 	    dh = d2i_DHparams_bio(in, NULL);
 	}
 	BIO_free(in);
@@ -254,7 +254,7 @@ ossl_dh_to_der(VALUE self)
     if((len = i2d_DHparams(pkey->pkey.dh, NULL)) <= 0)
 	ossl_raise(eDHError, NULL);
     str = rb_str_new(0, len);
-    p = RSTRING_PTR(str);
+    p = (unsigned char *)RSTRING_PTR(str);
     if(i2d_DHparams(pkey->pkey.dh, &p) < 0)
 	ossl_raise(eDHError, NULL);
     ossl_str_adjust(str, p);
@@ -407,7 +407,7 @@ ossl_dh_compute_key(VALUE self, VALUE pub)
     pub_key = GetBNPtr(pub);
     len = DH_size(dh);
     str = rb_str_new(0, len);
-    if ((len = DH_compute_key(RSTRING_PTR(str), pub_key, dh)) < 0) {
+    if ((len = DH_compute_key((unsigned char *)RSTRING_PTR(str), pub_key, dh)) < 0) {
 	ossl_raise(eDHError, NULL);
     }
     rb_str_set_len(str, len);
diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c
index a1f1397787..d39933b754 100644
--- a/ext/openssl/ossl_pkey_dsa.c
+++ b/ext/openssl/ossl_pkey_dsa.c
@@ -161,19 +161,19 @@ ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
 	in = ossl_obj2bio(arg);
 	dsa = PEM_read_bio_DSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
 	if (!dsa) {
-	    BIO_reset(in);
+	    (void)BIO_reset(in);
 	    dsa = PEM_read_bio_DSAPublicKey(in, NULL, NULL, NULL);
 	}
 	if (!dsa) {
-	    BIO_reset(in);
+	    (void)BIO_reset(in);
 	    dsa = PEM_read_bio_DSA_PUBKEY(in, NULL, NULL, NULL);
 	}
 	if (!dsa) {
-	    BIO_reset(in);
+	    (void)BIO_reset(in);
 	    dsa = d2i_DSAPrivateKey_bio(in, NULL);
 	}
 	if (!dsa) {
-	    BIO_reset(in);
+	    (void)BIO_reset(in);
 	    dsa = d2i_DSA_PUBKEY_bio(in, NULL);
 	}
 	BIO_free(in);
@@ -289,7 +289,7 @@ ossl_dsa_to_der(VALUE self)
     if((len = i2d_func(pkey->pkey.dsa, NULL)) <= 0)
 	ossl_raise(eDSAError, NULL);
     str = rb_str_new(0, len);
-    p = RSTRING_PTR(str);
+    p = (unsigned char *)RSTRING_PTR(str);
     if(i2d_func(pkey->pkey.dsa, &p) < 0)
 	ossl_raise(eDSAError, NULL);
     ossl_str_adjust(str, p);
@@ -387,7 +387,7 @@ static VALUE
 ossl_dsa_sign(VALUE self, VALUE data)
 {
     EVP_PKEY *pkey;
-    int buf_len;
+    unsigned int buf_len;
     VALUE str;
 
     GetPKeyDSA(self, pkey);
@@ -396,7 +396,8 @@ ossl_dsa_sign(VALUE self, VALUE data)
 	ossl_raise(eDSAError, "Private DSA key needed!");
     }
     str = rb_str_new(0, ossl_dsa_buf_size(pkey));
-    if (!DSA_sign(0, RSTRING_PTR(data), RSTRING_LEN(data), RSTRING_PTR(str),
+    if (!DSA_sign(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data),
+		  (unsigned char *)RSTRING_PTR(str),
 		  &buf_len, pkey->pkey.dsa)) { /* type is ignored (0) */
 	ossl_raise(eDSAError, NULL);
     }
@@ -420,8 +421,8 @@ ossl_dsa_verify(VALUE self, VALUE digest, VALUE sig)
     StringValue(digest);
     StringValue(sig);
     /* type is ignored (0) */
-    ret = DSA_verify(0, RSTRING_PTR(digest), RSTRING_LEN(digest),
-		     RSTRING_PTR(sig), RSTRING_LEN(sig), pkey->pkey.dsa);
+    ret = DSA_verify(0, (unsigned char *)RSTRING_PTR(digest), RSTRING_LEN(digest),
+		     (unsigned char *)RSTRING_PTR(sig), RSTRING_LEN(sig), pkey->pkey.dsa);
     if (ret < 0) {
 	ossl_raise(eDSAError, NULL);
     }
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c
index cbdad3f12b..000621eca1 100644
--- a/ext/openssl/ossl_pkey_ec.c
+++ b/ext/openssl/ossl_pkey_ec.c
@@ -186,22 +186,22 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
 
             ec = PEM_read_bio_ECPrivateKey(in, NULL, NULL, NULL);
             if (!ec) {
-                BIO_reset(in);
+                (void)BIO_reset(in);
                 ec = PEM_read_bio_EC_PUBKEY(in, NULL, NULL, NULL);
             }
             if (!ec) {
-                BIO_reset(in);
+                (void)BIO_reset(in);
                 ec = d2i_ECPrivateKey_bio(in, NULL);
             }
             if (!ec) {
-                BIO_reset(in);
+                (void)BIO_reset(in);
                 ec = d2i_EC_PUBKEY_bio(in, NULL);
             }
 
             BIO_free(in);
 
             if (ec == NULL) {
-                const char *name = STR2CSTR(arg);
+                const char *name = StringValueCStr(arg);
                 int nid = OBJ_sn2nid(name);
 
                 if (nid == NID_undef)
@@ -778,14 +778,14 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self)
 
             group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
             if (!group) {
-                BIO_reset(in);
+                (void)BIO_reset(in);
                 group = d2i_ECPKParameters_bio(in, NULL);
             }
 
             BIO_free(in);
 
             if (!group) {
-                const char *name = STR2CSTR(arg1);
+                const char *name = StringValueCStr(arg1);
                 int nid = OBJ_sn2nid(name);
 
                 if (nid == NID_undef)
@@ -1092,7 +1092,7 @@ static VALUE ossl_ec_group_get_seed(VALUE self)
     if (seed_len == 0)
         return Qnil;
 
-    return rb_str_new(EC_GROUP_get0_seed(group), seed_len);
+    return rb_str_new((const char *)EC_GROUP_get0_seed(group), seed_len);
 }
 
 /*  call-seq:
@@ -1107,7 +1107,7 @@ static VALUE ossl_ec_group_set_seed(VALUE self, VALUE seed)
     Require_EC_GROUP(self, group);
     StringValue(seed);
 
-    if (EC_GROUP_set_seed(group, RSTRING_PTR(seed), RSTRING_LEN(seed)) != RSTRING_LEN(seed))
+    if (EC_GROUP_set_seed(group, (unsigned char *)RSTRING_PTR(seed), RSTRING_LEN(seed)) != RSTRING_LEN(seed))
         ossl_raise(eEC_GROUP, "EC_GROUP_set_seed");
 
     return seed;
diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c
index 320bbf5207..80665cddbd 100644
--- a/ext/openssl/ossl_pkey_rsa.c
+++ b/ext/openssl/ossl_pkey_rsa.c
@@ -151,23 +151,23 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
 	in = ossl_obj2bio(arg);
 	rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
 	if (!rsa) {
-	    BIO_reset(in);
+	    (void)BIO_reset(in);
 	    rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
 	}
 	if (!rsa) {
-	    BIO_reset(in);
+	    (void)BIO_reset(in);
 	    rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
 	}
 	if (!rsa) {
-	    BIO_reset(in);
+	    (void)BIO_reset(in);
 	    rsa = d2i_RSAPrivateKey_bio(in, NULL);
 	}
 	if (!rsa) {
-	    BIO_reset(in);
+	    (void)BIO_reset(in);
 	    rsa = d2i_RSAPublicKey_bio(in, NULL);
 	}
 	if (!rsa) {
-	    BIO_reset(in);
+	    (void)BIO_reset(in);
 	    rsa = d2i_RSA_PUBKEY_bio(in, NULL);
 	}
 	BIO_free(in);
@@ -288,7 +288,7 @@ ossl_rsa_to_der(VALUE self)
     if((len = i2d_func(pkey->pkey.rsa, NULL)) <= 0)
 	ossl_raise(eRSAError, NULL);
     str = rb_str_new(0, len);
-    p = RSTRING_PTR(str);
+    p = (unsigned char *)RSTRING_PTR(str);
     if(i2d_func(pkey->pkey.rsa, &p) < 0)
 	ossl_raise(eRSAError, NULL);
     ossl_str_adjust(str, p);
@@ -315,8 +315,8 @@ ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self)
     pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
     StringValue(buffer);
     str = rb_str_new(0, ossl_rsa_buf_size(pkey));
-    buf_len = RSA_public_encrypt(RSTRING_LEN(buffer), RSTRING_PTR(buffer),
-				 RSTRING_PTR(str), pkey->pkey.rsa,
+    buf_len = RSA_public_encrypt(RSTRING_LEN(buffer), (unsigned char *)RSTRING_PTR(buffer),
+				 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
 				 pad);
     if (buf_len < 0) ossl_raise(eRSAError, NULL);
     rb_str_set_len(str, buf_len);
@@ -341,8 +341,8 @@ ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)
     pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
     StringValue(buffer);
     str = rb_str_new(0, ossl_rsa_buf_size(pkey));
-    buf_len = RSA_public_decrypt(RSTRING_LEN(buffer), RSTRING_PTR(buffer),
-				 RSTRING_PTR(str), pkey->pkey.rsa,
+    buf_len = RSA_public_decrypt(RSTRING_LEN(buffer), (unsigned char *)RSTRING_PTR(buffer),
+				 (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
 				 pad);
     if (buf_len < 0) ossl_raise(eRSAError, NULL);
     rb_str_set_len(str, buf_len);
@@ -370,8 +370,8 @@ ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self)
     pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
     StringValue(buffer);
     str = rb_str_new(0, ossl_rsa_buf_size(pkey));
-    buf_len = RSA_private_encrypt(RSTRING_LEN(buffer), RSTRING_PTR(buffer),
-				  RSTRING_PTR(str), pkey->pkey.rsa,
+    buf_len = RSA_private_encrypt(RSTRING_LEN(buffer), (unsigned char *)RSTRING_PTR(buffer),
+				  (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
 				  pad);
     if (buf_len < 0) ossl_raise(eRSAError, NULL);
     rb_str_set_len(str, buf_len);
@@ -400,8 +400,8 @@ ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
     pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
     StringValue(buffer);
     str = rb_str_new(0, ossl_rsa_buf_size(pkey));
-    buf_len = RSA_private_decrypt(RSTRING_LEN(buffer), RSTRING_PTR(buffer),
-				  RSTRING_PTR(str), pkey->pkey.rsa,
+    buf_len = RSA_private_decrypt(RSTRING_LEN(buffer), (unsigned char *)RSTRING_PTR(buffer),
+				  (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
 				  pad);
     if (buf_len < 0) ossl_raise(eRSAError, NULL);
     rb_str_set_len(str, buf_len);
diff --git a/ext/openssl/ossl_rand.c b/ext/openssl/ossl_rand.c
index ad830fbc98..af61fe33a0 100644
--- a/ext/openssl/ossl_rand.c
+++ b/ext/openssl/ossl_rand.c
@@ -99,7 +99,7 @@ ossl_rand_bytes(VALUE self, VALUE len)
     int n = NUM2INT(len);
 
     str = rb_str_new(0, n);
-    if (!RAND_bytes(RSTRING_PTR(str), n)) {
+    if (!RAND_bytes((unsigned char *)RSTRING_PTR(str), n)) {
 	ossl_raise(eRandomError, NULL);
     }
 
@@ -118,7 +118,7 @@ ossl_rand_pseudo_bytes(VALUE self, VALUE len)
     int n = NUM2INT(len);
 
     str = rb_str_new(0, n);
-    if (!RAND_pseudo_bytes(RSTRING_PTR(str), n)) {
+    if (!RAND_pseudo_bytes((unsigned char *)RSTRING_PTR(str), n)) {
 	ossl_raise(eRandomError, NULL);
     }
 
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 668408fd28..138b405a13 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -69,6 +69,9 @@ static const char *ossl_sslctx_attrs[] = {
     "verify_callback", "options", "cert_store", "extra_chain_cert",
     "client_cert_cb", "tmp_dh_callback", "session_id_context",
     "session_get_cb", "session_new_cb", "session_remove_cb",
+#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
+    "servername_cb",
+#endif
 };
 
 #define ossl_ssl_get_io(o)           rb_iv_get((o),"@io")
@@ -86,7 +89,12 @@ static const char *ossl_sslctx_attrs[] = {
 #define ossl_ssl_set_tmp_dh(o,v)     rb_iv_set((o),"@tmp_dh",(v))
 
 static const char *ossl_ssl_attr_readers[] = { "io", "context", };
-static const char *ossl_ssl_attrs[] = { "sync_close", };
+static const char *ossl_ssl_attrs[] = {
+#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
+    "hostname",
+#endif
+    "sync_close", 
+};
 
 ID ID_callback_state;
 
@@ -300,7 +308,7 @@ ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
 static VALUE
 ossl_call_session_get_cb(VALUE ary)
 {
-    VALUE ssl_obj, sslctx_obj, cb, ret;
+    VALUE ssl_obj, sslctx_obj, cb;
     
     Check_Type(ary, T_ARRAY);
     ssl_obj = rb_ary_entry(ary, 0);
@@ -328,7 +336,7 @@ ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
     ssl_obj = (VALUE)ptr;
     ary = rb_ary_new2(2);
     rb_ary_push(ary, ssl_obj);
-    rb_ary_push(ary, rb_str_new(buf, len));
+    rb_ary_push(ary, rb_str_new((const char *)buf, len));
 
     ret_obj = rb_protect((VALUE(*)_((VALUE)))ossl_call_session_get_cb, ary, &state);
     if (state) {
@@ -347,7 +355,7 @@ ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
 static VALUE
 ossl_call_session_new_cb(VALUE ary)
 {
-    VALUE ssl_obj, sslctx_obj, cb, ret;
+    VALUE ssl_obj, sslctx_obj, cb;
     
     Check_Type(ary, T_ARRAY);
     ssl_obj = rb_ary_entry(ary, 0);
@@ -390,10 +398,11 @@ ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
     return RTEST(ret_obj) ? 1 : 0;
 }
 
+#if 0				/* unused */
 static VALUE
 ossl_call_session_remove_cb(VALUE ary)
 {
-    VALUE sslctx_obj, cb, ret;
+    VALUE sslctx_obj, cb;
     
     Check_Type(ary, T_ARRAY);
     sslctx_obj = rb_ary_entry(ary, 0);
@@ -403,6 +412,7 @@ ossl_call_session_remove_cb(VALUE ary)
 
     return rb_funcall(cb, rb_intern("call"), 1, ary);
 }
+#endif
 
 static void
 ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess)
@@ -449,6 +459,66 @@ ossl_sslctx_add_extra_chain_cert_i(VALUE i, VALUE arg)
     return i;
 }
 
+static VALUE ossl_sslctx_setup(VALUE self);
+
+#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
+static VALUE
+ossl_call_servername_cb(VALUE ary)
+{
+    VALUE ssl_obj, sslctx_obj, cb, ret_obj;
+
+    Check_Type(ary, T_ARRAY);
+    ssl_obj = rb_ary_entry(ary, 0);
+
+    sslctx_obj = rb_iv_get(ssl_obj, "@context");
+    if (NIL_P(sslctx_obj)) return Qnil;
+    cb = rb_iv_get(sslctx_obj, "@servername_cb");
+    if (NIL_P(cb)) return Qnil;
+
+    ret_obj = rb_funcall(cb, rb_intern("call"), 1, ary);
+    if (rb_obj_is_kind_of(ret_obj, cSSLContext)) {
+        SSL *ssl;
+        SSL_CTX *ctx2;
+
+        ossl_sslctx_setup(ret_obj);
+        Data_Get_Struct(ssl_obj, SSL, ssl);
+        Data_Get_Struct(ret_obj, SSL_CTX, ctx2);
+        SSL_set_SSL_CTX(ssl, ctx2);
+    } else if (!NIL_P(ret_obj)) {
+            rb_raise(rb_eArgError, "servername_cb must return an OpenSSL::SSL::SSLContext object or nil");
+    }
+
+    return ret_obj;
+}
+
+static int
+ssl_servername_cb(SSL *ssl, int *ad, void *arg)
+{
+    VALUE ary, ssl_obj, ret_obj;
+    void *ptr;
+    int state = 0;
+    const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
+
+    if (!servername)
+        return SSL_TLSEXT_ERR_OK;
+
+    if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)
+    	return SSL_TLSEXT_ERR_ALERT_FATAL;
+    ssl_obj = (VALUE)ptr;
+    ary = rb_ary_new2(2);
+    rb_ary_push(ary, ssl_obj);
+    rb_ary_push(ary, rb_str_new2(servername));
+
+    ret_obj = rb_protect((VALUE(*)_((VALUE)))ossl_call_servername_cb, ary, &state);
+    if (state) {
+        rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));
+        return SSL_TLSEXT_ERR_ALERT_FATAL;
+    }
+
+    return SSL_TLSEXT_ERR_OK;
+}
+#endif
+
 /*
  * call-seq:
  *    ctx.setup => Qtrue # first time
@@ -566,7 +636,7 @@ ossl_sslctx_setup(VALUE self)
     val = ossl_sslctx_get_sess_id_ctx(self);
     if (!NIL_P(val)){
 	StringValue(val);
-	if (!SSL_CTX_set_session_id_context(ctx, RSTRING_PTR(val),
+	if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val),
 					    RSTRING_LEN(val))){
 	    ossl_raise(eSSLError, "SSL_CTX_set_session_id_context:");
 	}
@@ -584,6 +654,15 @@ ossl_sslctx_setup(VALUE self)
 	SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb);
 	OSSL_Debug("SSL SESSION remove callback added");
     }
+
+#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
+    val = rb_iv_get(self, "@servername_cb");
+    if (!NIL_P(val)) {
+        SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
+	OSSL_Debug("SSL TLSEXT servername callback added");
+    }
+#endif
+
     return Qtrue;
 }
 
@@ -818,7 +897,6 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
     VALUE arg1;
     SSL_CTX *ctx;
     time_t tm = 0;
-    int cb_state;
 
     rb_scan_args(argc, argv, "01", &arg1);
 
@@ -890,6 +968,9 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
     ossl_ssl_set_ctx(self, ctx);
     ossl_ssl_set_sync_close(self, Qfalse);
     ossl_sslctx_setup(ctx);
+
+    rb_iv_set(self, "@hostname", Qnil);
+
     rb_call_super(0, 0);
 
     return self;
@@ -905,6 +986,10 @@ ossl_ssl_setup(VALUE self)
 
     Data_Get_Struct(self, SSL, ssl);
     if(!ssl){
+#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
+	VALUE hostname = rb_iv_get(self, "@hostname");
+#endif
+
         v_ctx = ossl_ssl_get_ctx(self);
         Data_Get_Struct(v_ctx, SSL_CTX, ctx);
 
@@ -914,6 +999,12 @@ ossl_ssl_setup(VALUE self)
         }
         DATA_PTR(self) = ssl;
 
+#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
+        if (!NIL_P(hostname)) {
+           if (SSL_set_tlsext_host_name(ssl, StringValuePtr(hostname)) != 1)
+               ossl_raise(eSSLError, "SSL_set_tlsext_host_name:");
+        }
+#endif
         io = ossl_ssl_get_io(self);
         GetOpenFile(io, fptr);
         rb_io_check_readable(fptr);
@@ -950,7 +1041,15 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname)
     Data_Get_Struct(self, SSL, ssl);
     GetOpenFile(ossl_ssl_get_io(self), fptr);
     for(;;){
-	if((ret = func(ssl)) > 0) break;
+	ret = func(ssl);
+
+        cb_state = rb_ivar_get(self, ID_callback_state);
+        if (!NIL_P(cb_state))
+            rb_jump_tag(NUM2INT(cb_state));
+
+	if (ret > 0)
+	    break;
+
 	switch((ret2 = ssl_get_error(ssl, ret))){
 	case SSL_ERROR_WANT_WRITE:
             rb_io_wait_writable(FPTR_TO_FD(fptr));
@@ -966,10 +1065,6 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname)
 	}
     }
 
-    cb_state = rb_ivar_get(self, ID_callback_state);
-    if (!NIL_P(cb_state))
-        rb_jump_tag(NUM2INT(cb_state));
-
     return self;
 }
 
@@ -1347,13 +1442,13 @@ Init_ossl_ssl()
 
     ID_callback_state = rb_intern("@callback_state");
 
-    ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0,"ossl_ssl_ex_vcb_idx",0,0,0);
-    ossl_ssl_ex_store_p = SSL_get_ex_new_index(0,"ossl_ssl_ex_store_p",0,0,0);
-    ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0,"ossl_ssl_ex_ptr_idx",0,0,0);
+    ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_vcb_idx",0,0,0);
+    ossl_ssl_ex_store_p = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_store_p",0,0,0);
+    ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_ptr_idx",0,0,0);
     ossl_ssl_ex_client_cert_cb_idx =
-	SSL_get_ex_new_index(0,"ossl_ssl_ex_client_cert_cb_idx",0,0,0);
+	SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_client_cert_cb_idx",0,0,0);
     ossl_ssl_ex_tmp_dh_callback_idx =
-	SSL_get_ex_new_index(0,"ossl_ssl_ex_tmp_dh_callback_idx",0,0,0);
+	SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_tmp_dh_callback_idx",0,0,0);
 
     mSSL = rb_define_module_under(mOSSL, "SSL");
     eSSLError = rb_define_class_under(mSSL, "SSLError", eOSSLError);
diff --git a/ext/openssl/ossl_ssl_session.c b/ext/openssl/ossl_ssl_session.c
index b416e76920..fcbcf8cb24 100644
--- a/ext/openssl/ossl_ssl_session.c
+++ b/ext/openssl/ossl_ssl_session.c
@@ -36,8 +36,6 @@ static VALUE ossl_ssl_session_alloc(VALUE klass)
 static VALUE ossl_ssl_session_initialize(VALUE self, VALUE arg1)
 {
 	SSL_SESSION *ctx = NULL;
-	VALUE obj;
-	unsigned char *p;
 
 	if (RDATA(self)->data)
 		ossl_raise(eSSLSession, "SSL Session already initialized");
@@ -55,7 +53,7 @@ static VALUE ossl_ssl_session_initialize(VALUE self, VALUE arg1)
 		ctx = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL);
 
 		if (!ctx) {
-			BIO_reset(in);
+			(void)BIO_reset(in);
 			ctx = d2i_SSL_SESSION_bio(in, NULL);
 		}
 
diff --git a/ext/openssl/ossl_x509attr.c b/ext/openssl/ossl_x509attr.c
index 949785a80b..2a4c481ee3 100644
--- a/ext/openssl/ossl_x509attr.c
+++ b/ext/openssl/ossl_x509attr.c
@@ -92,16 +92,17 @@ static VALUE
 ossl_x509attr_initialize(int argc, VALUE *argv, VALUE self)
 {
     VALUE oid, value;
-    X509_ATTRIBUTE *attr;
-    unsigned char *p;
+    X509_ATTRIBUTE *attr, *x;
+    const unsigned char *p;
 
     GetX509Attr(self, attr);
     if(rb_scan_args(argc, argv, "11", &oid, &value) == 1){
 	oid = ossl_to_der_if_possible(oid);
 	StringValue(oid);
-	p = RSTRING_PTR(oid);
-	if(!d2i_X509_ATTRIBUTE((X509_ATTRIBUTE**)&DATA_PTR(self),
-			       &p, RSTRING_LEN(oid))){
+	p = (unsigned char *)RSTRING_PTR(oid);
+	x = d2i_X509_ATTRIBUTE(&attr, &p, RSTRING_LEN(oid));
+	DATA_PTR(self) = attr;
+	if(!x){
 	    ossl_raise(eX509AttrError, NULL);
 	}
 	return self;
@@ -212,7 +213,7 @@ ossl_x509attr_get_value(VALUE self)
     if(OSSL_X509ATTR_IS_SINGLE(attr)){
 	length = i2d_ASN1_TYPE(attr->value.single, NULL);
 	str = rb_str_new(0, length);
-	p = RSTRING_PTR(str);
+	p = (unsigned char *)RSTRING_PTR(str);
 	i2d_ASN1_TYPE(attr->value.single, &p);
 	ossl_str_adjust(str, p);
     }
@@ -221,7 +222,7 @@ ossl_x509attr_get_value(VALUE self)
 			(unsigned char **) NULL, i2d_ASN1_TYPE,
 			V_ASN1_SET, V_ASN1_UNIVERSAL, 0);
 	str = rb_str_new(0, length);
-	p = RSTRING_PTR(str);
+	p = (unsigned char *)RSTRING_PTR(str);
 	i2d_ASN1_SET_OF_ASN1_TYPE(attr->value.set, &p,
 			i2d_ASN1_TYPE, V_ASN1_SET, V_ASN1_UNIVERSAL, 0);
 	ossl_str_adjust(str, p);
@@ -247,7 +248,7 @@ ossl_x509attr_to_der(VALUE self)
     if((len = i2d_X509_ATTRIBUTE(attr, NULL)) <= 0)
 	ossl_raise(eX509AttrError, NULL);
     str = rb_str_new(0, len);
-    p = RSTRING_PTR(str);
+    p = (unsigned char *)RSTRING_PTR(str);
     if(i2d_X509_ATTRIBUTE(attr, &p) <= 0)
 	ossl_raise(eX509AttrError, NULL);
     rb_str_set_len(str, p - (unsigned char*)RSTRING_PTR(str)); 
diff --git a/ext/openssl/ossl_x509cert.c b/ext/openssl/ossl_x509cert.c
index b97f27ffa9..fec2d8b1a3 100644
--- a/ext/openssl/ossl_x509cert.c
+++ b/ext/openssl/ossl_x509cert.c
@@ -134,7 +134,7 @@ static VALUE
 ossl_x509_initialize(int argc, VALUE *argv, VALUE self)
 {
     BIO *in;
-    X509 *x509;
+    X509 *x509, *x = DATA_PTR(self);
     VALUE arg;
 
     if (rb_scan_args(argc, argv, "01", &arg) == 0) {
@@ -143,10 +143,12 @@ ossl_x509_initialize(int argc, VALUE *argv, VALUE self)
     }
     arg = ossl_to_der_if_possible(arg);
     in = ossl_obj2bio(arg);
-    x509 = PEM_read_bio_X509(in, (X509 **)&DATA_PTR(self), NULL, NULL);
+    x509 = PEM_read_bio_X509(in, &x, NULL, NULL);
+    DATA_PTR(self) = x;
     if (!x509) {
-	BIO_reset(in);
-	x509 = d2i_X509_bio(in, (X509 **)&DATA_PTR(self));
+	(void)BIO_reset(in);
+	x509 = d2i_X509_bio(in, &x);
+	DATA_PTR(self) = x;
     }
     BIO_free(in);
     if (!x509) ossl_raise(eX509CertError, NULL);
@@ -190,7 +192,7 @@ ossl_x509_to_der(VALUE self)
     if ((len = i2d_X509(x509, NULL)) <= 0)
 	ossl_raise(eX509CertError, NULL);
     str = rb_str_new(0, len);
-    p = RSTRING_PTR(str);
+    p = (unsigned char *)RSTRING_PTR(str);
     if (i2d_X509(x509, &p) <= 0)
 	ossl_raise(eX509CertError, NULL);
     ossl_str_adjust(str, p);
@@ -690,7 +692,7 @@ static VALUE
 ossl_x509_inspect(VALUE self)
 {
     VALUE str;
-    char *cname = rb_class2name(rb_obj_class(self));
+    const char *cname = rb_class2name(rb_obj_class(self));
 
     str = rb_str_new2("#<");
     rb_str_cat2(str, cname);
diff --git a/ext/openssl/ossl_x509crl.c b/ext/openssl/ossl_x509crl.c
index e6d0c2eb3c..818fdbaddb 100644
--- a/ext/openssl/ossl_x509crl.c
+++ b/ext/openssl/ossl_x509crl.c
@@ -91,7 +91,7 @@ static VALUE
 ossl_x509crl_initialize(int argc, VALUE *argv, VALUE self)
 {
     BIO *in;
-    X509_CRL *crl;
+    X509_CRL *crl, *x = DATA_PTR(self);
     VALUE arg;
 
     if (rb_scan_args(argc, argv, "01", &arg) == 0) {
@@ -99,10 +99,12 @@ ossl_x509crl_initialize(int argc, VALUE *argv, VALUE self)
     }
     arg = ossl_to_der_if_possible(arg);
     in = ossl_obj2bio(arg);
-    crl = PEM_read_bio_X509_CRL(in, (X509_CRL **)&DATA_PTR(self), NULL, NULL);
+    crl = PEM_read_bio_X509_CRL(in, &x, NULL, NULL);
+    DATA_PTR(self) = x;
     if (!crl) {
-	BIO_reset(in);
-	crl = d2i_X509_CRL_bio(in, (X509_CRL **)&DATA_PTR(self));
+	(void)BIO_reset(in);
+	crl = d2i_X509_CRL_bio(in, &x);
+	DATA_PTR(self) = x;
     }
     BIO_free(in);
     if (!crl) ossl_raise(eX509CRLError, NULL);
diff --git a/ext/openssl/ossl_x509ext.c b/ext/openssl/ossl_x509ext.c
index 591ae953bb..4724c67362 100644
--- a/ext/openssl/ossl_x509ext.c
+++ b/ext/openssl/ossl_x509ext.c
@@ -274,16 +274,17 @@ static VALUE
 ossl_x509ext_initialize(int argc, VALUE *argv, VALUE self)
 {
     VALUE oid, value, critical;
-    unsigned char *p;
-    X509_EXTENSION *ext;
+    const unsigned char *p;
+    X509_EXTENSION *ext, *x;
 
     GetX509Ext(self, ext);
     if(rb_scan_args(argc, argv, "12", &oid, &value, &critical) == 1){
 	oid = ossl_to_der_if_possible(oid);
 	StringValue(oid);
-	p  = RSTRING_PTR(oid);
-	if(!d2i_X509_EXTENSION((X509_EXTENSION**)&DATA_PTR(self),
-			       &p, RSTRING_LEN(oid)))
+	p = (unsigned char *)RSTRING_PTR(oid);
+	x = d2i_X509_EXTENSION(&ext, &p, RSTRING_LEN(oid));
+	DATA_PTR(self) = ext;
+	if(!x)
 	    ossl_raise(eX509ExtError, NULL);
 	return self;
     }
@@ -411,7 +412,7 @@ ossl_x509ext_to_der(VALUE obj)
     if((len = i2d_X509_EXTENSION(ext, NULL)) <= 0)
 	ossl_raise(eX509ExtError, NULL);
     str = rb_str_new(0, len);
-    p = RSTRING_PTR(str);
+    p = (unsigned char *)RSTRING_PTR(str);
     if(i2d_X509_EXTENSION(ext, &p) < 0)
 	ossl_raise(eX509ExtError, NULL);
     ossl_str_adjust(str, p);
diff --git a/ext/openssl/ossl_x509name.c b/ext/openssl/ossl_x509name.c
index 55f5b58d64..af7b7543c0 100644
--- a/ext/openssl/ossl_x509name.c
+++ b/ext/openssl/ossl_x509name.c
@@ -135,7 +135,7 @@ ossl_x509name_initialize(int argc, VALUE *argv, VALUE self)
 	    rb_block_call(tmp, rb_intern("each"), 0, 0, ossl_x509name_init_i, args);
 	}
 	else{
-	    unsigned char *p;
+	    const unsigned char *p;
 	    VALUE str = ossl_to_der_if_possible(arg);
 	    X509_NAME *x;
 	    StringValue(str);
@@ -167,7 +167,7 @@ VALUE ossl_x509name_add_entry(int argc, VALUE *argv, VALUE self)
     if(NIL_P(type)) type = rb_aref(OBJECT_TYPE_TEMPLATE, oid);
     GetX509Name(self, name);
     if (!X509_NAME_add_entry_by_txt(name, RSTRING_PTR(oid), NUM2INT(type),
-		RSTRING_PTR(value), RSTRING_LEN(value), -1, 0)) {
+		(const unsigned char *)RSTRING_PTR(value), RSTRING_LEN(value), -1, 0)) {
 	ossl_raise(eX509NameError, NULL);
     }
 
@@ -248,7 +248,7 @@ ossl_x509name_to_a(VALUE self)
 	}
 	short_name = OBJ_nid2sn(OBJ_ln2nid(long_name));
 	ary = rb_ary_new3(3, rb_str_new2(short_name),
-        		  rb_str_new(entry->value->data, entry->value->length),
+        		  rb_str_new((const char *)entry->value->data, entry->value->length),
         		  INT2FIX(entry->value->type));
 	rb_ary_push(ret, ary);
     }
@@ -343,7 +343,7 @@ ossl_x509name_to_der(VALUE self)
     if((len = i2d_X509_NAME(name, NULL)) <= 0)
 	ossl_raise(eX509NameError, NULL);
     str = rb_str_new(0, len);
-    p = RSTRING_PTR(str);
+    p = (unsigned char *)RSTRING_PTR(str);
     if(i2d_X509_NAME(name, &p) <= 0)
 	ossl_raise(eX509NameError, NULL);
     ossl_str_adjust(str, p);
diff --git a/ext/openssl/ossl_x509req.c b/ext/openssl/ossl_x509req.c
index 13a42dddaf..7c1b610159 100644
--- a/ext/openssl/ossl_x509req.c
+++ b/ext/openssl/ossl_x509req.c
@@ -99,7 +99,7 @@ static VALUE
 ossl_x509req_initialize(int argc, VALUE *argv, VALUE self)
 {
     BIO *in;
-    X509_REQ *req;
+    X509_REQ *req, *x = DATA_PTR(self);
     VALUE arg;
 
     if (rb_scan_args(argc, argv, "01", &arg) == 0) {
@@ -107,10 +107,12 @@ ossl_x509req_initialize(int argc, VALUE *argv, VALUE self)
     }
     arg = ossl_to_der_if_possible(arg);
     in = ossl_obj2bio(arg);
-    req = PEM_read_bio_X509_REQ(in, (X509_REQ **)&DATA_PTR(self), NULL, NULL);
+    req = PEM_read_bio_X509_REQ(in, &x, NULL, NULL);
+    DATA_PTR(self) = x;
     if (!req) {
-	BIO_reset(in);
-	req = d2i_X509_REQ_bio(in, (X509_REQ **)&DATA_PTR(self));
+	(void)BIO_reset(in);
+	req = d2i_X509_REQ_bio(in, &x);
+	DATA_PTR(self) = x;
     }
     BIO_free(in);
     if (!req) ossl_raise(eX509ReqError, NULL);
@@ -171,7 +173,7 @@ ossl_x509req_to_der(VALUE self)
     if ((len = i2d_X509_REQ(req, NULL)) <= 0)
 	ossl_raise(eX509CertError, NULL);
     str = rb_str_new(0, len);
-    p = RSTRING_PTR(str);
+    p = (unsigned char *)RSTRING_PTR(str);
     if (i2d_X509_REQ(req, &p) <= 0)
 	ossl_raise(eX509ReqError, NULL);
     ossl_str_adjust(str, p);
diff --git a/ext/openssl/ossl_x509store.c b/ext/openssl/ossl_x509store.c
index cd30226277..4a170c0d86 100644
--- a/ext/openssl/ossl_x509store.c
+++ b/ext/openssl/ossl_x509store.c
@@ -213,7 +213,7 @@ ossl_x509store_add_file(VALUE self, VALUE file)
     char *path = NULL;
 
     if(file != Qnil){
-        Check_SafeStr(file);
+        SafeStringValue(file);
 	path = RSTRING_PTR(file);
     }
     GetX509Store(self, store);
@@ -234,7 +234,7 @@ ossl_x509store_add_path(VALUE self, VALUE dir)
     char *path = NULL;
 
     if(dir != Qnil){
-        Check_SafeStr(dir);
+        SafeStringValue(dir);
 	path = RSTRING_PTR(dir);
     }
     GetX509Store(self, store);
-- 
2.12.0

