cryptopp 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +8 -0
- data/MIT-LICENSE +22 -0
- data/README +7 -0
- data/Rakefile +42 -0
- data/cryptopp.gemspec +199 -0
- data/ext/.gitignore +5 -0
- data/ext/Rakefile +16 -0
- data/ext/ciphers.cpp +1402 -0
- data/ext/cryptopp.cpp +285 -0
- data/ext/cryptopp_ruby_api.h +139 -0
- data/ext/defs/block_modes.def +10 -0
- data/ext/defs/checksums.def +10 -0
- data/ext/defs/ciphers.def +136 -0
- data/ext/defs/hashes.def +78 -0
- data/ext/defs/hmacs.def +54 -0
- data/ext/defs/paddings.def +9 -0
- data/ext/defs/rngs.def +7 -0
- data/ext/digests.cpp +1120 -0
- data/ext/extconf.rb +39 -0
- data/ext/j3way.cpp +22 -0
- data/ext/j3way.h +29 -0
- data/ext/jadler32.h +32 -0
- data/ext/jaes.cpp +22 -0
- data/ext/jaes.h +31 -0
- data/ext/jarc4.cpp +22 -0
- data/ext/jarc4.h +37 -0
- data/ext/jbase.cpp +172 -0
- data/ext/jbase.h +92 -0
- data/ext/jbasiccipherinfo.h +74 -0
- data/ext/jblowfish.cpp +22 -0
- data/ext/jblowfish.h +29 -0
- data/ext/jcamellia.cpp +24 -0
- data/ext/jcamellia.h +33 -0
- data/ext/jcast128.cpp +22 -0
- data/ext/jcast128.h +31 -0
- data/ext/jcast256.cpp +22 -0
- data/ext/jcast256.h +31 -0
- data/ext/jcipher.cpp +112 -0
- data/ext/jcipher.h +42 -0
- data/ext/jcipher_t.h +469 -0
- data/ext/jconfig.h +127 -0
- data/ext/jconstants.h +189 -0
- data/ext/jcrc32.h +32 -0
- data/ext/jdes.cpp +22 -0
- data/ext/jdes.h +31 -0
- data/ext/jdes_ede2.cpp +22 -0
- data/ext/jdes_ede2.h +31 -0
- data/ext/jdes_ede3.cpp +22 -0
- data/ext/jdes_ede3.h +31 -0
- data/ext/jdes_xex3.cpp +22 -0
- data/ext/jdes_xex3.h +31 -0
- data/ext/jdiamond2.cpp +22 -0
- data/ext/jdiamond2.h +31 -0
- data/ext/jdiamond2lite.cpp +22 -0
- data/ext/jdiamond2lite.h +31 -0
- data/ext/jexception.h +20 -0
- data/ext/jgost.cpp +22 -0
- data/ext/jgost.h +31 -0
- data/ext/jhash.cpp +92 -0
- data/ext/jhash.h +54 -0
- data/ext/jhash_t.h +121 -0
- data/ext/jhaval.h +64 -0
- data/ext/jhelpers.cpp +90 -0
- data/ext/jhelpers.h +38 -0
- data/ext/jhmac.cpp +44 -0
- data/ext/jhmac.h +34 -0
- data/ext/jhmac_t.h +125 -0
- data/ext/jidea.cpp +22 -0
- data/ext/jidea.h +31 -0
- data/ext/jmarc4.cpp +22 -0
- data/ext/jmarc4.h +37 -0
- data/ext/jmars.cpp +22 -0
- data/ext/jmars.h +31 -0
- data/ext/jmd2.h +56 -0
- data/ext/jmd4.h +56 -0
- data/ext/jmd5.h +56 -0
- data/ext/jpanamacipher.cpp +32 -0
- data/ext/jpanamacipher.h +46 -0
- data/ext/jpanamahash.h +44 -0
- data/ext/jrc2.cpp +44 -0
- data/ext/jrc2.h +39 -0
- data/ext/jrc5.cpp +22 -0
- data/ext/jrc5.h +31 -0
- data/ext/jrc6.cpp +22 -0
- data/ext/jrc6.h +31 -0
- data/ext/jripemd160.h +113 -0
- data/ext/jsafer.cpp +32 -0
- data/ext/jsafer.h +42 -0
- data/ext/jseal.cpp +32 -0
- data/ext/jseal.h +42 -0
- data/ext/jserpent.cpp +22 -0
- data/ext/jserpent.h +31 -0
- data/ext/jsha.h +122 -0
- data/ext/jshacal2.cpp +22 -0
- data/ext/jshacal2.h +31 -0
- data/ext/jshark.cpp +24 -0
- data/ext/jshark.h +33 -0
- data/ext/jsink.cpp +90 -0
- data/ext/jsink.h +154 -0
- data/ext/jskipjack.cpp +22 -0
- data/ext/jskipjack.h +31 -0
- data/ext/jsquare.cpp +22 -0
- data/ext/jsquare.h +31 -0
- data/ext/jstream.cpp +8 -0
- data/ext/jstream.h +20 -0
- data/ext/jstream_t.h +175 -0
- data/ext/jtea.cpp +22 -0
- data/ext/jtea.h +31 -0
- data/ext/jtiger.h +52 -0
- data/ext/jtwofish.cpp +22 -0
- data/ext/jtwofish.h +31 -0
- data/ext/jwhirlpool.h +52 -0
- data/ext/utils.cpp +8 -0
- data/extras/parser_c.rb +114 -0
- data/test/ciphers_test.rb +37 -0
- data/test/data/ciphers/3desval.dat +7 -0
- data/test/data/ciphers/3wayval.dat +6 -0
- data/test/data/ciphers/arc4.dat +8 -0
- data/test/data/ciphers/blowfish.dat +5 -0
- data/test/data/ciphers/camellia.dat +7 -0
- data/test/data/ciphers/cast128v.dat +5 -0
- data/test/data/ciphers/cast256v.dat +5 -0
- data/test/data/ciphers/descert.dat +198 -0
- data/test/data/ciphers/diamond.dat +9 -0
- data/test/data/ciphers/gostval.dat +10 -0
- data/test/data/ciphers/ideaval.dat +13 -0
- data/test/data/ciphers/marsval.dat +11 -0
- data/test/data/ciphers/panamac.dat +7 -0
- data/test/data/ciphers/rc2val.dat +10 -0
- data/test/data/ciphers/rc5val.dat +7 -0
- data/test/data/ciphers/rc6val.dat +8 -0
- data/test/data/ciphers/rijndael.dat +11 -0
- data/test/data/ciphers/saferval.dat +27 -0
- data/test/data/ciphers/seal.dat +3 -0
- data/test/data/ciphers/serpentv.dat +11 -0
- data/test/data/ciphers/shacal2.dat +7 -0
- data/test/data/ciphers/sharkval.dat +9 -0
- data/test/data/ciphers/skipjack.dat +3 -0
- data/test/data/ciphers/squareva.dat +10 -0
- data/test/data/ciphers/twofishv.dat +11 -0
- data/test/data/digests/adler32.dat +8 -0
- data/test/data/digests/crc32.dat +10 -0
- data/test/data/digests/haval.dat +4 -0
- data/test/data/digests/havalcer.dat +23 -0
- data/test/data/digests/md2.dat +9 -0
- data/test/data/digests/md4.dat +9 -0
- data/test/data/digests/md5.dat +9 -0
- data/test/data/digests/panamah.dat +8 -0
- data/test/data/digests/ripemd.dat +43 -0
- data/test/data/digests/sha.dat +19 -0
- data/test/data/digests/tiger.dat +11 -0
- data/test/data/digests/whirlpool.dat +13 -0
- data/test/data/hmacs/hmac.dat +6 -0
- data/test/digests_test.rb +29 -0
- data/test/hmacs_test.rb +38 -0
- data/test/test_helper.rb +42 -0
- metadata +220 -0
data/ext/defs/hashes.def
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#if ENABLED_HAVAL_HASH || defined(HASH_ALGORITHM_X_FORCE)
|
|
2
|
+
HASH_ALGORITHM_X(HAVAL, HAVAL, JHAVAL, haval)
|
|
3
|
+
#endif
|
|
4
|
+
|
|
5
|
+
#if ENABLED_HAVAL3_HASH || defined(HASH_ALGORITHM_X_FORCE)
|
|
6
|
+
HASH_ALGORITHM_X(HAVAL3, HAVAL3, JHAVAL3, haval3)
|
|
7
|
+
#endif
|
|
8
|
+
|
|
9
|
+
#if ENABLED_HAVAL4_HASH || defined(HASH_ALGORITHM_X_FORCE)
|
|
10
|
+
HASH_ALGORITHM_X(HAVAL4, HAVAL4, JHAVAL4, haval4)
|
|
11
|
+
#endif
|
|
12
|
+
|
|
13
|
+
#if ENABLED_HAVAL5_HASH || defined(HASH_ALGORITHM_X_FORCE)
|
|
14
|
+
HASH_ALGORITHM_X(HAVAL5, HAVAL5, JHAVAL5, haval5)
|
|
15
|
+
#endif
|
|
16
|
+
|
|
17
|
+
#if ENABLED_MD2_HASH || defined(HASH_ALGORITHM_X_FORCE)
|
|
18
|
+
HASH_ALGORITHM_X(MD2, MD2, JMD2, md2)
|
|
19
|
+
#endif
|
|
20
|
+
|
|
21
|
+
#if ENABLED_MD4_HASH || defined(HASH_ALGORITHM_X_FORCE)
|
|
22
|
+
HASH_ALGORITHM_X(MD4, MD4, JMD4, md4)
|
|
23
|
+
#endif
|
|
24
|
+
|
|
25
|
+
#if ENABLED_MD5_HASH || defined(HASH_ALGORITHM_X_FORCE)
|
|
26
|
+
HASH_ALGORITHM_X(MD5, MD5, JMD5, md5)
|
|
27
|
+
#endif
|
|
28
|
+
|
|
29
|
+
#if ENABLED_PANAMA_LITTLE_ENDIAN_HASH || defined(HASH_ALGORITHM_X_FORCE)
|
|
30
|
+
HASH_ALGORITHM_X(PanamaHashLE, PANAMA_LITTLE_ENDIAN, JPanamaHashLE, panama_le)
|
|
31
|
+
#endif
|
|
32
|
+
|
|
33
|
+
#if ENABLED_PANAMA_BIG_ENDIAN_HASH || defined(HASH_ALGORITHM_X_FORCE)
|
|
34
|
+
HASH_ALGORITHM_X(PanamaHashBE, PANAMA_BIG_ENDIAN, JPanamaHashBE, panama_be)
|
|
35
|
+
#endif
|
|
36
|
+
|
|
37
|
+
#if ENABLED_RIPEMD128_HASH || defined(HASH_ALGORITHM_X_FORCE)
|
|
38
|
+
HASH_ALGORITHM_X(RIPEMD128, RIPEMD128, JRIPEMD128, ripemd128)
|
|
39
|
+
#endif
|
|
40
|
+
|
|
41
|
+
#if ENABLED_RIPEMD160_HASH || defined(HASH_ALGORITHM_X_FORCE)
|
|
42
|
+
HASH_ALGORITHM_X(RIPEMD160, RIPEMD160, JRIPEMD160, ripemd160)
|
|
43
|
+
#endif
|
|
44
|
+
|
|
45
|
+
#if ENABLED_RIPEMD256_HASH || defined(HASH_ALGORITHM_X_FORCE)
|
|
46
|
+
HASH_ALGORITHM_X(RIPEMD256, RIPEMD256, JRIPEMD256, ripemd256)
|
|
47
|
+
#endif
|
|
48
|
+
|
|
49
|
+
#if ENABLED_RIPEMD320_HASH || defined(HASH_ALGORITHM_X_FORCE)
|
|
50
|
+
HASH_ALGORITHM_X(RIPEMD320, RIPEMD320, JRIPEMD320, ripemd320)
|
|
51
|
+
#endif
|
|
52
|
+
|
|
53
|
+
#if ENABLED_SHA1_HASH || defined(HASH_ALGORITHM_X_FORCE)
|
|
54
|
+
HASH_ALGORITHM_X(SHA1, SHA1, JSHA1, sha1)
|
|
55
|
+
#endif
|
|
56
|
+
|
|
57
|
+
#if ENABLED_SHA256_HASH || defined(HASH_ALGORITHM_X_FORCE)
|
|
58
|
+
HASH_ALGORITHM_X(SHA256, SHA256, JSHA256, sha256)
|
|
59
|
+
#endif
|
|
60
|
+
|
|
61
|
+
#if ENABLED_SHA384_HASH || defined(HASH_ALGORITHM_X_FORCE)
|
|
62
|
+
HASH_ALGORITHM_X(SHA384, SHA384, JSHA384, sha384)
|
|
63
|
+
#endif
|
|
64
|
+
|
|
65
|
+
#if ENABLED_SHA512_HASH || defined(HASH_ALGORITHM_X_FORCE)
|
|
66
|
+
HASH_ALGORITHM_X(SHA512, SHA512, JSHA512, sha512)
|
|
67
|
+
#endif
|
|
68
|
+
|
|
69
|
+
#if ENABLED_TIGER_HASH || defined(HASH_ALGORITHM_X_FORCE)
|
|
70
|
+
HASH_ALGORITHM_X(Tiger, TIGER, JTiger, tiger)
|
|
71
|
+
#endif
|
|
72
|
+
|
|
73
|
+
#if ENABLED_WHIRLPOOL_HASH || defined(HASH_ALGORITHM_X_FORCE)
|
|
74
|
+
HASH_ALGORITHM_X(Whirlpool, WHIRLPOOL, JWhirlpool, whirlpool)
|
|
75
|
+
#endif
|
|
76
|
+
|
|
77
|
+
#undef HASH_ALGORITHM_X
|
|
78
|
+
#undef HASH_ALGORITHM_X_FORCE
|
data/ext/defs/hmacs.def
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#if ENABLED_MD2_HMAC || HMAC_ALGORITHM_X_FORCE
|
|
2
|
+
HMAC_ALGORITHM_X(MD2_HMAC, MD2, JMD2_HMAC, md2_hmac)
|
|
3
|
+
#endif
|
|
4
|
+
|
|
5
|
+
#if ENABLED_MD4_HMAC || HMAC_ALGORITHM_X_FORCE
|
|
6
|
+
HMAC_ALGORITHM_X(MD4_HMAC, MD4, JMD4_HMAC, md4_hmac)
|
|
7
|
+
#endif
|
|
8
|
+
|
|
9
|
+
#if ENABLED_MD5_HMAC || HMAC_ALGORITHM_X_FORCE
|
|
10
|
+
HMAC_ALGORITHM_X(MD5_HMAC, MD5, JMD5_HMAC, md5_hmac)
|
|
11
|
+
#endif
|
|
12
|
+
|
|
13
|
+
#if ENABLED_RIPEMD128_HMAC || HMAC_ALGORITHM_X_FORCE
|
|
14
|
+
HMAC_ALGORITHM_X(RIPEMD128_HMAC, RIPEMD128, JRIPEMD128_HMAC, ripemd128_hmac)
|
|
15
|
+
#endif
|
|
16
|
+
|
|
17
|
+
#if ENABLED_RIPEMD160_HMAC || HMAC_ALGORITHM_X_FORCE
|
|
18
|
+
HMAC_ALGORITHM_X(RIPEMD160_HMAC, RIPEMD160, JRIPEMD160_HMAC, ripemd160_hmac)
|
|
19
|
+
#endif
|
|
20
|
+
|
|
21
|
+
#if ENABLED_RIPEMD256_HMAC || HMAC_ALGORITHM_X_FORCE
|
|
22
|
+
HMAC_ALGORITHM_X(RIPEMD256_HMAC, RIPEMD256, JRIPEMD256_HMAC, ripemd256_hmac)
|
|
23
|
+
#endif
|
|
24
|
+
|
|
25
|
+
#if ENABLED_RIPEMD320_HMAC || HMAC_ALGORITHM_X_FORCE
|
|
26
|
+
HMAC_ALGORITHM_X(RIPEMD320_HMAC, RIPEMD320, JRIPEMD320_HMAC, ripemd320_hmac)
|
|
27
|
+
#endif
|
|
28
|
+
|
|
29
|
+
#if ENABLED_SHA1_HMAC || HMAC_ALGORITHM_X_FORCE
|
|
30
|
+
HMAC_ALGORITHM_X(SHA1_HMAC, SHA1, JSHA1_HMAC, sha1_hmac)
|
|
31
|
+
#endif
|
|
32
|
+
|
|
33
|
+
#if ENABLED_SHA256_HMAC || HMAC_ALGORITHM_X_FORCE
|
|
34
|
+
HMAC_ALGORITHM_X(SHA256_HMAC, SHA256, JSHA256_HMAC, sha256_hmac)
|
|
35
|
+
#endif
|
|
36
|
+
|
|
37
|
+
#if ENABLED_SHA384_HMAC || HMAC_ALGORITHM_X_FORCE
|
|
38
|
+
HMAC_ALGORITHM_X(SHA384_HMAC, SHA384, JSHA384_HMAC, sha384_hmac)
|
|
39
|
+
#endif
|
|
40
|
+
|
|
41
|
+
#if ENABLED_SHA512_HMAC || HMAC_ALGORITHM_X_FORCE
|
|
42
|
+
HMAC_ALGORITHM_X(SHA512_HMAC, SHA512, JSHA512_HMAC, sha512_hmac)
|
|
43
|
+
#endif
|
|
44
|
+
|
|
45
|
+
#if ENABLED_TIGER_HMAC || HMAC_ALGORITHM_X_FORCE
|
|
46
|
+
HMAC_ALGORITHM_X(Tiger_HMAC, TIGER, JTiger_HMAC, tiger_hmac)
|
|
47
|
+
#endif
|
|
48
|
+
|
|
49
|
+
#if ENABLED_WHIRLPOOL_HMAC || HMAC_ALGORITHM_X_FORCE
|
|
50
|
+
HMAC_ALGORITHM_X(Whirlpool_HMAC, WHIRLPOOL, JWhirlpool_HMAC, whirlpool_hmac)
|
|
51
|
+
#endif
|
|
52
|
+
|
|
53
|
+
#undef HMAC_ALGORITHM_X
|
|
54
|
+
#undef HMAC_ALGORITHM_X_FORCE
|
data/ext/defs/rngs.def
ADDED
data/ext/digests.cpp
ADDED
|
@@ -0,0 +1,1120 @@
|
|
|
1
|
+
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2002-2010 J Smith <dark.panda@gmail.com>
|
|
4
|
+
* Crypto++ copyright (c) 1995-2010 Wei Dai
|
|
5
|
+
* See COPYING for the extact license
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// hash algorithms:
|
|
9
|
+
|
|
10
|
+
#include "jadler32.h"
|
|
11
|
+
#include "jcrc32.h"
|
|
12
|
+
#include "jhaval.h"
|
|
13
|
+
#include "jmd2.h"
|
|
14
|
+
#include "jmd4.h"
|
|
15
|
+
#include "jmd5.h"
|
|
16
|
+
#include "jpanamahash.h"
|
|
17
|
+
#include "jripemd160.h"
|
|
18
|
+
#include "jsha.h"
|
|
19
|
+
#include "jtiger.h"
|
|
20
|
+
#include "jwhirlpool.h"
|
|
21
|
+
|
|
22
|
+
#include "jexception.h"
|
|
23
|
+
|
|
24
|
+
#include "cryptopp_ruby_api.h"
|
|
25
|
+
|
|
26
|
+
extern void hash_mark(JHash *c);
|
|
27
|
+
extern void hash_free(JHash *c);
|
|
28
|
+
|
|
29
|
+
// forward declarations
|
|
30
|
+
|
|
31
|
+
static HashEnum digest_sym_to_const(VALUE hash);
|
|
32
|
+
static bool digest_enabled(HashEnum hash);
|
|
33
|
+
static void digest_options(VALUE self, VALUE options);
|
|
34
|
+
static JHash* digest_factory(VALUE algorithm);
|
|
35
|
+
static VALUE wrap_digest_in_ruby(JHash* hash);
|
|
36
|
+
static string digest_digest(VALUE self, bool hex);
|
|
37
|
+
static string digest_plaintext(VALUE self, bool hex);
|
|
38
|
+
static string digest_plaintext_eq(VALUE self, VALUE plaintext, bool hex);
|
|
39
|
+
static string digest_calculate(VALUE self, bool hex);
|
|
40
|
+
static string digest_digest_eq(VALUE self, VALUE digest, bool hex);
|
|
41
|
+
static string module_digest(int argc, VALUE *argv, VALUE self, bool hex);
|
|
42
|
+
static string module_digest_io(int argc, VALUE *argv, VALUE self, bool hex);
|
|
43
|
+
static string digest_digest_io(VALUE self, VALUE io, bool hex);
|
|
44
|
+
static void digest_hmac_options(VALUE self, VALUE options);
|
|
45
|
+
static string digest_hmac_key_eq(VALUE self, VALUE key, bool hex);
|
|
46
|
+
static string digest_hmac_key(VALUE self, bool hex);
|
|
47
|
+
static string module_hmac_digest(int argc, VALUE *argv, VALUE self, bool hex);
|
|
48
|
+
|
|
49
|
+
static HashEnum digest_sym_to_const(VALUE c)
|
|
50
|
+
{
|
|
51
|
+
HashEnum hash = UNKNOWN_HASH;
|
|
52
|
+
ID id = SYM2ID(c);
|
|
53
|
+
|
|
54
|
+
if (id == rb_intern("panama")) {
|
|
55
|
+
hash = PANAMA_HASH;
|
|
56
|
+
}
|
|
57
|
+
else if (id == rb_intern("sha")) {
|
|
58
|
+
hash = SHA1_HASH;
|
|
59
|
+
}
|
|
60
|
+
else if (id == rb_intern("sha_hmac")) {
|
|
61
|
+
hash = SHA1_HMAC;
|
|
62
|
+
}
|
|
63
|
+
# define CHECKSUM_ALGORITHM_X_FORCE 1
|
|
64
|
+
# define CHECKSUM_ALGORITHM_X(klass, r, c, s) \
|
|
65
|
+
else if (id == rb_intern(# s)) { \
|
|
66
|
+
hash = r ## _CHECKSUM; \
|
|
67
|
+
}
|
|
68
|
+
# include "defs/checksums.def"
|
|
69
|
+
|
|
70
|
+
# define HASH_ALGORITHM_X_FORCE 1
|
|
71
|
+
# define HASH_ALGORITHM_X(klass, r, c, s) \
|
|
72
|
+
else if (id == rb_intern(# s)) { \
|
|
73
|
+
hash = r ## _HASH; \
|
|
74
|
+
}
|
|
75
|
+
# include "defs/hashes.def"
|
|
76
|
+
|
|
77
|
+
# define HMAC_ALGORITHM_X_FORCE 1
|
|
78
|
+
# define HMAC_ALGORITHM_X(klass, r, c, s) \
|
|
79
|
+
else if (id == rb_intern(# s)) { \
|
|
80
|
+
hash = r ## _HMAC; \
|
|
81
|
+
}
|
|
82
|
+
# include "defs/hmacs.def"
|
|
83
|
+
return hash;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
/* See if a hash algorithm is enabled. */
|
|
88
|
+
static bool digest_enabled(HashEnum hash)
|
|
89
|
+
{
|
|
90
|
+
switch (hash) {
|
|
91
|
+
# define CHECKSUM_ALGORITHM_X(klass, r, c, s) \
|
|
92
|
+
case r ##_CHECKSUM:
|
|
93
|
+
# include "defs/checksums.def"
|
|
94
|
+
|
|
95
|
+
# define HASH_ALGORITHM_X(klass, r, c, s) \
|
|
96
|
+
case r ##_HASH:
|
|
97
|
+
# include "defs/hashes.def"
|
|
98
|
+
|
|
99
|
+
# define HMAC_ALGORITHM_X(klass, r, c, s) \
|
|
100
|
+
case r ##_HMAC:
|
|
101
|
+
# include "defs/hmacs.def"
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
/* Figure out options for a digest. */
|
|
109
|
+
static void digest_options(VALUE self, VALUE options)
|
|
110
|
+
{
|
|
111
|
+
Check_Type(options, T_HASH);
|
|
112
|
+
|
|
113
|
+
{
|
|
114
|
+
VALUE plaintext = rb_hash_aref(options, ID2SYM(rb_intern("plaintext")));
|
|
115
|
+
VALUE plaintext_hex = rb_hash_aref(options, ID2SYM(rb_intern("plaintext_hex")));
|
|
116
|
+
if (!NIL_P(plaintext) && !NIL_P(plaintext_hex)) {
|
|
117
|
+
rb_raise(rb_eCryptoPP_Error, "can't set both plaintext and plaintext_hex in options");
|
|
118
|
+
}
|
|
119
|
+
else if (!NIL_P(plaintext)) {
|
|
120
|
+
digest_plaintext_eq(self, plaintext, false);
|
|
121
|
+
}
|
|
122
|
+
else if (!NIL_P(plaintext_hex)) {
|
|
123
|
+
digest_plaintext_eq(self, plaintext_hex, true);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
{
|
|
128
|
+
VALUE digest = rb_hash_aref(options, ID2SYM(rb_intern("digest")));
|
|
129
|
+
VALUE digest_hex = rb_hash_aref(options, ID2SYM(rb_intern("digest_hex")));
|
|
130
|
+
if (!NIL_P(digest) && !NIL_P(digest_hex)) {
|
|
131
|
+
rb_raise(rb_eCryptoPP_Error, "can't set both digest and digest_hex in options");
|
|
132
|
+
}
|
|
133
|
+
else if (!NIL_P(digest)) {
|
|
134
|
+
digest_digest_eq(self, digest, false);
|
|
135
|
+
}
|
|
136
|
+
else if (!NIL_P(digest_hex)) {
|
|
137
|
+
digest_digest_eq(self, digest_hex, true);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
/* Creates a new Digest object. */
|
|
144
|
+
static JHash* digest_factory(VALUE algorithm)
|
|
145
|
+
{
|
|
146
|
+
try {
|
|
147
|
+
switch (digest_sym_to_const(algorithm)) {
|
|
148
|
+
default:
|
|
149
|
+
throw JException("the requested algorithm cannot be found");
|
|
150
|
+
break;
|
|
151
|
+
|
|
152
|
+
# define CHECKSUM_ALGORITHM_X(klass, r, c, s) \
|
|
153
|
+
case r ## _CHECKSUM: \
|
|
154
|
+
return static_cast<c*>(new c);
|
|
155
|
+
# include "defs/checksums.def"
|
|
156
|
+
|
|
157
|
+
# define HASH_ALGORITHM_X(klass, r, c, s) \
|
|
158
|
+
case r ## _HASH: \
|
|
159
|
+
return static_cast<c*>(new c);
|
|
160
|
+
# include "defs/hashes.def"
|
|
161
|
+
|
|
162
|
+
# define HMAC_ALGORITHM_X(klass, r, c, s) \
|
|
163
|
+
case r ## _HMAC: \
|
|
164
|
+
return static_cast<c*>(new c);
|
|
165
|
+
# include "defs/hmacs.def"
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
catch (Exception& e) {
|
|
169
|
+
throw JException("Crypto++ exception: " + e.GetWhat());
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/* Wraps a Digest/HMAC object into a Ruby object. May throw a JException if no
|
|
174
|
+
* suitable algorithm is found. */
|
|
175
|
+
static VALUE wrap_digest_in_ruby(JHash* hash)
|
|
176
|
+
{
|
|
177
|
+
const type_info& info = typeid(*hash);
|
|
178
|
+
# define CHECKSUM_ALGORITHM_X(klass, r, c, s) \
|
|
179
|
+
if (info == typeid(c)) { \
|
|
180
|
+
return Data_Wrap_Struct(rb_cCryptoPP_Digest_## r, hash_mark, hash_free, hash); \
|
|
181
|
+
} \
|
|
182
|
+
else
|
|
183
|
+
# include "defs/checksums.def"
|
|
184
|
+
|
|
185
|
+
# define HASH_ALGORITHM_X(klass, r, c, s) \
|
|
186
|
+
if (info == typeid(c)) { \
|
|
187
|
+
return Data_Wrap_Struct(rb_cCryptoPP_Digest_## r, hash_mark, hash_free, hash); \
|
|
188
|
+
} \
|
|
189
|
+
else
|
|
190
|
+
# include "defs/hashes.def"
|
|
191
|
+
|
|
192
|
+
# define HMAC_ALGORITHM_X(klass, r, c, s) \
|
|
193
|
+
if (info == typeid(c)) { \
|
|
194
|
+
return Data_Wrap_Struct(rb_cCryptoPP_Digest_HMAC_## r, hash_mark, hash_free, hash); \
|
|
195
|
+
} \
|
|
196
|
+
else
|
|
197
|
+
# include "defs/hmacs.def"
|
|
198
|
+
{
|
|
199
|
+
throw JException("the requested algorithm has been disabled");
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* call-seq:
|
|
205
|
+
* digest_factory(algorithm) => CryptoPP::Digest
|
|
206
|
+
* digest_factory(algorithm, plaintext) => CryptoPP::Digest
|
|
207
|
+
* digest_factory(algorithm, options) => CryptoPP::Digest
|
|
208
|
+
*
|
|
209
|
+
* Creates a new Digest object.
|
|
210
|
+
*
|
|
211
|
+
* See the Digest class for available options.
|
|
212
|
+
*/
|
|
213
|
+
VALUE rb_module_digest_factory(int argc, VALUE *argv, VALUE self)
|
|
214
|
+
{
|
|
215
|
+
JHash* hash = NULL;
|
|
216
|
+
VALUE algorithm, options, retval;
|
|
217
|
+
|
|
218
|
+
rb_scan_args(argc, argv, "11", &algorithm, &options);
|
|
219
|
+
{
|
|
220
|
+
HashEnum a = digest_sym_to_const(algorithm);
|
|
221
|
+
if (!IS_NON_HMAC(a)) {
|
|
222
|
+
rb_raise(rb_eCryptoPP_Error, "invalid digest algorithm");
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
try {
|
|
226
|
+
hash = digest_factory(algorithm);
|
|
227
|
+
retval = wrap_digest_in_ruby(hash);
|
|
228
|
+
}
|
|
229
|
+
catch (Exception& e) {
|
|
230
|
+
if (hash != NULL) {
|
|
231
|
+
delete hash;
|
|
232
|
+
}
|
|
233
|
+
rb_raise(rb_eCryptoPP_Error, e.GetWhat().c_str());
|
|
234
|
+
}
|
|
235
|
+
if (argc == 2) {
|
|
236
|
+
if (TYPE(options) == T_STRING) {
|
|
237
|
+
rb_digest_plaintext_eq(retval, options);
|
|
238
|
+
hash->hash();
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
digest_options(retval, options);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return retval;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
#define CHECKSUM_ALGORITHM_X(klass, r, n, s) \
|
|
250
|
+
VALUE rb_digest_ ## r ##_new(int argc, VALUE *argv, VALUE self) \
|
|
251
|
+
{ \
|
|
252
|
+
VALUE options, retval; \
|
|
253
|
+
JHash* hash = NULL; \
|
|
254
|
+
try { \
|
|
255
|
+
hash = digest_factory(ID2SYM(rb_intern(# s))); \
|
|
256
|
+
retval = wrap_digest_in_ruby(hash); \
|
|
257
|
+
} \
|
|
258
|
+
catch (Exception& e) { \
|
|
259
|
+
if (hash != NULL) { \
|
|
260
|
+
delete hash; \
|
|
261
|
+
} \
|
|
262
|
+
rb_raise(rb_eCryptoPP_Error, e.GetWhat().c_str()); \
|
|
263
|
+
} \
|
|
264
|
+
rb_scan_args(argc, argv, "01", &options); \
|
|
265
|
+
if (!NIL_P(options)) { \
|
|
266
|
+
if (TYPE(options) == T_STRING) { \
|
|
267
|
+
rb_digest_plaintext_eq(retval, options); \
|
|
268
|
+
hash->hash(); \
|
|
269
|
+
} \
|
|
270
|
+
else { \
|
|
271
|
+
digest_options(retval, options); \
|
|
272
|
+
} \
|
|
273
|
+
} \
|
|
274
|
+
return retval; \
|
|
275
|
+
}
|
|
276
|
+
#include "defs/checksums.def"
|
|
277
|
+
|
|
278
|
+
#define HASH_ALGORITHM_X(klass, r, n, s) \
|
|
279
|
+
VALUE rb_digest_ ## r ##_new(int argc, VALUE *argv, VALUE self) \
|
|
280
|
+
{ \
|
|
281
|
+
VALUE options, retval; \
|
|
282
|
+
JHash* hash = NULL; \
|
|
283
|
+
try { \
|
|
284
|
+
hash = digest_factory(ID2SYM(rb_intern(# s))); \
|
|
285
|
+
retval = wrap_digest_in_ruby(hash); \
|
|
286
|
+
} \
|
|
287
|
+
catch (Exception& e) { \
|
|
288
|
+
if (hash != NULL) { \
|
|
289
|
+
delete hash; \
|
|
290
|
+
} \
|
|
291
|
+
rb_raise(rb_eCryptoPP_Error, e.GetWhat().c_str()); \
|
|
292
|
+
} \
|
|
293
|
+
rb_scan_args(argc, argv, "01", &options); \
|
|
294
|
+
if (!NIL_P(options)) { \
|
|
295
|
+
if (TYPE(options) == T_STRING) { \
|
|
296
|
+
rb_digest_plaintext_eq(retval, options); \
|
|
297
|
+
hash->hash(); \
|
|
298
|
+
} \
|
|
299
|
+
else { \
|
|
300
|
+
digest_options(retval, options); \
|
|
301
|
+
} \
|
|
302
|
+
} \
|
|
303
|
+
return retval; \
|
|
304
|
+
}
|
|
305
|
+
#include "defs/hashes.def"
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* call-seq:
|
|
310
|
+
* update(plaintext) => String
|
|
311
|
+
*
|
|
312
|
+
* Updates the plaintext on a Digest and returns the new digested text.
|
|
313
|
+
*/
|
|
314
|
+
VALUE rb_digest_update(VALUE self, VALUE plaintext)
|
|
315
|
+
{
|
|
316
|
+
JHash *hash = NULL;
|
|
317
|
+
Check_Type(plaintext, T_STRING);
|
|
318
|
+
Data_Get_Struct(self, JHash, hash);
|
|
319
|
+
hash->updatePlaintext(string(StringValuePtr(plaintext), RSTRING(plaintext)->len));
|
|
320
|
+
hash->hash();
|
|
321
|
+
return rb_tainted_str_new(hash->getHashtext().data(), hash->getHashtext().length());
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
/* Returns the digested text. */
|
|
326
|
+
static string digest_digest(VALUE self, bool hex)
|
|
327
|
+
{
|
|
328
|
+
JHash *hash = NULL;
|
|
329
|
+
Data_Get_Struct(self, JHash, hash);
|
|
330
|
+
return hash->getHashtext(hex);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* call-seq:
|
|
335
|
+
* digest => String
|
|
336
|
+
*
|
|
337
|
+
* Returns the digested text in binary.
|
|
338
|
+
*/
|
|
339
|
+
VALUE rb_digest_digest(VALUE self)
|
|
340
|
+
{
|
|
341
|
+
string retval = digest_digest(self, false);
|
|
342
|
+
return rb_tainted_str_new(retval.data(), retval.length());
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* call-seq:
|
|
347
|
+
* digest_hex => String
|
|
348
|
+
*
|
|
349
|
+
* Returns the digested text in hex.
|
|
350
|
+
*/
|
|
351
|
+
VALUE rb_digest_digest_hex(VALUE self)
|
|
352
|
+
{
|
|
353
|
+
string retval = digest_digest(self, true);
|
|
354
|
+
return rb_tainted_str_new(retval.data(), retval.length());
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
/* Gets the plaintext from a hash. */
|
|
359
|
+
static string digest_plaintext(VALUE self, bool hex)
|
|
360
|
+
{
|
|
361
|
+
JHash *hash = NULL;
|
|
362
|
+
Data_Get_Struct(self, JHash, hash);
|
|
363
|
+
return hash->getPlaintext(hex);;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* call-seq:
|
|
368
|
+
* plaintext => String
|
|
369
|
+
*
|
|
370
|
+
* Returns the plaintext used to generate the digest in binary.
|
|
371
|
+
*/
|
|
372
|
+
VALUE rb_digest_plaintext(VALUE self)
|
|
373
|
+
{
|
|
374
|
+
string retval = digest_plaintext(self, false);
|
|
375
|
+
return rb_tainted_str_new(retval.data(), retval.length());
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* call-seq:
|
|
380
|
+
* plaintext_hex => String
|
|
381
|
+
*
|
|
382
|
+
* Returns the plaintext used to generate the digest in hex.
|
|
383
|
+
*/
|
|
384
|
+
VALUE rb_digest_plaintext_hex(VALUE self)
|
|
385
|
+
{
|
|
386
|
+
string retval = digest_plaintext(self, true);
|
|
387
|
+
return rb_tainted_str_new(retval.data(), retval.length());
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
/* Sets the plaintext on a digest. */
|
|
392
|
+
static string digest_plaintext_eq(VALUE self, VALUE plaintext, bool hex)
|
|
393
|
+
{
|
|
394
|
+
JHash *hash = NULL;
|
|
395
|
+
Check_Type(plaintext, T_STRING);
|
|
396
|
+
Data_Get_Struct(self, JHash, hash);
|
|
397
|
+
hash->setPlaintext(string(StringValuePtr(plaintext), RSTRING(plaintext)->len), hex);
|
|
398
|
+
return hash->getPlaintext(hex);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* call-seq:
|
|
403
|
+
* plaintext=(plaintext)
|
|
404
|
+
*
|
|
405
|
+
* Sets the plaintext on a Digest in binary.
|
|
406
|
+
*/
|
|
407
|
+
VALUE rb_digest_plaintext_eq(VALUE self, VALUE plaintext)
|
|
408
|
+
{
|
|
409
|
+
digest_plaintext_eq(self, plaintext, false);
|
|
410
|
+
return plaintext;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* call-seq:
|
|
415
|
+
* plaintext=(plaintext)
|
|
416
|
+
*
|
|
417
|
+
* Sets the plaintext on a Digest in hex.
|
|
418
|
+
*/
|
|
419
|
+
VALUE rb_digest_plaintext_hex_eq(VALUE self, VALUE plaintext)
|
|
420
|
+
{
|
|
421
|
+
digest_plaintext_eq(self, plaintext, true);
|
|
422
|
+
return plaintext;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
/* Calculates the digest. */
|
|
427
|
+
static string digest_calculate(VALUE self, bool hex)
|
|
428
|
+
{
|
|
429
|
+
JHash *hash = NULL;
|
|
430
|
+
Data_Get_Struct(self, JHash, hash);
|
|
431
|
+
hash->hash();
|
|
432
|
+
return hash->getHashtext(hex);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* call-seq:
|
|
437
|
+
* calculate => String
|
|
438
|
+
*
|
|
439
|
+
* Calculates the digest and returns the result in binary.
|
|
440
|
+
*/
|
|
441
|
+
VALUE rb_digest_calculate(VALUE self)
|
|
442
|
+
{
|
|
443
|
+
string retval = digest_calculate(self, false);
|
|
444
|
+
return rb_tainted_str_new(retval.data(), retval.length());
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* call-seq:
|
|
449
|
+
* calculate_hex => String
|
|
450
|
+
*
|
|
451
|
+
* Calculates the digest and returns the result in hex.
|
|
452
|
+
*/
|
|
453
|
+
VALUE rb_digest_calculate_hex(VALUE self)
|
|
454
|
+
{
|
|
455
|
+
string retval = digest_calculate(self, true);
|
|
456
|
+
return rb_tainted_str_new(retval.data(), retval.length());
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
/* Sets the hashtext on a digest. */
|
|
461
|
+
static string digest_digest_eq(VALUE self, VALUE digest, bool hex)
|
|
462
|
+
{
|
|
463
|
+
JHash *hash = NULL;
|
|
464
|
+
Check_Type(digest, T_STRING);
|
|
465
|
+
Data_Get_Struct(self, JHash, hash);
|
|
466
|
+
hash->setHashtext(string(StringValuePtr(digest), RSTRING(digest)->len), hex);
|
|
467
|
+
return hash->getHashtext(hex);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* call-seq:
|
|
472
|
+
* digest=(bin)
|
|
473
|
+
*
|
|
474
|
+
* Sets the digest text on a Digest in binary.
|
|
475
|
+
*/
|
|
476
|
+
VALUE rb_digest_digest_eq(VALUE self, VALUE digest)
|
|
477
|
+
{
|
|
478
|
+
digest_digest_eq(self, digest, false);
|
|
479
|
+
return digest;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* call-seq:
|
|
484
|
+
* digest_hex=(hex)
|
|
485
|
+
*
|
|
486
|
+
* Sets the digest text on a Digest in hex.
|
|
487
|
+
*/
|
|
488
|
+
VALUE rb_digest_digest_hex_eq(VALUE self, VALUE digest)
|
|
489
|
+
{
|
|
490
|
+
digest_digest_eq(self, digest, true);
|
|
491
|
+
return digest;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* call-seq:
|
|
497
|
+
* inspect => String
|
|
498
|
+
*
|
|
499
|
+
* Inspect method.
|
|
500
|
+
*/
|
|
501
|
+
VALUE rb_digest_inspect(VALUE self)
|
|
502
|
+
{
|
|
503
|
+
JHash* hash = NULL;
|
|
504
|
+
string retval;
|
|
505
|
+
string cname = rb_obj_classname(self);
|
|
506
|
+
Data_Get_Struct(self, JHash, hash);
|
|
507
|
+
retval = "#<" + cname + ": " + hash->getHashtext(true) + ">";
|
|
508
|
+
return rb_str_new(retval.c_str(), retval.length());
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Compares a Digest directly to a String. We'll attempt to detect whether or
|
|
514
|
+
* not the String is in binary or hex based on the number of characters in
|
|
515
|
+
* it -- if it's exactly double the expected number of bytes, then we'll
|
|
516
|
+
* assume we've got a hex String.
|
|
517
|
+
*/
|
|
518
|
+
VALUE rb_digest_equals(VALUE self, VALUE compare)
|
|
519
|
+
{
|
|
520
|
+
JHash *hash = NULL;
|
|
521
|
+
VALUE str1, str2;
|
|
522
|
+
Check_Type(compare, T_STRING);
|
|
523
|
+
Data_Get_Struct(self, JHash, hash);
|
|
524
|
+
if (RSTRING(compare)->len == ((long) hash->getDigestSize() / 2)) {
|
|
525
|
+
str1 = rb_str_new(hash->getHashtext(false).data(), hash->getHashtext(false).length());
|
|
526
|
+
str2 = compare;
|
|
527
|
+
}
|
|
528
|
+
else if (RSTRING(compare)->len == ((long) hash->getDigestSize())) {
|
|
529
|
+
str1 = rb_str_new(hash->getHashtext(true).data(), hash->getHashtext(true).length());
|
|
530
|
+
str2 = rb_funcall(compare, rb_intern("downcase"), 0);
|
|
531
|
+
}
|
|
532
|
+
else {
|
|
533
|
+
rb_raise(rb_eCryptoPP_Error, "expected %d bytes, got %d", hash->getDigestSize() / 2, RSTRING(compare)->len);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
if (rb_str_cmp(str1, str2) == 0) {
|
|
537
|
+
return Qtrue;
|
|
538
|
+
}
|
|
539
|
+
else {
|
|
540
|
+
return Qfalse;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
/* Singleton method for digesting good stuff. */
|
|
546
|
+
static string module_digest(int argc, VALUE *argv, VALUE self, bool hex)
|
|
547
|
+
{
|
|
548
|
+
JHash* hash = NULL;
|
|
549
|
+
VALUE algorithm, plaintext, key;
|
|
550
|
+
if (argc < 2) {
|
|
551
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 2)", argc);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
if (IS_HMAC(digest_sym_to_const(argv[0]))) {
|
|
555
|
+
rb_scan_args(argc, argv, "21", &algorithm, &plaintext, &key);
|
|
556
|
+
Check_Type(plaintext, T_STRING);
|
|
557
|
+
Check_Type(key, T_STRING);
|
|
558
|
+
}
|
|
559
|
+
else {
|
|
560
|
+
rb_scan_args(argc, argv, "2", &algorithm, &plaintext);
|
|
561
|
+
Check_Type(plaintext, T_STRING);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
try {
|
|
565
|
+
string retval;
|
|
566
|
+
hash = digest_factory(algorithm);
|
|
567
|
+
hash->setPlaintext(string(StringValuePtr(plaintext), RSTRING(plaintext)->len));
|
|
568
|
+
if (IS_HMAC(digest_sym_to_const(algorithm))) {
|
|
569
|
+
((JHMAC*) hash)->setKey(string(StringValuePtr(key), RSTRING(key)->len));
|
|
570
|
+
}
|
|
571
|
+
hash->hash();
|
|
572
|
+
retval = hash->getHashtext(hex);
|
|
573
|
+
|
|
574
|
+
delete hash;
|
|
575
|
+
return retval;
|
|
576
|
+
}
|
|
577
|
+
catch (Exception& e) {
|
|
578
|
+
if (hash != NULL) {
|
|
579
|
+
delete hash;
|
|
580
|
+
}
|
|
581
|
+
rb_raise(rb_eCryptoPP_Error, e.GetWhat().c_str());
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* call-seq:
|
|
587
|
+
* digest(algorithm, plaintext) => String
|
|
588
|
+
*
|
|
589
|
+
* Digest the plaintext and returns the result in binary.
|
|
590
|
+
*/
|
|
591
|
+
VALUE rb_module_digest(int argc, VALUE *argv, VALUE self)
|
|
592
|
+
{
|
|
593
|
+
string retval = module_digest(argc, argv, self, false);
|
|
594
|
+
return rb_tainted_str_new(retval.data(), retval.length());
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* call-seq:
|
|
599
|
+
* digest_hex(algorithm, plaintext) => String
|
|
600
|
+
*
|
|
601
|
+
* Digest the plaintext and returns the result in hex.
|
|
602
|
+
*/
|
|
603
|
+
VALUE rb_module_digest_hex(int argc, VALUE *argv, VALUE self)
|
|
604
|
+
{
|
|
605
|
+
string retval = module_digest(argc, argv, self, true);
|
|
606
|
+
return rb_tainted_str_new(retval.data(), retval.length());
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
|
|
610
|
+
/* Digests an appropriate Ruby IO object. */
|
|
611
|
+
static string module_digest_io(int argc, VALUE *argv, VALUE self, bool hex)
|
|
612
|
+
{
|
|
613
|
+
JHash* hash = NULL;
|
|
614
|
+
VALUE algorithm, io;
|
|
615
|
+
|
|
616
|
+
rb_scan_args(argc, argv, "2", &algorithm, &io);
|
|
617
|
+
try {
|
|
618
|
+
string retval;
|
|
619
|
+
hash = digest_factory(algorithm);
|
|
620
|
+
retval = hash->hashRubyIO(&io, hex);
|
|
621
|
+
|
|
622
|
+
delete hash;
|
|
623
|
+
return retval;
|
|
624
|
+
}
|
|
625
|
+
catch (Exception& e) {
|
|
626
|
+
if (hash != NULL) {
|
|
627
|
+
delete hash;
|
|
628
|
+
}
|
|
629
|
+
rb_raise(rb_eCryptoPP_Error, e.GetWhat().c_str());
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* call-seq:
|
|
635
|
+
* digest_io(io) => String
|
|
636
|
+
*
|
|
637
|
+
* Digests a Ruby IO object and spits out the result in binary. You can use
|
|
638
|
+
* any sort of Ruby object as long as it implements <tt>eof?</tt>,
|
|
639
|
+
* <tt>read</tt>, <tt>write</tt> and <tt>flush</tt>.
|
|
640
|
+
*
|
|
641
|
+
* Example:
|
|
642
|
+
*
|
|
643
|
+
* cipher.digest_io(File.open("http://example.com/"))
|
|
644
|
+
*/
|
|
645
|
+
VALUE rb_module_digest_io(int argc, VALUE *argv, VALUE self)
|
|
646
|
+
{
|
|
647
|
+
string retval = module_digest_io(argc, argv, self, false);
|
|
648
|
+
return rb_tainted_str_new(retval.data(), retval.length());
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* call-seq:
|
|
653
|
+
* digest_io_hex(io) => String
|
|
654
|
+
*
|
|
655
|
+
* Digests a Ruby IO object and spits out the result in hex. You can use
|
|
656
|
+
* any sort of Ruby object as long as it implements <tt>eof?</tt>,
|
|
657
|
+
* <tt>read</tt>, <tt>write</tt> and <tt>flush</tt>.
|
|
658
|
+
*
|
|
659
|
+
* Example:
|
|
660
|
+
*
|
|
661
|
+
* cipher.digest_io_hex(File.open("http://example.com/"))
|
|
662
|
+
*/
|
|
663
|
+
VALUE rb_module_digest_io_hex(int argc, VALUE *argv, VALUE self)
|
|
664
|
+
{
|
|
665
|
+
string retval = module_digest_io(argc, argv, self, true);
|
|
666
|
+
return rb_tainted_str_new(retval.data(), retval.length());
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
/**
|
|
671
|
+
* call-seq:
|
|
672
|
+
* digest_enabled? => Boolean
|
|
673
|
+
*
|
|
674
|
+
* Is a Digest/HMAC algorithm available?
|
|
675
|
+
*/
|
|
676
|
+
VALUE rb_module_digest_enabled(VALUE self, VALUE d)
|
|
677
|
+
{
|
|
678
|
+
if (digest_enabled(digest_sym_to_const(d))) {
|
|
679
|
+
return Qtrue;
|
|
680
|
+
}
|
|
681
|
+
else {
|
|
682
|
+
return Qfalse;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
|
|
687
|
+
/* Returns the name of a hash algorithm. */
|
|
688
|
+
VALUE rb_module_digest_name(VALUE self, VALUE h)
|
|
689
|
+
{
|
|
690
|
+
switch ((enum HashEnum) NUM2INT(h)) {
|
|
691
|
+
default:
|
|
692
|
+
rb_raise(rb_eCryptoPP_Error, "could not find a valid digest type");
|
|
693
|
+
break;
|
|
694
|
+
|
|
695
|
+
# define CHECKSUM_ALGORITHM_X(klass, r, c, s) \
|
|
696
|
+
case r ## _CHECKSUM: \
|
|
697
|
+
return rb_tainted_str_new2(c::getHashName().c_str());
|
|
698
|
+
# include "defs/checksums.def"
|
|
699
|
+
|
|
700
|
+
# define HASH_ALGORITHM_X(klass, r, c, s) \
|
|
701
|
+
case r ## _HASH: \
|
|
702
|
+
return rb_tainted_str_new2(c::getHashName().c_str());
|
|
703
|
+
# include "defs/hashes.def"
|
|
704
|
+
|
|
705
|
+
# define HMAC_ALGORITHM_X(klass, r, c, s) \
|
|
706
|
+
case r ## _HMAC: \
|
|
707
|
+
return rb_tainted_str_new2(c::getHashName().c_str());
|
|
708
|
+
# include "defs/hmacs.def"
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
/**
|
|
714
|
+
* call-seq:
|
|
715
|
+
* algorithm_name => String
|
|
716
|
+
*
|
|
717
|
+
* Returns the name of the algorithm being used.
|
|
718
|
+
*/
|
|
719
|
+
VALUE rb_digest_algorithm_name(VALUE self)
|
|
720
|
+
{
|
|
721
|
+
JHash *hash = NULL;
|
|
722
|
+
Data_Get_Struct(self, JHash, hash);
|
|
723
|
+
return rb_module_digest_name(self, INT2NUM(hash->getHashType()));
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* Clears a Digest's plaintext and hashtext.
|
|
729
|
+
*/
|
|
730
|
+
VALUE rb_digest_clear(VALUE self)
|
|
731
|
+
{
|
|
732
|
+
JHash *hash = NULL;
|
|
733
|
+
Data_Get_Struct(self, JHash, hash);
|
|
734
|
+
hash->clear();
|
|
735
|
+
return Qnil;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
|
|
739
|
+
/**
|
|
740
|
+
* call-seq:
|
|
741
|
+
* validate => Boolean
|
|
742
|
+
*
|
|
743
|
+
* Validates if the digest text is a valid digest for plaintext.
|
|
744
|
+
*/
|
|
745
|
+
VALUE rb_digest_validate(VALUE self)
|
|
746
|
+
{
|
|
747
|
+
JHash *hash = NULL;
|
|
748
|
+
Data_Get_Struct(self, JHash, hash);
|
|
749
|
+
if (hash->validate()) {
|
|
750
|
+
return Qtrue;
|
|
751
|
+
}
|
|
752
|
+
else {
|
|
753
|
+
return Qfalse;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
/* Instance version of <tt>CryptoPP#digest_io</tt>. */
|
|
759
|
+
static string digest_digest_io(VALUE self, VALUE io, bool hex)
|
|
760
|
+
{
|
|
761
|
+
try {
|
|
762
|
+
JHash *hash;
|
|
763
|
+
Data_Get_Struct(self, JHash, hash);
|
|
764
|
+
return hash->hashRubyIO(&io, hex);
|
|
765
|
+
}
|
|
766
|
+
catch (Exception& e) {
|
|
767
|
+
rb_raise(rb_eCryptoPP_Error, e.GetWhat().c_str());
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
/**
|
|
772
|
+
* call-seq:
|
|
773
|
+
* digest_io(in) => String
|
|
774
|
+
*
|
|
775
|
+
* Instance version of <tt>CryptoPP#digest_io</tt>.
|
|
776
|
+
*/
|
|
777
|
+
VALUE rb_digest_digest_io(VALUE self, VALUE io)
|
|
778
|
+
{
|
|
779
|
+
string retval = digest_digest_io(self, io, false);
|
|
780
|
+
return rb_tainted_str_new(retval.data(), retval.length());
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
/**
|
|
784
|
+
* call-seq:
|
|
785
|
+
* digest_io_hex(in) => String
|
|
786
|
+
*
|
|
787
|
+
* Instance version of <tt>CryptoPP#digest_io_hex</tt>.
|
|
788
|
+
*/
|
|
789
|
+
VALUE rb_digest_digest_io_hex(VALUE self, VALUE io)
|
|
790
|
+
{
|
|
791
|
+
string retval = digest_digest_io(self, io, true);
|
|
792
|
+
return rb_tainted_str_new(retval.data(), retval.length());
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
|
|
796
|
+
/**
|
|
797
|
+
* call-seq:
|
|
798
|
+
* digest_list => Array
|
|
799
|
+
*
|
|
800
|
+
* Returns an Array of available Digest algorithms.
|
|
801
|
+
*/
|
|
802
|
+
VALUE rb_module_digest_list(VALUE self)
|
|
803
|
+
{
|
|
804
|
+
VALUE ary;
|
|
805
|
+
ary = rb_ary_new();
|
|
806
|
+
|
|
807
|
+
# define CHECKSUM_ALGORITHM_X(klass, r, c, s) \
|
|
808
|
+
rb_ary_push(ary, INT2NUM(r ##_CHECKSUM));
|
|
809
|
+
# include "defs/checksums.def"
|
|
810
|
+
|
|
811
|
+
# define HASH_ALGORITHM_X(klass, r, c, s) \
|
|
812
|
+
rb_ary_push(ary, INT2NUM(r ##_HASH));
|
|
813
|
+
# include "defs/hashes.def"
|
|
814
|
+
|
|
815
|
+
return ary;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
/* Figure out options for a HMAC. */
|
|
820
|
+
static void digest_hmac_options(VALUE self, VALUE options)
|
|
821
|
+
{
|
|
822
|
+
digest_options(self, options);
|
|
823
|
+
|
|
824
|
+
{
|
|
825
|
+
VALUE key = rb_hash_aref(options, ID2SYM(rb_intern("key")));
|
|
826
|
+
VALUE key_hex = rb_hash_aref(options, ID2SYM(rb_intern("key_hex")));
|
|
827
|
+
if (!NIL_P(key) && !NIL_P(key_hex)) {
|
|
828
|
+
rb_raise(rb_eCryptoPP_Error, "can't set both key and key_hex in options");
|
|
829
|
+
}
|
|
830
|
+
else if (!NIL_P(key)) {
|
|
831
|
+
digest_hmac_key_eq(self, key, false);
|
|
832
|
+
}
|
|
833
|
+
else if (!NIL_P(key_hex)) {
|
|
834
|
+
digest_hmac_key_eq(self, key_hex, true);
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
{
|
|
839
|
+
VALUE key_length = rb_hash_aref(options, ID2SYM(rb_intern("key_length")));
|
|
840
|
+
if (!NIL_P(key_length)) {
|
|
841
|
+
rb_digest_hmac_key_length_eq(self, key_length);
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
|
|
847
|
+
/**
|
|
848
|
+
* call-seq:
|
|
849
|
+
* hmac_factory(algorithm) => CryptoPP::HMAC
|
|
850
|
+
* hmac_factory(algorithm, plaintext, key) => CryptoPP::HMAC
|
|
851
|
+
* hmac_factory(algorithm, options) => CryptoPP::HMAC
|
|
852
|
+
*
|
|
853
|
+
* Creates a new HMAC object.
|
|
854
|
+
*/
|
|
855
|
+
VALUE rb_module_hmac_factory(int argc, VALUE *argv, VALUE self)
|
|
856
|
+
{
|
|
857
|
+
if (argc < 1 || argc > 3) {
|
|
858
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1-3)", argc);
|
|
859
|
+
}
|
|
860
|
+
else {
|
|
861
|
+
JHash* hash = NULL;
|
|
862
|
+
VALUE algorithm = argv[0];
|
|
863
|
+
VALUE retval;
|
|
864
|
+
|
|
865
|
+
if (!IS_HMAC(digest_sym_to_const(algorithm))) {
|
|
866
|
+
rb_raise(rb_eCryptoPP_Error, "invalid HMAC algorithm");
|
|
867
|
+
}
|
|
868
|
+
else {
|
|
869
|
+
try {
|
|
870
|
+
hash = digest_factory(algorithm);
|
|
871
|
+
retval = wrap_digest_in_ruby(hash);
|
|
872
|
+
}
|
|
873
|
+
catch (Exception& e) {
|
|
874
|
+
if (hash != NULL) {
|
|
875
|
+
delete hash;
|
|
876
|
+
}
|
|
877
|
+
rb_raise(rb_eCryptoPP_Error, e.GetWhat().c_str());
|
|
878
|
+
}
|
|
879
|
+
if (argc >= 2) {
|
|
880
|
+
if (TYPE(argv[1]) == T_STRING) {
|
|
881
|
+
digest_plaintext_eq(retval, argv[1], false);
|
|
882
|
+
if (argc == 3) {
|
|
883
|
+
Check_Type(argv[2], T_STRING);
|
|
884
|
+
digest_hmac_key_eq(retval, argv[2], false);
|
|
885
|
+
}
|
|
886
|
+
hash->hash();
|
|
887
|
+
}
|
|
888
|
+
else if (argc > 2) {
|
|
889
|
+
rb_raise(rb_eArgError, "wrong argument types (expected a String or a Hash");
|
|
890
|
+
}
|
|
891
|
+
else {
|
|
892
|
+
digest_hmac_options(retval, argv[1]);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
return retval;
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
#define HMAC_ALGORITHM_X(klass, r, n, s) \
|
|
901
|
+
VALUE rb_digest_hmac_ ## r ##_new(int argc, VALUE *argv, VALUE self) \
|
|
902
|
+
{ \
|
|
903
|
+
if (argc > 2) { \
|
|
904
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 2)", argc); \
|
|
905
|
+
} \
|
|
906
|
+
else { \
|
|
907
|
+
VALUE retval; \
|
|
908
|
+
JHash* hash = NULL; \
|
|
909
|
+
try { \
|
|
910
|
+
hash = digest_factory(ID2SYM(rb_intern(# s))); \
|
|
911
|
+
retval = wrap_digest_in_ruby(hash); \
|
|
912
|
+
} \
|
|
913
|
+
catch (Exception& e) { \
|
|
914
|
+
if (hash != NULL) { \
|
|
915
|
+
delete hash; \
|
|
916
|
+
} \
|
|
917
|
+
rb_raise(rb_eCryptoPP_Error, e.GetWhat().c_str()); \
|
|
918
|
+
} \
|
|
919
|
+
if (argc >= 1) { \
|
|
920
|
+
if (TYPE(argv[0]) == T_STRING) { \
|
|
921
|
+
digest_plaintext_eq(retval, argv[0], false); \
|
|
922
|
+
if (argc == 2) { \
|
|
923
|
+
Check_Type(argv[1], T_STRING); \
|
|
924
|
+
digest_hmac_key_eq(retval, argv[1], false); \
|
|
925
|
+
} \
|
|
926
|
+
hash->hash(); \
|
|
927
|
+
} \
|
|
928
|
+
else if (argc > 1) { \
|
|
929
|
+
rb_raise(rb_eArgError, "wrong argument types (expected a String or a Hash"); \
|
|
930
|
+
} \
|
|
931
|
+
else { \
|
|
932
|
+
digest_hmac_options(retval, argv[0]); \
|
|
933
|
+
} \
|
|
934
|
+
} \
|
|
935
|
+
return retval; \
|
|
936
|
+
} \
|
|
937
|
+
}
|
|
938
|
+
#include "defs/hmacs.def"
|
|
939
|
+
|
|
940
|
+
|
|
941
|
+
/* Set the key. The true length of the key might not be what you expect,
|
|
942
|
+
* as different algorithms behave differently */
|
|
943
|
+
static string digest_hmac_key_eq(VALUE self, VALUE key, bool hex)
|
|
944
|
+
{
|
|
945
|
+
JHash *hash = NULL;
|
|
946
|
+
Check_Type(key, T_STRING);
|
|
947
|
+
Data_Get_Struct(self, JHash, hash);
|
|
948
|
+
((JHMAC*) hash)->setKey(string(StringValuePtr(key), RSTRING(key)->len), hex);
|
|
949
|
+
return ((JHMAC*) hash)->getKey(hex);
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
/**
|
|
953
|
+
* call-seq:
|
|
954
|
+
* key=(key)
|
|
955
|
+
*
|
|
956
|
+
* Sets the key on a HMAC in binary.
|
|
957
|
+
*/
|
|
958
|
+
VALUE rb_digest_hmac_key_eq(VALUE self, VALUE key)
|
|
959
|
+
{
|
|
960
|
+
digest_hmac_key_eq(self, key, false);
|
|
961
|
+
return key;
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
/**
|
|
965
|
+
* call-seq:
|
|
966
|
+
* key_hex=(key)
|
|
967
|
+
*
|
|
968
|
+
* Sets the key on a HMAC in hex.
|
|
969
|
+
*/
|
|
970
|
+
VALUE rb_digest_hmac_key_hex_eq(VALUE self, VALUE key)
|
|
971
|
+
{
|
|
972
|
+
digest_hmac_key_eq(self, key, true);
|
|
973
|
+
return key;
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
|
|
977
|
+
/* Get the key. */
|
|
978
|
+
static string digest_hmac_key(VALUE self, bool hex)
|
|
979
|
+
{
|
|
980
|
+
JHash *hash = NULL;
|
|
981
|
+
Data_Get_Struct(self, JHash, hash);
|
|
982
|
+
return ((JHMAC*) hash)->getKey(hex);
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
/**
|
|
986
|
+
* call-seq:
|
|
987
|
+
* key => String
|
|
988
|
+
*
|
|
989
|
+
* Returns the key from the HMAC in binary.
|
|
990
|
+
*/
|
|
991
|
+
VALUE rb_digest_hmac_key(VALUE self)
|
|
992
|
+
{
|
|
993
|
+
string retval = digest_hmac_key(self, false);
|
|
994
|
+
return rb_tainted_str_new(retval.data(), retval.length());
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
/**
|
|
998
|
+
* call-seq:
|
|
999
|
+
* key_hex => String
|
|
1000
|
+
*
|
|
1001
|
+
* Returns the key from the HMAC in hex.
|
|
1002
|
+
*/
|
|
1003
|
+
VALUE rb_digest_hmac_key_hex(VALUE self)
|
|
1004
|
+
{
|
|
1005
|
+
string retval = digest_hmac_key(self, false);
|
|
1006
|
+
return rb_tainted_str_new(retval.data(), retval.length());
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
|
|
1010
|
+
/**
|
|
1011
|
+
* call-seq:
|
|
1012
|
+
* key_length=(length)
|
|
1013
|
+
*
|
|
1014
|
+
* Sets the key length. Some HMACs require rather specific key lengths,
|
|
1015
|
+
* and if the key length you attempt to set is invalid, an exception will
|
|
1016
|
+
* be thrown. The key length being set is set in terms of bytes in binary, not
|
|
1017
|
+
* hex characters.
|
|
1018
|
+
*/
|
|
1019
|
+
VALUE rb_digest_hmac_key_length_eq(VALUE self, VALUE l)
|
|
1020
|
+
{
|
|
1021
|
+
JHash *hash = NULL;
|
|
1022
|
+
unsigned int length = NUM2UINT(l);
|
|
1023
|
+
Data_Get_Struct(self, JHash, hash);
|
|
1024
|
+
((JHMAC*) hash)->setKeylength(length);
|
|
1025
|
+
if (((JHMAC*) hash)->getKeylength() != length) {
|
|
1026
|
+
rb_raise(rb_eCryptoPP_Error, "tried to set a key length of %d but %d was used", length, ((JHMAC*) hash)->getKeylength());
|
|
1027
|
+
}
|
|
1028
|
+
else {
|
|
1029
|
+
return l;
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
|
|
1034
|
+
/**
|
|
1035
|
+
* call-seq:
|
|
1036
|
+
* key_length=(length) => Integer
|
|
1037
|
+
*
|
|
1038
|
+
* Sets the key length. Some HMACs require rather specific key lengths,
|
|
1039
|
+
* and if the key length you attempt to set is invalid, an exception will
|
|
1040
|
+
* be thrown. The key length being set is set in terms of bytes in binary, not
|
|
1041
|
+
* hex characters.
|
|
1042
|
+
*/
|
|
1043
|
+
VALUE rb_digest_hmac_key_length(VALUE self)
|
|
1044
|
+
{
|
|
1045
|
+
JHash *hash = NULL;
|
|
1046
|
+
Data_Get_Struct(self, JHash, hash);
|
|
1047
|
+
return rb_fix_new(((JHMAC*) hash)->getKeylength());
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
|
|
1051
|
+
/* Digest the plaintext. */
|
|
1052
|
+
static string module_hmac_digest(int argc, VALUE *argv, VALUE self, bool hex)
|
|
1053
|
+
{
|
|
1054
|
+
JHash *hash;
|
|
1055
|
+
VALUE algorithm, plaintext, key;
|
|
1056
|
+
|
|
1057
|
+
rb_scan_args(argc, argv, "12", &algorithm, &plaintext, &key);
|
|
1058
|
+
Check_Type(plaintext, T_STRING);
|
|
1059
|
+
{
|
|
1060
|
+
string retval;
|
|
1061
|
+
hash = digest_factory(algorithm);
|
|
1062
|
+
hash->setPlaintext(string(StringValuePtr(plaintext), RSTRING(plaintext)->len));
|
|
1063
|
+
if (argc == 3) {
|
|
1064
|
+
Check_Type(plaintext, T_STRING);
|
|
1065
|
+
((JHMAC*) hash)->setKey(string(StringValuePtr(key), RSTRING(key)->len));
|
|
1066
|
+
}
|
|
1067
|
+
hash->hash();
|
|
1068
|
+
retval = hash->getHashtext(hex);
|
|
1069
|
+
|
|
1070
|
+
delete hash;
|
|
1071
|
+
return retval;
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
/**
|
|
1076
|
+
* call-seq:
|
|
1077
|
+
* digest(algorithm, plaintext) => String
|
|
1078
|
+
* digest(algorithm, plaintext, key) => String
|
|
1079
|
+
*
|
|
1080
|
+
* Singleton method for digesting with a HMAC. The plaintext and key values
|
|
1081
|
+
* are in binary and the return value is in binary.
|
|
1082
|
+
*/
|
|
1083
|
+
VALUE rb_module_hmac_digest(int argc, VALUE *argv, VALUE self)
|
|
1084
|
+
{
|
|
1085
|
+
string retval = module_hmac_digest(argc, argv, self, false);
|
|
1086
|
+
return rb_tainted_str_new(retval.data(), retval.length());
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
/**
|
|
1090
|
+
* call-seq:
|
|
1091
|
+
* digest_hex(algorithm, plaintext) => String
|
|
1092
|
+
* digest_hex(algorithm, plaintext, key) => String
|
|
1093
|
+
*
|
|
1094
|
+
* Singleton method for digesting with a HMAC. The plaintext and key values
|
|
1095
|
+
* are in binary and the return value is in hex.
|
|
1096
|
+
*/
|
|
1097
|
+
VALUE rb_module_hmac_digest_hex(int argc, VALUE *argv, VALUE self)
|
|
1098
|
+
{
|
|
1099
|
+
string retval = module_hmac_digest(argc, argv, self, true);
|
|
1100
|
+
return rb_tainted_str_new(retval.data(), retval.length());
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
|
|
1104
|
+
/**
|
|
1105
|
+
* call-seq:
|
|
1106
|
+
* hmac_list => Array
|
|
1107
|
+
*
|
|
1108
|
+
* Returns an Array of available HMAC algorithms.
|
|
1109
|
+
*/
|
|
1110
|
+
VALUE rb_module_hmac_list(VALUE self)
|
|
1111
|
+
{
|
|
1112
|
+
VALUE ary;
|
|
1113
|
+
ary = rb_ary_new();
|
|
1114
|
+
|
|
1115
|
+
# define HMAC_ALGORITHM_X(klass, r, c, s) \
|
|
1116
|
+
rb_ary_push(ary, ID2SYM(rb_intern(# s)));
|
|
1117
|
+
# include "defs/hmacs.def"
|
|
1118
|
+
|
|
1119
|
+
return ary;
|
|
1120
|
+
}
|