aboutsummaryrefslogtreecommitdiffstats
path: root/ossl_digest.c
diff options
context:
space:
mode:
authorMichal Rokos <m.rokos@sh.cvut.cz>2001-11-16 11:20:13 +0000
committerMichal Rokos <m.rokos@sh.cvut.cz>2001-11-16 11:20:13 +0000
commit8903e757c052d3a99aada758bb628ec135360e60 (patch)
tree5f0e99803c1fc5c6909fd7d325d0f279265b97cf /ossl_digest.c
downloadruby-openssl-history-8903e757c052d3a99aada758bb628ec135360e60.tar.gz
Initial revision
Diffstat (limited to 'ossl_digest.c')
-rw-r--r--ossl_digest.c410
1 files changed, 410 insertions, 0 deletions
diff --git a/ossl_digest.c b/ossl_digest.c
new file mode 100644
index 0000000..0f5cc23
--- /dev/null
+++ b/ossl_digest.c
@@ -0,0 +1,410 @@
+/*
+ * $Id$
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+ */
+/*
+ * This program is licenced under the same licence as Ruby.
+ * (See the file 'LICENCE'.)
+ */
+#include "ossl.h"
+
+#define MakeDigest(klass, obj, digestp) {\
+ obj = Data_Make_Struct(klass, ossl_digest, 0, ossl_digest_free, digestp);\
+}
+
+#define GetDigest(obj, digestp) {\
+ Data_Get_Struct(obj, ossl_digest, digestp);\
+}
+
+/*
+ * Classes
+ */
+VALUE cDigest;
+VALUE eDigestError;
+VALUE cMD2;
+VALUE cMD5;
+VALUE cMDC2;
+VALUE cRIPEMD160;
+VALUE cSHA;
+VALUE cSHA1;
+VALUE cDSS;
+VALUE cDSS1;
+
+/*
+ * Struct
+ */
+typedef struct ossl_digest_st {
+ EVP_MD_CTX *md;
+} ossl_digest;
+
+static void ossl_digest_free(ossl_digest *digestp)
+{
+ if (digestp) {
+ if (digestp->md) free(digestp->md);
+ free(digestp);
+ }
+}
+
+/*
+ * PUBLIC
+ */
+int ossl_digest_get_NID(VALUE obj)
+{
+ ossl_digest *digestp = NULL;
+
+ GetDigest(obj, digestp);
+
+ return EVP_MD_CTX_type(digestp->md); /*== digestp->md->digest->type*/
+}
+
+const EVP_MD *ossl_digest_get_EVP_MD(VALUE obj)
+{
+ ossl_digest *digestp = NULL;
+
+ GetDigest(obj, digestp);
+
+ return EVP_MD_CTX_md(digestp->md); /*== digestp->md->digest*/
+}
+
+/*
+ * PRIVATE
+ */
+static VALUE ossl_digest_s_new(int argc, VALUE *argv, VALUE klass)
+{
+ ossl_digest *digestp = NULL;
+ VALUE obj;
+
+ if (klass == cDigest)
+ rb_raise(rb_eNotImpError, "cannot do Digest.new - Digest is an abstract class");
+
+ MakeDigest(klass, obj, digestp);
+ rb_obj_call_init(obj, argc, argv);
+
+ return obj;
+}
+
+static VALUE ossl_digest_update(VALUE self, VALUE data)
+{
+ ossl_digest *digestp = NULL;
+
+ GetDigest(self, digestp);
+
+ Check_Type(data, T_STRING);
+ EVP_DigestUpdate(digestp->md, RSTRING(data)->ptr, RSTRING(data)->len);
+
+ return self;
+}
+
+static VALUE ossl_digest_digest(VALUE self)
+{
+ ossl_digest *digestp = NULL;
+ char *digest_txt = NULL;
+ int digest_len = 0;
+ EVP_MD_CTX final;
+ VALUE digest;
+
+ GetDigest(self, digestp);
+
+ if (!EVP_MD_CTX_copy(&final, digestp->md)) {
+ rb_raise(eDigestError, "%s", ossl_error());
+ }
+
+ if (!(digest_txt = malloc(EVP_MD_CTX_size(digestp->md)))) {
+ rb_raise(eDigestError, "Cannot allocate memory for digest");
+ }
+ EVP_DigestFinal(&final, digest_txt, &digest_len);
+
+ digest = rb_str_new(digest_txt, digest_len);
+ free(digest_txt);
+
+ return digest;
+}
+
+/*
+ * RUBY attitude
+ */
+static VALUE ossl_digest_hexdigest(VALUE self)
+{
+ ossl_digest *digestp = NULL;
+ static const char hex[]="0123456789abcdef";
+ char *digest_txt = NULL, *hexdigest_txt = NULL;
+ int i,digest_len = 0;
+ EVP_MD_CTX final;
+ VALUE hexdigest;
+
+ GetDigest(self, digestp);
+
+ if (!EVP_MD_CTX_copy(&final, digestp->md)) {
+ rb_raise(eDigestError, "%s", ossl_error());
+ }
+
+ if (!(digest_txt = malloc(EVP_MD_CTX_size(digestp->md)))) {
+ rb_raise(eDigestError, "Cannot allocate memory for digest");
+ }
+ EVP_DigestFinal(&final, digest_txt, &digest_len);
+
+ if (!(hexdigest_txt = malloc(2*digest_len+1))) {
+ rb_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[i + i] = '\0';
+ hexdigest = rb_str_new(hexdigest_txt, 2*digest_len);
+ free(digest_txt);
+ free(hexdigest_txt);
+
+ return hexdigest;
+}
+
+/*
+ * OPENSSL attitude
+ *
+static VALUE ossl_digest_hexdigest(VALUE self)
+{
+ ossl_digest *digestp = NULL;
+ unsigned char *digest_txt = NULL, *hexdigest_txt = NULL;
+ int i,digest_len = 0;
+ EVP_MD_CTX final;
+ VALUE hexdigest;
+
+ GetDigest(self, digestp);
+
+ if (!EVP_MD_CTX_copy(&final, digestp->md)) {
+ rb_raise(eDigestError, "%s", ossl_error());
+ }
+
+ if (!(digest_txt = malloc(EVP_MD_CTX_size(digestp->md)))) {
+ rb_raise(eDigestError, "Cannot allocate memory for digest");
+ }
+ EVP_DigestFinal(&final, digest_txt, &digest_len);
+
+ hexdigest_txt = hex_to_string(digest_txt, digest_len);
+ hexdigest = rb_str_new2(hexdigest_txt);
+ free(digest_txt);
+ free(hexdigest_txt);
+
+ return hexdigest;
+}
+ */
+
+/*
+ * MD2
+ */
+static VALUE ossl_md2_initialize(int argc, VALUE *argv, VALUE self)
+{
+ ossl_digest *digestp = NULL;
+ VALUE data;
+
+ GetDigest(self, digestp);
+ if (!(digestp->md = malloc(sizeof(EVP_MD_CTX)))) {
+ rb_raise(eDigestError, "Cannot allocate memory for new digest");
+ }
+ EVP_DigestInit(digestp->md, EVP_md2());
+
+ if (rb_scan_args(argc, argv, "01", &data) == 1) {
+ Check_Type(data, T_STRING);
+ EVP_DigestUpdate(digestp->md, RSTRING(data)->ptr, RSTRING(data)->len);
+ }
+ return self;
+}
+
+/*
+ * MD5
+ */
+static VALUE ossl_md5_initialize(int argc, VALUE *argv, VALUE self)
+{
+ ossl_digest *digestp = NULL;
+ VALUE data;
+
+ GetDigest(self, digestp);
+ if (!(digestp->md = malloc(sizeof(EVP_MD_CTX)))) {
+ rb_raise(eDigestError, "Cannot allocate memory for new digest");
+ }
+ EVP_DigestInit(digestp->md, EVP_md5());
+
+ if (rb_scan_args(argc, argv, "01", &data) == 1) {
+ Check_Type(data, T_STRING);
+ EVP_DigestUpdate(digestp->md, RSTRING(data)->ptr, RSTRING(data)->len);
+ }
+ return self;
+}
+
+/*
+ * MDC2
+ */
+static VALUE ossl_mdc2_initialize(int argc, VALUE *argv, VALUE self)
+{
+ ossl_digest *digestp = NULL;
+ VALUE data;
+
+ GetDigest(self, digestp);
+ if (!(digestp->md = malloc(sizeof(EVP_MD_CTX)))) {
+ rb_raise(eDigestError, "Cannot allocate memory for new digest");
+ }
+ EVP_DigestInit(digestp->md, EVP_mdc2());
+
+ if (rb_scan_args(argc, argv, "01", &data) == 1) {
+ Check_Type(data, T_STRING);
+ EVP_DigestUpdate(digestp->md, RSTRING(data)->ptr, RSTRING(data)->len);
+ }
+ return self;
+}
+
+/*
+ * RIPEmd160
+ */
+static VALUE ossl_ripemd160_initialize(int argc, VALUE *argv, VALUE self)
+{
+ ossl_digest *digestp = NULL;
+ VALUE data;
+
+ GetDigest(self, digestp);
+ if (!(digestp->md = malloc(sizeof(EVP_MD_CTX)))) {
+ rb_raise(eDigestError, "Cannot allocate memory for new digest");
+ }
+ EVP_DigestInit(digestp->md, EVP_ripemd160());
+
+ if (rb_scan_args(argc, argv, "01", &data) == 1) {
+ Check_Type(data, T_STRING);
+ EVP_DigestUpdate(digestp->md, RSTRING(data)->ptr, RSTRING(data)->len);
+ }
+ return self;
+}
+
+/*
+ * SHA
+ */
+static VALUE ossl_sha_initialize(int argc, VALUE *argv, VALUE self)
+{
+ ossl_digest *digestp = NULL;
+ VALUE data;
+
+ GetDigest(self, digestp);
+ if (!(digestp->md = malloc(sizeof(EVP_MD_CTX)))) {
+ rb_raise(eDigestError, "Cannot allocate memory for new digest");
+ }
+ EVP_DigestInit(digestp->md, EVP_sha());
+
+ if (rb_scan_args(argc, argv, "01", &data) == 1) {
+ Check_Type(data, T_STRING);
+ EVP_DigestUpdate(digestp->md, RSTRING(data)->ptr, RSTRING(data)->len);
+ }
+ return self;
+}
+
+/*
+ * SHA1
+ */
+static VALUE ossl_sha1_initialize(int argc, VALUE *argv, VALUE self)
+{
+ ossl_digest *digestp = NULL;
+ VALUE data;
+
+ GetDigest(self, digestp);
+ if (!(digestp->md = malloc(sizeof(EVP_MD_CTX)))) {
+ rb_raise(eDigestError, "Cannot allocate memory for new digest");
+ }
+ EVP_DigestInit(digestp->md, EVP_sha1());
+
+ if (rb_scan_args(argc, argv, "01", &data) == 1) {
+ Check_Type(data, T_STRING);
+ EVP_DigestUpdate(digestp->md, RSTRING(data)->ptr, RSTRING(data)->len);
+ }
+ return self;
+}
+
+static VALUE ossl_dss_initialize(int argc, VALUE *argv, VALUE self)
+{
+ ossl_digest *digestp = NULL;
+ VALUE data;
+
+ GetDigest(self, digestp);
+ if (!(digestp->md = malloc(sizeof(EVP_MD_CTX)))) {
+ rb_raise(eDigestError, "Cannot allocate memory for new digest");
+ }
+ EVP_DigestInit(digestp->md, EVP_dss());
+
+ if (rb_scan_args(argc, argv, "01", &data) == 1) {
+ Check_Type(data, T_STRING);
+ EVP_DigestUpdate(digestp->md, RSTRING(data)->ptr, RSTRING(data)->len);
+ }
+ return self;
+}
+
+static VALUE ossl_dss1_initialize(int argc, VALUE *argv, VALUE self)
+{
+ ossl_digest *digestp = NULL;
+ VALUE data;
+
+ GetDigest(self, digestp);
+ if (!(digestp->md = malloc(sizeof(EVP_MD_CTX)))) {
+ rb_raise(eDigestError, "Cannot allocate memory for new digest");
+ }
+ EVP_DigestInit(digestp->md, EVP_dss1());
+
+ if (rb_scan_args(argc, argv, "01", &data) == 1) {
+ Check_Type(data, T_STRING);
+ EVP_DigestUpdate(digestp->md, RSTRING(data)->ptr, RSTRING(data)->len);
+ }
+ return self;
+}
+
+/*
+ * INIT
+ */
+void Init_ossl_digest(VALUE mDigest)
+{
+ eDigestError = rb_define_class_under(mDigest, "Error", rb_eStandardError);
+
+ cDigest = rb_define_class_under(mDigest, "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);
+ 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_str", "hexdigest");
+ /*rb_define_method(cDigest, "==", ossl_digest_equal, 1);*/
+
+ /* MD2 */
+ cMD2 = rb_define_class_under(mDigest, "MD2", cDigest);
+ rb_define_method(cMD2, "initialize", ossl_md2_initialize, -1);
+
+ /* MD5 */
+ cMD5 = rb_define_class_under(mDigest, "MD5", cDigest);
+ rb_define_method(cMD5, "initialize", ossl_md5_initialize, -1);
+
+ /* MDC2 */
+ cMDC2 = rb_define_class_under(mDigest, "MDC2", cDigest);
+ rb_define_method(cMDC2, "initialize", ossl_mdc2_initialize, -1);
+
+ /* RIPEmd160 */
+ cRIPEMD160 = rb_define_class_under(mDigest, "Ripemd160", cDigest);
+ rb_define_method(cRIPEMD160, "initialize", ossl_ripemd160_initialize, -1);
+
+ /* SHA */
+ cSHA = rb_define_class_under(mDigest, "SHA", cDigest);
+ rb_define_method(cSHA, "initialize", ossl_sha_initialize, -1);
+
+ /* SHA1 */
+ cSHA1 = rb_define_class_under(mDigest, "SHA1", cDigest);
+ rb_define_method(cSHA1, "initialize", ossl_sha1_initialize, -1);
+
+ /* SHA for DSA */
+ cDSS = rb_define_class_under(mDigest, "DSS", cDigest);
+ rb_define_method(cDSS, "initialize", ossl_dss_initialize, -1);
+
+ /* SHA1 for DSA */
+ cDSS1 = rb_define_class_under(mDigest, "DSS1", cDigest);
+ rb_define_method(cDSS1, "initialize", ossl_dss1_initialize, -1);
+}
+