summaryrefslogtreecommitdiff
path: root/ruby_1_9_3/ext/openssl/ossl_digest.c
diff options
context:
space:
mode:
Diffstat (limited to 'ruby_1_9_3/ext/openssl/ossl_digest.c')
-rw-r--r--ruby_1_9_3/ext/openssl/ossl_digest.c438
1 files changed, 0 insertions, 438 deletions
diff --git a/ruby_1_9_3/ext/openssl/ossl_digest.c b/ruby_1_9_3/ext/openssl/ossl_digest.c
deleted file mode 100644
index fdf13e98e5..0000000000
--- a/ruby_1_9_3/ext/openssl/ossl_digest.c
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * $Id$
- * 'OpenSSL for Ruby' project
- * Copyright (C) 2001-2002 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 GetDigest(obj, ctx) do { \
- Data_Get_Struct((obj), EVP_MD_CTX, (ctx)); \
- if (!(ctx)) { \
- ossl_raise(rb_eRuntimeError, "Digest CTX wasn't initialized!"); \
- } \
-} while (0)
-#define SafeGetDigest(obj, ctx) do { \
- OSSL_Check_Kind((obj), cDigest); \
- GetDigest((obj), (ctx)); \
-} while (0)
-
-/*
- * Classes
- */
-VALUE cDigest;
-VALUE eDigestError;
-
-static VALUE ossl_digest_alloc(VALUE klass);
-
-/*
- * Public
- */
-const EVP_MD *
-GetDigestPtr(VALUE obj)
-{
- const EVP_MD *md;
- ASN1_OBJECT *oid = NULL;
-
- if (TYPE(obj) == T_STRING) {
- const char *name = StringValueCStr(obj);
-
- md = EVP_get_digestbyname(name);
- if (!md) {
- oid = OBJ_txt2obj(name, 0);
- md = EVP_get_digestbyobj(oid);
- ASN1_OBJECT_free(oid);
- }
- if(!md)
- ossl_raise(rb_eRuntimeError, "Unsupported digest algorithm (%s).", name);
- } else {
- EVP_MD_CTX *ctx;
-
- SafeGetDigest(obj, ctx);
-
- md = EVP_MD_CTX_md(ctx);
- }
-
- return md;
-}
-
-VALUE
-ossl_digest_new(const EVP_MD *md)
-{
- VALUE ret;
- EVP_MD_CTX *ctx;
-
- ret = ossl_digest_alloc(cDigest);
- GetDigest(ret, ctx);
- if (EVP_DigestInit_ex(ctx, md, NULL) != 1) {
- ossl_raise(eDigestError, "Digest initialization failed.");
- }
-
- return ret;
-}
-
-/*
- * Private
- */
-static VALUE
-ossl_digest_alloc(VALUE klass)
-{
- EVP_MD_CTX *ctx;
- VALUE obj;
-
- ctx = EVP_MD_CTX_create();
- if (ctx == NULL)
- ossl_raise(rb_eRuntimeError, "EVP_MD_CTX_create() failed");
- obj = Data_Wrap_Struct(klass, 0, EVP_MD_CTX_destroy, ctx);
-
- return obj;
-}
-
-VALUE ossl_digest_update(VALUE, VALUE);
-
-/*
- * call-seq:
- * Digest.new(string [, data]) -> Digest
- *
- * Creates a Digest instance based on +string+, which is either the ln
- * (long name) or sn (short name) of a supported digest algorithm.
- * If +data+ (a +String+) is given, it is used as the initial input to the
- * Digest instance, i.e.
- * digest = OpenSSL::Digest.new('sha256', 'digestdata')
- * is equal to
- * digest = OpenSSL::Digest.new('sha256')
- * digest.update('digestdata')
- *
- * === Example
- * digest = OpenSSL::Digest.new('sha1')
- *
- *
- */
-static VALUE
-ossl_digest_initialize(int argc, VALUE *argv, VALUE self)
-{
- EVP_MD_CTX *ctx;
- const EVP_MD *md;
- VALUE type, data;
-
- rb_scan_args(argc, argv, "11", &type, &data);
- md = GetDigestPtr(type);
- if (!NIL_P(data)) StringValue(data);
-
- GetDigest(self, ctx);
- if (EVP_DigestInit_ex(ctx, md, NULL) != 1) {
- ossl_raise(eDigestError, "Digest initialization failed.");
- }
-
- if (!NIL_P(data)) return ossl_digest_update(self, data);
- return self;
-}
-
-static VALUE
-ossl_digest_copy(VALUE self, VALUE other)
-{
- EVP_MD_CTX *ctx1, *ctx2;
-
- rb_check_frozen(self);
- if (self == other) return self;
-
- GetDigest(self, ctx1);
- SafeGetDigest(other, ctx2);
-
- if (!EVP_MD_CTX_copy(ctx1, ctx2)) {
- ossl_raise(eDigestError, NULL);
- }
- return self;
-}
-
-/*
- * call-seq:
- * digest.reset -> self
- *
- * Resets the Digest in the sense that any Digest#update that has been
- * performed is abandoned and the Digest is set to its initial state again.
- *
- */
-static VALUE
-ossl_digest_reset(VALUE self)
-{
- EVP_MD_CTX *ctx;
-
- GetDigest(self, ctx);
- if (EVP_DigestInit_ex(ctx, EVP_MD_CTX_md(ctx), NULL) != 1) {
- ossl_raise(eDigestError, "Digest initialization failed.");
- }
-
- return self;
-}
-
-/*
- * call-seq:
- * digest.update(string) -> aString
- *
- * Not every message digest can be computed in one single pass. If a message
- * digest is to be computed from several subsequent sources, then each may
- * be passed individually to the Digest instance.
- *
- * === Example
- * digest = OpenSSL::Digest::SHA256.new
- * digest.update('First input')
- * digest << 'Second input' # equivalent to digest.update('Second input')
- * result = digest.digest
- *
- */
-VALUE
-ossl_digest_update(VALUE self, VALUE data)
-{
- EVP_MD_CTX *ctx;
-
- StringValue(data);
- GetDigest(self, ctx);
- EVP_DigestUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data));
-
- return self;
-}
-
-/*
- * call-seq:
- * digest.finish -> aString
- *
- */
-static VALUE
-ossl_digest_finish(int argc, VALUE *argv, VALUE self)
-{
- EVP_MD_CTX *ctx;
- VALUE str;
-
- rb_scan_args(argc, argv, "01", &str);
-
- GetDigest(self, ctx);
-
- 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));
- }
-
- EVP_DigestFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), NULL);
-
- return str;
-}
-
-/*
- * call-seq:
- * digest.name -> string
- *
- * Returns the sn of this Digest instance.
- *
- * === Example
- * digest = OpenSSL::Digest::SHA512.new
- * puts digest.name # => SHA512
- *
- */
-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)));
-}
-
-/*
- * call-seq:
- * digest.digest_length -> integer
- *
- * Returns the output size of the digest, i.e. the length in bytes of the
- * final message digest result.
- *
- * === Example
- * digest = OpenSSL::Digest::SHA1.new
- * puts digest.digest_length # => 20
- *
- */
-static VALUE
-ossl_digest_size(VALUE self)
-{
- EVP_MD_CTX *ctx;
-
- GetDigest(self, ctx);
-
- return INT2NUM(EVP_MD_CTX_size(ctx));
-}
-
-/*
- * call-seq:
- * digest.block_length -> integer
- *
- * Returns the block length of the digest algorithm, i.e. the length in bytes
- * of an individual block. Most modern algorithms partition a message to be
- * digested into a sequence of fix-sized blocks that are processed
- * consecutively.
- *
- * === Example
- * digest = OpenSSL::Digest::SHA1.new
- * puts digest.block_length # => 64
- */
-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("digest");
-
-#if 0
- mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
-#endif
-
- /* Document-class: OpenSSL::Digest
- *
- * OpenSSL::Digest allows you to compute message digests (sometimes
- * interchangeably called "hashes") of arbitrary data that are
- * cryptographically secure, i.e. a Digest implements a secure one-way
- * function.
- *
- * One-way functions offer some useful properties. E.g. given two
- * distinct inputs the probability that both yield the same output
- * is highly unlikely. Combined with the fact that every message digest
- * algorithm has a fixed-length output of just a few bytes, digests are
- * often used to create unique identifiers for arbitrary data. A common
- * example is the creation of a unique id for binary documents that are
- * stored in a database.
- *
- * Another useful characteristic of one-way functions (and thus the name)
- * is that given a digest there is no indication about the original
- * data that produced it, i.e. the only way to identify the original input
- * is to "brute-force" through every possible combination of inputs.
- *
- * These characteristics make one-way functions also ideal companions
- * for public key signature algorithms: instead of signing an entire
- * document, first a hash of the document is produced with a considerably
- * faster message digest algorithm and only the few bytes of its output
- * need to be signed using the slower public key algorithm. To validate
- * the integrity of a signed document, it suffices to re-compute the hash
- * and verify that it is equal to that in the signature.
- *
- * Among the supported message digest algorithms are:
- * * SHA, SHA1, SHA224, SHA256, SHA384 and SHA512
- * * MD2, MD4, MDC2 and MD5
- * * RIPEMD160
- * * DSS, DSS1 (Pseudo algorithms to be used for DSA signatures. DSS is
- * equal to SHA and DSS1 is equal to SHA1)
- *
- * For each of these algorithms, there is a sub-class of Digest that
- * can be instantiated as simply as e.g.
- *
- * digest = OpenSSL::Digest::SHA1.new
- *
- * === Mapping between Digest class and sn/ln
- *
- * The sn (short names) and ln (long names) are defined in
- * <openssl/object.h> and <openssl/obj_mac.h>. They are textual
- * representations of ASN.1 OBJECT IDENTIFIERs. Each supported digest
- * algorithm has an OBJECT IDENTIFIER associated to it and those again
- * have short/long names assigned to them.
- * E.g. the OBJECT IDENTIFIER for SHA-1 is 1.3.14.3.2.26 and its
- * sn is "SHA1" and its ln is "sha1".
- * ==== MD2
- * * sn: MD2
- * * ln: md2
- * ==== MD4
- * * sn: MD4
- * * ln: md4
- * ==== MD5
- * * sn: MD5
- * * ln: md5
- * ==== SHA
- * * sn: SHA
- * * ln: SHA
- * ==== SHA-1
- * * sn: SHA1
- * * ln: sha1
- * ==== SHA-224
- * * sn: SHA224
- * * ln: sha224
- * ==== SHA-256
- * * sn: SHA256
- * * ln: sha256
- * ==== SHA-384
- * * sn: SHA384
- * * ln: sha384
- * ==== SHA-512
- * * sn: SHA512
- * * ln: sha512
- *
- * "Breaking" a message digest algorithm means defying its one-way
- * function characteristics, i.e. producing a collision or finding a way
- * to get to the original data by means that are more efficient than
- * brute-forcing etc. Most of the supported digest algorithms can be
- * considered broken in this sense, even the very popular MD5 and SHA1
- * algorithms. Should security be your highest concern, then you should
- * probably rely on SHA224, SHA256, SHA384 or SHA512.
- *
- * === Hashing a file
- *
- * data = File.read('document')
- * sha256 = OpenSSL::Digest::SHA256.new
- * digest = sha256.digest(data)
- *
- * === Hashing several pieces of data at once
- *
- * data1 = File.read('file1')
- * data2 = File.read('file2')
- * data3 = File.read('file3')
- * sha256 = OpenSSL::Digest::SHA256.new
- * sha256 << data1
- * sha256 << data2
- * sha256 << data3
- * digest = sha256.digest
- *
- * === Reuse a Digest instance
- *
- * data1 = File.read('file1')
- * sha256 = OpenSSL::Digest::SHA256.new
- * digest1 = sha256.digest(data1)
- *
- * data2 = File.read('file2')
- * sha256.reset
- * digest2 = sha256.digest(data2)
- *
- */
- cDigest = rb_define_class_under(mOSSL, "Digest", rb_path2class("Digest::Class"));
- /* Document-class: OpenSSL::Digest::DigestError
- *
- * Generic Exception class that is raised if an error occurs during a
- * Digest operation.
- */
- eDigestError = rb_define_class_under(cDigest, "DigestError", eOSSLError);
-
- rb_define_alloc_func(cDigest, ossl_digest_alloc);
-
- rb_define_method(cDigest, "initialize", ossl_digest_initialize, -1);
- rb_define_copy_func(cDigest, ossl_digest_copy);
- 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_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);
-}