source: EcnlProtoTool/trunk/mrbgems/mruby-digest/src/digest.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 21.0 KB
Line 
1/*
2** digest.c - Digest and subclasses
3**
4** See Copyright Notice in mruby.h
5*/
6
7#include "mruby.h"
8
9#ifdef __APPLE__
10#define USE_DIGEST_OSX_COMMONCRYPTO
11#else
12#define USE_DIGEST_OPENSSL
13#endif
14
15#if defined(USE_DIGEST_OPENSSL)
16#include <openssl/evp.h>
17#include <openssl/hmac.h>
18#include <openssl/sha.h>
19#elif defined(USE_DIGEST_OSX_COMMONCRYPTO)
20#include <CommonCrypto/CommonDigest.h>
21#include <CommonCrypto/CommonHMAC.h>
22#else
23#error "define USE_DIGEST_OPENSSL or USE_DIGEST_OSX_COMMONCRYPTO"
24#endif
25#include <limits.h>
26#include <stdio.h>
27#include <string.h>
28#include "mruby/array.h"
29#include "mruby/class.h"
30#include "mruby/data.h"
31#include "mruby/string.h"
32#include "mruby/variable.h"
33
34#define TYPESYM "__type__"
35
36
37/*
38 * library-independent layer API
39 */
40enum {
41 MD_TYPE_MD5,
42 MD_TYPE_RMD160,
43 MD_TYPE_SHA1,
44 MD_TYPE_SHA256,
45 MD_TYPE_SHA384,
46 MD_TYPE_SHA512,
47};
48
49struct mrb_md;
50struct mrb_hmac;
51
52static void lib_init(void);
53static int lib_md_block_length(const struct mrb_md *);
54static mrb_value lib_md_digest(mrb_state *, const struct mrb_md *);
55static mrb_value lib_md_digest_bang(mrb_state *, struct mrb_md *);
56static int lib_md_digest_length(const struct mrb_md *);
57static void lib_md_free(mrb_state *, void *);
58static void lib_md_init(mrb_state *, struct mrb_md *, int);
59static void lib_md_init_copy(mrb_state *, struct mrb_md *, struct mrb_md *);
60static void lib_md_reset(mrb_state *, struct mrb_md *);
61static void lib_md_update(mrb_state *, struct mrb_md *, unsigned char *, mrb_int);
62
63static mrb_value lib_hmac_digest(mrb_state *, const struct mrb_hmac *);
64static int lib_hmac_block_length(const struct mrb_hmac *);
65static int lib_hmac_digest_length(const struct mrb_hmac *);
66static void lib_hmac_free(mrb_state *, void *);
67static void lib_hmac_init(mrb_state *, struct mrb_hmac *, int, const unsigned char *, mrb_int);
68static void lib_hmac_update(mrb_state *, struct mrb_hmac *, unsigned char *, mrb_int);
69
70
71#if defined(USE_DIGEST_OPENSSL)
72/*
73 * OpenSSL Implementation
74 */
75
76#define HAVE_MD5
77
78#ifndef OPENSSL_NO_RIPEMD
79#define HAVE_RMD160
80#endif
81
82#define HAVE_SHA1
83#ifdef SHA256_DIGEST_LENGTH
84#define HAVE_SHA256
85#endif
86#ifdef SHA512_DIGEST_LENGTH
87#define HAVE_SHA384
88#define HAVE_SHA512
89#endif
90
91struct mrb_md {
92 EVP_MD_CTX *ctx;
93};
94
95struct mrb_hmac {
96#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined LIBRESSL_VERSION_NUMBER)
97 HMAC_CTX *ctx;
98#else
99 HMAC_CTX ctx;
100#endif
101 const EVP_MD *md;
102};
103
104static void
105lib_md_free(mrb_state *mrb, void *ptr)
106{
107 struct mrb_md *md = ptr;
108
109 if (md != NULL) {
110 if (md->ctx != NULL) {
111 EVP_MD_CTX_destroy(md->ctx);
112 }
113 mrb_free(mrb, md);
114 }
115}
116
117static void
118lib_hmac_free(mrb_state *mrb, void *ptr)
119{
120 struct mrb_hmac *hmac = ptr;
121
122 if (hmac != NULL) {
123#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined LIBRESSL_VERSION_NUMBER)
124 HMAC_CTX_free(hmac->ctx);
125#else
126 HMAC_CTX_cleanup(&hmac->ctx);
127#endif
128 mrb_free(mrb, hmac);
129 }
130}
131
132static struct mrb_data_type mrb_md_type = { "MD", lib_md_free };
133static struct mrb_data_type mrb_hmac_type = { "HMAC", lib_hmac_free };
134
135static void
136lib_init(void)
137{
138 OpenSSL_add_all_digests();
139}
140
141static int
142lib_md_block_length(const struct mrb_md *md)
143{
144 return EVP_MD_CTX_block_size(md->ctx);
145}
146
147static mrb_value
148lib_md_digest(mrb_state *mrb, const struct mrb_md *md)
149{
150#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined LIBRESSL_VERSION_NUMBER)
151 EVP_MD_CTX *ctx;
152#else
153 EVP_MD_CTX ctx;
154#endif
155 unsigned int mdlen;
156 unsigned char mdstr[EVP_MAX_MD_SIZE];
157
158#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined LIBRESSL_VERSION_NUMBER)
159 ctx = EVP_MD_CTX_new();
160 EVP_MD_CTX_copy(ctx, md->ctx);
161 EVP_DigestFinal(ctx, mdstr, &mdlen);
162 EVP_MD_CTX_free(ctx);
163#else
164 EVP_MD_CTX_copy(&ctx, md->ctx);
165 EVP_DigestFinal(&ctx, mdstr, &mdlen);
166#endif
167 return mrb_str_new(mrb, (char *)mdstr, mdlen);
168}
169
170static mrb_value
171lib_md_digest_bang(mrb_state *mrb, struct mrb_md *md)
172{
173 unsigned int mdlen;
174 unsigned char mdstr[EVP_MAX_MD_SIZE];
175
176 EVP_DigestFinal_ex(md->ctx, mdstr, &mdlen);
177 EVP_DigestInit_ex(md->ctx, EVP_MD_CTX_md(md->ctx), NULL);
178 return mrb_str_new(mrb, (char *)mdstr, mdlen);
179}
180
181static int
182lib_md_digest_length(const struct mrb_md *md)
183{
184 return EVP_MD_CTX_size(md->ctx);
185}
186
187const EVP_MD *
188md_type_md(int type)
189{
190 switch (type) {
191 case MD_TYPE_MD5: return EVP_md5();
192#ifdef HAVE_RMD160
193 case MD_TYPE_RMD160: return EVP_ripemd160();
194#endif
195 case MD_TYPE_SHA1: return EVP_sha1();
196#ifdef HAVE_SHA256
197 case MD_TYPE_SHA256: return EVP_sha256();
198#endif
199#ifdef HAVE_SHA512
200 case MD_TYPE_SHA384: return EVP_sha384();
201 case MD_TYPE_SHA512: return EVP_sha512();
202#endif
203 default: return NULL;
204 }
205}
206
207static void
208lib_md_init(mrb_state *mrb, struct mrb_md *md, int type)
209{
210 const EVP_MD *evpmd;
211
212 md->ctx = NULL;
213 evpmd = md_type_md(type);
214 if (!evpmd) {
215 mrb_raise(mrb, E_NOTIMP_ERROR, "not supported");
216 }
217 md->ctx = EVP_MD_CTX_create();
218 EVP_DigestInit_ex(md->ctx, evpmd, NULL);
219}
220
221static void
222lib_md_init_copy(mrb_state *mrb, struct mrb_md *mdnew, struct mrb_md *mdold)
223{
224 mdnew->ctx = EVP_MD_CTX_create();
225 EVP_DigestInit_ex(mdnew->ctx, EVP_MD_CTX_md(mdold->ctx), NULL);
226}
227
228static void
229lib_md_reset(mrb_state *mrb, struct mrb_md *md)
230{
231 //EVP_MD_CTX_init(&md->ctx);
232 EVP_DigestInit_ex(md->ctx, EVP_MD_CTX_md(md->ctx), NULL);
233}
234
235static void
236lib_md_update(mrb_state *mrb, struct mrb_md *md, unsigned char *str, mrb_int len)
237{
238#if MRB_INT_MAX > SIZE_MAX
239 if (len > SIZE_MAX) {
240 mrb_raise(mrb, E_ARGUMENT_ERROR, "too long string (not supported yet)");
241 }
242#endif
243 EVP_DigestUpdate(md->ctx, str, len);
244}
245
246static mrb_value
247lib_hmac_digest(mrb_state *mrb, const struct mrb_hmac *hmac)
248{
249#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined LIBRESSL_VERSION_NUMBER)
250 HMAC_CTX *ctx;
251#else
252 HMAC_CTX ctx;
253#endif
254 unsigned int mdlen;
255 unsigned char mdstr[EVP_MAX_MD_SIZE];
256
257 memcpy(&ctx, &hmac->ctx, sizeof(ctx));
258#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined LIBRESSL_VERSION_NUMBER)
259 HMAC_Final(ctx, mdstr, &mdlen);
260#else
261 HMAC_Final(&ctx, mdstr, &mdlen);
262#endif
263 return mrb_str_new(mrb, (char *)mdstr, mdlen);
264}
265
266static int
267lib_hmac_block_length(const struct mrb_hmac *hmac)
268{
269 return EVP_MD_block_size(hmac->md);
270}
271
272static int
273lib_hmac_digest_length(const struct mrb_hmac *hmac)
274{
275 return EVP_MD_size(hmac->md);
276}
277
278static void
279lib_hmac_init(mrb_state *mrb, struct mrb_hmac *hmac, int type, const unsigned char *key, mrb_int keylen)
280{
281#if MRB_INT_MAX > INT_MAX
282 if (keylen > INT_MAX) {
283 mrb_raise(mrb, E_ARGUMENT_ERROR, "too long key");
284 }
285#endif
286 hmac->md = md_type_md(type);
287#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined LIBRESSL_VERSION_NUMBER)
288 hmac->ctx = HMAC_CTX_new();
289 HMAC_Init_ex(hmac->ctx, key, keylen, hmac->md, NULL);
290#else
291 HMAC_CTX_init(&hmac->ctx);
292 HMAC_Init_ex(&hmac->ctx, key, keylen, hmac->md, NULL);
293#endif
294}
295
296static void
297lib_hmac_update(mrb_state *mrb, struct mrb_hmac *hmac, unsigned char *data, mrb_int len)
298{
299#if MRB_INT_MAX > INT_MAX
300 if (len > INT_MAX) {
301 mrb_raise(mrb, E_ARGUMENT_ERROR, "too long string (not supported yet)");
302 }
303#endif
304#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined LIBRESSL_VERSION_NUMBER)
305 HMAC_Update(hmac->ctx, data, len);
306#else
307 HMAC_Update(&hmac->ctx, data, len);
308#endif
309}
310
311#elif defined(USE_DIGEST_OSX_COMMONCRYPTO)
312/*
313 * Mac OS X CommonCrypto Implementation
314 */
315
316#define HAVE_MD5
317/* #define HAVE_RMD160 */
318#define HAVE_SHA1
319#define HAVE_SHA256
320#define HAVE_SHA384
321#define HAVE_SHA512
322
323struct mrb_md {
324 int type;
325 void *ctx;
326 int ctx_size;
327};
328
329struct mrb_hmac {
330 int type;
331 CCHmacContext ctx;
332};
333
334static int
335md_ctx_size(int type)
336{
337 switch (type) {
338 case MD_TYPE_MD5: return sizeof(CC_MD5_CTX);
339 case MD_TYPE_SHA1: return sizeof(CC_SHA1_CTX);
340 case MD_TYPE_SHA256: return sizeof(CC_SHA256_CTX);
341 case MD_TYPE_SHA384: return sizeof(CC_SHA512_CTX); /* ! */
342 case MD_TYPE_SHA512: return sizeof(CC_SHA512_CTX);
343 default: return 0;
344 }
345}
346
347static void
348lib_md_free(mrb_state *mrb, void *ptr)
349{
350 struct mrb_md *md = ptr;
351
352 memset(md->ctx, 0, md_ctx_size(md->type));
353 mrb_free(mrb, md->ctx);
354 mrb_free(mrb, md);
355}
356
357static void
358lib_hmac_free(mrb_state *mrb, void *ptr)
359{
360 struct mrb_hmac *hmac = ptr;
361
362 memset(&hmac->ctx, 0, sizeof(hmac->ctx));
363 mrb_free(mrb, hmac);
364}
365
366static struct mrb_data_type mrb_md_type = { "MD", lib_md_free };
367static struct mrb_data_type mrb_hmac_type = { "HMAC", lib_hmac_free };
368
369#define MAX_DIGEST_LENGTH CC_SHA512_DIGEST_LENGTH
370
371union ctx_union {
372 CC_MD5_CTX md5;
373 CC_SHA1_CTX sha1;
374 CC_SHA256_CTX sha256;
375 /* we don't have CC_SHA384_CTX! */
376 CC_SHA512_CTX sha512;
377};
378
379static void
380lib_init(void)
381{
382}
383
384static int
385md_block_length(int type)
386{
387 switch (type) {
388 case MD_TYPE_MD5: return CC_MD5_BLOCK_BYTES;
389 case MD_TYPE_SHA1: return CC_SHA1_BLOCK_BYTES;
390 case MD_TYPE_SHA256: return CC_SHA256_BLOCK_BYTES;
391 case MD_TYPE_SHA384: return CC_SHA384_BLOCK_BYTES;
392 case MD_TYPE_SHA512: return CC_SHA512_BLOCK_BYTES;
393 default: return 0;
394 }
395}
396
397static int
398lib_md_block_length(const struct mrb_md *md)
399{
400 return md_block_length(md->type);
401}
402
403static void
404md_init(int type, void *ctxp)
405{
406 switch (type) {
407 case MD_TYPE_MD5: CC_MD5_Init(ctxp); break;
408 case MD_TYPE_SHA1: CC_SHA1_Init(ctxp); break;
409 case MD_TYPE_SHA256: CC_SHA256_Init(ctxp); break;
410 case MD_TYPE_SHA384: CC_SHA384_Init(ctxp); break;
411 case MD_TYPE_SHA512: CC_SHA512_Init(ctxp); break;
412 default: break;
413 }
414}
415
416static void
417md_final(int type, unsigned char *str, void *ctx)
418{
419 switch (type) {
420 case MD_TYPE_MD5: CC_MD5_Final(str, ctx); break;
421 case MD_TYPE_SHA1: CC_SHA1_Final(str, ctx); break;
422 case MD_TYPE_SHA256: CC_SHA256_Final(str, ctx); break;
423 case MD_TYPE_SHA384: CC_SHA384_Final(str, ctx); break;
424 case MD_TYPE_SHA512: CC_SHA512_Final(str, ctx); break;
425 default: break;
426 }
427}
428
429static int
430md_digest_length(int type)
431{
432 switch (type) {
433 case MD_TYPE_MD5: return 16;
434 case MD_TYPE_SHA1: return 20;
435 case MD_TYPE_SHA256: return 32;
436 case MD_TYPE_SHA384: return 48;
437 case MD_TYPE_SHA512: return 64;
438 default: return 0;
439 }
440}
441
442static mrb_value
443lib_md_digest(mrb_state *mrb, const struct mrb_md *md)
444{
445 union ctx_union ctx;
446 unsigned char mdstr[MAX_DIGEST_LENGTH];
447
448 memcpy(&ctx, md->ctx, md_ctx_size(md->type));
449 md_final(md->type, mdstr, &ctx);
450 return mrb_str_new(mrb, (char *)mdstr, md_digest_length(md->type));
451}
452
453static mrb_value
454lib_md_digest_bang(mrb_state *mrb, struct mrb_md *md)
455{
456 unsigned char mdstr[MAX_DIGEST_LENGTH];
457
458 md_final(md->type, mdstr, md->ctx);
459 md_init(md->type, md->ctx);
460 return mrb_str_new(mrb, (char *)mdstr, md_digest_length(md->type));
461}
462
463static int
464lib_md_digest_length(const struct mrb_md *md)
465{
466 return md_digest_length(md->type);
467}
468
469static void
470lib_md_init(mrb_state *mrb, struct mrb_md *md, int type)
471{
472 int ctxsize;
473
474 ctxsize = md_ctx_size(type);
475 if (ctxsize == 0) {
476 mrb_raise(mrb, E_NOTIMP_ERROR, "not supported");
477 }
478 md->type = type;
479 md->ctx = NULL;
480 md->ctx = mrb_malloc(mrb, ctxsize);
481 md_init(type, md->ctx);
482}
483
484static void
485lib_md_init_copy(mrb_state *mrb, struct mrb_md *mdnew, struct mrb_md *mdold)
486{
487 lib_md_init(mrb, mdnew, mdold->type);
488}
489
490static void
491lib_md_reset(mrb_state *mrb, struct mrb_md *md)
492{
493 md_init(md->type, md->ctx);
494}
495
496static void
497lib_md_update(mrb_state *mrb, struct mrb_md *md, unsigned char *data, mrb_int len)
498{
499 if (sizeof(len) > sizeof(CC_LONG)) {
500 if (len != (CC_LONG)len) {
501 mrb_raise(mrb, E_ARGUMENT_ERROR, "too long string (not supported yet)");
502 }
503 }
504 switch (md->type) {
505 case MD_TYPE_MD5: CC_MD5_Update(md->ctx, data, len); break;
506 case MD_TYPE_SHA1: CC_SHA1_Update(md->ctx, data, len); break;
507 case MD_TYPE_SHA256: CC_SHA256_Update(md->ctx, data, len); break;
508 case MD_TYPE_SHA384: CC_SHA384_Update(md->ctx, data, len); break;
509 case MD_TYPE_SHA512: CC_SHA512_Update(md->ctx, data, len); break;
510 default: break;
511 }
512}
513
514static int
515lib_hmac_block_length(const struct mrb_hmac *hmac)
516{
517 return md_block_length(hmac->type);
518}
519
520static mrb_value
521lib_hmac_digest(mrb_state *mrb, const struct mrb_hmac *hmac)
522{
523 CCHmacContext ctx;
524 unsigned char str[MAX_DIGEST_LENGTH];
525
526 memcpy(&ctx, &hmac->ctx, sizeof(ctx));
527 CCHmacFinal(&ctx, str);
528 return mrb_str_new(mrb, (const char *)str, md_digest_length(hmac->type));
529}
530
531static int
532lib_hmac_digest_length(const struct mrb_hmac *hmac)
533{
534 return md_digest_length(hmac->type);
535}
536
537static void
538lib_hmac_init(mrb_state *mrb, struct mrb_hmac *hmac, int type, const unsigned char *key, mrb_int keylen)
539{
540 CCHmacAlgorithm algorithm;
541
542#if MRB_INT_MAX > SIZE_MAX
543 if (len > SIZE_MAX) {
544 mrb_raise(mrb, E_ARGUMENT_ERROR, "too long key");
545 }
546#endif
547 switch (type) {
548 case MD_TYPE_MD5: algorithm = kCCHmacAlgMD5; break;
549 case MD_TYPE_SHA1: algorithm = kCCHmacAlgSHA1; break;
550 case MD_TYPE_SHA256: algorithm = kCCHmacAlgSHA256; break;
551 case MD_TYPE_SHA384: algorithm = kCCHmacAlgSHA384; break;
552 case MD_TYPE_SHA512: algorithm = kCCHmacAlgSHA512; break;
553 default:
554 mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-digest: internal error: unexpected HMAC type: %S", mrb_fixnum_value(type));
555 algorithm = 0;
556 break;
557 }
558 hmac->type = type;
559 CCHmacInit(&hmac->ctx, algorithm, key, keylen);
560}
561
562static void
563lib_hmac_update(mrb_state *mrb, struct mrb_hmac *hmac, unsigned char *data, mrb_int len)
564{
565#if MRB_INT_MAX > SIZE_MAX
566 if (len > SIZE_MAX) {
567 mrb_raise(mrb, E_ARGUMENT_ERROR, "too long string");
568 }
569#endif
570 CCHmacUpdate(&hmac->ctx, data, len);
571}
572
573#endif
574
575static void
576basecheck(mrb_state *mrb, mrb_value self, struct mrb_md **mdp)
577{
578 struct RClass *c;
579 struct mrb_md *md;
580 mrb_value t;
581
582 c = mrb_obj_class(mrb, self);
583 t = mrb_const_get(mrb, mrb_obj_value(c), mrb_intern_lit(mrb, TYPESYM));
584 if (mrb_nil_p(t)) {
585 mrb_raise(mrb, E_NOTIMP_ERROR, "Digest::Base is an abstract class");
586 }
587 md = (struct mrb_md *)DATA_PTR(self);
588 if (!md) {
589 mrb_raise(mrb, E_RUNTIME_ERROR, "no md found (BUG?)");
590 }
591 if (mdp) *mdp = md;
592}
593
594static mrb_value
595mrb_digest_block_length(mrb_state *mrb, mrb_value self)
596{
597 struct mrb_md *md;
598
599 basecheck(mrb, self, &md);
600 return mrb_fixnum_value(lib_md_block_length(md));
601}
602
603static mrb_value
604mrb_digest_digest(mrb_state *mrb, mrb_value self)
605{
606 struct mrb_md *md;
607
608 md = (struct mrb_md *)DATA_PTR(self);
609 if (!md) return mrb_nil_value();
610 return lib_md_digest(mrb, md);
611}
612
613static mrb_value
614mrb_digest_digest_bang(mrb_state *mrb, mrb_value self)
615{
616 struct mrb_md *md;
617
618 md = (struct mrb_md *)DATA_PTR(self);
619 if (!md) return mrb_nil_value();
620 return lib_md_digest_bang(mrb, md);
621}
622
623static mrb_value
624mrb_digest_digest_length(mrb_state *mrb, mrb_value self)
625{
626 struct mrb_md *md;
627
628 basecheck(mrb, self, &md);
629 return mrb_fixnum_value(lib_md_digest_length(md));
630}
631
632static mrb_value
633digest2hexdigest(mrb_state *mrb, mrb_value b)
634{
635 mrb_value h;
636 int i, len;
637 char *bp, buf[3];
638
639 bp = RSTRING_PTR(b);
640 len = RSTRING_LEN(b);
641 h = mrb_str_buf_new(mrb, len * 2);
642 for (i = 0; i < len; i++) {
643 snprintf(buf, sizeof(buf), "%02x", (unsigned char )bp[i]);
644 mrb_str_buf_cat(mrb, h, buf, 2);
645 }
646 return h;
647}
648
649static mrb_value
650mrb_digest_hexdigest(mrb_state *mrb, mrb_value self)
651{
652 return digest2hexdigest(mrb, mrb_digest_digest(mrb, self));
653}
654
655static mrb_value
656mrb_digest_init(mrb_state *mrb, mrb_value self)
657{
658 struct RClass *c;
659 struct mrb_md *md;
660 mrb_value t;
661
662 md = (struct mrb_md *)DATA_PTR(self);
663 if (md) {
664 lib_md_free(mrb, md);
665 }
666 DATA_TYPE(self) = &mrb_md_type;
667 DATA_PTR(self) = NULL;
668
669 c = mrb_obj_class(mrb, self);
670 if (!mrb_const_defined(mrb, mrb_obj_value(c), mrb_intern_lit(mrb, TYPESYM))) {
671 mrb_raise(mrb, E_NOTIMP_ERROR, "Digest::Base is an abstract class");
672 }
673 t = mrb_const_get(mrb, mrb_obj_value(c), mrb_intern_lit(mrb, TYPESYM));
674#if 0
675 if (lib_md_supported(t)) {
676 mrb_raise(mrb, E_NOTIMP_ERROR, "unknown algorithm");
677 }
678#endif
679
680 md = (struct mrb_md *)mrb_malloc(mrb, sizeof(*md));
681 DATA_PTR(self) = md;
682 lib_md_init(mrb, md, mrb_fixnum(t));
683 return self;
684}
685
686static mrb_value
687mrb_digest_init_copy(mrb_state *mrb, mrb_value copy)
688{
689 struct mrb_md *m1, *m2;
690 mrb_value src;
691
692 mrb_get_args(mrb, "o", &src);
693 if (mrb_obj_equal(mrb, copy, src)) return copy;
694 if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) {
695 mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class");
696 }
697 if (!DATA_PTR(copy)) {
698 DATA_PTR(copy) = mrb_malloc(mrb, sizeof(struct mrb_md));
699 DATA_TYPE(copy) = &mrb_md_type;
700 }
701 m1 = DATA_PTR(src);
702 m2 = DATA_PTR(copy);
703 lib_md_init_copy(mrb, m2, m1);
704 return copy;
705}
706
707static mrb_value
708mrb_digest_reset(mrb_state *mrb, mrb_value self)
709{
710 struct mrb_md *md;
711
712 md = (struct mrb_md *)DATA_PTR(self);
713 if (!md) return mrb_nil_value();
714 lib_md_reset(mrb, md);
715 return self;
716}
717
718static mrb_value
719mrb_digest_update(mrb_state *mrb, mrb_value self)
720{
721 struct mrb_md *md;
722 mrb_int len;
723 char *str;
724
725 md = (struct mrb_md *)DATA_PTR(self);
726 if (!md) return mrb_nil_value();
727 mrb_get_args(mrb, "s", &str, &len);
728 lib_md_update(mrb, md, (unsigned char *)str, len);
729 return self;
730}
731
732static mrb_value
733mrb_hmac_block_length(mrb_state *mrb, mrb_value self)
734{
735 struct mrb_hmac *hmac;
736
737 hmac = (struct mrb_hmac *)DATA_PTR(self);
738 if (!hmac) return mrb_nil_value();
739 return mrb_fixnum_value(lib_hmac_block_length(hmac));
740}
741
742static mrb_value
743mrb_hmac_digest(mrb_state *mrb, mrb_value self)
744{
745 struct mrb_hmac *hmac;
746
747 hmac = (struct mrb_hmac *)DATA_PTR(self);
748 if (!hmac) return mrb_nil_value();
749 return lib_hmac_digest(mrb, hmac);
750}
751
752static mrb_value
753mrb_hmac_digest_length(mrb_state *mrb, mrb_value self)
754{
755 struct mrb_hmac *hmac;
756
757 hmac = (struct mrb_hmac *)DATA_PTR(self);
758 if (!hmac) return mrb_nil_value();
759 return mrb_fixnum_value(lib_hmac_digest_length(hmac));
760}
761
762static mrb_value
763mrb_hmac_hexdigest(mrb_state *mrb, mrb_value self)
764{
765 return digest2hexdigest(mrb, mrb_hmac_digest(mrb, self));
766}
767
768static mrb_value
769mrb_hmac_init(mrb_state *mrb, mrb_value self)
770{
771 struct mrb_hmac *hmac;
772 mrb_value digest, t;
773 mrb_int keylen;
774 char *key;
775
776 hmac = (struct mrb_hmac *)DATA_PTR(self);
777 if (hmac) {
778 lib_hmac_free(mrb, hmac);
779 }
780 DATA_TYPE(self) = &mrb_hmac_type;
781 DATA_PTR(self) = NULL;
782
783 mrb_get_args(mrb, "so", &key, &keylen, &digest);
784 t = mrb_const_get(mrb, digest, mrb_intern_lit(mrb, TYPESYM));
785 if (mrb_nil_p(t)) {
786 mrb_raise(mrb, E_RUNTIME_ERROR, "not a digester");
787 }
788
789 hmac = (struct mrb_hmac *)mrb_malloc(mrb, sizeof(*hmac));
790 DATA_PTR(self) = hmac;
791 lib_hmac_init(mrb, hmac, mrb_fixnum(t), (unsigned char *)key, keylen);
792 return self;
793}
794
795static mrb_value
796mrb_hmac_init_copy(mrb_state *mrb, mrb_value copy)
797{
798 mrb_raise(mrb, E_RUNTIME_ERROR, "cannot duplicate HMAC");
799 return copy;
800}
801
802static mrb_value
803mrb_hmac_update(mrb_state *mrb, mrb_value self)
804{
805 struct mrb_hmac *hmac;
806 mrb_int len;
807 char *str;
808
809 hmac = (struct mrb_hmac *)DATA_PTR(self);
810 if (!hmac) return mrb_nil_value();
811 mrb_get_args(mrb, "s", &str, &len);
812 lib_hmac_update(mrb, hmac, (unsigned char *)str, len);
813 return self;
814}
815
816
817void
818mrb_mruby_digest_gem_init(mrb_state *mrb)
819{
820 struct RClass *b, *d, *h;
821
822 lib_init();
823
824 d = mrb_define_module(mrb, "Digest");
825
826 b = mrb_define_class_under(mrb, d, "Base", mrb->object_class);
827 mrb_define_method(mrb, b, "block_length", mrb_digest_block_length, MRB_ARGS_NONE());
828 mrb_define_method(mrb, b, "digest", mrb_digest_digest, MRB_ARGS_NONE());
829 mrb_define_method(mrb, b, "digest!", mrb_digest_digest_bang, MRB_ARGS_NONE()); /* XXX: can be defined in mrblib... */
830 mrb_define_method(mrb, b, "digest_length", mrb_digest_digest_length, MRB_ARGS_NONE());
831 //mrb_define_method(mrb, b, "file", mrb_digest_file, MRB_ARGS_REQ(1));
832 mrb_define_method(mrb, b, "hexdigest", mrb_digest_hexdigest, MRB_ARGS_NONE());
833 //mrb_define_method(mrb, b, "hexdigest!", mrb_digest_hexdigest_bang, MRB_ARGS_NONE()); /* XXX: can be defined in mrblib... */
834 mrb_define_method(mrb, b, "initialize", mrb_digest_init, MRB_ARGS_NONE());
835 mrb_define_method(mrb, b, "initialize_copy", mrb_digest_init_copy, MRB_ARGS_REQ(1));
836 mrb_define_method(mrb, b, "reset", mrb_digest_reset, MRB_ARGS_NONE());
837 mrb_define_method(mrb, b, "update", mrb_digest_update, MRB_ARGS_REQ(1));
838
839#define DEFCLASS(n) \
840do { \
841 struct RClass *a = mrb_define_class_under(mrb, d, #n, b); \
842 MRB_SET_INSTANCE_TT(a, MRB_TT_DATA); \
843 mrb_define_const(mrb, a, TYPESYM, mrb_fixnum_value(MD_TYPE_##n)); \
844} while (0)
845
846#ifdef HAVE_MD5
847 DEFCLASS(MD5);
848#endif
849#ifdef HAVE_RMD160
850 DEFCLASS(RMD160);
851#endif
852#ifdef HAVE_SHA1
853 DEFCLASS(SHA1);
854#endif
855#ifdef HAVE_SHA256
856 DEFCLASS(SHA256);
857#endif
858#ifdef HAVE_SHA384
859 DEFCLASS(SHA384);
860#endif
861#ifdef HAVE_SHA512
862 DEFCLASS(SHA512);
863#endif
864
865 h = mrb_define_class_under(mrb, d, "HMAC", mrb->object_class);
866 MRB_SET_INSTANCE_TT(h, MRB_TT_DATA);
867 mrb_define_method(mrb, h, "block_length", mrb_hmac_block_length, MRB_ARGS_NONE());
868 mrb_define_method(mrb, h, "digest", mrb_hmac_digest, MRB_ARGS_NONE());
869 mrb_define_method(mrb, h, "digest_length", mrb_hmac_digest_length, MRB_ARGS_NONE());
870 mrb_define_method(mrb, h, "hexdigest", mrb_hmac_hexdigest, MRB_ARGS_NONE());
871 mrb_define_method(mrb, h, "initialize", mrb_hmac_init, MRB_ARGS_REQ(2));
872 mrb_define_method(mrb, h, "initialize_copy", mrb_hmac_init_copy, MRB_ARGS_REQ(1));
873 mrb_define_method(mrb, h, "update", mrb_hmac_update, MRB_ARGS_REQ(1));
874}
875
876void
877mrb_mruby_digest_gem_final(mrb_state *mrb)
878{
879}
Note: See TracBrowser for help on using the repository browser.