diff options
Diffstat (limited to 'ossl_digest.c')
-rw-r--r-- | ossl_digest.c | 261 |
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 */ |