From: Jamis Buck Date: 2004-06-13T01:59:50+09:00 Subject: OpenSSL: patch --------------000506080602020001080008 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Attached is a patch for the Ruby/OpenSSL module, done against the code in the snapshot.tar.gz file as currently available from http://www.ruby-lang.org. This patch adds functionality necessary to support SSH operations. I have also added a new method to Cipher::Cipher: called "crypt". I did this because I couldn't get the update/final stuff to work. This may have been because I do not have a complete understanding of how they are *supposed* to work. Still, I have a very hacked-together SSH client in Ruby now, using the routines provided by this patch. Please let me know if you have any questions! -- Jamis Buck jgb3@email.byu.edu http://www.jamisbuck.org/jamis ruby -h | ruby -e 'a=[];readlines.join.scan(/-(.)\[e|Kk(\S*)|le.l(..)e|#!(\S*)/) {|r| a << r.compact.first };puts "\n>#{a.join(%q/ /)}<\n\n"' --------------000506080602020001080008 Content-Type: text/x-patch; name="openssl.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="openssl.patch" Only in ruby.mod/ext/openssl: :q diff -ur ruby/ext/openssl/ossl_cipher.c ruby.mod/ext/openssl/ossl_cipher.c --- ruby/ext/openssl/ossl_cipher.c 2003-09-17 03:05:02.000000000 -0600 +++ ruby.mod/ext/openssl/ossl_cipher.c 2004-06-09 22:27:07.000000000 -0600 @@ -228,6 +228,28 @@ return self; } +static VALUE +ossl_cipher_crypt(VALUE self, VALUE data) +{ + EVP_CIPHER_CTX *ctx; + VALUE result; + + GetCipher(self, ctx); + + StringValue(data); + + if( RSTRING(data)->len % EVP_CIPHER_CTX_block_size(ctx) ) + ossl_raise(eCipherError, "data length not multiple of block size" ); + + result = rb_str_buf_new( RSTRING(data)->len ); + if( EVP_Cipher(ctx, RSTRING(result)->ptr, RSTRING(data)->ptr, RSTRING(data)->len ) == 0 ) + ossl_raise(eCipherError, NULL); + + RSTRING(result)->len = RSTRING(data)->len; + + return result; +} + static VALUE ossl_cipher_update(VALUE self, VALUE data) { @@ -357,6 +379,7 @@ rb_define_method(cCipher, "reset", ossl_cipher_reset, 0); + rb_define_method(cCipher, "crypt", ossl_cipher_crypt, 1); rb_define_method(cCipher, "encrypt", ossl_cipher_encrypt, -1); rb_define_method(cCipher, "decrypt", ossl_cipher_decrypt, -1); rb_define_method(cCipher, "update", ossl_cipher_update, 1); diff -ur ruby/ext/openssl/ossl_pkey_dh.c ruby.mod/ext/openssl/ossl_pkey_dh.c --- ruby/ext/openssl/ossl_pkey_dh.c 2004-01-08 05:24:22.000000000 -0700 +++ ruby.mod/ext/openssl/ossl_pkey_dh.c 2004-06-06 06:54:45.000000000 -0600 @@ -129,29 +129,33 @@ VALUE arg, gen; GetPKey(self, pkey); - rb_scan_args(argc, argv, "11", &arg, &gen); - if (FIXNUM_P(arg)) { - if (!NIL_P(gen)) { - g = FIX2INT(gen); - } - if (!(dh = dh_generate(FIX2INT(arg), g))) { - ossl_raise(eDHError, NULL); - } + if( 0 == rb_scan_args(argc, argv, "02", &arg, &gen) ) { + dh = DH_new(); } else { - arg = ossl_to_der_if_possible(arg); - in = ossl_obj2bio(arg); - dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); - if (!dh){ - BIO_reset(in); - dh = d2i_DHparams_bio(in, NULL); - } - BIO_free(in); - if (!dh) ossl_raise(eDHError, NULL); + if (FIXNUM_P(arg)) { + if (!NIL_P(gen)) { + g = FIX2INT(gen); + } + if (!(dh = dh_generate(FIX2INT(arg), g))) { + ossl_raise(eDHError, NULL); + } + } + else { + arg = ossl_to_der_if_possible(arg); + in = ossl_obj2bio(arg); + dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); + if (!dh){ + BIO_reset(in); + dh = d2i_DHparams_bio(in, NULL); + } + BIO_free(in); + if (!dh) ossl_raise(eDHError, NULL); + } } if (!EVP_PKEY_assign_DH(pkey, dh)) { - DH_free(dh); - ossl_raise(eRSAError, NULL); + DH_free(dh); + ossl_raise(eRSAError, NULL); } return self; } @@ -299,7 +303,7 @@ dh = pkey->pkey.dh; if (!DH_check(dh, &codes)) { - return Qfalse; + return Qfalse; } return codes == 0 ? Qtrue : Qfalse; @@ -315,7 +319,7 @@ dh = pkey->pkey.dh; if (!DH_generate_key(dh)) - ossl_raise(eDHError, "Failed to generate key"); + ossl_raise(eDHError, "Failed to generate key"); return self; } @@ -342,6 +346,30 @@ return str; } +#define dh_bignum_accessors( varname ) \ + static VALUE \ + ossl_dh_get_##varname( VALUE self ) \ + { \ + EVP_PKEY *pkey; \ + GetPKeyDH( self, pkey ); \ + if( pkey->pkey.dh->varname == NULL ) return Qnil; \ + return ossl_bn_new( pkey->pkey.dh->varname ); \ + } \ + static VALUE \ + ossl_dh_set_##varname( VALUE self, VALUE varname ) \ + { \ + EVP_PKEY *pkey; \ + GetPKeyDH(self, pkey); \ + if( pkey->pkey.dh->varname != NULL ) BN_clear_free( pkey->pkey.dh->varname ); \ + pkey->pkey.dh->varname = BN_dup( GetBNPtr( varname ) ); \ + return varname; \ + } + +dh_bignum_accessors( p ) +dh_bignum_accessors( g ) +dh_bignum_accessors( pub_key ) +dh_bignum_accessors( priv_key ) + /* * INIT */ @@ -368,6 +396,15 @@ rb_define_method(cDH, "generate_key!", ossl_dh_generate_key, 0); rb_define_method(cDH, "compute_key", ossl_dh_compute_key, 1); + rb_define_method(cDH, "p", ossl_dh_get_p, 0 ); + rb_define_method(cDH, "p=", ossl_dh_set_p, 1 ); + rb_define_method(cDH, "g", ossl_dh_get_g, 0 ); + rb_define_method(cDH, "g=", ossl_dh_set_g, 1 ); + rb_define_method(cDH, "pub_key", ossl_dh_get_pub_key, 0 ); + rb_define_method(cDH, "pub_key=", ossl_dh_set_pub_key, 1 ); + rb_define_method(cDH, "priv_key", ossl_dh_get_priv_key, 0 ); + rb_define_method(cDH, "priv_key=", ossl_dh_set_priv_key, 1 ); + rb_define_method(cDH, "params", ossl_dh_get_params, 0); } diff -ur ruby/ext/openssl/ossl_pkey_dsa.c ruby.mod/ext/openssl/ossl_pkey_dsa.c --- ruby/ext/openssl/ossl_pkey_dsa.c 2004-01-08 05:24:22.000000000 -0700 +++ ruby.mod/ext/openssl/ossl_pkey_dsa.c 2004-06-06 21:31:26.000000000 -0600 @@ -129,39 +129,43 @@ VALUE arg, pass; GetPKey(self, pkey); - rb_scan_args(argc, argv, "11", &arg, &pass); - if (FIXNUM_P(arg)) { - if (!(dsa = dsa_generate(FIX2INT(arg)))) { - ossl_raise(eDSAError, NULL); - } + if( rb_scan_args(argc, argv, "02", &arg, &pass) == 0 ) { + dsa = DH_new(); } else { - if (!NIL_P(pass)) passwd = StringValuePtr(pass); - arg = ossl_to_der_if_possible(arg); - in = ossl_obj2bio(arg); - dsa = PEM_read_bio_DSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd); - if (!dsa) { - BIO_reset(in); - dsa = PEM_read_bio_DSAPublicKey(in, NULL, NULL, NULL); - } - if (!dsa) { - BIO_reset(in); - dsa = PEM_read_bio_DSA_PUBKEY(in, NULL, NULL, NULL); - } - if (!dsa) { - BIO_reset(in); - dsa = d2i_DSAPrivateKey_bio(in, NULL); - } - if (!dsa) { - BIO_reset(in); - dsa = d2i_DSA_PUBKEY_bio(in, NULL); - } - BIO_free(in); - if (!dsa) ossl_raise(eDSAError, "Neither PUB key nor PRIV key:"); + if (FIXNUM_P(arg)) { + if (!(dsa = dsa_generate(FIX2INT(arg)))) { + ossl_raise(eDSAError, NULL); + } + } + else { + if (!NIL_P(pass)) passwd = StringValuePtr(pass); + arg = ossl_to_der_if_possible(arg); + in = ossl_obj2bio(arg); + dsa = PEM_read_bio_DSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd); + if (!dsa) { + BIO_reset(in); + dsa = PEM_read_bio_DSAPublicKey(in, NULL, NULL, NULL); + } + if (!dsa) { + BIO_reset(in); + dsa = PEM_read_bio_DSA_PUBKEY(in, NULL, NULL, NULL); + } + if (!dsa) { + BIO_reset(in); + dsa = d2i_DSAPrivateKey_bio(in, NULL); + } + if (!dsa) { + BIO_reset(in); + dsa = d2i_DSA_PUBKEY_bio(in, NULL); + } + BIO_free(in); + if (!dsa) ossl_raise(eDSAError, "Neither PUB key nor PRIV key:"); + } } if (!EVP_PKEY_assign_DSA(pkey, dsa)) { - DSA_free(dsa); - ossl_raise(eDSAError, NULL); + DSA_free(dsa); + ossl_raise(eDSAError, NULL); } return self; @@ -370,6 +374,12 @@ return Qfalse; } +OSSL_PKEY_BN(dsa, p); +OSSL_PKEY_BN(dsa, q); +OSSL_PKEY_BN(dsa, g); +OSSL_PKEY_BN(dsa, pub_key); +OSSL_PKEY_BN(dsa, priv_key); + /* * INIT */ @@ -394,6 +404,12 @@ rb_define_method(cDSA, "syssign", ossl_dsa_sign, 1); rb_define_method(cDSA, "sysverify", ossl_dsa_verify, 2); + DEF_OSSL_PKEY_BN(cDSA, dsa, p); + DEF_OSSL_PKEY_BN(cDSA, dsa, q); + DEF_OSSL_PKEY_BN(cDSA, dsa, g); + DEF_OSSL_PKEY_BN(cDSA, dsa, pub_key); + DEF_OSSL_PKEY_BN(cDSA, dsa, priv_key); + rb_define_method(cDSA, "params", ossl_dsa_get_params, 0); } diff -ur ruby/ext/openssl/ossl_pkey_rsa.c ruby.mod/ext/openssl/ossl_pkey_rsa.c --- ruby/ext/openssl/ossl_pkey_rsa.c 2004-01-08 05:24:22.000000000 -0700 +++ ruby.mod/ext/openssl/ossl_pkey_rsa.c 2004-06-05 21:17:06.000000000 -0600 @@ -119,42 +119,46 @@ VALUE arg, pass; GetPKey(self, pkey); - rb_scan_args(argc, argv, "11", &arg, &pass); - if (FIXNUM_P(arg)) { - rsa = rsa_generate(FIX2INT(arg), NIL_P(pass) ? RSA_F4 : NUM2INT(pass)); - if (!rsa) ossl_raise(eRSAError, NULL); + if( rb_scan_args(argc, argv, "02", &arg, &pass) == 0 ) { + rsa = RSA_new(); } else { - if (!NIL_P(pass)) passwd = StringValuePtr(pass); - arg = ossl_to_der_if_possible(arg); - in = ossl_obj2bio(arg); - rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd); - if (!rsa) { - BIO_reset(in); - rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL); - } - if (!rsa) { - BIO_reset(in); - rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL); - } - if (!rsa) { - BIO_reset(in); - rsa = d2i_RSAPrivateKey_bio(in, NULL); - } - if (!rsa) { - BIO_reset(in); - rsa = d2i_RSAPublicKey_bio(in, NULL); - } - if (!rsa) { - BIO_reset(in); - rsa = d2i_RSA_PUBKEY_bio(in, NULL); - } - BIO_free(in); - if (!rsa) ossl_raise(eRSAError, "Neither PUB key nor PRIV key:"); + if (FIXNUM_P(arg)) { + rsa = rsa_generate(FIX2INT(arg), NIL_P(pass) ? RSA_F4 : NUM2INT(pass)); + if (!rsa) ossl_raise(eRSAError, NULL); + } + else { + if (!NIL_P(pass)) passwd = StringValuePtr(pass); + arg = ossl_to_der_if_possible(arg); + in = ossl_obj2bio(arg); + rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd); + if (!rsa) { + BIO_reset(in); + rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL); + } + if (!rsa) { + BIO_reset(in); + rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL); + } + if (!rsa) { + BIO_reset(in); + rsa = d2i_RSAPrivateKey_bio(in, NULL); + } + if (!rsa) { + BIO_reset(in); + rsa = d2i_RSAPublicKey_bio(in, NULL); + } + if (!rsa) { + BIO_reset(in); + rsa = d2i_RSA_PUBKEY_bio(in, NULL); + } + BIO_free(in); + if (!rsa) ossl_raise(eRSAError, "Neither PUB key nor PRIV key:"); + } } if (!EVP_PKEY_assign_RSA(pkey, rsa)) { - RSA_free(rsa); - ossl_raise(eRSAError, NULL); + RSA_free(rsa); + ossl_raise(eRSAError, NULL); } return self; --------------000506080602020001080008--