Ruby 2.0.0p247(2013-06-27revision41674)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

digest.c
Go to the documentation of this file.
1 /************************************************
2
3 digest.c -
4
5 $Author: eregon $
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 36588 2012-08-01 13:30:51Z eregon $
13
14 ************************************************/
15
16 #include "digest.h"
17
18 static VALUE rb_mDigest;
19 static VALUE rb_mDigest_Instance;
20 static VALUE rb_cDigest_Class;
21 static VALUE rb_cDigest_Base;
22
23 static ID id_reset, id_update, id_finish, id_digest, id_hexdigest, id_digest_length;
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
82 hexencode_str_new(VALUE str_digest)
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_usascii_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
121 rb_digest_s_hexencode(VALUE klass, VALUE str)
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
154 rb_digest_instance_update(VALUE self, VALUE str)
155 {
156 rb_digest_instance_method_unimpl(self, "update");
157
158 UNREACHABLE;
159 }
160
161 /*
162 * call-seq:
163 * digest_obj.instance_eval { finish } -> digest_obj
164 *
165 * Finishes the digest and returns the resulting hash value.
166 *
167 * This method is overridden by each implementation subclass and often
168 * made private, because some of those subclasses may leave internal
169 * data uninitialized. Do not call this method from outside. Use
170 * #digest!() instead, which ensures that internal data be reset for
171 * security reasons.
172 */
173 static VALUE
174 rb_digest_instance_finish(VALUE self)
175 {
176 rb_digest_instance_method_unimpl(self, "finish");
177
178 UNREACHABLE;
179 }
180
181 /*
182 * call-seq:
183 * digest_obj.reset -> digest_obj
184 *
185 * Resets the digest to the initial state and returns self.
186 *
187 * This method is overridden by each implementation subclass.
188 */
189 static VALUE
190 rb_digest_instance_reset(VALUE self)
191 {
192 rb_digest_instance_method_unimpl(self, "reset");
193
194 UNREACHABLE;
195 }
196
197 /*
198 * call-seq:
199 * digest_obj.new -> another_digest_obj
200 *
201 * Returns a new, initialized copy of the digest object. Equivalent
202 * to digest_obj.clone().reset().
203 */
204 static VALUE
205 rb_digest_instance_new(VALUE self)
206 {
207 VALUE clone = rb_obj_clone(self);
208 rb_funcall(clone, id_reset, 0);
209 return clone;
210 }
211
212 /*
213 * call-seq:
214 * digest_obj.digest -> string
215 * digest_obj.digest(string) -> string
216 *
217 * If none is given, returns the resulting hash value of the digest,
218 * keeping the digest's state.
219 *
220 * If a _string_ is given, returns the hash value for the given
221 * _string_, resetting the digest to the initial state before and
222 * after the process.
223 */
224 static VALUE
225 rb_digest_instance_digest(int argc, VALUE *argv, VALUE self)
226 {
227 VALUE str, value;
228
229 if (rb_scan_args(argc, argv, "01", &str) > 0) {
230 rb_funcall(self, id_reset, 0);
231 rb_funcall(self, id_update, 1, str);
232 value = rb_funcall(self, id_finish, 0);
233 rb_funcall(self, id_reset, 0);
234 } else {
235 value = rb_funcall(rb_obj_clone(self), id_finish, 0);
236 }
237
238 return value;
239 }
240
241 /*
242 * call-seq:
243 * digest_obj.digest! -> string
244 *
245 * Returns the resulting hash value and resets the digest to the
246 * initial state.
247 */
248 static VALUE
249 rb_digest_instance_digest_bang(VALUE self)
250 {
251 VALUE value = rb_funcall(self, id_finish, 0);
252 rb_funcall(self, id_reset, 0);
253
254 return value;
255 }
256
257 /*
258 * call-seq:
259 * digest_obj.hexdigest -> string
260 * digest_obj.hexdigest(string) -> string
261 *
262 * If none is given, returns the resulting hash value of the digest in
263 * a hex-encoded form, keeping the digest's state.
264 *
265 * If a _string_ is given, returns the hash value for the given
266 * _string_ in a hex-encoded form, resetting the digest to the initial
267 * state before and after the process.
268 */
269 static VALUE
270 rb_digest_instance_hexdigest(int argc, VALUE *argv, VALUE self)
271 {
272 VALUE str, value;
273
274 if (rb_scan_args(argc, argv, "01", &str) > 0) {
275 rb_funcall(self, id_reset, 0);
276 rb_funcall(self, id_update, 1, str);
277 value = rb_funcall(self, id_finish, 0);
278 rb_funcall(self, id_reset, 0);
279 } else {
280 value = rb_funcall(rb_obj_clone(self), id_finish, 0);
281 }
282
283 return hexencode_str_new(value);
284 }
285
286 /*
287 * call-seq:
288 * digest_obj.hexdigest! -> string
289 *
290 * Returns the resulting hash value in a hex-encoded form and resets
291 * the digest to the initial state.
292 */
293 static VALUE
294 rb_digest_instance_hexdigest_bang(VALUE self)
295 {
296 VALUE value = rb_funcall(self, id_finish, 0);
297 rb_funcall(self, id_reset, 0);
298
299 return hexencode_str_new(value);
300 }
301
302 /*
303 * call-seq:
304 * digest_obj.to_s -> string
305 *
306 * Returns digest_obj.hexdigest().
307 */
308 static VALUE
309 rb_digest_instance_to_s(VALUE self)
310 {
311 return rb_funcall(self, id_hexdigest, 0);
312 }
313
314 /*
315 * call-seq:
316 * digest_obj.inspect -> string
317 *
318 * Creates a printable version of the digest object.
319 */
320 static VALUE
321 rb_digest_instance_inspect(VALUE self)
322 {
323 VALUE str;
324 size_t digest_len = 32; /* about this size at least */
325 const char *cname;
326
327 cname = rb_obj_classname(self);
328
329 /* #<Digest::ClassName: xxxxx...xxxx> */
330 str = rb_str_buf_new(2 + strlen(cname) + 2 + digest_len * 2 + 1);
331 rb_str_buf_cat2(str, "#<");
332 rb_str_buf_cat2(str, cname);
333 rb_str_buf_cat2(str, ": ");
334 rb_str_buf_append(str, rb_digest_instance_hexdigest(0, 0, self));
335 rb_str_buf_cat2(str, ">");
336 return str;
337 }
338
339 /*
340 * call-seq:
341 * digest_obj == another_digest_obj -> boolean
342 * digest_obj == string -> boolean
343 *
344 * If a string is given, checks whether it is equal to the hex-encoded
345 * hash value of the digest object. If another digest instance is
346 * given, checks whether they have the same hash value. Otherwise
347 * returns false.
348 */
349 static VALUE
350 rb_digest_instance_equal(VALUE self, VALUE other)
351 {
352 VALUE str1, str2;
353
354 if (rb_obj_is_kind_of(other, rb_mDigest_Instance) == Qtrue) {
355 str1 = rb_digest_instance_digest(0, 0, self);
356 str2 = rb_digest_instance_digest(0, 0, other);
357 } else {
358 str1 = rb_digest_instance_to_s(self);
359 str2 = other;
360 }
361
362 /* never blindly assume that subclass methods return strings */
363 StringValue(str1);
364 StringValue(str2);
365
366 if (RSTRING_LEN(str1) == RSTRING_LEN(str2) &&
367 rb_str_cmp(str1, str2) == 0) {
368 return Qtrue;
369 }
370 return Qfalse;
371 }
372
373 /*
374 * call-seq:
375 * digest_obj.digest_length -> integer
376 *
377 * Returns the length of the hash value of the digest.
378 *
379 * This method should be overridden by each implementation subclass.
380 * If not, digest_obj.digest().length() is returned.
381 */
382 static VALUE
383 rb_digest_instance_digest_length(VALUE self)
384 {
385 /* subclasses really should redefine this method */
386 VALUE digest = rb_digest_instance_digest(0, 0, self);
387
388 /* never blindly assume that #digest() returns a string */
389 StringValue(digest);
390 return INT2NUM(RSTRING_LEN(digest));
391 }
392
393 /*
394 * call-seq:
395 * digest_obj.length -> integer
396 * digest_obj.size -> integer
397 *
398 * Returns digest_obj.digest_length().
399 */
400 static VALUE
401 rb_digest_instance_length(VALUE self)
402 {
403 return rb_funcall(self, id_digest_length, 0);
404 }
405
406 /*
407 * call-seq:
408 * digest_obj.block_length -> integer
409 *
410 * Returns the block length of the digest.
411 *
412 * This method is overridden by each implementation subclass.
413 */
414 static VALUE
415 rb_digest_instance_block_length(VALUE self)
416 {
417 rb_digest_instance_method_unimpl(self, "block_length");
418
419 UNREACHABLE;
420 }
421
422 /*
423 * Document-class: Digest::Class
424 *
425 * This module stands as a base class for digest implementation
426 * classes.
427 */
428
429 /*
430 * call-seq:
431 * Digest::Class.digest(string, *parameters) -> hash_string
432 *
433 * Returns the hash value of a given _string_. This is equivalent to
434 * Digest::Class.new(*parameters).digest(string), where extra
435 * _parameters_, if any, are passed through to the constructor and the
436 * _string_ is passed to #digest().
437 */
438 static VALUE
439 rb_digest_class_s_digest(int argc, VALUE *argv, VALUE klass)
440 {
441 VALUE str;
442 volatile VALUE obj;
443
444 if (argc < 1) {
445 rb_raise(rb_eArgError, "no data given");
446 }
447
448 str = *argv++;
449 argc--;
450
451 StringValue(str);
452
453 obj = rb_obj_alloc(klass);
454 rb_obj_call_init(obj, argc, argv);
455
456 return rb_funcall(obj, id_digest, 1, str);
457 }
458
459 /*
460 * call-seq:
461 * Digest::Class.hexdigest(string[, ...]) -> hash_string
462 *
463 * Returns the hex-encoded hash value of a given _string_. This is
464 * almost equivalent to
465 * Digest.hexencode(Digest::Class.new(*parameters).digest(string)).
466 */
467 static VALUE
468 rb_digest_class_s_hexdigest(int argc, VALUE *argv, VALUE klass)
469 {
470 return hexencode_str_new(rb_funcall2(klass, id_digest, argc, argv));
471 }
472
473 /* :nodoc: */
474 static VALUE
475 rb_digest_class_init(VALUE self)
476 {
477 return self;
478 }
479
480 /*
481 * Document-class: Digest::Base
482 *
483 * This abstract class provides a common interface to message digest
484 * implementation classes written in C.
485 */
486
487 static rb_digest_metadata_t *
488 get_digest_base_metadata(VALUE klass)
489 {
490 VALUE p;
491 VALUE obj;
492 rb_digest_metadata_t *algo;
493
494 for (p = klass; !NIL_P(p); p = rb_class_superclass(p)) {
495 if (rb_ivar_defined(p, id_metadata)) {
496 obj = rb_ivar_get(p, id_metadata);
497 break;
498 }
499 }
500
501 if (NIL_P(p))
502 rb_raise(rb_eRuntimeError, "Digest::Base cannot be directly inherited in Ruby");
503
504 Data_Get_Struct(obj, rb_digest_metadata_t, algo);
505
506 switch (algo->api_version) {
507 case 2:
508 break;
509
510 /*
511 * put conversion here if possible when API is updated
512 */
513
514 default:
515 rb_raise(rb_eRuntimeError, "Incompatible digest API version");
516 }
517
518 return algo;
519 }
520
521 static VALUE
522 rb_digest_base_alloc(VALUE klass)
523 {
524 rb_digest_metadata_t *algo;
525 VALUE obj;
526 void *pctx;
527
528 if (klass == rb_cDigest_Base) {
529 rb_raise(rb_eNotImpError, "Digest::Base is an abstract class");
530 }
531
532 algo = get_digest_base_metadata(klass);
533
534 pctx = xmalloc(algo->ctx_size);
535 algo->init_func(pctx);
536
537 obj = Data_Wrap_Struct(klass, 0, xfree, pctx);
538
539 return obj;
540 }
541
542 /* :nodoc: */
543 static VALUE
544 rb_digest_base_copy(VALUE copy, VALUE obj)
545 {
546 rb_digest_metadata_t *algo;
547 void *pctx1, *pctx2;
548
549 if (copy == obj) return copy;
550
551 rb_check_frozen(copy);
552
553 algo = get_digest_base_metadata(rb_obj_class(copy));
554
555 Data_Get_Struct(obj, void, pctx1);
556 Data_Get_Struct(copy, void, pctx2);
557 memcpy(pctx2, pctx1, algo->ctx_size);
558
559 return copy;
560 }
561
562 /* :nodoc: */
563 static VALUE
564 rb_digest_base_reset(VALUE self)
565 {
566 rb_digest_metadata_t *algo;
567 void *pctx;
568
569 algo = get_digest_base_metadata(rb_obj_class(self));
570
571 Data_Get_Struct(self, void, pctx);
572
573 algo->init_func(pctx);
574
575 return self;
576 }
577
578 /* :nodoc: */
579 static VALUE
580 rb_digest_base_update(VALUE self, VALUE str)
581 {
582 rb_digest_metadata_t *algo;
583 void *pctx;
584
585 algo = get_digest_base_metadata(rb_obj_class(self));
586
587 Data_Get_Struct(self, void, pctx);
588
589 StringValue(str);
590 algo->update_func(pctx, (unsigned char *)RSTRING_PTR(str), RSTRING_LEN(str));
591
592 return self;
593 }
594
595 /* :nodoc: */
596 static VALUE
597 rb_digest_base_finish(VALUE self)
598 {
599 rb_digest_metadata_t *algo;
600 void *pctx;
601 VALUE str;
602
603 algo = get_digest_base_metadata(rb_obj_class(self));
604
605 Data_Get_Struct(self, void, pctx);
606
607 str = rb_str_new(0, algo->digest_len);
608 algo->finish_func(pctx, (unsigned char *)RSTRING_PTR(str));
609
610 /* avoid potential coredump caused by use of a finished context */
611 algo->init_func(pctx);
612
613 return str;
614 }
615
616 /* :nodoc: */
617 static VALUE
618 rb_digest_base_digest_length(VALUE self)
619 {
620 rb_digest_metadata_t *algo;
621
622 algo = get_digest_base_metadata(rb_obj_class(self));
623
624 return INT2NUM(algo->digest_len);
625 }
626
627 /* :nodoc: */
628 static VALUE
629 rb_digest_base_block_length(VALUE self)
630 {
631 rb_digest_metadata_t *algo;
632
633 algo = get_digest_base_metadata(rb_obj_class(self));
634
635 return INT2NUM(algo->block_len);
636 }
637
638 void
639 Init_digest(void)
640 {
641 id_reset = rb_intern("reset");
642 id_update = rb_intern("update");
643 id_finish = rb_intern("finish");
644 id_digest = rb_intern("digest");
645 id_hexdigest = rb_intern("hexdigest");
646 id_digest_length = rb_intern("digest_length");
647
648 /*
649 * module Digest
650 */
651 rb_mDigest = rb_define_module("Digest");
652
653 /* module functions */
654 rb_define_module_function(rb_mDigest, "hexencode", rb_digest_s_hexencode, 1);
655
656 /*
657 * module Digest::Instance
658 */
659 rb_mDigest_Instance = rb_define_module_under(rb_mDigest, "Instance");
660
661 /* instance methods that should be overridden */
662 rb_define_method(rb_mDigest_Instance, "update", rb_digest_instance_update, 1);
663 rb_define_method(rb_mDigest_Instance, "<<", rb_digest_instance_update, 1);
664 rb_define_private_method(rb_mDigest_Instance, "finish", rb_digest_instance_finish, 0);
665 rb_define_method(rb_mDigest_Instance, "reset", rb_digest_instance_reset, 0);
666 rb_define_method(rb_mDigest_Instance, "digest_length", rb_digest_instance_digest_length, 0);
667 rb_define_method(rb_mDigest_Instance, "block_length", rb_digest_instance_block_length, 0);
668
669 /* instance methods that may be overridden */
670 rb_define_method(rb_mDigest_Instance, "==", rb_digest_instance_equal, 1);
671 rb_define_method(rb_mDigest_Instance, "inspect", rb_digest_instance_inspect, 0);
672
673 /* instance methods that need not usually be overridden */
674 rb_define_method(rb_mDigest_Instance, "new", rb_digest_instance_new, 0);
675 rb_define_method(rb_mDigest_Instance, "digest", rb_digest_instance_digest, -1);
676 rb_define_method(rb_mDigest_Instance, "digest!", rb_digest_instance_digest_bang, 0);
677 rb_define_method(rb_mDigest_Instance, "hexdigest", rb_digest_instance_hexdigest, -1);
678 rb_define_method(rb_mDigest_Instance, "hexdigest!", rb_digest_instance_hexdigest_bang, 0);
679 rb_define_method(rb_mDigest_Instance, "to_s", rb_digest_instance_to_s, 0);
680 rb_define_method(rb_mDigest_Instance, "length", rb_digest_instance_length, 0);
681 rb_define_method(rb_mDigest_Instance, "size", rb_digest_instance_length, 0);
682
683 /*
684 * class Digest::Class
685 */
686 rb_cDigest_Class = rb_define_class_under(rb_mDigest, "Class", rb_cObject);
687 rb_define_method(rb_cDigest_Class, "initialize", rb_digest_class_init, 0);
688 rb_include_module(rb_cDigest_Class, rb_mDigest_Instance);
689
690 /* class methods */
691 rb_define_singleton_method(rb_cDigest_Class, "digest", rb_digest_class_s_digest, -1);
692 rb_define_singleton_method(rb_cDigest_Class, "hexdigest", rb_digest_class_s_hexdigest, -1);
693
694 id_metadata = rb_intern("metadata");
695
696 /* class Digest::Base < Digest::Class */
697 rb_cDigest_Base = rb_define_class_under(rb_mDigest, "Base", rb_cDigest_Class);
698
699 rb_define_alloc_func(rb_cDigest_Base, rb_digest_base_alloc);
700
701 rb_define_method(rb_cDigest_Base, "initialize_copy", rb_digest_base_copy, 1);
702 rb_define_method(rb_cDigest_Base, "reset", rb_digest_base_reset, 0);
703 rb_define_method(rb_cDigest_Base, "update", rb_digest_base_update, 1);
704 rb_define_method(rb_cDigest_Base, "<<", rb_digest_base_update, 1);
705 rb_define_private_method(rb_cDigest_Base, "finish", rb_digest_base_finish, 0);
706 rb_define_method(rb_cDigest_Base, "digest_length", rb_digest_base_digest_length, 0);
707 rb_define_method(rb_cDigest_Base, "block_length", rb_digest_base_block_length, 0);
708 }
709