Object
static VALUE
ossl_digest_s_digest(VALUE klass, VALUE str, VALUE data)
{
VALUE obj = rb_class_new_instance(1, &str, klass);
ossl_digest_update(obj, data);
return ossl_digest_digest(obj);
}
static VALUE
ossl_digest_s_hexdigest(VALUE klass, VALUE str, VALUE data)
{
VALUE obj = rb_class_new_instance(1, &str, klass);
ossl_digest_update(obj, data);
return ossl_digest_hexdigest(obj);
}
static VALUE
ossl_digest_initialize(int argc, VALUE *argv, VALUE self)
{
EVP_MD_CTX *ctx;
const EVP_MD *md;
char *name;
VALUE type, data;
rb_scan_args(argc, argv, "11", &type, &data);
StringValue(type);
if (!NIL_P(data)) StringValue(data);
name = StringValuePtr(type);
md = EVP_get_digestbyname(name);
if (!md) {
ossl_raise(rb_eRuntimeError, "Unsupported digest algorithm (%s).", name);
}
GetDigest(self, ctx);
EVP_DigestInit_ex(ctx, md, NULL);
if (!NIL_P(data)) return ossl_digest_update(self, data);
return self;
}
static VALUE
ossl_digest_equal(VALUE self, VALUE other)
{
EVP_MD_CTX *ctx;
VALUE str1, str2;
if (rb_obj_is_kind_of(other, cDigest) == Qtrue) {
str2 = ossl_digest_digest(other);
} else {
StringValue(other);
str2 = other;
}
GetDigest(self, ctx);
if (RSTRING(str2)->len == EVP_MD_CTX_size(ctx)) {
str1 = ossl_digest_digest(self);
} else {
str1 = ossl_digest_hexdigest(self);
}
if (RSTRING(str1)->len == RSTRING(str2)->len
&& rb_str_cmp(str1, str2) == 0) {
return Qtrue;
}
return Qfalse;
}
static VALUE
ossl_digest_digest(VALUE self)
{
EVP_MD_CTX *ctx;
char *buf;
int buf_len;
VALUE digest;
GetDigest(self, ctx);
digest_final(ctx, &buf, &buf_len);
digest = ossl_buf2str(buf, buf_len);
return digest;
}
static VALUE
ossl_digest_hexdigest(VALUE self)
{
EVP_MD_CTX *ctx;
char *buf, *hexbuf;
int buf_len;
VALUE hexdigest;
GetDigest(self, ctx);
digest_final(ctx, &buf, &buf_len);
if (string2hex(buf, buf_len, &hexbuf, NULL) != 2 * buf_len) {
OPENSSL_free(buf);
ossl_raise(eDigestError, "Memory alloc error");
}
OPENSSL_free(buf);
hexdigest = ossl_buf2str(hexbuf, 2 * buf_len);
return hexdigest;
}
static VALUE
ossl_digest_name(VALUE self)
{
EVP_MD_CTX *ctx;
GetDigest(self, ctx);
return rb_str_new2(EVP_MD_name(EVP_MD_CTX_md(ctx)));
}
static VALUE
ossl_digest_reset(VALUE self)
{
EVP_MD_CTX *ctx;
GetDigest(self, ctx);
EVP_DigestInit_ex(ctx, EVP_MD_CTX_md(ctx), NULL);
return self;
}
static VALUE
ossl_digest_size(VALUE self)
{
EVP_MD_CTX *ctx;
GetDigest(self, ctx);
return INT2NUM(EVP_MD_CTX_size(ctx));
}
VALUE
ossl_digest_update(VALUE self, VALUE data)
{
EVP_MD_CTX *ctx;
StringValue(data);
GetDigest(self, ctx);
EVP_DigestUpdate(ctx, RSTRING(data)->ptr, RSTRING(data)->len);
return self;
}