aboutsummaryrefslogtreecommitdiffstats
path: root/ossl_digest.c
diff options
context:
space:
mode:
Diffstat (limited to 'ossl_digest.c')
-rw-r--r--ossl_digest.c261
1 files changed, 108 insertions, 153 deletions
diff --git a/ossl_digest.c b/ossl_digest.c
index 8a62b3f..0c284c3 100644
--- a/ossl_digest.c
+++ b/ossl_digest.c
@@ -10,15 +10,19 @@
*/
#include "ossl.h"
-#define WrapDigest(klass, obj, ctx) obj = Data_Wrap_Struct(klass, 0, CRYPTO_free, ctx)
-#define GetDigest(obj, ctx) Data_Get_Struct(obj, EVP_MD_CTX, ctx)
+#define WrapDigest OSSLWrapDigest
+#define GetDigest(obj, ctx) do { \
+ Data_Get_Struct(obj, EVP_MD_CTX, ctx); \
+ if (!ctx) { \
+ rb_raise(rb_eRuntimeError, "Digest CTX wasn't initialized!"); \
+ } \
+} while (0)
/*
* Classes
*/
VALUE cDigest;
VALUE eDigestError;
-VALUE cMD2, cMD4, cMD5, cMDC2, cRIPEMD160, cSHA, cSHA1, cDSS, cDSS1;
/*
* Public
@@ -28,9 +32,7 @@ ossl_digest_get_NID(VALUE obj)
{
EVP_MD_CTX *ctx = NULL;
- OSSL_Check_Type(obj, cDigest);
-
- GetDigest(obj, ctx);
+ OSSLGetDigest(obj, ctx);
return EVP_MD_CTX_type(ctx); /*== ctx->digest->type*/
}
@@ -40,9 +42,7 @@ ossl_digest_get_EVP_MD(VALUE obj)
{
EVP_MD_CTX *ctx = NULL;
- OSSL_Check_Type(obj, cDigest);
-
- GetDigest(obj, ctx);
+ OSSLGetDigest(obj, ctx);
return EVP_MD_CTX_md(ctx); /*== ctx->digest*/
}
@@ -51,32 +51,46 @@ ossl_digest_get_EVP_MD(VALUE obj)
* Private
*/
static VALUE
-ossl_digest_s_new(int argc, VALUE *argv, VALUE klass)
+ossl_digest_s_allocate(VALUE klass)
{
EVP_MD_CTX *ctx = NULL;
VALUE obj;
- if (klass == cDigest)
- rb_raise(rb_eNotImpError, "cannot do Digest::ANY.new - it is an abstract class");
-
if (!(ctx = OPENSSL_malloc(sizeof(EVP_MD_CTX)))) {
OSSL_Raise(eDigestError, "Cannot allocate memory for a digest's CTX");
}
WrapDigest(klass, obj, ctx);
- rb_obj_call_init(obj, argc, argv);
-
return obj;
}
static VALUE
+ossl_digest_initialize(VALUE self, VALUE str)
+{
+ EVP_MD_CTX *ctx = NULL;
+ const EVP_MD *md;
+ char *md_name = NULL;
+
+ GetDigest(self, ctx);
+
+ md_name = StringValuePtr(str);
+
+ if (!(md = EVP_get_digestbyname(md_name))) {
+ rb_raise(rb_eRuntimeError, "Unsupported digest algorithm (%s).", md_name);
+ }
+ EVP_DigestInit(ctx, md);
+
+ return self;
+}
+
+static VALUE
ossl_digest_update(VALUE self, VALUE data)
{
EVP_MD_CTX *ctx = NULL;
GetDigest(self, ctx);
- data = rb_String(data);
+ StringValue(data);
EVP_DigestUpdate(ctx, RSTRING(data)->ptr, RSTRING(data)->len);
@@ -107,9 +121,6 @@ ossl_digest_digest(VALUE self)
return digest;
}
-/*
- * RUBY attitude
- */
static VALUE
ossl_digest_hexdigest(VALUE self)
{
@@ -129,176 +140,120 @@ ossl_digest_hexdigest(VALUE self)
}
EVP_DigestFinal(&final, digest_txt, &digest_len);
- if (!(hexdigest_txt = OPENSSL_malloc(2*digest_len+1))) {
+ if (!(hexdigest_txt = OPENSSL_malloc(2 * digest_len + 1))) {
OPENSSL_free(digest_txt);
OSSL_Raise(eDigestError, "Memory alloc error");
}
for (i = 0; i < digest_len; i++) {
- hexdigest_txt[i + i] = hex[((unsigned char)digest_txt[i]) >> 4];
- hexdigest_txt[i + i + 1] = hex[digest_txt[i] & 0x0f];
+ hexdigest_txt[2 * i] = hex[((unsigned char)digest_txt[i]) >> 4];
+ hexdigest_txt[2 * i + 1] = hex[digest_txt[i] & 0x0f];
}
- hexdigest_txt[i + i] = '\0';
- hexdigest = rb_str_new(hexdigest_txt, 2*digest_len);
+ hexdigest_txt[2 * i] = '\0';
+ hexdigest = rb_str_new(hexdigest_txt, 2 * digest_len);
OPENSSL_free(digest_txt);
OPENSSL_free(hexdigest_txt);
return hexdigest;
}
-/*
- * OPENSSL attitude
- *
static VALUE
-ossl_digest_hexdigest(VALUE self)
+ossl_digest_s_digest(VALUE klass, VALUE str, VALUE data)
{
- EVP_MD_CTX *ctx = NULL, final;
- unsigned char *digest_txt = NULL, *hexdigest_txt = NULL;
- int i,digest_len = 0;
- VALUE hexdigest;
+ VALUE obj = rb_class_new_instance(1, &str, cDigest);
+
+ 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, cDigest);
+
+ ossl_digest_update(obj, data);
+
+ return ossl_digest_hexdigest(obj);
+}
+
+static VALUE
+ossl_digest_clone(VALUE self)
+{
+ EVP_MD_CTX *ctx = NULL, *other;
+ VALUE obj;
GetDigest(self, ctx);
- if (!EVP_MD_CTX_copy(&final, ctx)) {
+ obj = rb_obj_alloc(CLASS_OF(self));
+
+ GetDigest(obj, other);
+
+ if (!EVP_MD_CTX_copy(other, ctx)) {
OSSL_Raise(eDigestError, "");
}
+
+ return obj;
+}
- if (!(digest_txt = OPENSSL_malloc(EVP_MD_CTX_size(&final)))) {
- OSSL_Raise(eDigestError, "Cannot allocate memory for digest");
- }
- EVP_DigestFinal(&final, digest_txt, &digest_len);
+static VALUE
+ossl_digest_equal(VALUE self, VALUE other)
+{
+ EVP_MD_CTX *ctx = NULL;
+ VALUE str1, str2;
- hexdigest_txt = hex_to_string(digest_txt, digest_len);
- hexdigest = rb_str_new2(hexdigest_txt);
- OPENSSL_free(digest_txt);
- OPENSSL_free(hexdigest_txt);
+ GetDigest(self, ctx);
+
+ if (CLASS_OF(other) == CLASS_OF(self)) {
+ str2 = ossl_digest_digest(other);
+ } else {
+ StringValue(other);
+ str2 = other;
+ }
- return hexdigest;
-}
- */
+ if (RSTRING(str2)->len == EVP_MD_CTX_size(ctx)) {
+ str1 = ossl_digest_digest(self);
+ } else {
+ str1 = ossl_digest_hexdigest(self);
+ }
-/*
- * automation of digest initialization method
- */
-#define DefDigestInit(dgst) \
- static VALUE \
- ossl_##dgst##_initialize(int argc, VALUE *argv, VALUE self) \
- { \
- EVP_MD_CTX *ctx = NULL; \
- VALUE data; \
- \
- GetDigest(self, ctx); \
- \
- EVP_DigestInit(ctx, EVP_##dgst()); \
- \
- if (rb_scan_args(argc, argv, "01", &data) == 1) { \
- data = rb_String(data); \
- EVP_DigestUpdate(ctx, RSTRING(data)->ptr, RSTRING(data)->len); \
- } \
- return self; \
+ if (RSTRING(str1)->len == RSTRING(str2)->len &&
+ rb_str_cmp(str1, str2) == 0) {
+ return Qtrue;
}
-/*
- * Define digest initialize methods
- */
-#if !defined(NO_MD2) && !defined(OPENSSL_NO_MD2)
- DefDigestInit(md2);
-#endif
-#if !defined(NO_MD4) && !defined(OPENSSL_NO_MD4)
- DefDigestInit(md4);
-#endif
-#if !defined(NO_MD5) && !defined(OPENSSL_NO_MD5)
- DefDigestInit(md5);
-#endif
-#if !defined(NO_SHA) && !defined(OPENSSL_NO_SHA)
- DefDigestInit(sha);
- DefDigestInit(sha1);
- DefDigestInit(dss);
- DefDigestInit(dss1);
-#endif
-#if !defined(NO_RIPEMD) && !defined(OPENSSL_NO_RIPEMD)
- DefDigestInit(ripemd160);
-#endif
-#if !defined(NO_MDC2) && !defined(OPENSSL_NO_MDC2)
- DefDigestInit(mdc2);
-#endif
+ return Qfalse;
+}
/*
* INIT
*/
void
-Init_ossl_digest(VALUE module)
+Init_ossl_digest()
{
- eDigestError = rb_define_class_under(module, "DigestError", rb_eStandardError);
+ mDigest = rb_define_module_under(mOSSL, "Digest");
- cDigest = rb_define_class_under(module, "ANY", rb_cObject);
- rb_define_singleton_method(cDigest, "new", ossl_digest_s_new, -1);
-/* rb_define_singleton_method(cDigest, "digest", ossl_digest_s_digest, 1);
- rb_define_singleton_method(cDigest, "hexdigest", ossl_digest_s_hexdigest, 1);
- rb_define_method(cDigest, "initialize", ossl_digest_init, -1);
+ eDigestError = rb_define_class_under(mDigest, "DigestError", eOSSLError);
+
+ cDigest = rb_define_class_under(mDigest, "Digest", rb_cObject);
+
+ rb_define_singleton_method(cDigest, "allocate", ossl_digest_s_allocate, 0);
+ rb_define_singleton_method(cDigest, "digest", ossl_digest_s_digest, 2);
+ rb_define_singleton_method(cDigest, "hexdigest", ossl_digest_s_hexdigest, 2);
+
+ rb_define_method(cDigest, "initialize", ossl_digest_initialize, 1);
+ rb_enable_super(cDigest, "initialize");
+
rb_define_method(cDigest, "clone", ossl_digest_clone, 0);
- */
- rb_define_method(cDigest, "update", ossl_digest_update, 1);
- rb_define_alias(cDigest, "<<", "update");
+
rb_define_method(cDigest, "digest", ossl_digest_digest, 0);
rb_define_method(cDigest, "hexdigest", ossl_digest_hexdigest, 0);
rb_define_alias(cDigest, "inspect", "hexdigest");
rb_define_alias(cDigest, "to_s", "hexdigest");
- /*rb_define_method(cDigest, "==", ossl_digest_equal, 1);*/
-
-/*
- * automation for classes creation and initialize method binding
- */
-#define DefDigest(name, func) \
- c##name = rb_define_class_under(module, #name, cDigest); \
- rb_define_method(c##name, "initialize", ossl_##func##_initialize, -1)
-
-/*
- * create classes and bind initialize method
- */
-#if !defined(NO_MD2) && !defined(OPENSSL_NO_MD2)
- DefDigest(MD2, md2);
-#else
-# warning >>> OpenSSL is compiled without MD2 support <<<
- rb_warning("OpenSSL is compiled without MD2 support");
-#endif /* NO_MD2 */
-
-#if !defined(NO_MD4) && !defined(OPENSSL_NO_MD4)
- DefDigest(MD4, md4);
-#else
-# warning >>> OpenSSL is compiled without MD4 support <<<
- rb_warning("OpenSSL is compiled without MD4 support");
-#endif /* NO_MD4 */
-
-#if !defined(NO_MD5) && !defined(OPENSSL_NO_MD5)
- DefDigest(MD5, md5);
-#else
-# warning >>> OpenSSL is compiled without MD5 support <<<
- rb_warning("OpenSSL is compiled without MD5 support");
-#endif /* NO_MD5 */
-#if !defined(NO_SHA) && !defined(OPENSSL_NO_SHA)
- DefDigest(SHA, sha);
- DefDigest(SHA1, sha1);
- DefDigest(DSS, dss);
- DefDigest(DSS1, dss1);
-#else
-# warning >>> OpenSSL is compiled without SHA, DSS support <<<
- rb_warning("OpenSSL is compiled without SHA, DSS support");
-#endif /* NO_SHA */
-
-#if !defined(NO_RIPEMD) && !defined(OPENSSL_NO_RIPEMD)
- DefDigest(RIPEMD160, ripemd160);
-#else
-# warning >>> OpenSSL is compiled without RIPEMD160 support <<<
- rb_warning("OpenSSL is compiled without RIPEMD160 support");
-#endif /* NO_RIPEMD */
-
-#if !defined(NO_MDC2) && !defined(OPENSSL_NO_MDC2)
- DefDigest(MDC2, mdc2);
-#else
-# warning >>> OpenSSL is compiled without MDC2 support <<<
- rb_warning("OpenSSL is compiled without MDC2 support");
-#endif /* NO_MDC2 */
+ rb_define_method(cDigest, "update", ossl_digest_update, 1);
+ rb_define_alias(cDigest, "<<", "update");
-} /* Init_ */
+ rb_define_method(cDigest, "==", ossl_digest_equal, 1);
+
+} /* Init_ossl_digest */