Ruby  2.1.10p492(2016-04-01revision54464)
ossl_digest.c
Go to the documentation of this file.
1 /*
2  * $Id: ossl_digest.c 33634 2011-11-04 07:19:23Z nobu $
3  * 'OpenSSL for Ruby' project
4  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5  * All rights reserved.
6  */
7 /*
8  * This program is licenced under the same licence as Ruby.
9  * (See the file 'LICENCE'.)
10  */
11 #include "ossl.h"
12 
13 #define GetDigest(obj, ctx) do { \
14  Data_Get_Struct((obj), EVP_MD_CTX, (ctx)); \
15  if (!(ctx)) { \
16  ossl_raise(rb_eRuntimeError, "Digest CTX wasn't initialized!"); \
17  } \
18 } while (0)
19 #define SafeGetDigest(obj, ctx) do { \
20  OSSL_Check_Kind((obj), cDigest); \
21  GetDigest((obj), (ctx)); \
22 } while (0)
23 
24 /*
25  * Classes
26  */
29 
30 static VALUE ossl_digest_alloc(VALUE klass);
31 
32 /*
33  * Public
34  */
35 const EVP_MD *
37 {
38  const EVP_MD *md;
39  ASN1_OBJECT *oid = NULL;
40 
41  if (TYPE(obj) == T_STRING) {
42  const char *name = StringValueCStr(obj);
43 
44  md = EVP_get_digestbyname(name);
45  if (!md) {
46  oid = OBJ_txt2obj(name, 0);
47  md = EVP_get_digestbyobj(oid);
48  ASN1_OBJECT_free(oid);
49  }
50  if(!md)
51  ossl_raise(rb_eRuntimeError, "Unsupported digest algorithm (%s).", name);
52  } else {
53  EVP_MD_CTX *ctx;
54 
55  SafeGetDigest(obj, ctx);
56 
57  md = EVP_MD_CTX_md(ctx);
58  }
59 
60  return md;
61 }
62 
63 VALUE
64 ossl_digest_new(const EVP_MD *md)
65 {
66  VALUE ret;
67  EVP_MD_CTX *ctx;
68 
70  GetDigest(ret, ctx);
71  if (EVP_DigestInit_ex(ctx, md, NULL) != 1) {
72  ossl_raise(eDigestError, "Digest initialization failed.");
73  }
74 
75  return ret;
76 }
77 
78 /*
79  * Private
80  */
81 static VALUE
83 {
84  EVP_MD_CTX *ctx;
85  VALUE obj;
86 
87  ctx = EVP_MD_CTX_create();
88  if (ctx == NULL)
89  ossl_raise(rb_eRuntimeError, "EVP_MD_CTX_create() failed");
90  obj = Data_Wrap_Struct(klass, 0, EVP_MD_CTX_destroy, ctx);
91 
92  return obj;
93 }
94 
96 
97 /*
98  * call-seq:
99  * Digest.new(string [, data]) -> Digest
100  *
101  * Creates a Digest instance based on +string+, which is either the ln
102  * (long name) or sn (short name) of a supported digest algorithm.
103  * If +data+ (a +String+) is given, it is used as the initial input to the
104  * Digest instance, i.e.
105  * digest = OpenSSL::Digest.new('sha256', 'digestdata')
106  * is equal to
107  * digest = OpenSSL::Digest.new('sha256')
108  * digest.update('digestdata')
109  *
110  * === Example
111  * digest = OpenSSL::Digest.new('sha1')
112  *
113  *
114  */
115 static VALUE
117 {
118  EVP_MD_CTX *ctx;
119  const EVP_MD *md;
120  VALUE type, data;
121 
122  rb_scan_args(argc, argv, "11", &type, &data);
123  md = GetDigestPtr(type);
124  if (!NIL_P(data)) StringValue(data);
125 
126  GetDigest(self, ctx);
127  if (EVP_DigestInit_ex(ctx, md, NULL) != 1) {
128  ossl_raise(eDigestError, "Digest initialization failed.");
129  }
130 
131  if (!NIL_P(data)) return ossl_digest_update(self, data);
132  return self;
133 }
134 
135 static VALUE
137 {
138  EVP_MD_CTX *ctx1, *ctx2;
139 
140  rb_check_frozen(self);
141  if (self == other) return self;
142 
143  GetDigest(self, ctx1);
144  SafeGetDigest(other, ctx2);
145 
146  if (!EVP_MD_CTX_copy(ctx1, ctx2)) {
148  }
149  return self;
150 }
151 
152 /*
153  * call-seq:
154  * digest.reset -> self
155  *
156  * Resets the Digest in the sense that any Digest#update that has been
157  * performed is abandoned and the Digest is set to its initial state again.
158  *
159  */
160 static VALUE
162 {
163  EVP_MD_CTX *ctx;
164 
165  GetDigest(self, ctx);
166  if (EVP_DigestInit_ex(ctx, EVP_MD_CTX_md(ctx), NULL) != 1) {
167  ossl_raise(eDigestError, "Digest initialization failed.");
168  }
169 
170  return self;
171 }
172 
173 /*
174  * call-seq:
175  * digest.update(string) -> aString
176  *
177  * Not every message digest can be computed in one single pass. If a message
178  * digest is to be computed from several subsequent sources, then each may
179  * be passed individually to the Digest instance.
180  *
181  * === Example
182  * digest = OpenSSL::Digest::SHA256.new
183  * digest.update('First input')
184  * digest << 'Second input' # equivalent to digest.update('Second input')
185  * result = digest.digest
186  *
187  */
188 VALUE
190 {
191  EVP_MD_CTX *ctx;
192 
193  StringValue(data);
194  GetDigest(self, ctx);
195  EVP_DigestUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data));
196 
197  return self;
198 }
199 
200 /*
201  * call-seq:
202  * digest.finish -> aString
203  *
204  */
205 static VALUE
207 {
208  EVP_MD_CTX *ctx;
209  VALUE str;
210 
211  rb_scan_args(argc, argv, "01", &str);
212 
213  GetDigest(self, ctx);
214 
215  if (NIL_P(str)) {
216  str = rb_str_new(NULL, EVP_MD_CTX_size(ctx));
217  } else {
218  StringValue(str);
219  rb_str_resize(str, EVP_MD_CTX_size(ctx));
220  }
221 
222  EVP_DigestFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), NULL);
223 
224  return str;
225 }
226 
227 /*
228  * call-seq:
229  * digest.name -> string
230  *
231  * Returns the sn of this Digest instance.
232  *
233  * === Example
234  * digest = OpenSSL::Digest::SHA512.new
235  * puts digest.name # => SHA512
236  *
237  */
238 static VALUE
240 {
241  EVP_MD_CTX *ctx;
242 
243  GetDigest(self, ctx);
244 
245  return rb_str_new2(EVP_MD_name(EVP_MD_CTX_md(ctx)));
246 }
247 
248 /*
249  * call-seq:
250  * digest.digest_length -> integer
251  *
252  * Returns the output size of the digest, i.e. the length in bytes of the
253  * final message digest result.
254  *
255  * === Example
256  * digest = OpenSSL::Digest::SHA1.new
257  * puts digest.digest_length # => 20
258  *
259  */
260 static VALUE
262 {
263  EVP_MD_CTX *ctx;
264 
265  GetDigest(self, ctx);
266 
267  return INT2NUM(EVP_MD_CTX_size(ctx));
268 }
269 
270 /*
271  * call-seq:
272  * digest.block_length -> integer
273  *
274  * Returns the block length of the digest algorithm, i.e. the length in bytes
275  * of an individual block. Most modern algorithms partition a message to be
276  * digested into a sequence of fix-sized blocks that are processed
277  * consecutively.
278  *
279  * === Example
280  * digest = OpenSSL::Digest::SHA1.new
281  * puts digest.block_length # => 64
282  */
283 static VALUE
285 {
286  EVP_MD_CTX *ctx;
287 
288  GetDigest(self, ctx);
289 
290  return INT2NUM(EVP_MD_CTX_block_size(ctx));
291 }
292 
293 /*
294  * INIT
295  */
296 void
298 {
299  rb_require("digest");
300 
301 #if 0
302  mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
303 #endif
304 
305  /* Document-class: OpenSSL::Digest
306  *
307  * OpenSSL::Digest allows you to compute message digests (sometimes
308  * interchangeably called "hashes") of arbitrary data that are
309  * cryptographically secure, i.e. a Digest implements a secure one-way
310  * function.
311  *
312  * One-way functions offer some useful properties. E.g. given two
313  * distinct inputs the probability that both yield the same output
314  * is highly unlikely. Combined with the fact that every message digest
315  * algorithm has a fixed-length output of just a few bytes, digests are
316  * often used to create unique identifiers for arbitrary data. A common
317  * example is the creation of a unique id for binary documents that are
318  * stored in a database.
319  *
320  * Another useful characteristic of one-way functions (and thus the name)
321  * is that given a digest there is no indication about the original
322  * data that produced it, i.e. the only way to identify the original input
323  * is to "brute-force" through every possible combination of inputs.
324  *
325  * These characteristics make one-way functions also ideal companions
326  * for public key signature algorithms: instead of signing an entire
327  * document, first a hash of the document is produced with a considerably
328  * faster message digest algorithm and only the few bytes of its output
329  * need to be signed using the slower public key algorithm. To validate
330  * the integrity of a signed document, it suffices to re-compute the hash
331  * and verify that it is equal to that in the signature.
332  *
333  * Among the supported message digest algorithms are:
334  * * SHA, SHA1, SHA224, SHA256, SHA384 and SHA512
335  * * MD2, MD4, MDC2 and MD5
336  * * RIPEMD160
337  * * DSS, DSS1 (Pseudo algorithms to be used for DSA signatures. DSS is
338  * equal to SHA and DSS1 is equal to SHA1)
339  *
340  * For each of these algorithms, there is a sub-class of Digest that
341  * can be instantiated as simply as e.g.
342  *
343  * digest = OpenSSL::Digest::SHA1.new
344  *
345  * === Mapping between Digest class and sn/ln
346  *
347  * The sn (short names) and ln (long names) are defined in
348  * <openssl/object.h> and <openssl/obj_mac.h>. They are textual
349  * representations of ASN.1 OBJECT IDENTIFIERs. Each supported digest
350  * algorithm has an OBJECT IDENTIFIER associated to it and those again
351  * have short/long names assigned to them.
352  * E.g. the OBJECT IDENTIFIER for SHA-1 is 1.3.14.3.2.26 and its
353  * sn is "SHA1" and its ln is "sha1".
354  * ==== MD2
355  * * sn: MD2
356  * * ln: md2
357  * ==== MD4
358  * * sn: MD4
359  * * ln: md4
360  * ==== MD5
361  * * sn: MD5
362  * * ln: md5
363  * ==== SHA
364  * * sn: SHA
365  * * ln: SHA
366  * ==== SHA-1
367  * * sn: SHA1
368  * * ln: sha1
369  * ==== SHA-224
370  * * sn: SHA224
371  * * ln: sha224
372  * ==== SHA-256
373  * * sn: SHA256
374  * * ln: sha256
375  * ==== SHA-384
376  * * sn: SHA384
377  * * ln: sha384
378  * ==== SHA-512
379  * * sn: SHA512
380  * * ln: sha512
381  *
382  * "Breaking" a message digest algorithm means defying its one-way
383  * function characteristics, i.e. producing a collision or finding a way
384  * to get to the original data by means that are more efficient than
385  * brute-forcing etc. Most of the supported digest algorithms can be
386  * considered broken in this sense, even the very popular MD5 and SHA1
387  * algorithms. Should security be your highest concern, then you should
388  * probably rely on SHA224, SHA256, SHA384 or SHA512.
389  *
390  * === Hashing a file
391  *
392  * data = File.read('document')
393  * sha256 = OpenSSL::Digest::SHA256.new
394  * digest = sha256.digest(data)
395  *
396  * === Hashing several pieces of data at once
397  *
398  * data1 = File.read('file1')
399  * data2 = File.read('file2')
400  * data3 = File.read('file3')
401  * sha256 = OpenSSL::Digest::SHA256.new
402  * sha256 << data1
403  * sha256 << data2
404  * sha256 << data3
405  * digest = sha256.digest
406  *
407  * === Reuse a Digest instance
408  *
409  * data1 = File.read('file1')
410  * sha256 = OpenSSL::Digest::SHA256.new
411  * digest1 = sha256.digest(data1)
412  *
413  * data2 = File.read('file2')
414  * sha256.reset
415  * digest2 = sha256.digest(data2)
416  *
417  */
418  cDigest = rb_define_class_under(mOSSL, "Digest", rb_path2class("Digest::Class"));
419  /* Document-class: OpenSSL::Digest::DigestError
420  *
421  * Generic Exception class that is raised if an error occurs during a
422  * Digest operation.
423  */
425 
427 
428  rb_define_method(cDigest, "initialize", ossl_digest_initialize, -1);
432  rb_define_alias(cDigest, "<<", "update");
434  rb_define_method(cDigest, "digest_length", ossl_digest_size, 0);
436 
438 }
VALUE mOSSL
Definition: ossl.c:259
VALUE cDigest
Definition: ossl_digest.c:27
#define INT2NUM(x)
Definition: ruby.h:1296
#define EVP_DigestFinal_ex(ctx, buf, len)
void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1491
static VALUE ossl_digest_block_length(VALUE self)
Definition: ossl_digest.c:284
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:657
VALUE eDigestError
Definition: ossl_digest.c:28
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE rb_path2class(const char *)
Definition: variable.c:379
#define Data_Wrap_Struct(klass, mark, free, sval)
Definition: ruby.h:1018
#define EVP_MD_name(e)
#define rb_define_copy_func(klass, func)
Definition: ruby_missing.h:14
VALUE rb_require(const char *)
Definition: load.c:1036
static VALUE ossl_digest_name(VALUE self)
Definition: ossl_digest.c:239
VALUE rb_eRuntimeError
Definition: error.c:547
VALUE ossl_digest_new(const EVP_MD *md)
Definition: ossl_digest.c:64
#define NIL_P(v)
Definition: ruby.h:438
const EVP_MD * GetDigestPtr(VALUE obj)
Definition: ossl_digest.c:36
VALUE eOSSLError
Definition: ossl.c:264
#define TYPE(x)
Definition: ruby.h:505
int argc
Definition: ruby.c:131
#define rb_str_new2
Definition: intern.h:840
VALUE rb_str_resize(VALUE, long)
Definition: string.c:2024
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1688
#define RSTRING_LEN(str)
Definition: ruby.h:841
EVP_MD_CTX * EVP_MD_CTX_create(void)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1719
int type
Definition: tcltklib.c:112
unsigned long VALUE
Definition: ruby.h:88
#define StringValueCStr(v)
Definition: ruby.h:541
void Init_ossl_digest()
Definition: ossl_digest.c:297
#define RSTRING_PTR(str)
Definition: ruby.h:845
static VALUE ossl_digest_initialize(int argc, VALUE *argv, VALUE self)
Definition: ossl_digest.c:116
static VALUE ossl_digest_copy(VALUE self, VALUE other)
Definition: ossl_digest.c:136
static VALUE ossl_digest_alloc(VALUE klass)
Definition: ossl_digest.c:82
#define SafeGetDigest(obj, ctx)
Definition: ossl_digest.c:19
#define T_STRING
Definition: ruby.h:482
#define EVP_DigestInit_ex(ctx, md, engine)
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:333
const char * name
Definition: nkf.c:208
static VALUE ossl_digest_finish(int argc, VALUE *argv, VALUE self)
Definition: ossl_digest.c:206
static VALUE ossl_digest_size(VALUE self)
Definition: ossl_digest.c:261
#define rb_check_frozen(obj)
Definition: intern.h:277
#define GetDigest(obj, ctx)
Definition: ossl_digest.c:13
VALUE rb_define_module(const char *name)
Definition: class.c:727
VALUE ossl_digest_update(VALUE, VALUE)
Definition: ossl_digest.c:189
#define NULL
Definition: _sdbm.c:102
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1479
static VALUE ossl_digest_reset(VALUE self)
Definition: ossl_digest.c:161
char ** argv
Definition: ruby.c:132
#define StringValue(v)
Definition: ruby.h:539
VALUE rb_str_new(const char *, long)
Definition: string.c:534