[前][次][番号順一覧][スレッド一覧]

ruby-changes:19514

From: emboss <ko1@a...>
Date: Sat, 14 May 2011 04:25:27 +0900 (JST)
Subject: [ruby-changes:19514] emboss:r31554 (trunk): * NEWS: Describe altered behaviour for RSA and DSA public key

emboss	2011-05-14 04:25:18 +0900 (Sat, 14 May 2011)

  New Revision: 31554

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=31554

  Log:
    * NEWS: Describe altered behaviour for RSA and DSA public key
    encoding. [Ruby 1.9 - Bug #4421, Bug #4422]
    [ruby-core:35327,35328]
    
    Previous revision: 31553

  Modified files:
    trunk/ChangeLog
    trunk/NEWS
    trunk/ext/openssl/ossl_digest.c
    trunk/ext/openssl/ossl_pkey.c
    trunk/ext/openssl/ossl_pkey.h
    trunk/test/openssl/test_pkey_rsa.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 31553)
+++ ChangeLog	(revision 31554)
@@ -1,3 +1,9 @@
+Sat May 14 04:19:06 2011  Martin Bosslet  <Martin.Bosslet@g...>
+
+	* NEWS: Describe altered behaviour for RSA and DSA public key
+	encoding. [Ruby 1.9 - Bug #4421, Bug #4422]
+	[ruby-core:35327,35328]
+
 Sat May 14 02:57:52 2011  Eric Hodel  <drbrain@s...>
 
 	* lib/ipaddr.rb (unless Socket):  Document valid*? methods.  Patch by
Index: ext/openssl/ossl_digest.c
===================================================================
--- ext/openssl/ossl_digest.c	(revision 31553)
+++ ext/openssl/ossl_digest.c	(revision 31554)
@@ -239,6 +239,8 @@
     mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
 #endif
 
+    /* Allows you to compute cryptographic hashes of arbitrary data. 
+     */
     cDigest = rb_define_class_under(mOSSL, "Digest", rb_path2class("Digest::Class"));
     eDigestError = rb_define_class_under(cDigest, "DigestError", eOSSLError);
 
Index: ext/openssl/ossl_pkey.c
===================================================================
--- ext/openssl/ossl_pkey.c	(revision 31553)
+++ ext/openssl/ossl_pkey.c	(revision 31554)
@@ -18,6 +18,9 @@
 VALUE ePKeyError;
 ID id_private_q;
 
+#define reset_bio(b)		(void)BIO_reset((b)); \
+				(void)ERR_get_error();
+
 /*
  * callback for generating keys
  */
@@ -65,23 +68,50 @@
     return Qnil; /* not reached */
 }
 
-VALUE
-ossl_pkey_new_from_file(VALUE filename)
+/*
+ *  call-seq:
+ *     OpenSSL::PKey.read(string [, pwd ] ) -> PKey
+ *     OpenSSL::PKey.read(file [, pwd ]) -> PKey
+ *
+ *  === Parameters
+ *  * +string+ is a DER- or PEM-encoded string containing an arbitrary private
+ *             or public key.
+ *  * +file+ is an instance of +File+ containing a DER- or PEM-encoded
+ *	     arbitrary private or public key.
+ *  * +pwd+ is an optional password in case +string+ or +file+ is an encrypted
+ *          PEM resource.
+ */
+VALUE 
+ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
 {
-    FILE *fp;
     EVP_PKEY *pkey;
+    BIO *bio;
+    VALUE data, pass;
+    char *passwd = NULL;
 
-    SafeStringValue(filename);
-    if (!(fp = fopen(RSTRING_PTR(filename), "r"))) {
-	ossl_raise(ePKeyError, "%s", strerror(errno));
-    }
+    rb_scan_args(argc, argv, "11", &data, &pass);
 
-    pkey = PEM_read_PrivateKey(fp, NULL, ossl_pem_passwd_cb, NULL);
-    fclose(fp);
-    if (!pkey) {
-	ossl_raise(ePKeyError, NULL);
+    bio = ossl_obj2bio(data);
+    if (!(pkey = d2i_PrivateKey_bio(bio, NULL))) {
+	reset_bio(bio);
+	if (!NIL_P(pass)) {
+	    passwd = StringValuePtr(pass);
+	}
+	if (!(pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, passwd))) {
+	    reset_bio(bio);
+	    if (!(pkey = d2i_PUBKEY_bio(bio, NULL))) {
+		reset_bio(bio);
+		if (!NIL_P(pass)) {
+		    passwd = StringValuePtr(pass);
+		}
+		pkey = PEM_read_bio_PUBKEY(bio, NULL, ossl_pem_passwd_cb, passwd);
+	    }
+	}
     }
-
+    
+    BIO_free(bio);
+    if (!pkey)
+	ossl_raise(rb_eArgError, "Could not parse PKey");
     return ossl_pkey_new(pkey);
 }
 
@@ -221,6 +251,8 @@
 
     cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject);
 
+    rb_define_module_function(mPKey, "read", ossl_pkey_new_from_data, -1);
+
     rb_define_alloc_func(cPKey, ossl_pkey_alloc);
     rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0);
 
Index: ext/openssl/ossl_pkey.h
===================================================================
--- ext/openssl/ossl_pkey.h	(revision 31553)
+++ ext/openssl/ossl_pkey.h	(revision 31554)
@@ -41,7 +41,7 @@
 void ossl_generate_cb(int, int, void *);
 
 VALUE ossl_pkey_new(EVP_PKEY *);
-VALUE ossl_pkey_new_from_file(VALUE);
+VALUE ossl_pkey_new_from_data(int, VALUE *, VALUE);
 EVP_PKEY *GetPKeyPtr(VALUE);
 EVP_PKEY *DupPKeyPtr(VALUE);
 EVP_PKEY *GetPrivPKeyPtr(VALUE);
Index: NEWS
===================================================================
--- NEWS	(revision 31553)
+++ NEWS	(revision 31554)
@@ -98,6 +98,12 @@
 * net/http
   * SNI (Server Name Indication) supported for HTTPS. 
 
+* openssl
+  * PKey::RSA and PKey::DSA now use the generic X.509 encoding scheme 
+    (e.g. used in a X.509 certificate's Subject Public Key Info) when
+    exporting public keys to DER or PEM. Backward compatibility is 
+    ensured by (already existing) fallbacks during creation.
+
 * optparse
   * support for bash/zsh completion.
 
Index: test/openssl/test_pkey_rsa.rb
===================================================================
--- test/openssl/test_pkey_rsa.rb	(revision 31553)
+++ test/openssl/test_pkey_rsa.rb	(revision 31554)
@@ -46,6 +46,48 @@
     OpenSSL::PKey::RSA.new pem
     assert_equal([], OpenSSL.errors)
   end
+
+  def test_read_private_key_der
+    der = OpenSSL::TestUtils::TEST_KEY_RSA1024.to_der
+    key = OpenSSL::PKey.read(der)
+    assert(key.private?)
+    assert_equal(der, key.to_der)
+  end
+
+  def test_read_private_key_pem
+    pem = OpenSSL::TestUtils::TEST_KEY_RSA1024.to_pem
+    key = OpenSSL::PKey.read(pem)
+    assert(key.private?)
+    assert_equal(pem, key.to_pem)
+  end
+
+  def test_read_public_key_der
+    der = OpenSSL::TestUtils::TEST_KEY_RSA1024.public_key.to_der
+    key = OpenSSL::PKey.read(der)
+    assert(!key.private?)
+    assert_equal(der, key.to_der)
+  end
+
+  def test_read_public_key_pem
+    pem = OpenSSL::TestUtils::TEST_KEY_RSA1024.public_key.to_pem
+    key = OpenSSL::PKey.read(pem)
+    assert(!key.private?)
+    assert_equal(pem, key.to_pem)
+  end
+
+  def test_read_private_key_pem_pw
+    pem = OpenSSL::TestUtils::TEST_KEY_RSA1024.to_pem(OpenSSL::Cipher.new('AES-128-CBC'), 'secret')
+    #callback form for password
+    key = OpenSSL::PKey.read(pem) do
+      'secret'
+    end
+    assert(key.private?)
+    # pass password directly
+    key = OpenSSL::PKey.read(pem, 'secret')
+    assert(key.private?)
+    #omit pem equality check, will be different due to cipher iv
+  end
+
 end
 
 end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]