Ruby  1.9.3p429(2013-05-15revision40747)
digest.c
Go to the documentation of this file.
1 /************************************************
2 
3  digest.c -
4 
5  $Author: drbrain $
6  created at: Fri May 25 08:57:27 JST 2001
7 
8  Copyright (C) 1995-2001 Yukihiro Matsumoto
9  Copyright (C) 2001-2006 Akinori MUSHA
10 
11  $RoughId: digest.c,v 1.16 2001/07/13 15:38:27 knu Exp $
12  $Id: digest.c 32951 2011-08-12 17:26:00Z drbrain $
13 
14 ************************************************/
15 
16 #include "digest.h"
17 
22 
24 static ID id_metadata;
25 
26 RUBY_EXTERN void Init_digest_base(void);
27 
28 /*
29  * Document-module: Digest
30  *
31  * This module provides a framework for message digest libraries.
32  *
33  * You may want to look at OpenSSL::Digest as it supports support more
34  * algorithms.
35  *
36  * A cryptographic hash function is a procedure that takes data and return a
37  * fixed bit string : the hash value, also known as _digest_. Hash functions
38  * are also called one-way functions, it is easy to compute a digest from
39  * a message, but it is infeasible to generate a message from a digest.
40  *
41  * == Example
42  *
43  * require 'digest'
44  *
45  * # Compute a complete digest
46  * sha256 = Digest::SHA256.new
47  * digest = sha256.digest message
48  *
49  * # Compute digest by chunks
50  * sha256 = Digest::SHA256.new
51  * sha256.update message1
52  * sha256 << message2 # << is an alias for update
53  *
54  * digest = sha256.digest
55  *
56  * == Digest algorithms
57  *
58  * Different digest algorithms (or hash functions) are available :
59  *
60  * HMAC::
61  * See FIPS PUB 198 The Keyed-Hash Message Authentication Code (HMAC)
62  * RIPEMD-160::
63  * (as Digest::RMD160) see
64  * http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
65  * SHA1::
66  * See FIPS 180 Secure Hash Standard
67  * SHA2 family::
68  * See FIPS 180 Secure Hash Standard which defines the following algorithms:
69  * * SHA512
70  * * SHA384
71  * * SHA256
72  *
73  * The latest versions of the FIPS publications can be found here:
74  * http://csrc.nist.gov/publications/PubsFIPS.html
75  *
76  * Additionally Digest::BubbleBabble encodes a digest as a sequence of
77  * consonants and vowels which is more recognizable and comparable than a
78  * hexadecimal digest. See http://en.wikipedia.org/wiki/Bubblebabble
79  */
80 
81 static VALUE
83 {
84  char *digest;
85  size_t digest_len;
86  size_t i;
87  VALUE str;
88  char *p;
89  static const char hex[] = {
90  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
91  'a', 'b', 'c', 'd', 'e', 'f'
92  };
93 
94  StringValue(str_digest);
95  digest = RSTRING_PTR(str_digest);
96  digest_len = RSTRING_LEN(str_digest);
97 
98  if (LONG_MAX / 2 < digest_len) {
99  rb_raise(rb_eRuntimeError, "digest string too long");
100  }
101 
102  str = rb_str_new(0, digest_len * 2);
103 
104  for (i = 0, p = RSTRING_PTR(str); i < digest_len; i++) {
105  unsigned char byte = digest[i];
106 
107  p[i + i] = hex[byte >> 4];
108  p[i + i + 1] = hex[byte & 0x0f];
109  }
110 
111  return str;
112 }
113 
114 /*
115  * call-seq:
116  * Digest.hexencode(string) -> hexencoded_string
117  *
118  * Generates a hex-encoded version of a given _string_.
119  */
120 static VALUE
122 {
123  return hexencode_str_new(str);
124 }
125 
126 NORETURN(static void rb_digest_instance_method_unimpl(VALUE self, const char *method));
127 
128 /*
129  * Document-module: Digest::Instance
130  *
131  * This module provides instance methods for a digest implementation
132  * object to calculate message digest values.
133  */
134 
135 static void
136 rb_digest_instance_method_unimpl(VALUE self, const char *method)
137 {
138  rb_raise(rb_eRuntimeError, "%s does not implement %s()",
139  rb_obj_classname(self), method);
140 }
141 
142 /*
143  * call-seq:
144  * digest_obj.update(string) -> digest_obj
145  * digest_obj << string -> digest_obj
146  *
147  * Updates the digest using a given _string_ and returns self.
148  *
149  * The update() method and the left-shift operator are overridden by
150  * each implementation subclass. (One should be an alias for the
151  * other)
152  */
153 static VALUE
155 {
156  rb_digest_instance_method_unimpl(self, "update");
157 }
158 
159 /*
160  * call-seq:
161  * digest_obj.instance_eval { finish } -> digest_obj
162  *
163  * Finishes the digest and returns the resulting hash value.
164  *
165  * This method is overridden by each implementation subclass and often
166  * made private, because some of those subclasses may leave internal
167  * data uninitialized. Do not call this method from outside. Use
168  * #digest!() instead, which ensures that internal data be reset for
169  * security reasons.
170  */
171 static VALUE
173 {
174  rb_digest_instance_method_unimpl(self, "finish");
175 }
176 
177 /*
178  * call-seq:
179  * digest_obj.reset -> digest_obj
180  *
181  * Resets the digest to the initial state and returns self.
182  *
183  * This method is overridden by each implementation subclass.
184  */
185 static VALUE
187 {
188  rb_digest_instance_method_unimpl(self, "reset");
189 }
190 
191 /*
192  * call-seq:
193  * digest_obj.new -> another_digest_obj
194  *
195  * Returns a new, initialized copy of the digest object. Equivalent
196  * to digest_obj.clone().reset().
197  */
198 static VALUE
200 {
201  VALUE clone = rb_obj_clone(self);
202  rb_funcall(clone, id_reset, 0);
203  return clone;
204 }
205 
206 /*
207  * call-seq:
208  * digest_obj.digest -> string
209  * digest_obj.digest(string) -> string
210  *
211  * If none is given, returns the resulting hash value of the digest,
212  * keeping the digest's state.
213  *
214  * If a _string_ is given, returns the hash value for the given
215  * _string_, resetting the digest to the initial state before and
216  * after the process.
217  */
218 static VALUE
220 {
221  VALUE str, value;
222 
223  if (rb_scan_args(argc, argv, "01", &str) > 0) {
224  rb_funcall(self, id_reset, 0);
225  rb_funcall(self, id_update, 1, str);
226  value = rb_funcall(self, id_finish, 0);
227  rb_funcall(self, id_reset, 0);
228  } else {
229  value = rb_funcall(rb_obj_clone(self), id_finish, 0);
230  }
231 
232  return value;
233 }
234 
235 /*
236  * call-seq:
237  * digest_obj.digest! -> string
238  *
239  * Returns the resulting hash value and resets the digest to the
240  * initial state.
241  */
242 static VALUE
244 {
245  VALUE value = rb_funcall(self, id_finish, 0);
246  rb_funcall(self, id_reset, 0);
247 
248  return value;
249 }
250 
251 /*
252  * call-seq:
253  * digest_obj.hexdigest -> string
254  * digest_obj.hexdigest(string) -> string
255  *
256  * If none is given, returns the resulting hash value of the digest in
257  * a hex-encoded form, keeping the digest's state.
258  *
259  * If a _string_ is given, returns the hash value for the given
260  * _string_ in a hex-encoded form, resetting the digest to the initial
261  * state before and after the process.
262  */
263 static VALUE
265 {
266  VALUE str, value;
267 
268  if (rb_scan_args(argc, argv, "01", &str) > 0) {
269  rb_funcall(self, id_reset, 0);
270  rb_funcall(self, id_update, 1, str);
271  value = rb_funcall(self, id_finish, 0);
272  rb_funcall(self, id_reset, 0);
273  } else {
274  value = rb_funcall(rb_obj_clone(self), id_finish, 0);
275  }
276 
277  return hexencode_str_new(value);
278 }
279 
280 /*
281  * call-seq:
282  * digest_obj.hexdigest! -> string
283  *
284  * Returns the resulting hash value in a hex-encoded form and resets
285  * the digest to the initial state.
286  */
287 static VALUE
289 {
290  VALUE value = rb_funcall(self, id_finish, 0);
291  rb_funcall(self, id_reset, 0);
292 
293  return hexencode_str_new(value);
294 }
295 
296 /*
297  * call-seq:
298  * digest_obj.to_s -> string
299  *
300  * Returns digest_obj.hexdigest().
301  */
302 static VALUE
304 {
305  return rb_funcall(self, id_hexdigest, 0);
306 }
307 
308 /*
309  * call-seq:
310  * digest_obj.inspect -> string
311  *
312  * Creates a printable version of the digest object.
313  */
314 static VALUE
316 {
317  VALUE str;
318  size_t digest_len = 32; /* about this size at least */
319  const char *cname;
320 
321  cname = rb_obj_classname(self);
322 
323  /* #<Digest::ClassName: xxxxx...xxxx> */
324  str = rb_str_buf_new(2 + strlen(cname) + 2 + digest_len * 2 + 1);
325  rb_str_buf_cat2(str, "#<");
326  rb_str_buf_cat2(str, cname);
327  rb_str_buf_cat2(str, ": ");
329  rb_str_buf_cat2(str, ">");
330  return str;
331 }
332 
333 /*
334  * call-seq:
335  * digest_obj == another_digest_obj -> boolean
336  * digest_obj == string -> boolean
337  *
338  * If a string is given, checks whether it is equal to the hex-encoded
339  * hash value of the digest object. If another digest instance is
340  * given, checks whether they have the same hash value. Otherwise
341  * returns false.
342  */
343 static VALUE
345 {
346  VALUE str1, str2;
347 
349  str1 = rb_digest_instance_digest(0, 0, self);
350  str2 = rb_digest_instance_digest(0, 0, other);
351  } else {
352  str1 = rb_digest_instance_to_s(self);
353  str2 = other;
354  }
355 
356  /* never blindly assume that subclass methods return strings */
357  StringValue(str1);
358  StringValue(str2);
359 
360  if (RSTRING_LEN(str1) == RSTRING_LEN(str2) &&
361  rb_str_cmp(str1, str2) == 0) {
362  return Qtrue;
363  }
364  return Qfalse;
365 }
366 
367 /*
368  * call-seq:
369  * digest_obj.digest_length -> integer
370  *
371  * Returns the length of the hash value of the digest.
372  *
373  * This method should be overridden by each implementation subclass.
374  * If not, digest_obj.digest().length() is returned.
375  */
376 static VALUE
378 {
379  /* subclasses really should redefine this method */
380  VALUE digest = rb_digest_instance_digest(0, 0, self);
381 
382  /* never blindly assume that #digest() returns a string */
383  StringValue(digest);
384  return INT2NUM(RSTRING_LEN(digest));
385 }
386 
387 /*
388  * call-seq:
389  * digest_obj.length -> integer
390  * digest_obj.size -> integer
391  *
392  * Returns digest_obj.digest_length().
393  */
394 static VALUE
396 {
397  return rb_funcall(self, id_digest_length, 0);
398 }
399 
400 /*
401  * call-seq:
402  * digest_obj.block_length -> integer
403  *
404  * Returns the block length of the digest.
405  *
406  * This method is overridden by each implementation subclass.
407  */
408 static VALUE
410 {
411  rb_digest_instance_method_unimpl(self, "block_length");
412 }
413 
414 /*
415  * Document-class: Digest::Class
416  *
417  * This module stands as a base class for digest implementation
418  * classes.
419  */
420 
421 /*
422  * call-seq:
423  * Digest::Class.digest(string, *parameters) -> hash_string
424  *
425  * Returns the hash value of a given _string_. This is equivalent to
426  * Digest::Class.new(*parameters).digest(string), where extra
427  * _parameters_, if any, are passed through to the constructor and the
428  * _string_ is passed to #digest().
429  */
430 static VALUE
432 {
433  VALUE str;
434  volatile VALUE obj;
435 
436  if (argc < 1) {
437  rb_raise(rb_eArgError, "no data given");
438  }
439 
440  str = *argv++;
441  argc--;
442 
443  StringValue(str);
444 
445  obj = rb_obj_alloc(klass);
446  rb_obj_call_init(obj, argc, argv);
447 
448  return rb_funcall(obj, id_digest, 1, str);
449 }
450 
451 /*
452  * call-seq:
453  * Digest::Class.hexdigest(string[, ...]) -> hash_string
454  *
455  * Returns the hex-encoded hash value of a given _string_. This is
456  * almost equivalent to
457  * Digest.hexencode(Digest::Class.new(*parameters).digest(string)).
458  */
459 static VALUE
461 {
462  return hexencode_str_new(rb_funcall2(klass, id_digest, argc, argv));
463 }
464 
465 /* :nodoc: */
466 static VALUE
468 {
469  return self;
470 }
471 
472 /*
473  * Document-class: Digest::Base
474  *
475  * This abstract class provides a common interface to message digest
476  * implementation classes written in C.
477  */
478 
479 static rb_digest_metadata_t *
481 {
482  VALUE p;
483  VALUE obj;
484  rb_digest_metadata_t *algo;
485 
486  for (p = klass; !NIL_P(p); p = rb_class_superclass(p)) {
487  if (rb_ivar_defined(p, id_metadata)) {
488  obj = rb_ivar_get(p, id_metadata);
489  break;
490  }
491  }
492 
493  if (NIL_P(p))
494  rb_raise(rb_eRuntimeError, "Digest::Base cannot be directly inherited in Ruby");
495 
497 
498  switch (algo->api_version) {
499  case 2:
500  break;
501 
502  /*
503  * put conversion here if possible when API is updated
504  */
505 
506  default:
507  rb_raise(rb_eRuntimeError, "Incompatible digest API version");
508  }
509 
510  return algo;
511 }
512 
513 static VALUE
515 {
516  rb_digest_metadata_t *algo;
517  VALUE obj;
518  void *pctx;
519 
520  if (klass == rb_cDigest_Base) {
521  rb_raise(rb_eNotImpError, "Digest::Base is an abstract class");
522  }
523 
524  algo = get_digest_base_metadata(klass);
525 
526  pctx = xmalloc(algo->ctx_size);
527  algo->init_func(pctx);
528 
529  obj = Data_Wrap_Struct(klass, 0, xfree, pctx);
530 
531  return obj;
532 }
533 
534 /* :nodoc: */
535 static VALUE
537 {
538  rb_digest_metadata_t *algo;
539  void *pctx1, *pctx2;
540 
541  if (copy == obj) return copy;
542 
543  rb_check_frozen(copy);
544 
546 
547  Data_Get_Struct(obj, void, pctx1);
548  Data_Get_Struct(copy, void, pctx2);
549  memcpy(pctx2, pctx1, algo->ctx_size);
550 
551  return copy;
552 }
553 
554 /* :nodoc: */
555 static VALUE
557 {
558  rb_digest_metadata_t *algo;
559  void *pctx;
560 
562 
563  Data_Get_Struct(self, void, pctx);
564 
565  algo->init_func(pctx);
566 
567  return self;
568 }
569 
570 /* :nodoc: */
571 static VALUE
573 {
574  rb_digest_metadata_t *algo;
575  void *pctx;
576 
578 
579  Data_Get_Struct(self, void, pctx);
580 
581  StringValue(str);
582  algo->update_func(pctx, (unsigned char *)RSTRING_PTR(str), RSTRING_LEN(str));
583 
584  return self;
585 }
586 
587 /* :nodoc: */
588 static VALUE
590 {
591  rb_digest_metadata_t *algo;
592  void *pctx;
593  VALUE str;
594 
596 
597  Data_Get_Struct(self, void, pctx);
598 
599  str = rb_str_new(0, algo->digest_len);
600  algo->finish_func(pctx, (unsigned char *)RSTRING_PTR(str));
601 
602  /* avoid potential coredump caused by use of a finished context */
603  algo->init_func(pctx);
604 
605  return str;
606 }
607 
608 /* :nodoc: */
609 static VALUE
611 {
612  rb_digest_metadata_t *algo;
613 
615 
616  return INT2NUM(algo->digest_len);
617 }
618 
619 /* :nodoc: */
620 static VALUE
622 {
623  rb_digest_metadata_t *algo;
624 
626 
627  return INT2NUM(algo->block_len);
628 }
629 
630 void
632 {
633  id_reset = rb_intern("reset");
634  id_update = rb_intern("update");
635  id_finish = rb_intern("finish");
636  id_digest = rb_intern("digest");
637  id_hexdigest = rb_intern("hexdigest");
638  id_digest_length = rb_intern("digest_length");
639 
640  /*
641  * module Digest
642  */
643  rb_mDigest = rb_define_module("Digest");
644 
645  /* module functions */
647 
648  /*
649  * module Digest::Instance
650  */
652 
653  /* instance methods that should be overridden */
660 
661  /* instance methods that may be overridden */
664 
665  /* instance methods that need not usually be overridden */
674 
675  /*
676  * class Digest::Class
677  */
681 
682  /* class methods */
685 
686  id_metadata = rb_intern("metadata");
687 
688  /* class Digest::Base < Digest::Class */
690 
692 
693  rb_define_method(rb_cDigest_Base, "initialize_copy", rb_digest_base_copy, 1);
700 }
701