rubysl-digest 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +0 -1
  3. data/.travis.yml +7 -0
  4. data/README.md +2 -2
  5. data/Rakefile +0 -1
  6. data/ext/rubysl/digest/bubblebabble/.gitignore +2 -0
  7. data/ext/rubysl/digest/bubblebabble/bubblebabble.c +147 -0
  8. data/ext/rubysl/digest/bubblebabble/bubblebabble.h +2 -0
  9. data/ext/rubysl/digest/bubblebabble/depend +3 -0
  10. data/ext/rubysl/digest/bubblebabble/extconf.h +4 -0
  11. data/ext/rubysl/digest/bubblebabble/extconf.rb +6 -0
  12. data/ext/rubysl/digest/defs.h +19 -0
  13. data/ext/rubysl/digest/digest.c +660 -0
  14. data/ext/rubysl/digest/digest.h +32 -0
  15. data/ext/rubysl/digest/extconf.rb +10 -0
  16. data/ext/rubysl/digest/md5/.gitignore +2 -0
  17. data/ext/rubysl/digest/md5/extconf.rb +29 -0
  18. data/ext/rubysl/digest/md5/md5.c +422 -0
  19. data/ext/rubysl/digest/md5/md5.h +80 -0
  20. data/ext/rubysl/digest/md5/md5init.c +40 -0
  21. data/ext/rubysl/digest/md5/md5ossl.c +9 -0
  22. data/ext/rubysl/digest/md5/md5ossl.h +13 -0
  23. data/ext/rubysl/digest/rmd160/.gitignore +2 -0
  24. data/ext/rubysl/digest/rmd160/extconf.rb +28 -0
  25. data/ext/rubysl/digest/rmd160/rmd160.c +457 -0
  26. data/ext/rubysl/digest/rmd160/rmd160.h +56 -0
  27. data/ext/rubysl/digest/rmd160/rmd160init.c +40 -0
  28. data/ext/rubysl/digest/rmd160/rmd160ossl.c +8 -0
  29. data/ext/rubysl/digest/rmd160/rmd160ossl.h +19 -0
  30. data/ext/rubysl/digest/sha1/.gitignore +2 -0
  31. data/ext/rubysl/digest/sha1/extconf.rb +28 -0
  32. data/ext/rubysl/digest/sha1/sha1.c +269 -0
  33. data/ext/rubysl/digest/sha1/sha1.h +39 -0
  34. data/ext/rubysl/digest/sha1/sha1init.c +40 -0
  35. data/ext/rubysl/digest/sha1/sha1ossl.c +10 -0
  36. data/ext/rubysl/digest/sha1/sha1ossl.h +20 -0
  37. data/ext/rubysl/digest/sha2/.gitignore +2 -0
  38. data/ext/rubysl/digest/sha2/extconf.rb +24 -0
  39. data/ext/rubysl/digest/sha2/sha2.c +919 -0
  40. data/ext/rubysl/digest/sha2/sha2.h +109 -0
  41. data/ext/rubysl/digest/sha2/sha2init.c +52 -0
  42. data/lib/digest/bubblebabble.rb +1 -0
  43. data/lib/digest/hmac.rb +302 -0
  44. data/lib/digest/md5.rb +23 -0
  45. data/lib/digest/rmd160.rb +1 -0
  46. data/lib/digest/sha1.rb +23 -0
  47. data/lib/digest/sha2.rb +74 -0
  48. data/lib/digest.rb +1 -0
  49. data/lib/rubysl/digest/digest.rb +88 -0
  50. data/lib/{rubysl-digest → rubysl/digest}/version.rb +1 -1
  51. data/lib/rubysl/digest.rb +2 -0
  52. data/rubysl-digest.gemspec +25 -17
  53. data/spec/hexencode_spec.rb +30 -0
  54. data/spec/md5/append_spec.rb +6 -0
  55. data/spec/md5/block_length_spec.rb +11 -0
  56. data/spec/md5/digest_bang_spec.rb +12 -0
  57. data/spec/md5/digest_length_spec.rb +11 -0
  58. data/spec/md5/digest_spec.rb +31 -0
  59. data/spec/md5/equal_spec.rb +37 -0
  60. data/spec/md5/file_spec.rb +42 -0
  61. data/spec/md5/hexdigest_bang_spec.rb +13 -0
  62. data/spec/md5/hexdigest_spec.rb +31 -0
  63. data/spec/md5/inspect_spec.rb +11 -0
  64. data/spec/md5/length_spec.rb +7 -0
  65. data/spec/md5/reset_spec.rb +14 -0
  66. data/spec/md5/shared/constants.rb +16 -0
  67. data/spec/md5/shared/length.rb +8 -0
  68. data/spec/md5/shared/sample.rb +15 -0
  69. data/spec/md5/shared/update.rb +7 -0
  70. data/spec/md5/size_spec.rb +7 -0
  71. data/spec/md5/to_s_spec.rb +21 -0
  72. data/spec/md5/update_spec.rb +6 -0
  73. data/spec/sha1/digest_spec.rb +19 -0
  74. data/spec/sha1/file_spec.rb +42 -0
  75. data/spec/sha1/shared/constants.rb +16 -0
  76. data/spec/sha256/append_spec.rb +6 -0
  77. data/spec/sha256/block_length_spec.rb +11 -0
  78. data/spec/sha256/digest_bang_spec.rb +12 -0
  79. data/spec/sha256/digest_length_spec.rb +11 -0
  80. data/spec/sha256/digest_spec.rb +31 -0
  81. data/spec/sha256/equal_spec.rb +36 -0
  82. data/spec/sha256/file_spec.rb +42 -0
  83. data/spec/sha256/hexdigest_bang_spec.rb +13 -0
  84. data/spec/sha256/hexdigest_spec.rb +31 -0
  85. data/spec/sha256/inspect_spec.rb +11 -0
  86. data/spec/sha256/length_spec.rb +7 -0
  87. data/spec/sha256/reset_spec.rb +14 -0
  88. data/spec/sha256/shared/constants.rb +16 -0
  89. data/spec/sha256/shared/length.rb +8 -0
  90. data/spec/sha256/shared/update.rb +7 -0
  91. data/spec/sha256/size_spec.rb +7 -0
  92. data/spec/sha256/to_s_spec.rb +20 -0
  93. data/spec/sha256/update_spec.rb +6 -0
  94. data/spec/sha384/append_spec.rb +6 -0
  95. data/spec/sha384/block_length_spec.rb +11 -0
  96. data/spec/sha384/digest_bang_spec.rb +12 -0
  97. data/spec/sha384/digest_length_spec.rb +11 -0
  98. data/spec/sha384/digest_spec.rb +31 -0
  99. data/spec/sha384/equal_spec.rb +36 -0
  100. data/spec/sha384/file_spec.rb +42 -0
  101. data/spec/sha384/hexdigest_bang_spec.rb +13 -0
  102. data/spec/sha384/hexdigest_spec.rb +31 -0
  103. data/spec/sha384/inspect_spec.rb +11 -0
  104. data/spec/sha384/length_spec.rb +7 -0
  105. data/spec/sha384/reset_spec.rb +14 -0
  106. data/spec/sha384/shared/constants.rb +17 -0
  107. data/spec/sha384/shared/length.rb +8 -0
  108. data/spec/sha384/shared/update.rb +7 -0
  109. data/spec/sha384/size_spec.rb +7 -0
  110. data/spec/sha384/to_s_spec.rb +20 -0
  111. data/spec/sha384/update_spec.rb +6 -0
  112. data/spec/sha512/append_spec.rb +6 -0
  113. data/spec/sha512/block_length_spec.rb +11 -0
  114. data/spec/sha512/digest_bang_spec.rb +12 -0
  115. data/spec/sha512/digest_length_spec.rb +11 -0
  116. data/spec/sha512/digest_spec.rb +31 -0
  117. data/spec/sha512/equal_spec.rb +36 -0
  118. data/spec/sha512/file_spec.rb +42 -0
  119. data/spec/sha512/hexdigest_bang_spec.rb +13 -0
  120. data/spec/sha512/hexdigest_spec.rb +31 -0
  121. data/spec/sha512/inspect_spec.rb +11 -0
  122. data/spec/sha512/length_spec.rb +7 -0
  123. data/spec/sha512/reset_spec.rb +14 -0
  124. data/spec/sha512/shared/constants.rb +16 -0
  125. data/spec/sha512/shared/length.rb +8 -0
  126. data/spec/sha512/shared/update.rb +7 -0
  127. data/spec/sha512/size_spec.rb +7 -0
  128. data/spec/sha512/to_s_spec.rb +20 -0
  129. data/spec/sha512/update_spec.rb +6 -0
  130. metadata +283 -88
  131. data/lib/rubysl-digest.rb +0 -7
@@ -0,0 +1,660 @@
1
+ /************************************************
2
+
3
+ digest.c -
4
+
5
+ $Author: shyouhei $
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 17775 2008-07-01 10:36:22Z shyouhei $
13
+
14
+ ************************************************/
15
+
16
+ #include "digest.h"
17
+
18
+ #include <string.h>
19
+ #include <stdlib.h>
20
+
21
+ static VALUE rb_mDigest;
22
+ static VALUE rb_mDigest_Instance;
23
+ static VALUE rb_cDigest_Class;
24
+ static VALUE rb_cDigest_Base;
25
+
26
+ static ID id_reset, id_update, id_finish, id_digest, id_hexdigest, id_digest_length;
27
+ static ID id_metadata;
28
+
29
+ RUBY_EXTERN void Init_digest_base(void);
30
+
31
+ /*
32
+ * Document-module: Digest
33
+ *
34
+ * This module provides a framework for message digest libraries.
35
+ */
36
+
37
+ static VALUE
38
+ hexencode_str_new(VALUE str_digest)
39
+ {
40
+ char *digest;
41
+ size_t digest_len;
42
+ int i;
43
+ VALUE str;
44
+ char *p;
45
+ char *buf;
46
+ static const char hex[] = {
47
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
48
+ 'a', 'b', 'c', 'd', 'e', 'f'
49
+ };
50
+
51
+ StringValue(str_digest);
52
+ digest_len = RSTRING_LEN(str_digest);
53
+
54
+ if (LONG_MAX / 2 < digest_len) {
55
+ rb_raise(rb_eRuntimeError, "digest string too long");
56
+ }
57
+
58
+ digest = rb_str_ptr_readonly(str_digest);
59
+ buf = calloc(digest_len * 2, sizeof(char));
60
+
61
+ for (i = 0, p = buf; i < digest_len; i++) {
62
+ unsigned char byte = digest[i];
63
+
64
+ p[i + i] = hex[byte >> 4];
65
+ p[i + i + 1] = hex[byte & 0x0f];
66
+ }
67
+
68
+ str = rb_str_new(buf, digest_len * 2);
69
+ free(buf);
70
+ return str;
71
+ }
72
+
73
+ /*
74
+ * call-seq:
75
+ * Digest.hexencode(string) -> hexencoded_string
76
+ *
77
+ * Generates a hex-encoded version of a given _string_.
78
+ */
79
+ static VALUE
80
+ rb_digest_s_hexencode(VALUE klass, VALUE str)
81
+ {
82
+ return hexencode_str_new(str);
83
+ }
84
+
85
+ /*
86
+ * Document-module: Digest::Instance
87
+ *
88
+ * This module provides instance methods for a digest implementation
89
+ * object to calculate message digest values.
90
+ */
91
+
92
+ /*
93
+ * call-seq:
94
+ * digest_obj.update(string) -> digest_obj
95
+ * digest_obj << string -> digest_obj
96
+ *
97
+ * Updates the digest using a given _string_ and returns self.
98
+ *
99
+ * The update() method and the left-shift operator are overridden by
100
+ * each implementation subclass. (One should be an alias for the
101
+ * other)
102
+ */
103
+ static VALUE
104
+ rb_digest_instance_update(VALUE self, VALUE str)
105
+ {
106
+ rb_raise(rb_eRuntimeError, "%s does not implement update()",
107
+ rb_str_ptr_readonly(rb_inspect(self)));
108
+ return Qnil; /* Keep compiler happy */
109
+ }
110
+
111
+ /*
112
+ * call-seq:
113
+ * digest_obj.instance_eval { finish } -> digest_obj
114
+ *
115
+ * Finishes the digest and returns the resulting hash value.
116
+ *
117
+ * This method is overridden by each implementation subclass and often
118
+ * made private, because some of those subclasses may leave internal
119
+ * data uninitialized. Do not call this method from outside. Use
120
+ * #digest!() instead, which ensures that internal data be reset for
121
+ * security reasons.
122
+ */
123
+ static VALUE
124
+ rb_digest_instance_finish(VALUE self)
125
+ {
126
+ rb_raise(rb_eRuntimeError, "%s does not implement finish()",
127
+ rb_str_ptr_readonly(rb_inspect(self)));
128
+ return Qnil; /* Keep compiler happy */
129
+ }
130
+
131
+ /*
132
+ * call-seq:
133
+ * digest_obj.reset -> digest_obj
134
+ *
135
+ * Resets the digest to the initial state and returns self.
136
+ *
137
+ * This method is overridden by each implementation subclass.
138
+ */
139
+ static VALUE
140
+ rb_digest_instance_reset(VALUE self)
141
+ {
142
+ rb_raise(rb_eRuntimeError, "%s does not implement reset()",
143
+ rb_str_ptr_readonly(rb_inspect(self)));
144
+ return Qnil; /* Keep compiler happy */
145
+ }
146
+
147
+ /*
148
+ * call-seq:
149
+ * digest_obj.new -> another_digest_obj
150
+ *
151
+ * Returns a new, initialized copy of the digest object. Equivalent
152
+ * to digest_obj.clone().reset().
153
+ */
154
+ static VALUE
155
+ rb_digest_instance_new(VALUE self)
156
+ {
157
+ VALUE clone = rb_obj_clone(self);
158
+ rb_funcall(clone, id_reset, 0);
159
+ return clone;
160
+ }
161
+
162
+ /*
163
+ * call-seq:
164
+ * digest_obj.digest -> string
165
+ * digest_obj.digest(string) -> string
166
+ *
167
+ * If none is given, returns the resulting hash value of the digest,
168
+ * keeping the digest's state.
169
+ *
170
+ * If a _string_ is given, returns the hash value for the given
171
+ * _string_, resetting the digest to the initial state before and
172
+ * after the process.
173
+ */
174
+ static VALUE
175
+ rb_digest_instance_digest(int argc, VALUE *argv, VALUE self)
176
+ {
177
+ VALUE str, value;
178
+
179
+ if (rb_scan_args(argc, argv, "01", &str) > 0) {
180
+ rb_funcall(self, id_reset, 0);
181
+ rb_funcall(self, id_update, 1, str);
182
+ value = rb_funcall(self, id_finish, 0);
183
+ rb_funcall(self, id_reset, 0);
184
+ } else {
185
+ VALUE clone = rb_obj_clone(self);
186
+
187
+ value = rb_funcall(clone, id_finish, 0);
188
+ rb_funcall(clone, id_reset, 0);
189
+ }
190
+
191
+ return value;
192
+ }
193
+
194
+ /*
195
+ * call-seq:
196
+ * digest_obj.digest! -> string
197
+ *
198
+ * Returns the resulting hash value and resets the digest to the
199
+ * initial state.
200
+ */
201
+ static VALUE
202
+ rb_digest_instance_digest_bang(VALUE self)
203
+ {
204
+ VALUE value = rb_funcall(self, id_finish, 0);
205
+ rb_funcall(self, id_reset, 0);
206
+
207
+ return value;
208
+ }
209
+
210
+ /*
211
+ * call-seq:
212
+ * digest_obj.hexdigest -> string
213
+ * digest_obj.hexdigest(string) -> string
214
+ *
215
+ * If none is given, returns the resulting hash value of the digest in
216
+ * a hex-encoded form, keeping the digest's state.
217
+ *
218
+ * If a _string_ is given, returns the hash value for the given
219
+ * _string_ in a hex-encoded form, resetting the digest to the initial
220
+ * state before and after the process.
221
+ */
222
+ static VALUE
223
+ rb_digest_instance_hexdigest(int argc, VALUE *argv, VALUE self)
224
+ {
225
+ VALUE str, value;
226
+
227
+ if (rb_scan_args(argc, argv, "01", &str) > 0) {
228
+ rb_funcall(self, id_reset, 0);
229
+ rb_funcall(self, id_update, 1, str);
230
+ value = rb_funcall(self, id_finish, 0);
231
+ rb_funcall(self, id_reset, 0);
232
+ } else {
233
+ VALUE clone = rb_obj_clone(self);
234
+
235
+ value = rb_funcall(clone, id_finish, 0);
236
+ rb_funcall(clone, id_reset, 0);
237
+ }
238
+
239
+ return hexencode_str_new(value);
240
+ }
241
+
242
+ /*
243
+ * call-seq:
244
+ * digest_obj.hexdigest! -> string
245
+ *
246
+ * Returns the resulting hash value and resets the digest to the
247
+ * initial state.
248
+ */
249
+ static VALUE
250
+ rb_digest_instance_hexdigest_bang(VALUE self)
251
+ {
252
+ VALUE value = rb_funcall(self, id_finish, 0);
253
+ rb_funcall(self, id_reset, 0);
254
+
255
+ return hexencode_str_new(value);
256
+ }
257
+
258
+ /*
259
+ * call-seq:
260
+ * digest_obj.to_s -> string
261
+ *
262
+ * Returns digest_obj.hexdigest().
263
+ */
264
+ static VALUE
265
+ rb_digest_instance_to_s(VALUE self)
266
+ {
267
+ return rb_funcall(self, id_hexdigest, 0);
268
+ }
269
+
270
+ /*
271
+ * call-seq:
272
+ * digest_obj.inspect -> string
273
+ *
274
+ * Creates a printable version of the digest object.
275
+ */
276
+ static VALUE
277
+ rb_digest_instance_inspect(VALUE self)
278
+ {
279
+ VALUE str;
280
+ size_t digest_len = 32; /* about this size at least */
281
+ const char *cname;
282
+
283
+ cname = rb_obj_classname(self);
284
+
285
+ /* #<Digest::ClassName: xxxxx...xxxx> */
286
+ str = rb_str_buf_new(2 + strlen(cname) + 2 + digest_len * 2 + 1);
287
+ rb_str_buf_cat2(str, "#<");
288
+ rb_str_buf_cat2(str, cname);
289
+ rb_str_buf_cat2(str, ": ");
290
+ rb_str_buf_append(str, rb_digest_instance_hexdigest(0, 0, self));
291
+ rb_str_buf_cat2(str, ">");
292
+ return str;
293
+ }
294
+
295
+ /*
296
+ * call-seq:
297
+ * digest_obj == another_digest_obj -> boolean
298
+ * digest_obj == string -> boolean
299
+ *
300
+ * If a string is given, checks whether it is equal to the hex-encoded
301
+ * hash value of the digest object. If another digest instance is
302
+ * given, checks whether they have the same hash value. Otherwise
303
+ * returns false.
304
+ */
305
+ static VALUE
306
+ rb_digest_instance_equal(VALUE self, VALUE other)
307
+ {
308
+ VALUE str1, str2;
309
+
310
+ if (rb_obj_is_kind_of(other, rb_mDigest_Instance) == Qtrue) {
311
+ str1 = rb_digest_instance_digest(0, 0, self);
312
+ str2 = rb_digest_instance_digest(0, 0, other);
313
+ } else {
314
+ str1 = rb_digest_instance_to_s(self);
315
+ str2 = other;
316
+ }
317
+
318
+ /* never blindly assume that subclass methods return strings */
319
+ StringValue(str1);
320
+ StringValue(str2);
321
+
322
+ if (RSTRING_LEN(str1) == RSTRING_LEN(str2) &&
323
+ rb_str_cmp(str1, str2) == 0) {
324
+ return Qtrue;
325
+ }
326
+ return Qfalse;
327
+ }
328
+
329
+ /*
330
+ * call-seq:
331
+ * digest_obj.digest_length -> integer
332
+ *
333
+ * Returns the length of the hash value of the digest.
334
+ *
335
+ * This method should be overridden by each implementation subclass.
336
+ * If not, digest_obj.digest().length() is returned.
337
+ */
338
+ static VALUE
339
+ rb_digest_instance_digest_length(VALUE self)
340
+ {
341
+ /* subclasses really should redefine this method */
342
+ VALUE digest = rb_digest_instance_digest(0, 0, self);
343
+
344
+ /* never blindly assume that #digest() returns a string */
345
+ StringValue(digest);
346
+ return INT2NUM(RSTRING_LEN(digest));
347
+ }
348
+
349
+ /*
350
+ * call-seq:
351
+ * digest_obj.length -> integer
352
+ * digest_obj.size -> integer
353
+ *
354
+ * Returns digest_obj.digest_length().
355
+ */
356
+ static VALUE
357
+ rb_digest_instance_length(VALUE self)
358
+ {
359
+ return rb_funcall(self, id_digest_length, 0);
360
+ }
361
+
362
+ /*
363
+ * call-seq:
364
+ * digest_obj.block_length -> integer
365
+ *
366
+ * Returns the block length of the digest.
367
+ *
368
+ * This method is overridden by each implementation subclass.
369
+ */
370
+ static VALUE
371
+ rb_digest_instance_block_length(VALUE self)
372
+ {
373
+ rb_raise(rb_eRuntimeError, "%s does not implement block_length()",
374
+ rb_str_ptr_readonly(rb_inspect(self)));
375
+ return Qnil; /* Keep compiler happy */
376
+ }
377
+
378
+ /*
379
+ * Document-class: Digest::Class
380
+ *
381
+ * This module stands as a base class for digest implementation
382
+ * classes.
383
+ */
384
+
385
+ /*
386
+ * call-seq:
387
+ * Digest::Class.digest(string, *parameters) -> hash_string
388
+ *
389
+ * Returns the hash value of a given _string_. This is equivalent to
390
+ * Digest::Class.new(*parameters).digest(string), where extra
391
+ * _parameters_, if any, are passed through to the constructor and the
392
+ * _string_ is passed to #digest().
393
+ */
394
+ static VALUE
395
+ rb_digest_class_s_digest(int argc, VALUE *argv, VALUE klass)
396
+ {
397
+ VALUE str;
398
+ volatile VALUE obj;
399
+
400
+ if (argc < 1) {
401
+ rb_raise(rb_eArgError, "no data given");
402
+ }
403
+
404
+ str = *argv++;
405
+ argc--;
406
+
407
+ StringValue(str);
408
+
409
+ obj = rb_obj_alloc(klass);
410
+ rb_obj_call_init(obj, argc, argv);
411
+
412
+ return rb_funcall(obj, id_digest, 1, str);
413
+ }
414
+
415
+ /*
416
+ * call-seq:
417
+ * Digest::Class.hexdigest(string[, ...]) -> hash_string
418
+ *
419
+ * Returns the hex-encoded hash value of a given _string_. This is
420
+ * almost equivalent to
421
+ * Digest.hexencode(Digest::Class.new(*parameters).digest(string)).
422
+ */
423
+ static VALUE
424
+ rb_digest_class_s_hexdigest(int argc, VALUE *argv, VALUE klass)
425
+ {
426
+ return hexencode_str_new(rb_funcall2(klass, id_digest, argc, argv));
427
+ }
428
+
429
+ /*
430
+ * Document-class: Digest::Base
431
+ *
432
+ * This abstract class provides a common interface to message digest
433
+ * implementation classes written in C.
434
+ */
435
+
436
+ static rb_digest_metadata_t *
437
+ get_digest_base_metadata(VALUE klass)
438
+ {
439
+ VALUE p;
440
+ VALUE obj = 0;
441
+ rb_digest_metadata_t *algo;
442
+
443
+ for (p = klass; p; p = RCLASS_SUPER(p)) {
444
+ if (rb_ivar_defined(p, id_metadata)) {
445
+ obj = rb_ivar_get(p, id_metadata);
446
+ break;
447
+ }
448
+ }
449
+
450
+ if (!p)
451
+ rb_raise(rb_eRuntimeError, "Digest::Base cannot be directly inherited in Ruby");
452
+
453
+ Data_Get_Struct(obj, rb_digest_metadata_t, algo);
454
+
455
+ switch (algo->api_version) {
456
+ case 2:
457
+ break;
458
+
459
+ /*
460
+ * put conversion here if possible when API is updated
461
+ */
462
+
463
+ default:
464
+ rb_raise(rb_eRuntimeError, "Incompatible digest API version");
465
+ }
466
+
467
+ return algo;
468
+ }
469
+
470
+ static VALUE
471
+ rb_digest_base_alloc(VALUE klass)
472
+ {
473
+ rb_digest_metadata_t *algo;
474
+ VALUE obj;
475
+ void *pctx;
476
+
477
+ if (klass == rb_cDigest_Base) {
478
+ rb_raise(rb_eNotImpError, "Digest::Base is an abstract class");
479
+ }
480
+
481
+ algo = get_digest_base_metadata(klass);
482
+
483
+ pctx = xmalloc(algo->ctx_size);
484
+ algo->init_func(pctx);
485
+
486
+ obj = Data_Wrap_Struct(klass, 0, xfree, pctx);
487
+
488
+ return obj;
489
+ }
490
+
491
+ /* :nodoc: */
492
+ static VALUE
493
+ rb_digest_base_copy(VALUE copy, VALUE obj)
494
+ {
495
+ rb_digest_metadata_t *algo;
496
+ void *pctx1, *pctx2;
497
+
498
+ if (copy == obj) return copy;
499
+
500
+ rb_check_frozen(copy);
501
+
502
+ algo = get_digest_base_metadata(rb_obj_class(copy));
503
+
504
+ Data_Get_Struct(obj, void, pctx1);
505
+ Data_Get_Struct(copy, void, pctx2);
506
+ memcpy(pctx2, pctx1, algo->ctx_size);
507
+
508
+ return copy;
509
+ }
510
+
511
+ /* :nodoc: */
512
+ static VALUE
513
+ rb_digest_base_reset(VALUE self)
514
+ {
515
+ rb_digest_metadata_t *algo;
516
+ void *pctx;
517
+
518
+ algo = get_digest_base_metadata(rb_obj_class(self));
519
+
520
+ Data_Get_Struct(self, void, pctx);
521
+
522
+ algo->init_func(pctx);
523
+
524
+ return self;
525
+ }
526
+
527
+ /* :nodoc: */
528
+ static VALUE
529
+ rb_digest_base_update(VALUE self, VALUE str)
530
+ {
531
+ rb_digest_metadata_t *algo;
532
+ void *pctx;
533
+
534
+ algo = get_digest_base_metadata(rb_obj_class(self));
535
+
536
+ Data_Get_Struct(self, void, pctx);
537
+
538
+ StringValue(str);
539
+ algo->update_func(pctx, (unsigned char *)rb_str_ptr_readonly(str), RSTRING_LEN(str));
540
+
541
+ return self;
542
+ }
543
+
544
+ /* :nodoc: */
545
+ static VALUE
546
+ rb_digest_base_finish(VALUE self)
547
+ {
548
+ rb_digest_metadata_t *algo;
549
+ void *pctx;
550
+ VALUE str;
551
+
552
+ algo = get_digest_base_metadata(rb_obj_class(self));
553
+
554
+ Data_Get_Struct(self, void, pctx);
555
+
556
+ char* buf = calloc(algo->digest_len, sizeof(char));
557
+
558
+ algo->finish_func(pctx, (unsigned char*)buf);
559
+
560
+ /* avoid potential coredump caused by use of a finished context */
561
+ algo->init_func(pctx);
562
+
563
+ str = rb_str_new(buf, algo->digest_len);
564
+ free(buf);
565
+
566
+ return str;
567
+ }
568
+
569
+ /* :nodoc: */
570
+ static VALUE
571
+ rb_digest_base_digest_length(VALUE self)
572
+ {
573
+ rb_digest_metadata_t *algo;
574
+
575
+ algo = get_digest_base_metadata(rb_obj_class(self));
576
+
577
+ return INT2NUM(algo->digest_len);
578
+ }
579
+
580
+ /* :nodoc: */
581
+ static VALUE
582
+ rb_digest_base_block_length(VALUE self)
583
+ {
584
+ rb_digest_metadata_t *algo;
585
+
586
+ algo = get_digest_base_metadata(rb_obj_class(self));
587
+
588
+ return INT2NUM(algo->block_len);
589
+ }
590
+
591
+ void
592
+ Init_digest(void)
593
+ {
594
+ id_reset = rb_intern("reset");
595
+ id_update = rb_intern("update");
596
+ id_finish = rb_intern("finish");
597
+ id_digest = rb_intern("digest");
598
+ id_hexdigest = rb_intern("hexdigest");
599
+ id_digest_length = rb_intern("digest_length");
600
+
601
+ /*
602
+ * module Digest
603
+ */
604
+ rb_mDigest = rb_define_module("Digest");
605
+
606
+ /* module functions */
607
+ rb_define_module_function(rb_mDigest, "hexencode", rb_digest_s_hexencode, 1);
608
+
609
+ /*
610
+ * module Digest::Instance
611
+ */
612
+ rb_mDigest_Instance = rb_define_module_under(rb_mDigest, "Instance");
613
+
614
+ /* instance methods that should be overridden */
615
+ rb_define_method(rb_mDigest_Instance, "update", rb_digest_instance_update, 1);
616
+ rb_define_method(rb_mDigest_Instance, "<<", rb_digest_instance_update, 1);
617
+ rb_define_private_method(rb_mDigest_Instance, "finish", rb_digest_instance_finish, 0);
618
+ rb_define_method(rb_mDigest_Instance, "reset", rb_digest_instance_reset, 0);
619
+ rb_define_method(rb_mDigest_Instance, "digest_length", rb_digest_instance_digest_length, 0);
620
+ rb_define_method(rb_mDigest_Instance, "block_length", rb_digest_instance_block_length, 0);
621
+
622
+ /* instance methods that may be overridden */
623
+ rb_define_method(rb_mDigest_Instance, "==", rb_digest_instance_equal, 1);
624
+ rb_define_method(rb_mDigest_Instance, "inspect", rb_digest_instance_inspect, 0);
625
+
626
+ /* instance methods that need not usually be overridden */
627
+ rb_define_method(rb_mDigest_Instance, "new", rb_digest_instance_new, 0);
628
+ rb_define_method(rb_mDigest_Instance, "digest", rb_digest_instance_digest, -1);
629
+ rb_define_method(rb_mDigest_Instance, "digest!", rb_digest_instance_digest_bang, 0);
630
+ rb_define_method(rb_mDigest_Instance, "hexdigest", rb_digest_instance_hexdigest, -1);
631
+ rb_define_method(rb_mDigest_Instance, "hexdigest!", rb_digest_instance_hexdigest_bang, 0);
632
+ rb_define_method(rb_mDigest_Instance, "to_s", rb_digest_instance_to_s, 0);
633
+ rb_define_method(rb_mDigest_Instance, "length", rb_digest_instance_length, 0);
634
+ rb_define_method(rb_mDigest_Instance, "size", rb_digest_instance_length, 0);
635
+
636
+ /*
637
+ * class Digest::Class
638
+ */
639
+ rb_cDigest_Class = rb_define_class_under(rb_mDigest, "Class", rb_cObject);
640
+ rb_include_module(rb_cDigest_Class, rb_mDigest_Instance);
641
+
642
+ /* class methods */
643
+ rb_define_singleton_method(rb_cDigest_Class, "digest", rb_digest_class_s_digest, -1);
644
+ rb_define_singleton_method(rb_cDigest_Class, "hexdigest", rb_digest_class_s_hexdigest, -1);
645
+
646
+ id_metadata = rb_intern("metadata");
647
+
648
+ /* class Digest::Base < Digest::Class */
649
+ rb_cDigest_Base = rb_define_class_under(rb_mDigest, "Base", rb_cDigest_Class);
650
+
651
+ rb_define_alloc_func(rb_cDigest_Base, rb_digest_base_alloc);
652
+
653
+ rb_define_method(rb_cDigest_Base, "initialize_copy", rb_digest_base_copy, 1);
654
+ rb_define_method(rb_cDigest_Base, "reset", rb_digest_base_reset, 0);
655
+ rb_define_method(rb_cDigest_Base, "update", rb_digest_base_update, 1);
656
+ rb_define_method(rb_cDigest_Base, "<<", rb_digest_base_update, 1);
657
+ rb_define_private_method(rb_cDigest_Base, "finish", rb_digest_base_finish, 0);
658
+ rb_define_method(rb_cDigest_Base, "digest_length", rb_digest_base_digest_length, 0);
659
+ rb_define_method(rb_cDigest_Base, "block_length", rb_digest_base_block_length, 0);
660
+ }
@@ -0,0 +1,32 @@
1
+ /************************************************
2
+
3
+ digest.h - header file for ruby digest modules
4
+
5
+ $Author: shyouhei $
6
+ created at: Fri May 25 08:54:56 JST 2001
7
+
8
+
9
+ Copyright (C) 2001-2006 Akinori MUSHA
10
+
11
+ $RoughId: digest.h,v 1.3 2001/07/13 15:38:27 knu Exp $
12
+ $Id: digest.h 11708 2007-02-12 23:01:19Z shyouhei $
13
+
14
+ ************************************************/
15
+
16
+ #include "ruby.h"
17
+
18
+ #define RUBY_DIGEST_API_VERSION 2
19
+
20
+ typedef void (*rb_digest_hash_init_func_t)(void *);
21
+ typedef void (*rb_digest_hash_update_func_t)(void *, unsigned char *, size_t);
22
+ typedef void (*rb_digest_hash_finish_func_t)(void *, unsigned char *);
23
+
24
+ typedef struct {
25
+ int api_version;
26
+ size_t digest_len;
27
+ size_t block_len;
28
+ size_t ctx_size;
29
+ rb_digest_hash_init_func_t init_func;
30
+ rb_digest_hash_update_func_t update_func;
31
+ rb_digest_hash_finish_func_t finish_func;
32
+ } rb_digest_metadata_t;
@@ -0,0 +1,10 @@
1
+ # $RoughId: extconf.rb,v 1.6 2001/07/13 15:38:27 knu Exp $
2
+ # $Id$
3
+
4
+ require "mkmf"
5
+
6
+ $INSTALLFILES = {
7
+ "digest.h" => "$(RUBYARCHDIR)"
8
+ }
9
+
10
+ create_makefile("digest/digest")
@@ -0,0 +1,2 @@
1
+ Makefile
2
+ *.log