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

ruby-changes:65591

From: Kazuki <ko1@a...>
Date: Tue, 16 Mar 2021 20:38:51 +0900 (JST)
Subject: [ruby-changes:65591] b91f62f384 (master): [ruby/openssl] hmac: migrate from the low-level HMAC API to the EVP API

https://git.ruby-lang.org/ruby.git/commit/?id=b91f62f384

From b91f62f3840582bb3e4fbece15654e1d852c829b Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@r...>
Date: Mon, 18 May 2020 16:15:07 +0900
Subject: [ruby/openssl] hmac: migrate from the low-level HMAC API to the EVP
 API

Use the EVP API instead of the low-level HMAC API. Use of the HMAC API
has been discouraged and is being marked as deprecated starting from
OpenSSL 3.0.0.

The two singleton methods OpenSSL::HMAC, HMAC.digest and HMAC.hexdigest
are now in lib/openssl/hmac.rb.

https://github.com/ruby/openssl/commit/0317e2fc02
---
 ext/openssl/extconf.rb          |   3 +-
 ext/openssl/lib/openssl/hmac.rb |  40 +++++++++
 ext/openssl/openssl_missing.c   |  26 ------
 ext/openssl/openssl_missing.h   |  10 +--
 ext/openssl/ossl.h              |   1 -
 ext/openssl/ossl_hmac.c         | 179 +++++++++++-----------------------------
 6 files changed, 89 insertions(+), 170 deletions(-)

diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
index 693e55c..063498a 100644
--- a/ext/openssl/extconf.rb
+++ b/ext/openssl/extconf.rb
@@ -141,8 +141,7 @@ have_func("BN_GENCB_free") https://github.com/ruby/ruby/blob/trunk/ext/openssl/extconf.rb#L141
 have_func("BN_GENCB_get_arg")
 have_func("EVP_MD_CTX_new")
 have_func("EVP_MD_CTX_free")
-have_func("HMAC_CTX_new")
-have_func("HMAC_CTX_free")
+have_func("EVP_MD_CTX_pkey_ctx")
 have_func("X509_STORE_get_ex_data")
 have_func("X509_STORE_set_ex_data")
 have_func("X509_STORE_get_ex_new_index")
diff --git a/ext/openssl/lib/openssl/hmac.rb b/ext/openssl/lib/openssl/hmac.rb
index 3d44276..9bc8bc8 100644
--- a/ext/openssl/lib/openssl/hmac.rb
+++ b/ext/openssl/lib/openssl/hmac.rb
@@ -9,5 +9,45 @@ module OpenSSL https://github.com/ruby/ruby/blob/trunk/ext/openssl/lib/openssl/hmac.rb#L9
 
       OpenSSL.fixed_length_secure_compare(self.digest, other.digest)
     end
+
+    class << self
+      # :call-seq:
+      #    HMAC.digest(digest, key, data) -> aString
+      #
+      # Returns the authentication code as a binary string. The _digest_ parameter
+      # specifies the digest algorithm to use. This may be a String representing
+      # the algorithm name or an instance of OpenSSL::Digest.
+      #
+      # === Example
+      #  key = 'key'
+      #  data = 'The quick brown fox jumps over the lazy dog'
+      #
+      #  hmac = OpenSSL::HMAC.digest('SHA1', key, data)
+      #  #=> "\xDE|\x9B\x85\xB8\xB7\x8A\xA6\xBC\x8Az6\xF7\n\x90p\x1C\x9D\xB4\xD9"
+      def digest(digest, key, data)
+        hmac = new(key, digest)
+        hmac << data
+        hmac.digest
+      end
+
+      # :call-seq:
+      #    HMAC.hexdigest(digest, key, data) -> aString
+      #
+      # Returns the authentication code as a hex-encoded string. The _digest_
+      # parameter specifies the digest algorithm to use. This may be a String
+      # representing the algorithm name or an instance of OpenSSL::Digest.
+      #
+      # === Example
+      #  key = 'key'
+      #  data = 'The quick brown fox jumps over the lazy dog'
+      #
+      #  hmac = OpenSSL::HMAC.hexdigest('SHA1', key, data)
+      #  #=> "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"
+      def hexdigest(digest, key, data)
+        hmac = new(key, digest)
+        hmac << data
+        hmac.hexdigest
+      end
+    end
   end
 end
diff --git a/ext/openssl/openssl_missing.c b/ext/openssl/openssl_missing.c
index b36ef02..010c158 100644
--- a/ext/openssl/openssl_missing.c
+++ b/ext/openssl/openssl_missing.c
@@ -13,9 +13,6 @@ https://github.com/ruby/ruby/blob/trunk/ext/openssl/openssl_missing.c#L13
 #if !defined(OPENSSL_NO_ENGINE)
 # include <openssl/engine.h>
 #endif
-#if !defined(OPENSSL_NO_HMAC)
-# include <openssl/hmac.h>
-#endif
 #include <openssl/x509_vfy.h>
 
 #include "openssl_missing.h"
@@ -58,29 +55,6 @@ ossl_EC_curve_nist2nid(const char *name) https://github.com/ruby/ruby/blob/trunk/ext/openssl/openssl_missing.c#L55
 #endif
 
 /*** added in 1.1.0 ***/
-#if !defined(HAVE_HMAC_CTX_NEW)
-HMAC_CTX *
-ossl_HMAC_CTX_new(void)
-{
-    HMAC_CTX *ctx = OPENSSL_malloc(sizeof(HMAC_CTX));
-    if (!ctx)
-	return NULL;
-    HMAC_CTX_init(ctx);
-    return ctx;
-}
-#endif
-
-#if !defined(HAVE_HMAC_CTX_FREE)
-void
-ossl_HMAC_CTX_free(HMAC_CTX *ctx)
-{
-    if (ctx) {
-	HMAC_CTX_cleanup(ctx);
-	OPENSSL_free(ctx);
-    }
-}
-#endif
-
 #if !defined(HAVE_X509_CRL_GET0_SIGNATURE)
 void
 ossl_X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig,
diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h
index 7d218f8..06d2a90 100644
--- a/ext/openssl/openssl_missing.h
+++ b/ext/openssl/openssl_missing.h
@@ -54,14 +54,8 @@ int ossl_EC_curve_nist2nid(const char *); https://github.com/ruby/ruby/blob/trunk/ext/openssl/openssl_missing.h#L54
 #  define EVP_MD_CTX_free EVP_MD_CTX_destroy
 #endif
 
-#if !defined(HAVE_HMAC_CTX_NEW)
-HMAC_CTX *ossl_HMAC_CTX_new(void);
-#  define HMAC_CTX_new ossl_HMAC_CTX_new
-#endif
-
-#if !defined(HAVE_HMAC_CTX_FREE)
-void ossl_HMAC_CTX_free(HMAC_CTX *);
-#  define HMAC_CTX_free ossl_HMAC_CTX_free
+#if !defined(HAVE_EVP_MD_CTX_PKEY_CTX)
+#  define EVP_MD_CTX_pkey_ctx(x) (x)->pctx
 #endif
 
 #if !defined(HAVE_X509_STORE_GET_EX_DATA)
diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h
index c20f506..577eb6d 100644
--- a/ext/openssl/ossl.h
+++ b/ext/openssl/ossl.h
@@ -24,7 +24,6 @@ https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl.h#L24
 #include <openssl/ssl.h>
 #include <openssl/pkcs12.h>
 #include <openssl/pkcs7.h>
-#include <openssl/hmac.h>
 #include <openssl/rand.h>
 #include <openssl/conf.h>
 #ifndef OPENSSL_NO_TS
diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c
index 70e9fb8..a21db6c 100644
--- a/ext/openssl/ossl_hmac.c
+++ b/ext/openssl/ossl_hmac.c
@@ -7,14 +7,12 @@ https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_hmac.c#L7
  * This program is licensed under the same licence as Ruby.
  * (See the file 'LICENCE'.)
  */
-#if !defined(OPENSSL_NO_HMAC)
-
 #include "ossl.h"
 
 #define NewHMAC(klass) \
     TypedData_Wrap_Struct((klass), &ossl_hmac_type, 0)
 #define GetHMAC(obj, ctx) do { \
-    TypedData_Get_Struct((obj), HMAC_CTX, &ossl_hmac_type, (ctx)); \
+    TypedData_Get_Struct((obj), EVP_MD_CTX, &ossl_hmac_type, (ctx)); \
     if (!(ctx)) { \
 	ossl_raise(rb_eRuntimeError, "HMAC wasn't initialized"); \
     } \
@@ -36,7 +34,7 @@ VALUE eHMACError; https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_hmac.c#L34
 static void
 ossl_hmac_free(void *ctx)
 {
-    HMAC_CTX_free(ctx);
+    EVP_MD_CTX_free(ctx);
 }
 
 static const rb_data_type_t ossl_hmac_type = {
@@ -51,12 +49,12 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_hmac.c#L49
 ossl_hmac_alloc(VALUE klass)
 {
     VALUE obj;
-    HMAC_CTX *ctx;
+    EVP_MD_CTX *ctx;
 
     obj = NewHMAC(klass);
-    ctx = HMAC_CTX_new();
+    ctx = EVP_MD_CTX_new();
     if (!ctx)
-	ossl_raise(eHMACError, NULL);
+        ossl_raise(eHMACError, "EVP_MD_CTX");
     RTYPEDDATA_DATA(obj) = ctx;
 
     return obj;
@@ -76,8 +74,7 @@ ossl_hmac_alloc(VALUE klass) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_hmac.c#L74
  * === Example
  *
  *	key = 'key'
- * 	digest = OpenSSL::Digest.new('sha1')
- * 	instance = OpenSSL::HMAC.new(key, digest)
+ * 	instance = OpenSSL::HMAC.new(key, 'SHA1')
  * 	#=> f42bb0eeb018ebbd4597ae7213711ec60760843f
  * 	instance.class
  * 	#=> OpenSSL::HMAC
@@ -86,7 +83,7 @@ ossl_hmac_alloc(VALUE klass) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_hmac.c#L83
  *
  * Two instances can be securely compared with #== in constant time:
  *
- *	other_instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
+ *	other_instance = OpenSSL::HMAC.new('key', 'SHA1')
  *  #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
  *  instance == other_instance
  *  #=> true
@@ -95,12 +92,23 @@ ossl_hmac_alloc(VALUE klass) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_hmac.c#L92
 static VALUE
 ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
 {
-    HMAC_CTX *ctx;
+    EVP_MD_CTX *ctx;
+    EVP_PKEY *pkey;
 
-    StringValue(key);
     GetHMAC(self, ctx);
-    HMAC_Init_ex(ctx, RSTRING_PTR(key), RSTRING_LENINT(key),
-		 ossl_evp_get_digestbyname(digest), NULL);
+    StringValue(key);
+    pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
+                                (unsigned char *)RSTRING_PTR(key),
+                                RSTRING_LENINT(key));
+    if (!pkey)
+        ossl_raise(eHMACError, "EVP_PKEY_new_mac_key");
+    if (EVP_DigestSignInit(ctx, NULL, ossl_evp_get_digestbyname(digest),
+                           NULL, pkey) != 1) {
+        EVP_PKEY_free(pkey);
+        ossl_raise(eHMACError, "EVP_DigestSignInit");
+    }
+    /* Decrement reference counter; EVP_MD_CTX still keeps it */
+    EVP_PKEY_free(pkey);
 
     return self;
 }
@@ -108,16 +116,15 @@ ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_hmac.c#L116
 static VALUE
 ossl_hmac_copy(VALUE self, VALUE other)
 {
-    HMAC_CTX *ctx1, *ctx2;
+    EVP_MD_CTX *ctx1, *ctx2;
 
     rb_check_frozen(self);
     if (self == other) return self;
 
     GetHMAC(self, ctx1);
     GetHMAC(other, ctx2);
-
-    if (!HMAC_CTX_copy(ctx1, ctx2))
-	ossl_raise(eHMACError, "HMAC_CTX_copy");
+    if (EVP_MD_CTX_copy(ctx1, ctx2) != 1)
+        ossl_raise(eHMACError, "EVP_MD_CTX_copy");
     return self;
 }
 
@@ -142,33 +149,16 @@ ossl_hmac_copy(VALUE self, VALUE other) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_hmac.c#L149
 static VALUE
 ossl_hmac_update(VALUE self, VALUE data)
 {
-    HMAC_CTX *ctx;
+    EVP_MD_CTX *ctx;
 
     StringValue(data);
     GetHMAC(self, ctx);
-    HMAC_Update(ctx, (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data));
+    if (EVP_DigestSignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1)
+        ossl_raise(eHMACError, "EVP_DigestSignUpdate");
 
     return self;
 }
 
-static void
-hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len)
-{
-    HMAC_CTX *final;
-
-     (... truncated)

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

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