diff options
author | rhe <rhe@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-08-29 05:47:09 +0000 |
---|---|---|
committer | rhe <rhe@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-08-29 05:47:09 +0000 |
commit | 86048989b2460d1dd762037449f8c9a9f6d35d3a (patch) | |
tree | 831281099f54c0be80293785761a46688a0711f3 /ext/openssl/ossl_hmac.c | |
parent | 796285b70303b376244d9b526113face212f230c (diff) | |
download | ruby-86048989b2460d1dd762037449f8c9a9f6d35d3a.tar.gz |
import Ruby/OpenSSL 2.0.0.beta.1
* NEWS, {ext,test,sample}/openssl: Import Ruby/OpenSSL 2.0.0.beta.1.
ext/openssl is now converted into a default gem. The full commit
history since r55538 can be found at:
https://github.com/ruby/openssl/compare/08e1881f5663...v2.0.0.beta.1
[Feature #9612]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56027 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/openssl/ossl_hmac.c')
-rw-r--r-- | ext/openssl/ossl_hmac.c | 100 |
1 files changed, 58 insertions, 42 deletions
diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c index bb4b57846e..270979ed92 100644 --- a/ext/openssl/ossl_hmac.c +++ b/ext/openssl/ossl_hmac.c @@ -162,7 +162,7 @@ ossl_hmac_update(VALUE self, VALUE data) } static void -hmac_final(HMAC_CTX *ctx, unsigned char **buf, unsigned int *buf_len) +hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len) { HMAC_CTX *final; @@ -175,12 +175,7 @@ hmac_final(HMAC_CTX *ctx, unsigned char **buf, unsigned int *buf_len) ossl_raise(eHMACError, "HMAC_CTX_copy"); } - if (!(*buf = OPENSSL_malloc(HMAC_size(final)))) { - HMAC_CTX_free(final); - OSSL_Debug("Allocating %d mem", (int)HMAC_size(final)); - ossl_raise(eHMACError, "Cannot allocate memory for hmac"); - } - HMAC_Final(final, *buf, buf_len); + HMAC_Final(final, buf, buf_len); HMAC_CTX_free(final); } @@ -191,26 +186,25 @@ 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')) - * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f - * instance.digest - * #=> "\xF4+\xB0\xEE\xB0\x18\xEB\xBDE\x97\xAEr\x13q\x1E\xC6\a`\x84?" - * + * instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1')) + * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f + * instance.digest + * #=> "\xF4+\xB0\xEE\xB0\x18\xEB\xBDE\x97\xAEr\x13q\x1E\xC6\a`\x84?" */ static VALUE ossl_hmac_digest(VALUE self) { HMAC_CTX *ctx; - unsigned char *buf; unsigned int buf_len; - VALUE digest; + VALUE ret; GetHMAC(self, ctx); - hmac_final(ctx, &buf, &buf_len); - digest = ossl_buf2str((char *)buf, buf_len); + 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); - return digest; + return ret; } /* @@ -219,27 +213,21 @@ ossl_hmac_digest(VALUE self) * * Returns the authentication code an instance represents as a hex-encoded * string. - * */ static VALUE ossl_hmac_hexdigest(VALUE self) { HMAC_CTX *ctx; - unsigned char *buf; - char *hexbuf; + unsigned char buf[EVP_MAX_MD_SIZE]; unsigned int buf_len; - VALUE hexdigest; + VALUE ret; GetHMAC(self, ctx); - hmac_final(ctx, &buf, &buf_len); - if (string2hex(buf, buf_len, &hexbuf, NULL) != 2 * (int)buf_len) { - OPENSSL_free(buf); - ossl_raise(eHMACError, "Memory alloc error"); - } - OPENSSL_free(buf); - hexdigest = ossl_buf2str(hexbuf, 2 * buf_len); + hmac_final(ctx, buf, &buf_len); + ret = rb_str_new(NULL, buf_len * 2); + ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len); - return hexdigest; + return ret; } /* @@ -323,22 +311,22 @@ ossl_hmac_s_digest(VALUE klass, VALUE digest, VALUE key, VALUE data) static VALUE ossl_hmac_s_hexdigest(VALUE klass, VALUE digest, VALUE key, VALUE data) { - unsigned char *buf; - char *hexbuf; + unsigned char buf[EVP_MAX_MD_SIZE]; unsigned int buf_len; - VALUE hexdigest; + VALUE ret; StringValue(key); StringValue(data); - buf = HMAC(GetDigestPtr(digest), RSTRING_PTR(key), RSTRING_LENINT(key), - (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data), NULL, &buf_len); - if (string2hex(buf, buf_len, &hexbuf, NULL) != 2 * (int)buf_len) { - ossl_raise(eHMACError, "Cannot convert buf to hexbuf"); - } - hexdigest = ossl_buf2str(hexbuf, 2 * buf_len); + if (!HMAC(GetDigestPtr(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 hexdigest; + return ret; } /* @@ -348,10 +336,38 @@ void Init_ossl_hmac(void) { #if 0 - /* :nodoc: */ - mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */ + mOSSL = rb_define_module("OpenSSL"); + eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); #endif + /* + * Document-class: OpenSSL::HMAC + * + * OpenSSL::HMAC allows computing Hash-based Message Authentication Code + * (HMAC). It is a type of message authentication code (MAC) involving a + * hash function in combination with a key. HMAC can be used to verify the + * integrity of a message as well as the authenticity. + * + * OpenSSL::HMAC has a similar interface to OpenSSL::Digest. + * + * === HMAC-SHA256 using one-shot interface + * + * key = "key" + * data = "message-to-be-authenticated" + * mac = OpenSSL::HMAC.hexdigest("SHA256", key, data) + * #=> "cddb0db23f469c8bf072b21fd837149bd6ace9ab771cceef14c9e517cc93282e" + * + * === HMAC-SHA256 using incremental interface + * + * data1 = File.read("file1") + * data2 = File.read("file2") + * key = "key" + * digest = OpenSSL::Digest::SHA256.new + * hmac = OpenSSL::HMAC.new(key, digest) + * hmac << data1 + * hmac << data2 + * mac = hmac.digest + */ eHMACError = rb_define_class_under(mOSSL, "HMACError", eOSSLError); cHMAC = rb_define_class_under(mOSSL, "HMAC", rb_cObject); |