pvalena / rpms / ruby

Forked from rpms/ruby 2 years ago
Clone
Blob Blame Raw
diff --git a/ext/openssl/lib/openssl/digest.rb b/ext/openssl/lib/openssl/digest.rb
index b3e4484..4810f01 100644
--- a/ext/openssl/lib/openssl/digest.rb
+++ b/ext/openssl/lib/openssl/digest.rb
@@ -19,13 +19,17 @@
 #require 'openssl'
 
 module OpenSSL
-  module Digest
+  class Digest
 
     alg = %w(DSS DSS1 MD2 MD4 MD5 MDC2 RIPEMD160 SHA SHA1)
     if OPENSSL_VERSION_NUMBER > 0x00908000
       alg += %w(SHA224 SHA256 SHA384 SHA512)
     end
 
+    def self.digest(name, data)
+        super(data, name)
+    end
+
     alg.each{|name|
       klass = Class.new(Digest){
         define_method(:initialize){|*data|
@@ -44,6 +48,14 @@ module OpenSSL
       const_set(name, klass)
     }
 
+    # This class is only provided for backwards compatibility.  Use OpenSSL::Digest in the future.
+    class Digest < Digest
+      def initialize(*args)
+        # add warning
+        super(*args)
+      end
+    end
+
   end # Digest
 end # OpenSSL
 
diff --git a/ext/openssl/ossl_digest.c b/ext/openssl/ossl_digest.c
index 4096b09..b0308f0 100644
--- a/ext/openssl/ossl_digest.c
+++ b/ext/openssl/ossl_digest.c
@@ -40,7 +40,7 @@ GetDigestPtr(VALUE obj)
 
     SafeGetDigest(obj, ctx);
 
-    return EVP_MD_CTX_md(ctx); /*== ctx->digest*/
+    return EVP_MD_CTX_md(ctx);
 }
 
 VALUE
@@ -51,7 +51,6 @@ ossl_digest_new(const EVP_MD *md)
 
     ret = ossl_digest_alloc(cDigest);
     GetDigest(ret, ctx);
-    EVP_MD_CTX_init(ctx);
     EVP_DigestInit_ex(ctx, md, NULL);
    
     return ret;
@@ -69,9 +68,8 @@ ossl_digest_alloc(VALUE klass)
     ctx = EVP_MD_CTX_create();
     if (ctx == NULL)
 	ossl_raise(rb_eRuntimeError, "EVP_MD_CTX_create() failed");
-    EVP_MD_CTX_init(ctx);
     obj = Data_Wrap_Struct(klass, 0, EVP_MD_CTX_destroy, ctx);
-	
+
     return obj;
 }
 
@@ -86,14 +84,9 @@ ossl_digest_initialize(int argc, VALUE *argv, VALUE self)
     VALUE type, data;
 
     rb_scan_args(argc, argv, "11", &type, &data);
-    StringValue(type);
+    md = GetDigestPtr(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);
     
@@ -141,75 +134,25 @@ ossl_digest_update(VALUE self, VALUE data)
     return self;
 }
 
-static void
-digest_final(EVP_MD_CTX *ctx, char **buf, int *buf_len)
-{
-    EVP_MD_CTX final;
-
-    if (!EVP_MD_CTX_copy(&final, ctx)) {
-	ossl_raise(eDigestError, NULL);
-    }
-    if (!(*buf = OPENSSL_malloc(EVP_MD_CTX_size(&final)))) {
-	EVP_MD_CTX_cleanup(&final);
-	ossl_raise(eDigestError, "Cannot allocate mem for digest");
-    }
-    EVP_DigestFinal_ex(&final, *buf, buf_len);
-    EVP_MD_CTX_cleanup(&final);
-}
-
-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)
+ossl_digest_finish(int argc, VALUE *argv, VALUE self)
 {
     EVP_MD_CTX *ctx;
-    char *buf, *hexbuf;
-    int buf_len;
-    VALUE hexdigest;
+    VALUE str;
+    rb_scan_args(argc, argv, "01", &str);
 
     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");
+    if (NIL_P(str)) {
+        str = rb_str_new(NULL, EVP_MD_CTX_size(ctx));
+    } else {
+        StringValue(str);
+        rb_str_resize(str, EVP_MD_CTX_size(ctx));
     }
-    OPENSSL_free(buf);
-    hexdigest = ossl_buf2str(hexbuf, 2 * buf_len);
 
-    return hexdigest;
-}
-
-static VALUE
-ossl_digest_s_digest(VALUE klass, VALUE str, VALUE data)
-{
-    VALUE obj = rb_class_new_instance(1, &str, klass);
+    EVP_DigestFinal_ex(ctx, RSTRING_PTR(str), NULL);
 
-    ossl_digest_update(obj, data);
+    return str;
 
-    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
@@ -258,41 +201,44 @@ ossl_digest_size(VALUE self)
     return INT2NUM(EVP_MD_CTX_size(ctx));
 }
 
+static VALUE
+ossl_digest_block_length(VALUE self)
+{
+    EVP_MD_CTX *ctx;
+ 
+    GetDigest(self, ctx);
+ 
+    return INT2NUM(EVP_MD_CTX_block_size(ctx));
+}
+
+
 /*
  * INIT
  */
 void
 Init_ossl_digest()
 {
+    rb_require("openssl");
+    rb_require("digest");
+
 #if 0 /* let rdoc know about mOSSL */
     mOSSL = rb_define_module("OpenSSL");
 #endif
 
-    mDigest = rb_define_module_under(mOSSL, "Digest");
-	
-    eDigestError = rb_define_class_under(mDigest, "DigestError", eOSSLError);
-	
-    cDigest = rb_define_class_under(mDigest, "Digest", rb_cObject);
-	
+    cDigest = rb_define_class_under(mOSSL, "Digest", rb_path2class("Digest::Class"));
+    eDigestError = rb_define_class_under(cDigest, "DigestError", eOSSLError);
+
     rb_define_alloc_func(cDigest, ossl_digest_alloc);
-    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_define_method(cDigest, "reset", ossl_digest_reset, 0);
-    
     rb_define_copy_func(cDigest, ossl_digest_copy);
-    
-    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, "reset", ossl_digest_reset, 0);
     rb_define_method(cDigest, "update", ossl_digest_update, 1);
     rb_define_alias(cDigest, "<<", "update");
-    
-    rb_define_method(cDigest, "==", ossl_digest_equal, 1);
-    
+    rb_define_private_method(cDigest, "finish", ossl_digest_finish, -1);
+    rb_define_method(cDigest, "digest_length", ossl_digest_size, 0);
+    rb_define_method(cDigest, "block_length", ossl_digest_block_length, 0);
+
     rb_define_method(cDigest, "name", ossl_digest_name, 0);
-    rb_define_method(cDigest, "size", ossl_digest_size, 0);
 }
+