2022-01-25 16:32:16 +00:00
|
|
|
From 8253d7c9cea16c2aa009b59db4f5d93afb74c6eb Mon Sep 17 00:00:00 2001
|
|
|
|
From: Kazuki Yamaguchi <k@rhe.jp>
|
|
|
|
Date: Tue, 30 Jun 2020 14:27:13 +0900
|
|
|
|
Subject: [PATCH 1/2] hmac: add a test case for OpenSSL::HMAC singleton methods
|
|
|
|
|
|
|
|
---
|
|
|
|
test/openssl/test_hmac.rb | 9 +++++++++
|
|
|
|
1 file changed, 9 insertions(+)
|
|
|
|
|
|
|
|
diff --git a/test/openssl/test_hmac.rb b/test/openssl/test_hmac.rb
|
|
|
|
index 9cb3c5a86..7202a5902 100644
|
|
|
|
--- a/test/openssl/test_hmac.rb
|
|
|
|
+++ b/test/openssl/test_hmac.rb
|
|
|
|
@@ -49,6 +49,15 @@ def test_eq
|
|
|
|
refute_equal h1, h2.digest
|
|
|
|
refute_equal h1, h3
|
|
|
|
end
|
|
|
|
+
|
|
|
|
+ def test_singleton_methods
|
|
|
|
+ # RFC 2202 2. Test Cases for HMAC-MD5
|
|
|
|
+ key = ["0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"].pack("H*")
|
|
|
|
+ digest = OpenSSL::HMAC.digest("MD5", key, "Hi There")
|
|
|
|
+ assert_equal ["9294727a3638bb1c13f48ef8158bfc9d"].pack("H*"), digest
|
|
|
|
+ hexdigest = OpenSSL::HMAC.hexdigest("MD5", key, "Hi There")
|
|
|
|
+ assert_equal "9294727a3638bb1c13f48ef8158bfc9d", hexdigest
|
|
|
|
+ end
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
From 0317e2fc028be40a7d64d0e4337d3e21539613ce Mon Sep 17 00:00:00 2001
|
|
|
|
From: Kazuki Yamaguchi <k@rhe.jp>
|
|
|
|
Date: Mon, 18 May 2020 16:15:07 +0900
|
|
|
|
Subject: [PATCH 2/2] 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.
|
|
|
|
---
|
|
|
|
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 693e55cd9..063498a76 100644
|
|
|
|
--- a/ext/openssl/extconf.rb
|
|
|
|
+++ b/ext/openssl/extconf.rb
|
2024-04-30 13:10:59 +00:00
|
|
|
@@ -148,8 +148,7 @@ def find_openssl_library
|
2022-01-25 16:32:16 +00:00
|
|
|
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 3d4427611d..9bc8bc8df3 100644
|
|
|
|
--- a/ext/openssl/lib/openssl/hmac.rb
|
|
|
|
+++ b/ext/openssl/lib/openssl/hmac.rb
|
|
|
|
@@ -9,5 +9,45 @@ def ==(other)
|
|
|
|
|
|
|
|
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 b36ef0288..010c158dc 100644
|
|
|
|
--- a/ext/openssl/openssl_missing.c
|
|
|
|
+++ b/ext/openssl/openssl_missing.c
|
|
|
|
@@ -13,9 +13,6 @@
|
|
|
|
#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)
|
|
|
|
#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 7d218f86f..06d2a9082 100644
|
|
|
|
--- a/ext/openssl/openssl_missing.h
|
|
|
|
+++ b/ext/openssl/openssl_missing.h
|
|
|
|
@@ -54,14 +54,8 @@ int ossl_EC_curve_nist2nid(const char *);
|
|
|
|
# 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 c20f506bd..577eb6d6b 100644
|
|
|
|
--- a/ext/openssl/ossl.h
|
|
|
|
+++ b/ext/openssl/ossl.h
|
|
|
|
@@ -24,7 +24,6 @@
|
|
|
|
#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 70e9fb819..a21db6c48 100644
|
|
|
|
--- a/ext/openssl/ossl_hmac.c
|
|
|
|
+++ b/ext/openssl/ossl_hmac.c
|
|
|
|
@@ -7,14 +7,12 @@
|
|
|
|
* 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;
|
|
|
|
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
|
|
|
|
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)
|
|
|
|
* === 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)
|
|
|
|
*
|
|
|
|
* 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)
|
|
|
|
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)
|
|
|
|
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)
|
|
|
|
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;
|
|
|
|
-
|
|
|
|
- final = HMAC_CTX_new();
|
|
|
|
- if (!final)
|
|
|
|
- ossl_raise(eHMACError, "HMAC_CTX_new");
|
|
|
|
-
|
|
|
|
- if (!HMAC_CTX_copy(final, ctx)) {
|
|
|
|
- HMAC_CTX_free(final);
|
|
|
|
- ossl_raise(eHMACError, "HMAC_CTX_copy");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- HMAC_Final(final, buf, buf_len);
|
|
|
|
- HMAC_CTX_free(final);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* hmac.digest -> string
|
|
|
|
@@ -176,7 +166,7 @@ hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len)
|
|
|
|
* Returns the authentication code an instance represents as a binary string.
|
|
|
|
*
|
|
|
|
* === Example
|
|
|
|
- * instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
|
|
|
|
+ * instance = OpenSSL::HMAC.new('key', 'SHA1')
|
|
|
|
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
|
|
|
* instance.digest
|
|
|
|
* #=> "\xF4+\xB0\xEE\xB0\x18\xEB\xBDE\x97\xAEr\x13q\x1E\xC6\a`\x84?"
|
|
|
|
@@ -184,15 +174,16 @@ hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len)
|
|
|
|
static VALUE
|
|
|
|
ossl_hmac_digest(VALUE self)
|
|
|
|
{
|
|
|
|
- HMAC_CTX *ctx;
|
|
|
|
- unsigned int buf_len;
|
|
|
|
+ EVP_MD_CTX *ctx;
|
|
|
|
+ size_t buf_len;
|
|
|
|
VALUE ret;
|
|
|
|
|
|
|
|
GetHMAC(self, ctx);
|
|
|
|
ret = rb_str_new(NULL, EVP_MAX_MD_SIZE);
|
|
|
|
- hmac_final(ctx, (unsigned char *)RSTRING_PTR(ret), &buf_len);
|
|
|
|
- assert(buf_len <= EVP_MAX_MD_SIZE);
|
|
|
|
- rb_str_set_len(ret, buf_len);
|
|
|
|
+ if (EVP_DigestSignFinal(ctx, (unsigned char *)RSTRING_PTR(ret),
|
|
|
|
+ &buf_len) != 1)
|
|
|
|
+ ossl_raise(eHMACError, "EVP_DigestSignFinal");
|
|
|
|
+ rb_str_set_len(ret, (long)buf_len);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
@@ -207,13 +198,14 @@ ossl_hmac_digest(VALUE self)
|
|
|
|
static VALUE
|
|
|
|
ossl_hmac_hexdigest(VALUE self)
|
|
|
|
{
|
|
|
|
- HMAC_CTX *ctx;
|
|
|
|
+ EVP_MD_CTX *ctx;
|
|
|
|
unsigned char buf[EVP_MAX_MD_SIZE];
|
|
|
|
- unsigned int buf_len;
|
|
|
|
+ size_t buf_len;
|
|
|
|
VALUE ret;
|
|
|
|
|
|
|
|
GetHMAC(self, ctx);
|
|
|
|
- hmac_final(ctx, buf, &buf_len);
|
|
|
|
+ if (EVP_DigestSignFinal(ctx, buf, &buf_len) != 1)
|
|
|
|
+ ossl_raise(eHMACError, "EVP_DigestSignFinal");
|
|
|
|
ret = rb_str_new(NULL, buf_len * 2);
|
|
|
|
ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len);
|
|
|
|
|
|
|
|
@@ -230,7 +222,7 @@ ossl_hmac_hexdigest(VALUE self)
|
|
|
|
* === Example
|
|
|
|
*
|
|
|
|
* data = "The quick brown fox jumps over the lazy dog"
|
|
|
|
- * instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
|
|
|
|
+ * instance = OpenSSL::HMAC.new('key', 'SHA1')
|
|
|
|
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
|
|
|
*
|
|
|
|
* instance.update(data)
|
|
|
|
@@ -242,84 +234,17 @@ ossl_hmac_hexdigest(VALUE self)
|
|
|
|
static VALUE
|
|
|
|
ossl_hmac_reset(VALUE self)
|
|
|
|
{
|
|
|
|
- HMAC_CTX *ctx;
|
|
|
|
+ EVP_MD_CTX *ctx;
|
|
|
|
+ EVP_PKEY *pkey;
|
|
|
|
|
|
|
|
GetHMAC(self, ctx);
|
|
|
|
- HMAC_Init_ex(ctx, NULL, 0, NULL, NULL);
|
|
|
|
+ pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx));
|
|
|
|
+ if (EVP_DigestSignInit(ctx, NULL, EVP_MD_CTX_md(ctx), NULL, pkey) != 1)
|
|
|
|
+ ossl_raise(eHMACError, "EVP_DigestSignInit");
|
|
|
|
|
|
|
|
return 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"
|
|
|
|
- *
|
|
|
|
- */
|
|
|
|
-static VALUE
|
|
|
|
-ossl_hmac_s_digest(VALUE klass, VALUE digest, VALUE key, VALUE data)
|
|
|
|
-{
|
|
|
|
- unsigned char *buf;
|
|
|
|
- unsigned int buf_len;
|
|
|
|
-
|
|
|
|
- StringValue(key);
|
|
|
|
- StringValue(data);
|
|
|
|
- buf = HMAC(ossl_evp_get_digestbyname(digest), RSTRING_PTR(key),
|
|
|
|
- RSTRING_LENINT(key), (unsigned char *)RSTRING_PTR(data),
|
|
|
|
- RSTRING_LEN(data), NULL, &buf_len);
|
|
|
|
-
|
|
|
|
- return rb_str_new((const char *)buf, buf_len);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/*
|
|
|
|
- * 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"
|
|
|
|
- *
|
|
|
|
- */
|
|
|
|
-static VALUE
|
|
|
|
-ossl_hmac_s_hexdigest(VALUE klass, VALUE digest, VALUE key, VALUE data)
|
|
|
|
-{
|
|
|
|
- unsigned char buf[EVP_MAX_MD_SIZE];
|
|
|
|
- unsigned int buf_len;
|
|
|
|
- VALUE ret;
|
|
|
|
-
|
|
|
|
- StringValue(key);
|
|
|
|
- StringValue(data);
|
|
|
|
-
|
|
|
|
- if (!HMAC(ossl_evp_get_digestbyname(digest), RSTRING_PTR(key),
|
|
|
|
- RSTRING_LENINT(key), (unsigned char *)RSTRING_PTR(data),
|
|
|
|
- RSTRING_LEN(data), buf, &buf_len))
|
|
|
|
- ossl_raise(eHMACError, "HMAC");
|
|
|
|
-
|
|
|
|
- ret = rb_str_new(NULL, buf_len * 2);
|
|
|
|
- ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len);
|
|
|
|
-
|
|
|
|
- return ret;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
/*
|
|
|
|
* INIT
|
|
|
|
*/
|
|
|
|
@@ -353,8 +278,7 @@ Init_ossl_hmac(void)
|
|
|
|
* data1 = File.read("file1")
|
|
|
|
* data2 = File.read("file2")
|
|
|
|
* key = "key"
|
|
|
|
- * digest = OpenSSL::Digest.new('SHA256')
|
|
|
|
- * hmac = OpenSSL::HMAC.new(key, digest)
|
|
|
|
+ * hmac = OpenSSL::HMAC.new(key, 'SHA256')
|
|
|
|
* hmac << data1
|
|
|
|
* hmac << data2
|
|
|
|
* mac = hmac.digest
|
|
|
|
@@ -364,8 +288,6 @@ Init_ossl_hmac(void)
|
|
|
|
cHMAC = rb_define_class_under(mOSSL, "HMAC", rb_cObject);
|
|
|
|
|
|
|
|
rb_define_alloc_func(cHMAC, ossl_hmac_alloc);
|
|
|
|
- rb_define_singleton_method(cHMAC, "digest", ossl_hmac_s_digest, 3);
|
|
|
|
- rb_define_singleton_method(cHMAC, "hexdigest", ossl_hmac_s_hexdigest, 3);
|
|
|
|
|
|
|
|
rb_define_method(cHMAC, "initialize", ossl_hmac_initialize, 2);
|
|
|
|
rb_define_method(cHMAC, "initialize_copy", ossl_hmac_copy, 1);
|
|
|
|
@@ -378,12 +300,3 @@ Init_ossl_hmac(void)
|
|
|
|
rb_define_alias(cHMAC, "inspect", "hexdigest");
|
|
|
|
rb_define_alias(cHMAC, "to_s", "hexdigest");
|
|
|
|
}
|
|
|
|
-
|
|
|
|
-#else /* NO_HMAC */
|
|
|
|
-# warning >>> OpenSSL is compiled without HMAC support <<<
|
|
|
|
-void
|
|
|
|
-Init_ossl_hmac(void)
|
|
|
|
-{
|
|
|
|
- rb_warning("HMAC is not available: OpenSSL is compiled without HMAC.");
|
|
|
|
-}
|
|
|
|
-#endif /* NO_HMAC */
|
|
|
|
--
|
|
|
|
2.34.1
|
|
|
|
|