aboutsummaryrefslogtreecommitdiffstats
path: root/ext/openssl/ossl_hmac.c
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2016-08-24 02:08:43 +0900
committerKazuki Yamaguchi <k@rhe.jp>2016-08-26 19:32:40 +0900
commitef3b30ddb6cff80c1ead60cb63940e80d0fb9ec5 (patch)
tree51ce13db65e6761108bd8c1d6bcac036b484350c /ext/openssl/ossl_hmac.c
parent9e331f2b33b562bb760f5db301d7ab76eb4922a0 (diff)
downloadruby-openssl-ef3b30ddb6cff80c1ead60cb63940e80d0fb9ec5.tar.gz
Avoid unnecessary memory allocation in string2hex()
Remove string2hex() and replace with newly added ossl_bin2hex(). Since the output hex string is always returned to users as a String, we can avoid the memory allocation by writing directly to the String buffer. This also reduces some lines of code.
Diffstat (limited to 'ext/openssl/ossl_hmac.c')
-rw-r--r--ext/openssl/ossl_hmac.c68
1 files changed, 28 insertions, 40 deletions
diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c
index ec3f9de7..270979ed 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;
}
/*