mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
[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.
0317e2fc02
This commit is contained in:
parent
baea36c955
commit
b91f62f384
Notes:
git
2021-03-16 20:38:49 +09:00
6 changed files with 89 additions and 170 deletions
|
@ -141,8 +141,7 @@ have_func("BN_GENCB_free")
|
||||||
have_func("BN_GENCB_get_arg")
|
have_func("BN_GENCB_get_arg")
|
||||||
have_func("EVP_MD_CTX_new")
|
have_func("EVP_MD_CTX_new")
|
||||||
have_func("EVP_MD_CTX_free")
|
have_func("EVP_MD_CTX_free")
|
||||||
have_func("HMAC_CTX_new")
|
have_func("EVP_MD_CTX_pkey_ctx")
|
||||||
have_func("HMAC_CTX_free")
|
|
||||||
have_func("X509_STORE_get_ex_data")
|
have_func("X509_STORE_get_ex_data")
|
||||||
have_func("X509_STORE_set_ex_data")
|
have_func("X509_STORE_set_ex_data")
|
||||||
have_func("X509_STORE_get_ex_new_index")
|
have_func("X509_STORE_get_ex_new_index")
|
||||||
|
|
|
@ -9,5 +9,45 @@ module OpenSSL
|
||||||
|
|
||||||
OpenSSL.fixed_length_secure_compare(self.digest, other.digest)
|
OpenSSL.fixed_length_secure_compare(self.digest, other.digest)
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,9 +13,6 @@
|
||||||
#if !defined(OPENSSL_NO_ENGINE)
|
#if !defined(OPENSSL_NO_ENGINE)
|
||||||
# include <openssl/engine.h>
|
# include <openssl/engine.h>
|
||||||
#endif
|
#endif
|
||||||
#if !defined(OPENSSL_NO_HMAC)
|
|
||||||
# include <openssl/hmac.h>
|
|
||||||
#endif
|
|
||||||
#include <openssl/x509_vfy.h>
|
#include <openssl/x509_vfy.h>
|
||||||
|
|
||||||
#include "openssl_missing.h"
|
#include "openssl_missing.h"
|
||||||
|
@ -58,29 +55,6 @@ ossl_EC_curve_nist2nid(const char *name)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*** added in 1.1.0 ***/
|
/*** 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)
|
#if !defined(HAVE_X509_CRL_GET0_SIGNATURE)
|
||||||
void
|
void
|
||||||
ossl_X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig,
|
ossl_X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig,
|
||||||
|
|
|
@ -54,14 +54,8 @@ int ossl_EC_curve_nist2nid(const char *);
|
||||||
# define EVP_MD_CTX_free EVP_MD_CTX_destroy
|
# define EVP_MD_CTX_free EVP_MD_CTX_destroy
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(HAVE_HMAC_CTX_NEW)
|
#if !defined(HAVE_EVP_MD_CTX_PKEY_CTX)
|
||||||
HMAC_CTX *ossl_HMAC_CTX_new(void);
|
# define EVP_MD_CTX_pkey_ctx(x) (x)->pctx
|
||||||
# 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
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(HAVE_X509_STORE_GET_EX_DATA)
|
#if !defined(HAVE_X509_STORE_GET_EX_DATA)
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
#include <openssl/pkcs12.h>
|
#include <openssl/pkcs12.h>
|
||||||
#include <openssl/pkcs7.h>
|
#include <openssl/pkcs7.h>
|
||||||
#include <openssl/hmac.h>
|
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
#include <openssl/conf.h>
|
#include <openssl/conf.h>
|
||||||
#ifndef OPENSSL_NO_TS
|
#ifndef OPENSSL_NO_TS
|
||||||
|
|
|
@ -7,14 +7,12 @@
|
||||||
* This program is licensed under the same licence as Ruby.
|
* This program is licensed under the same licence as Ruby.
|
||||||
* (See the file 'LICENCE'.)
|
* (See the file 'LICENCE'.)
|
||||||
*/
|
*/
|
||||||
#if !defined(OPENSSL_NO_HMAC)
|
|
||||||
|
|
||||||
#include "ossl.h"
|
#include "ossl.h"
|
||||||
|
|
||||||
#define NewHMAC(klass) \
|
#define NewHMAC(klass) \
|
||||||
TypedData_Wrap_Struct((klass), &ossl_hmac_type, 0)
|
TypedData_Wrap_Struct((klass), &ossl_hmac_type, 0)
|
||||||
#define GetHMAC(obj, ctx) do { \
|
#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)) { \
|
if (!(ctx)) { \
|
||||||
ossl_raise(rb_eRuntimeError, "HMAC wasn't initialized"); \
|
ossl_raise(rb_eRuntimeError, "HMAC wasn't initialized"); \
|
||||||
} \
|
} \
|
||||||
|
@ -36,7 +34,7 @@ VALUE eHMACError;
|
||||||
static void
|
static void
|
||||||
ossl_hmac_free(void *ctx)
|
ossl_hmac_free(void *ctx)
|
||||||
{
|
{
|
||||||
HMAC_CTX_free(ctx);
|
EVP_MD_CTX_free(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const rb_data_type_t ossl_hmac_type = {
|
static const rb_data_type_t ossl_hmac_type = {
|
||||||
|
@ -51,12 +49,12 @@ static VALUE
|
||||||
ossl_hmac_alloc(VALUE klass)
|
ossl_hmac_alloc(VALUE klass)
|
||||||
{
|
{
|
||||||
VALUE obj;
|
VALUE obj;
|
||||||
HMAC_CTX *ctx;
|
EVP_MD_CTX *ctx;
|
||||||
|
|
||||||
obj = NewHMAC(klass);
|
obj = NewHMAC(klass);
|
||||||
ctx = HMAC_CTX_new();
|
ctx = EVP_MD_CTX_new();
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
ossl_raise(eHMACError, NULL);
|
ossl_raise(eHMACError, "EVP_MD_CTX");
|
||||||
RTYPEDDATA_DATA(obj) = ctx;
|
RTYPEDDATA_DATA(obj) = ctx;
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
|
@ -76,8 +74,7 @@ ossl_hmac_alloc(VALUE klass)
|
||||||
* === Example
|
* === Example
|
||||||
*
|
*
|
||||||
* key = 'key'
|
* key = 'key'
|
||||||
* digest = OpenSSL::Digest.new('sha1')
|
* instance = OpenSSL::HMAC.new(key, 'SHA1')
|
||||||
* instance = OpenSSL::HMAC.new(key, digest)
|
|
||||||
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
||||||
* instance.class
|
* instance.class
|
||||||
* #=> OpenSSL::HMAC
|
* #=> OpenSSL::HMAC
|
||||||
|
@ -86,7 +83,7 @@ ossl_hmac_alloc(VALUE klass)
|
||||||
*
|
*
|
||||||
* Two instances can be securely compared with #== in constant time:
|
* 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
|
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
||||||
* instance == other_instance
|
* instance == other_instance
|
||||||
* #=> true
|
* #=> true
|
||||||
|
@ -95,12 +92,23 @@ ossl_hmac_alloc(VALUE klass)
|
||||||
static VALUE
|
static VALUE
|
||||||
ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
|
ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
|
||||||
{
|
{
|
||||||
HMAC_CTX *ctx;
|
EVP_MD_CTX *ctx;
|
||||||
|
EVP_PKEY *pkey;
|
||||||
|
|
||||||
StringValue(key);
|
|
||||||
GetHMAC(self, ctx);
|
GetHMAC(self, ctx);
|
||||||
HMAC_Init_ex(ctx, RSTRING_PTR(key), RSTRING_LENINT(key),
|
StringValue(key);
|
||||||
ossl_evp_get_digestbyname(digest), NULL);
|
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;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -108,16 +116,15 @@ ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
|
||||||
static VALUE
|
static VALUE
|
||||||
ossl_hmac_copy(VALUE self, VALUE other)
|
ossl_hmac_copy(VALUE self, VALUE other)
|
||||||
{
|
{
|
||||||
HMAC_CTX *ctx1, *ctx2;
|
EVP_MD_CTX *ctx1, *ctx2;
|
||||||
|
|
||||||
rb_check_frozen(self);
|
rb_check_frozen(self);
|
||||||
if (self == other) return self;
|
if (self == other) return self;
|
||||||
|
|
||||||
GetHMAC(self, ctx1);
|
GetHMAC(self, ctx1);
|
||||||
GetHMAC(other, ctx2);
|
GetHMAC(other, ctx2);
|
||||||
|
if (EVP_MD_CTX_copy(ctx1, ctx2) != 1)
|
||||||
if (!HMAC_CTX_copy(ctx1, ctx2))
|
ossl_raise(eHMACError, "EVP_MD_CTX_copy");
|
||||||
ossl_raise(eHMACError, "HMAC_CTX_copy");
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,33 +149,16 @@ ossl_hmac_copy(VALUE self, VALUE other)
|
||||||
static VALUE
|
static VALUE
|
||||||
ossl_hmac_update(VALUE self, VALUE data)
|
ossl_hmac_update(VALUE self, VALUE data)
|
||||||
{
|
{
|
||||||
HMAC_CTX *ctx;
|
EVP_MD_CTX *ctx;
|
||||||
|
|
||||||
StringValue(data);
|
StringValue(data);
|
||||||
GetHMAC(self, ctx);
|
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;
|
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:
|
* call-seq:
|
||||||
* hmac.digest -> string
|
* 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.
|
* Returns the authentication code an instance represents as a binary string.
|
||||||
*
|
*
|
||||||
* === Example
|
* === Example
|
||||||
* instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
|
* instance = OpenSSL::HMAC.new('key', 'SHA1')
|
||||||
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
||||||
* instance.digest
|
* instance.digest
|
||||||
* #=> "\xF4+\xB0\xEE\xB0\x18\xEB\xBDE\x97\xAEr\x13q\x1E\xC6\a`\x84?"
|
* #=> "\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
|
static VALUE
|
||||||
ossl_hmac_digest(VALUE self)
|
ossl_hmac_digest(VALUE self)
|
||||||
{
|
{
|
||||||
HMAC_CTX *ctx;
|
EVP_MD_CTX *ctx;
|
||||||
unsigned int buf_len;
|
size_t buf_len;
|
||||||
VALUE ret;
|
VALUE ret;
|
||||||
|
|
||||||
GetHMAC(self, ctx);
|
GetHMAC(self, ctx);
|
||||||
ret = rb_str_new(NULL, EVP_MAX_MD_SIZE);
|
ret = rb_str_new(NULL, EVP_MAX_MD_SIZE);
|
||||||
hmac_final(ctx, (unsigned char *)RSTRING_PTR(ret), &buf_len);
|
if (EVP_DigestSignFinal(ctx, (unsigned char *)RSTRING_PTR(ret),
|
||||||
assert(buf_len <= EVP_MAX_MD_SIZE);
|
&buf_len) != 1)
|
||||||
rb_str_set_len(ret, buf_len);
|
ossl_raise(eHMACError, "EVP_DigestSignFinal");
|
||||||
|
rb_str_set_len(ret, (long)buf_len);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -207,13 +198,14 @@ ossl_hmac_digest(VALUE self)
|
||||||
static VALUE
|
static VALUE
|
||||||
ossl_hmac_hexdigest(VALUE self)
|
ossl_hmac_hexdigest(VALUE self)
|
||||||
{
|
{
|
||||||
HMAC_CTX *ctx;
|
EVP_MD_CTX *ctx;
|
||||||
unsigned char buf[EVP_MAX_MD_SIZE];
|
unsigned char buf[EVP_MAX_MD_SIZE];
|
||||||
unsigned int buf_len;
|
size_t buf_len;
|
||||||
VALUE ret;
|
VALUE ret;
|
||||||
|
|
||||||
GetHMAC(self, ctx);
|
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);
|
ret = rb_str_new(NULL, buf_len * 2);
|
||||||
ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len);
|
ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len);
|
||||||
|
|
||||||
|
@ -230,7 +222,7 @@ ossl_hmac_hexdigest(VALUE self)
|
||||||
* === Example
|
* === Example
|
||||||
*
|
*
|
||||||
* data = "The quick brown fox jumps over the lazy dog"
|
* 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
|
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
||||||
*
|
*
|
||||||
* instance.update(data)
|
* instance.update(data)
|
||||||
|
@ -242,84 +234,17 @@ ossl_hmac_hexdigest(VALUE self)
|
||||||
static VALUE
|
static VALUE
|
||||||
ossl_hmac_reset(VALUE self)
|
ossl_hmac_reset(VALUE self)
|
||||||
{
|
{
|
||||||
HMAC_CTX *ctx;
|
EVP_MD_CTX *ctx;
|
||||||
|
EVP_PKEY *pkey;
|
||||||
|
|
||||||
GetHMAC(self, ctx);
|
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;
|
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
|
* INIT
|
||||||
*/
|
*/
|
||||||
|
@ -353,8 +278,7 @@ Init_ossl_hmac(void)
|
||||||
* data1 = File.binread("file1")
|
* data1 = File.binread("file1")
|
||||||
* data2 = File.binread("file2")
|
* data2 = File.binread("file2")
|
||||||
* key = "key"
|
* key = "key"
|
||||||
* digest = OpenSSL::Digest.new('SHA256')
|
* hmac = OpenSSL::HMAC.new(key, 'SHA256')
|
||||||
* hmac = OpenSSL::HMAC.new(key, digest)
|
|
||||||
* hmac << data1
|
* hmac << data1
|
||||||
* hmac << data2
|
* hmac << data2
|
||||||
* mac = hmac.digest
|
* mac = hmac.digest
|
||||||
|
@ -364,8 +288,6 @@ Init_ossl_hmac(void)
|
||||||
cHMAC = rb_define_class_under(mOSSL, "HMAC", rb_cObject);
|
cHMAC = rb_define_class_under(mOSSL, "HMAC", rb_cObject);
|
||||||
|
|
||||||
rb_define_alloc_func(cHMAC, ossl_hmac_alloc);
|
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", ossl_hmac_initialize, 2);
|
||||||
rb_define_method(cHMAC, "initialize_copy", ossl_hmac_copy, 1);
|
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, "inspect", "hexdigest");
|
||||||
rb_define_alias(cHMAC, "to_s", "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 */
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue