ruby-changes:43101
From: rhe <ko1@a...>
Date: Thu, 26 May 2016 14:25:02 +0900 (JST)
Subject: [ruby-changes:43101] rhe:r55175 (trunk): openssl: avoid NULL dereference in {DH, DSA, RSA}_size()
rhe 2016-05-26 14:24:58 +0900 (Thu, 26 May 2016) New Revision: 55175 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=55175 Log: openssl: avoid NULL dereference in {DH,DSA,RSA}_size() * ext/openssl/ossl_pkey_dh.c (ossl_dh_compute_key): Check that the DH has 'p' (the prime) before calling DH_size(). We can create a DH with no parameter but DH_size() does not check and dereferences NULL. [ruby-core:75720] [Bug #12428] * ext/openssl/ossl_pkey_dsa.c (ossl_dsa_sign): Ditto. DSA_size() does not check dsa->q. * ext/openssl/ossl_pkey_rsa.c (ossl_rsa_public_encrypt, ossl_rsa_public_decrypt, ossl_rsa_private_encrypt, ossl_rsa_private_decrypt): Ditto. RSA_size() does not check rsa->n. Modified files: trunk/ChangeLog trunk/ext/openssl/ossl_pkey_dh.c trunk/ext/openssl/ossl_pkey_dsa.c trunk/ext/openssl/ossl_pkey_rsa.c Index: ext/openssl/ossl_pkey_rsa.c =================================================================== --- ext/openssl/ossl_pkey_rsa.c (revision 55174) +++ ext/openssl/ossl_pkey_rsa.c (revision 55175) @@ -382,6 +382,8 @@ ossl_rsa_public_encrypt(int argc, VALUE https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_pkey_rsa.c#L382 VALUE str, buffer, padding; GetPKeyRSA(self, pkey); + if (!pkey->pkey.rsa->n) + ossl_raise(eRSAError, "incomplete RSA"); rb_scan_args(argc, argv, "11", &buffer, &padding); pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding); StringValue(buffer); @@ -411,6 +413,8 @@ ossl_rsa_public_decrypt(int argc, VALUE https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_pkey_rsa.c#L413 VALUE str, buffer, padding; GetPKeyRSA(self, pkey); + if (!pkey->pkey.rsa->n) + ossl_raise(eRSAError, "incomplete RSA"); rb_scan_args(argc, argv, "11", &buffer, &padding); pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding); StringValue(buffer); @@ -440,9 +444,10 @@ ossl_rsa_private_encrypt(int argc, VALUE https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_pkey_rsa.c#L444 VALUE str, buffer, padding; GetPKeyRSA(self, pkey); - if (!RSA_PRIVATE(self, pkey->pkey.rsa)) { - ossl_raise(eRSAError, "private key needed."); - } + if (!pkey->pkey.rsa->n) + ossl_raise(eRSAError, "incomplete RSA"); + if (!RSA_PRIVATE(self, pkey->pkey.rsa)) + ossl_raise(eRSAError, "private key needed"); rb_scan_args(argc, argv, "11", &buffer, &padding); pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding); StringValue(buffer); @@ -472,9 +477,10 @@ ossl_rsa_private_decrypt(int argc, VALUE https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_pkey_rsa.c#L477 VALUE str, buffer, padding; GetPKeyRSA(self, pkey); - if (!RSA_PRIVATE(self, pkey->pkey.rsa)) { - ossl_raise(eRSAError, "private key needed."); - } + if (!pkey->pkey.rsa->n) + ossl_raise(eRSAError, "incomplete RSA"); + if (!RSA_PRIVATE(self, pkey->pkey.rsa)) + ossl_raise(eRSAError, "private key needed"); rb_scan_args(argc, argv, "11", &buffer, &padding); pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding); StringValue(buffer); Index: ext/openssl/ossl_pkey_dh.c =================================================================== --- ext/openssl/ossl_pkey_dh.c (revision 55174) +++ ext/openssl/ossl_pkey_dh.c (revision 55175) @@ -501,6 +501,8 @@ ossl_dh_compute_key(VALUE self, VALUE pu https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_pkey_dh.c#L501 GetPKeyDH(self, pkey); dh = pkey->pkey.dh; + if (!dh->p) + ossl_raise(eDHError, "incomplete DH"); pub_key = GetBNPtr(pub); len = DH_size(dh); str = rb_str_new(0, len); Index: ext/openssl/ossl_pkey_dsa.c =================================================================== --- ext/openssl/ossl_pkey_dsa.c (revision 55174) +++ ext/openssl/ossl_pkey_dsa.c (revision 55175) @@ -488,10 +488,11 @@ ossl_dsa_sign(VALUE self, VALUE data) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_pkey_dsa.c#L488 VALUE str; GetPKeyDSA(self, pkey); - StringValue(data); - if (!DSA_PRIVATE(self, pkey->pkey.dsa)) { + if (!pkey->pkey.dsa->q) + ossl_raise(eDSAError, "incomplete DSA"); + if (!DSA_PRIVATE(self, pkey->pkey.dsa)) ossl_raise(eDSAError, "Private DSA key needed!"); - } + StringValue(data); str = rb_str_new(0, ossl_dsa_buf_size(pkey)); if (!DSA_sign(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *)RSTRING_PTR(str), Index: ChangeLog =================================================================== --- ChangeLog (revision 55174) +++ ChangeLog (revision 55175) @@ -1,3 +1,17 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Thu May 26 14:21:10 2016 Kazuki Yamaguchi <k@r...> + + * ext/openssl/ossl_pkey_dh.c (ossl_dh_compute_key): Check that the DH + has 'p' (the prime) before calling DH_size(). We can create a DH with + no parameter but DH_size() does not check and dereferences NULL. + [ruby-core:75720] [Bug #12428] + + * ext/openssl/ossl_pkey_dsa.c (ossl_dsa_sign): Ditto. DSA_size() does + not check dsa->q. + + * ext/openssl/ossl_pkey_rsa.c (ossl_rsa_public_encrypt, + ossl_rsa_public_decrypt, ossl_rsa_private_encrypt, + ossl_rsa_private_decrypt): Ditto. RSA_size() does not check rsa->n. + Thu May 26 14:13:52 2016 Nobuyoshi Nakada <nobu@r...> * include/ruby/ruby.h (rb_scan_args_count): verify length with -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/