summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authoremboss <emboss@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-05-11 23:05:29 +0000
committeremboss <emboss@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-05-11 23:05:29 +0000
commitf14d97e1c0ce23412c2612085feda5d92db44f20 (patch)
tree501228ce2dcb869f9b04ab456519cf907d6a4c47 /ext
parent615e7987ca619a9d8df01844b61d95796b95fd19 (diff)
Thu May 12 08:01:14 2011 Martin Bosslet <Martin.Bosslet@googlemail.com>
* ext/openssl/ossl_pkey_ec.c: Allow encryption when PEM-encoding Elliptic Curve private keys. [ruby-core:35329] [Bug #4423] Previous revision: 31525 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31526 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext')
-rw-r--r--ext/openssl/ossl_pkey_ec.c63
1 files changed, 31 insertions, 32 deletions
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c
index 4e084b08d95..51864c80c6b 100644
--- a/ext/openssl/ossl_pkey_ec.c
+++ b/ext/openssl/ossl_pkey_ec.c
@@ -152,6 +152,7 @@ VALUE ossl_ec_new(EVP_PKEY *pkey)
* OpenSSL::PKey::EC.new(ec_group)
* OpenSSL::PKey::EC.new("secp112r1")
* OpenSSL::PKey::EC.new(pem_string)
+ * OpenSSL::PKey::EC.new(pem_string [, pwd])
* OpenSSL::PKey::EC.new(der_string)
*
* See the OpenSSL documentation for:
@@ -163,6 +164,7 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
EC_KEY *ec = NULL;
VALUE arg, pass;
VALUE group = Qnil;
+ char *passwd = NULL;
GetPKey(self, pkey);
if (pkey->pkey.ec)
@@ -184,11 +186,14 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
} else {
BIO *in = ossl_obj2bio(arg);
- ec = PEM_read_bio_ECPrivateKey(in, NULL, NULL, NULL);
+ if (!NIL_P(pass)) {
+ passwd = StringValuePtr(pass);
+ }
+ ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
if (!ec) {
(void)BIO_reset(in);
(void)ERR_get_error();
- ec = PEM_read_bio_EC_PUBKEY(in, NULL, NULL, NULL);
+ ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, passwd);
}
if (!ec) {
(void)BIO_reset(in);
@@ -461,16 +466,13 @@ static VALUE ossl_ec_key_is_private_key(VALUE self)
return (EC_KEY_get0_private_key(ec) ? Qtrue : Qfalse);
}
-static VALUE ossl_ec_key_to_string(VALUE self, int format)
+static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int format)
{
EC_KEY *ec;
BIO *out;
int i = -1;
int private = 0;
-#if 0 /* unused now */
- EVP_CIPHER *cipher = NULL;
char *password = NULL;
-#endif
VALUE str;
Require_EC_KEY(self, ec);
@@ -490,37 +492,26 @@ static VALUE ossl_ec_key_to_string(VALUE self, int format)
switch(format) {
case EXPORT_PEM:
if (private) {
-#if 0 /* unused now */
- if (cipher || password)
-/* BUG: finish cipher/password key export */
- rb_notimplement();
+ const EVP_CIPHER *cipher;
+ if (!NIL_P(ciph)) {
+ cipher = GetCipherPtr(ciph);
+ if (!NIL_P(pass)) {
+ password = StringValuePtr(pass);
+ }
+ }
+ else {
+ cipher = NULL;
+ }
i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, NULL, password);
-#endif
- i = PEM_write_bio_ECPrivateKey(out, ec, NULL, NULL, 0, NULL, NULL);
} else {
-#if 0 /* unused now */
- if (cipher || password)
- rb_raise(rb_eArgError, "encryption is not supported when exporting this key type");
-#endif
-
i = PEM_write_bio_EC_PUBKEY(out, ec);
}
break;
case EXPORT_DER:
if (private) {
-#if 0 /* unused now */
- if (cipher || password)
- rb_raise(rb_eArgError, "encryption is not supported when exporting this key type");
-#endif
-
i = i2d_ECPrivateKey_bio(out, ec);
} else {
-#if 0 /* unused now */
- if (cipher || password)
- rb_raise(rb_eArgError, "encryption is not supported when exporting this key type");
-#endif
-
i = i2d_EC_PUBKEY_bio(out, ec);
}
@@ -543,12 +534,20 @@ static VALUE ossl_ec_key_to_string(VALUE self, int format)
/*
* call-seq:
* key.to_pem => String
+ * key.to_pem(cipher, pass_phrase) => String
+ *
+ * Outputs the EC key in PEM encoding. If +cipher+ and +pass_phrase+ are
+ * given they will be used to encrypt the key. +cipher+ must be an
+ * OpenSSL::Cipher::Cipher instance. Note that encryption will only be
+ * effective for a private key, public keys will always be encoded in plain
+ * text.
*
- * See the OpenSSL documentation for PEM_write_bio_ECPrivateKey()
*/
-static VALUE ossl_ec_key_to_pem(VALUE self)
+static VALUE ossl_ec_key_to_pem(int argc, VALUE *argv, VALUE self)
{
- return ossl_ec_key_to_string(self, EXPORT_PEM);
+ VALUE cipher, passwd;
+ rb_scan_args(argc, argv, "02", &cipher, &passwd);
+ return ossl_ec_key_to_string(self, cipher, passwd, EXPORT_PEM);
}
/*
@@ -559,7 +558,7 @@ static VALUE ossl_ec_key_to_pem(VALUE self)
*/
static VALUE ossl_ec_key_to_der(VALUE self)
{
- return ossl_ec_key_to_string(self, EXPORT_DER);
+ return ossl_ec_key_to_string(self, Qnil, Qnil, EXPORT_DER);
}
/*
@@ -1530,7 +1529,7 @@ void Init_ossl_ec()
rb_define_method(cEC, "dsa_verify_asn1", ossl_ec_key_dsa_verify_asn1, 2);
/* do_sign/do_verify */
- rb_define_method(cEC, "to_pem", ossl_ec_key_to_pem, 0);
+ rb_define_method(cEC, "to_pem", ossl_ec_key_to_pem, -1);
rb_define_method(cEC, "to_der", ossl_ec_key_to_der, 0);
rb_define_method(cEC, "to_text", ossl_ec_key_to_text, 0);