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.
Files changed (157) hide show
  1. data/.gitignore +8 -0
  2. data/MIT-LICENSE +22 -0
  3. data/README +7 -0
  4. data/Rakefile +42 -0
  5. data/cryptopp.gemspec +199 -0
  6. data/ext/.gitignore +5 -0
  7. data/ext/Rakefile +16 -0
  8. data/ext/ciphers.cpp +1402 -0
  9. data/ext/cryptopp.cpp +285 -0
  10. data/ext/cryptopp_ruby_api.h +139 -0
  11. data/ext/defs/block_modes.def +10 -0
  12. data/ext/defs/checksums.def +10 -0
  13. data/ext/defs/ciphers.def +136 -0
  14. data/ext/defs/hashes.def +78 -0
  15. data/ext/defs/hmacs.def +54 -0
  16. data/ext/defs/paddings.def +9 -0
  17. data/ext/defs/rngs.def +7 -0
  18. data/ext/digests.cpp +1120 -0
  19. data/ext/extconf.rb +39 -0
  20. data/ext/j3way.cpp +22 -0
  21. data/ext/j3way.h +29 -0
  22. data/ext/jadler32.h +32 -0
  23. data/ext/jaes.cpp +22 -0
  24. data/ext/jaes.h +31 -0
  25. data/ext/jarc4.cpp +22 -0
  26. data/ext/jarc4.h +37 -0
  27. data/ext/jbase.cpp +172 -0
  28. data/ext/jbase.h +92 -0
  29. data/ext/jbasiccipherinfo.h +74 -0
  30. data/ext/jblowfish.cpp +22 -0
  31. data/ext/jblowfish.h +29 -0
  32. data/ext/jcamellia.cpp +24 -0
  33. data/ext/jcamellia.h +33 -0
  34. data/ext/jcast128.cpp +22 -0
  35. data/ext/jcast128.h +31 -0
  36. data/ext/jcast256.cpp +22 -0
  37. data/ext/jcast256.h +31 -0
  38. data/ext/jcipher.cpp +112 -0
  39. data/ext/jcipher.h +42 -0
  40. data/ext/jcipher_t.h +469 -0
  41. data/ext/jconfig.h +127 -0
  42. data/ext/jconstants.h +189 -0
  43. data/ext/jcrc32.h +32 -0
  44. data/ext/jdes.cpp +22 -0
  45. data/ext/jdes.h +31 -0
  46. data/ext/jdes_ede2.cpp +22 -0
  47. data/ext/jdes_ede2.h +31 -0
  48. data/ext/jdes_ede3.cpp +22 -0
  49. data/ext/jdes_ede3.h +31 -0
  50. data/ext/jdes_xex3.cpp +22 -0
  51. data/ext/jdes_xex3.h +31 -0
  52. data/ext/jdiamond2.cpp +22 -0
  53. data/ext/jdiamond2.h +31 -0
  54. data/ext/jdiamond2lite.cpp +22 -0
  55. data/ext/jdiamond2lite.h +31 -0
  56. data/ext/jexception.h +20 -0
  57. data/ext/jgost.cpp +22 -0
  58. data/ext/jgost.h +31 -0
  59. data/ext/jhash.cpp +92 -0
  60. data/ext/jhash.h +54 -0
  61. data/ext/jhash_t.h +121 -0
  62. data/ext/jhaval.h +64 -0
  63. data/ext/jhelpers.cpp +90 -0
  64. data/ext/jhelpers.h +38 -0
  65. data/ext/jhmac.cpp +44 -0
  66. data/ext/jhmac.h +34 -0
  67. data/ext/jhmac_t.h +125 -0
  68. data/ext/jidea.cpp +22 -0
  69. data/ext/jidea.h +31 -0
  70. data/ext/jmarc4.cpp +22 -0
  71. data/ext/jmarc4.h +37 -0
  72. data/ext/jmars.cpp +22 -0
  73. data/ext/jmars.h +31 -0
  74. data/ext/jmd2.h +56 -0
  75. data/ext/jmd4.h +56 -0
  76. data/ext/jmd5.h +56 -0
  77. data/ext/jpanamacipher.cpp +32 -0
  78. data/ext/jpanamacipher.h +46 -0
  79. data/ext/jpanamahash.h +44 -0
  80. data/ext/jrc2.cpp +44 -0
  81. data/ext/jrc2.h +39 -0
  82. data/ext/jrc5.cpp +22 -0
  83. data/ext/jrc5.h +31 -0
  84. data/ext/jrc6.cpp +22 -0
  85. data/ext/jrc6.h +31 -0
  86. data/ext/jripemd160.h +113 -0
  87. data/ext/jsafer.cpp +32 -0
  88. data/ext/jsafer.h +42 -0
  89. data/ext/jseal.cpp +32 -0
  90. data/ext/jseal.h +42 -0
  91. data/ext/jserpent.cpp +22 -0
  92. data/ext/jserpent.h +31 -0
  93. data/ext/jsha.h +122 -0
  94. data/ext/jshacal2.cpp +22 -0
  95. data/ext/jshacal2.h +31 -0
  96. data/ext/jshark.cpp +24 -0
  97. data/ext/jshark.h +33 -0
  98. data/ext/jsink.cpp +90 -0
  99. data/ext/jsink.h +154 -0
  100. data/ext/jskipjack.cpp +22 -0
  101. data/ext/jskipjack.h +31 -0
  102. data/ext/jsquare.cpp +22 -0
  103. data/ext/jsquare.h +31 -0
  104. data/ext/jstream.cpp +8 -0
  105. data/ext/jstream.h +20 -0
  106. data/ext/jstream_t.h +175 -0
  107. data/ext/jtea.cpp +22 -0
  108. data/ext/jtea.h +31 -0
  109. data/ext/jtiger.h +52 -0
  110. data/ext/jtwofish.cpp +22 -0
  111. data/ext/jtwofish.h +31 -0
  112. data/ext/jwhirlpool.h +52 -0
  113. data/ext/utils.cpp +8 -0
  114. data/extras/parser_c.rb +114 -0
  115. data/test/ciphers_test.rb +37 -0
  116. data/test/data/ciphers/3desval.dat +7 -0
  117. data/test/data/ciphers/3wayval.dat +6 -0
  118. data/test/data/ciphers/arc4.dat +8 -0
  119. data/test/data/ciphers/blowfish.dat +5 -0
  120. data/test/data/ciphers/camellia.dat +7 -0
  121. data/test/data/ciphers/cast128v.dat +5 -0
  122. data/test/data/ciphers/cast256v.dat +5 -0
  123. data/test/data/ciphers/descert.dat +198 -0
  124. data/test/data/ciphers/diamond.dat +9 -0
  125. data/test/data/ciphers/gostval.dat +10 -0
  126. data/test/data/ciphers/ideaval.dat +13 -0
  127. data/test/data/ciphers/marsval.dat +11 -0
  128. data/test/data/ciphers/panamac.dat +7 -0
  129. data/test/data/ciphers/rc2val.dat +10 -0
  130. data/test/data/ciphers/rc5val.dat +7 -0
  131. data/test/data/ciphers/rc6val.dat +8 -0
  132. data/test/data/ciphers/rijndael.dat +11 -0
  133. data/test/data/ciphers/saferval.dat +27 -0
  134. data/test/data/ciphers/seal.dat +3 -0
  135. data/test/data/ciphers/serpentv.dat +11 -0
  136. data/test/data/ciphers/shacal2.dat +7 -0
  137. data/test/data/ciphers/sharkval.dat +9 -0
  138. data/test/data/ciphers/skipjack.dat +3 -0
  139. data/test/data/ciphers/squareva.dat +10 -0
  140. data/test/data/ciphers/twofishv.dat +11 -0
  141. data/test/data/digests/adler32.dat +8 -0
  142. data/test/data/digests/crc32.dat +10 -0
  143. data/test/data/digests/haval.dat +4 -0
  144. data/test/data/digests/havalcer.dat +23 -0
  145. data/test/data/digests/md2.dat +9 -0
  146. data/test/data/digests/md4.dat +9 -0
  147. data/test/data/digests/md5.dat +9 -0
  148. data/test/data/digests/panamah.dat +8 -0
  149. data/test/data/digests/ripemd.dat +43 -0
  150. data/test/data/digests/sha.dat +19 -0
  151. data/test/data/digests/tiger.dat +11 -0
  152. data/test/data/digests/whirlpool.dat +13 -0
  153. data/test/data/hmacs/hmac.dat +6 -0
  154. data/test/digests_test.rb +29 -0
  155. data/test/hmacs_test.rb +38 -0
  156. data/test/test_helper.rb +42 -0
  157. metadata +220 -0
@@ -0,0 +1,8 @@
1
+ ext/*.bundle
2
+ ext/*.o
3
+ doc
4
+ *.kpf
5
+ *~
6
+ .DS_Store
7
+ *tmp*
8
+ pkg/
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2002-2010 J Smith <dark.panda@gmail.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,7 @@
1
+ == cryptopp-ruby
2
+
3
+ cryptopp-ruby is a collection of strong encryption routines for Ruby
4
+ built on Wei Dai's Crypto++ library. Included in the extension are
5
+ algorithms for symmetric block and stream ciphers, checksums, digests
6
+ and HMACs.
7
+
@@ -0,0 +1,42 @@
1
+
2
+ # -*- ruby -*-
3
+
4
+ require 'rubygems'
5
+ require 'rake/gempackagetask'
6
+ require 'rake/testtask'
7
+ require 'rake/rdoctask'
8
+
9
+ $:.push 'lib'
10
+
11
+ begin
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ gem.name = "cryptopp"
15
+ gem.version = "0.0.4"
16
+ gem.summary = "cryptopp is a cryptographic library for Ruby built on Wei Dai's Crypto++."
17
+ gem.description = gem.summary
18
+ gem.email = "dark.panda@gmail.com"
19
+ gem.homepage = "http://github.com/dark-panda/ruby-cryptopp"
20
+ gem.authors = [ "J Smith" ]
21
+ end
22
+ Jeweler::GemcutterTasks.new
23
+ rescue LoadError
24
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
25
+ end
26
+
27
+ desc 'Test cryptopp interface'
28
+ Rake::TestTask.new(:test) do |t|
29
+ t.libs << 'lib'
30
+ t.pattern = 'test/**/*_test.rb'
31
+ t.verbose = false
32
+ end
33
+
34
+ desc 'Build docs'
35
+ Rake::RDocTask.new do |t|
36
+ require 'rdoc/rdoc'
37
+ require 'extras/parser_c.rb'
38
+ t.main = 'README'
39
+ t.rdoc_dir = 'doc'
40
+ t.rdoc_files.include('README', 'ext/cryptopp.cpp', 'ext/ciphers.cpp', 'ext/digests.cpp')
41
+ end
42
+
@@ -0,0 +1,199 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{cryptopp}
8
+ s.version = "0.0.4"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["J Smith"]
12
+ s.date = %q{2010-07-01}
13
+ s.description = %q{cryptopp is a cryptographic library for Ruby built on Wei Dai's Crypto++.}
14
+ s.email = %q{dark.panda@gmail.com}
15
+ s.extensions = ["ext/extconf.rb"]
16
+ s.extra_rdoc_files = [
17
+ "README"
18
+ ]
19
+ s.files = [
20
+ ".gitignore",
21
+ "MIT-LICENSE",
22
+ "README",
23
+ "Rakefile",
24
+ "cryptopp.gemspec",
25
+ "ext/.gitignore",
26
+ "ext/Rakefile",
27
+ "ext/ciphers.cpp",
28
+ "ext/cryptopp.cpp",
29
+ "ext/cryptopp_ruby_api.h",
30
+ "ext/defs/block_modes.def",
31
+ "ext/defs/checksums.def",
32
+ "ext/defs/ciphers.def",
33
+ "ext/defs/hashes.def",
34
+ "ext/defs/hmacs.def",
35
+ "ext/defs/paddings.def",
36
+ "ext/defs/rngs.def",
37
+ "ext/digests.cpp",
38
+ "ext/extconf.rb",
39
+ "ext/j3way.cpp",
40
+ "ext/j3way.h",
41
+ "ext/jadler32.h",
42
+ "ext/jaes.cpp",
43
+ "ext/jaes.h",
44
+ "ext/jarc4.cpp",
45
+ "ext/jarc4.h",
46
+ "ext/jbase.cpp",
47
+ "ext/jbase.h",
48
+ "ext/jbasiccipherinfo.h",
49
+ "ext/jblowfish.cpp",
50
+ "ext/jblowfish.h",
51
+ "ext/jcamellia.cpp",
52
+ "ext/jcamellia.h",
53
+ "ext/jcast128.cpp",
54
+ "ext/jcast128.h",
55
+ "ext/jcast256.cpp",
56
+ "ext/jcast256.h",
57
+ "ext/jcipher.cpp",
58
+ "ext/jcipher.h",
59
+ "ext/jcipher_t.h",
60
+ "ext/jconfig.h",
61
+ "ext/jconstants.h",
62
+ "ext/jcrc32.h",
63
+ "ext/jdes.cpp",
64
+ "ext/jdes.h",
65
+ "ext/jdes_ede2.cpp",
66
+ "ext/jdes_ede2.h",
67
+ "ext/jdes_ede3.cpp",
68
+ "ext/jdes_ede3.h",
69
+ "ext/jdes_xex3.cpp",
70
+ "ext/jdes_xex3.h",
71
+ "ext/jdiamond2.cpp",
72
+ "ext/jdiamond2.h",
73
+ "ext/jdiamond2lite.cpp",
74
+ "ext/jdiamond2lite.h",
75
+ "ext/jexception.h",
76
+ "ext/jgost.cpp",
77
+ "ext/jgost.h",
78
+ "ext/jhash.cpp",
79
+ "ext/jhash.h",
80
+ "ext/jhash_t.h",
81
+ "ext/jhaval.h",
82
+ "ext/jhelpers.cpp",
83
+ "ext/jhelpers.h",
84
+ "ext/jhmac.cpp",
85
+ "ext/jhmac.h",
86
+ "ext/jhmac_t.h",
87
+ "ext/jidea.cpp",
88
+ "ext/jidea.h",
89
+ "ext/jmarc4.cpp",
90
+ "ext/jmarc4.h",
91
+ "ext/jmars.cpp",
92
+ "ext/jmars.h",
93
+ "ext/jmd2.h",
94
+ "ext/jmd4.h",
95
+ "ext/jmd5.h",
96
+ "ext/jpanamacipher.cpp",
97
+ "ext/jpanamacipher.h",
98
+ "ext/jpanamahash.h",
99
+ "ext/jrc2.cpp",
100
+ "ext/jrc2.h",
101
+ "ext/jrc5.cpp",
102
+ "ext/jrc5.h",
103
+ "ext/jrc6.cpp",
104
+ "ext/jrc6.h",
105
+ "ext/jripemd160.h",
106
+ "ext/jsafer.cpp",
107
+ "ext/jsafer.h",
108
+ "ext/jseal.cpp",
109
+ "ext/jseal.h",
110
+ "ext/jserpent.cpp",
111
+ "ext/jserpent.h",
112
+ "ext/jsha.h",
113
+ "ext/jshacal2.cpp",
114
+ "ext/jshacal2.h",
115
+ "ext/jshark.cpp",
116
+ "ext/jshark.h",
117
+ "ext/jsink.cpp",
118
+ "ext/jsink.h",
119
+ "ext/jskipjack.cpp",
120
+ "ext/jskipjack.h",
121
+ "ext/jsquare.cpp",
122
+ "ext/jsquare.h",
123
+ "ext/jstream.cpp",
124
+ "ext/jstream.h",
125
+ "ext/jstream_t.h",
126
+ "ext/jtea.cpp",
127
+ "ext/jtea.h",
128
+ "ext/jtiger.h",
129
+ "ext/jtwofish.cpp",
130
+ "ext/jtwofish.h",
131
+ "ext/jwhirlpool.h",
132
+ "ext/utils.cpp",
133
+ "extras/parser_c.rb",
134
+ "test/ciphers_test.rb",
135
+ "test/data/ciphers/3desval.dat",
136
+ "test/data/ciphers/3wayval.dat",
137
+ "test/data/ciphers/arc4.dat",
138
+ "test/data/ciphers/blowfish.dat",
139
+ "test/data/ciphers/camellia.dat",
140
+ "test/data/ciphers/cast128v.dat",
141
+ "test/data/ciphers/cast256v.dat",
142
+ "test/data/ciphers/descert.dat",
143
+ "test/data/ciphers/diamond.dat",
144
+ "test/data/ciphers/gostval.dat",
145
+ "test/data/ciphers/ideaval.dat",
146
+ "test/data/ciphers/marsval.dat",
147
+ "test/data/ciphers/panamac.dat",
148
+ "test/data/ciphers/rc2val.dat",
149
+ "test/data/ciphers/rc5val.dat",
150
+ "test/data/ciphers/rc6val.dat",
151
+ "test/data/ciphers/rijndael.dat",
152
+ "test/data/ciphers/saferval.dat",
153
+ "test/data/ciphers/seal.dat",
154
+ "test/data/ciphers/serpentv.dat",
155
+ "test/data/ciphers/shacal2.dat",
156
+ "test/data/ciphers/sharkval.dat",
157
+ "test/data/ciphers/skipjack.dat",
158
+ "test/data/ciphers/squareva.dat",
159
+ "test/data/ciphers/twofishv.dat",
160
+ "test/data/digests/adler32.dat",
161
+ "test/data/digests/crc32.dat",
162
+ "test/data/digests/haval.dat",
163
+ "test/data/digests/havalcer.dat",
164
+ "test/data/digests/md2.dat",
165
+ "test/data/digests/md4.dat",
166
+ "test/data/digests/md5.dat",
167
+ "test/data/digests/panamah.dat",
168
+ "test/data/digests/ripemd.dat",
169
+ "test/data/digests/sha.dat",
170
+ "test/data/digests/tiger.dat",
171
+ "test/data/digests/whirlpool.dat",
172
+ "test/data/hmacs/hmac.dat",
173
+ "test/digests_test.rb",
174
+ "test/hmacs_test.rb",
175
+ "test/test_helper.rb"
176
+ ]
177
+ s.homepage = %q{http://github.com/dark-panda/ruby-cryptopp}
178
+ s.rdoc_options = ["--charset=UTF-8"]
179
+ s.require_paths = ["lib"]
180
+ s.rubygems_version = %q{1.3.6}
181
+ s.summary = %q{cryptopp is a cryptographic library for Ruby built on Wei Dai's Crypto++.}
182
+ s.test_files = [
183
+ "test/ciphers_test.rb",
184
+ "test/digests_test.rb",
185
+ "test/hmacs_test.rb",
186
+ "test/test_helper.rb"
187
+ ]
188
+
189
+ if s.respond_to? :specification_version then
190
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
191
+ s.specification_version = 3
192
+
193
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
194
+ else
195
+ end
196
+ else
197
+ end
198
+ end
199
+
@@ -0,0 +1,5 @@
1
+ *.o
2
+ *.so
3
+ mkmf.log
4
+ Makefile
5
+
@@ -0,0 +1,16 @@
1
+
2
+ require 'rake/clean'
3
+
4
+ CLEAN.include '*.o', 'Makefile', 'mkmf.log'
5
+ CLOBBER.include 'cryptopp.so'
6
+
7
+ task :default => ['cryptopp.so']
8
+
9
+ file 'cryptopp.so' => [ 'Makefile' ] do
10
+ sh 'make'
11
+ end
12
+
13
+ file 'Makefile' do
14
+ ruby 'extconf.rb'
15
+ end
16
+
@@ -0,0 +1,1402 @@
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
+ #include "j3way.h"
9
+ #include "jaes.h"
10
+ #include "jblowfish.h"
11
+ #include "jcamellia.h"
12
+ #include "jcast128.h"
13
+ #include "jcast256.h"
14
+ #include "jdes.h"
15
+ #include "jdes_ede2.h"
16
+ #include "jdes_ede3.h"
17
+ #include "jdes_xex3.h"
18
+ #include "jdiamond2.h"
19
+ #include "jdiamond2lite.h"
20
+ #include "jgost.h"
21
+ #include "jidea.h"
22
+ #include "jmars.h"
23
+ #include "jrc2.h"
24
+ #include "jrc5.h"
25
+ #include "jrc6.h"
26
+ #include "jsafer.h"
27
+ #include "jserpent.h"
28
+ #include "jshacal2.h"
29
+ #include "jshark.h"
30
+ #include "jskipjack.h"
31
+ #include "jsquare.h"
32
+ #include "jtea.h"
33
+ #include "jtwofish.h"
34
+
35
+
36
+ // stream cipher algorithms:
37
+
38
+ #include "jarc4.h"
39
+ #include "jmarc4.h"
40
+ #include "jpanamacipher.h"
41
+ #include "jseal.h"
42
+
43
+ #include "jbasiccipherinfo.h"
44
+ #include "jexception.h"
45
+
46
+ #include "cryptopp_ruby_api.h"
47
+
48
+ extern void cipher_mark(JBase *c);
49
+ extern void cipher_free(JBase *c);
50
+
51
+ // forward declarations
52
+
53
+ static CipherEnum cipher_sym_to_const(VALUE cipher);
54
+ static ModeEnum mode_sym_to_const(VALUE m);
55
+ static PaddingEnum padding_sym_to_const(VALUE p);
56
+ static RNGEnum rng_sym_to_const(VALUE rng);
57
+
58
+ static bool cipher_enabled(CipherEnum cipher);
59
+ static void cipher_options(VALUE self, VALUE options);
60
+ static JBase* cipher_factory(long algorithm);
61
+ static VALUE wrap_cipher_in_ruby(JBase* cipher);
62
+ static void cipher_rand_iv(VALUE self, VALUE l);
63
+ static string cipher_iv_eq(VALUE self, VALUE iv, bool hex);
64
+ static string cipher_iv(VALUE self, bool hex);
65
+ static string cipher_plaintext_eq(VALUE self, VALUE plaintext, bool hex);
66
+ static string cipher_plaintext(VALUE self, bool hex);
67
+ static string cipher_ciphertext_eq(VALUE self, VALUE ciphertext, bool hex);
68
+ static string cipher_ciphertext(VALUE self, bool hex);
69
+ static string cipher_key_eq(VALUE self, VALUE key, bool hex);
70
+ static string cipher_key(VALUE self, bool hex);
71
+ static VALUE cipher_encrypt(VALUE self, bool hex);
72
+ static VALUE cipher_decrypt(VALUE self, bool hex);
73
+
74
+ static CipherEnum cipher_sym_to_const(VALUE c)
75
+ {
76
+ CipherEnum cipher = UNKNOWN_CIPHER;
77
+ ID id = SYM2ID(c);
78
+
79
+ if (id == rb_intern("rijndael")) {
80
+ cipher = AES_CIPHER;
81
+ }
82
+ else if (id == rb_intern("panama")) {
83
+ cipher = PANAMA_CIPHER;
84
+ }
85
+ else if (id == rb_intern("seal")) {
86
+ cipher = SEAL_CIPHER;
87
+ }
88
+ # define CIPHER_ALGORITHM_X_FORCE 1
89
+ # define CIPHER_ALGORITHM_X(klass, r, c, s) \
90
+ else if (id == rb_intern(# s)) { \
91
+ cipher = r ## _CIPHER; \
92
+ }
93
+ # include "defs/ciphers.def"
94
+ return cipher;
95
+ }
96
+
97
+
98
+ static ModeEnum mode_sym_to_const(VALUE m)
99
+ {
100
+ ModeEnum mode = UNKNOWN_MODE;
101
+ ID id = SYM2ID(m);
102
+
103
+ if (id == rb_intern("counter")) {
104
+ mode = CTR_MODE;
105
+ }
106
+ # define BLOCK_MODE_X(c, s) \
107
+ else if (id == rb_intern(# s)) { \
108
+ mode = c ## _MODE; \
109
+ }
110
+ # include "defs/block_modes.def"
111
+ return mode;
112
+ }
113
+
114
+ static PaddingEnum padding_sym_to_const(VALUE p)
115
+ {
116
+ PaddingEnum padding = UNKNOWN_PADDING;
117
+ ID id = SYM2ID(p);
118
+
119
+ if (id == rb_intern("none")) {
120
+ padding = NO_PADDING;
121
+ }
122
+ else if (id == rb_intern("zeroes")) {
123
+ padding = ZEROS_PADDING;
124
+ }
125
+ else if (id == rb_intern("one_and_zeroes")) {
126
+ padding = ONE_AND_ZEROS_PADDING;
127
+ }
128
+ # define PADDING_X(c, s) \
129
+ else if (id == rb_intern(# s)) { \
130
+ padding = c ## _PADDING; \
131
+ }
132
+ # include "defs/paddings.def"
133
+ return padding;
134
+ }
135
+
136
+ static RNGEnum rng_sym_to_const(VALUE r)
137
+ {
138
+ RNGEnum rng = UNKNOWN_RNG;
139
+ ID id = SYM2ID(r);
140
+
141
+ if (false) {
142
+ // no-op so we can use our x-macro
143
+ }
144
+ # define RNG_X(c, s) \
145
+ else if (id == rb_intern(# s)) { \
146
+ rng = c ## _RNG; \
147
+ }
148
+ # include "defs/rngs.def"
149
+ return rng;
150
+ }
151
+
152
+
153
+ /* See if a cipher algorithm is enabled. */
154
+ static bool cipher_enabled(CipherEnum cipher)
155
+ {
156
+ switch (cipher) {
157
+ # define CIPHER_ALGORITHM_X(klass, r, c, s) \
158
+ case r ##_CIPHER:
159
+ # include "defs/ciphers.def"
160
+ return true;
161
+ }
162
+ return false;
163
+ }
164
+
165
+
166
+ /* Figure out options for a cipher. We only check for Symbols, not Strings. */
167
+ static void cipher_options(VALUE self, VALUE options)
168
+ {
169
+ Check_Type(options, T_HASH);
170
+
171
+ {
172
+ VALUE plaintext = rb_hash_aref(options, ID2SYM(rb_intern("plaintext")));
173
+ VALUE plaintext_hex = rb_hash_aref(options, ID2SYM(rb_intern("plaintext_hex")));
174
+ if (!NIL_P(plaintext) && !NIL_P(plaintext_hex)) {
175
+ rb_raise(rb_eCryptoPP_Error, "can't set both plaintext and plaintext_hex in options");
176
+ }
177
+ else if (!NIL_P(plaintext)) {
178
+ cipher_plaintext_eq(self, plaintext, false);
179
+ }
180
+ else if (!NIL_P(plaintext_hex)) {
181
+ cipher_plaintext_eq(self, plaintext_hex, true);
182
+ }
183
+ }
184
+
185
+ {
186
+ VALUE ciphertext = rb_hash_aref(options, ID2SYM(rb_intern("ciphertext")));
187
+ VALUE ciphertext_hex = rb_hash_aref(options, ID2SYM(rb_intern("ciphertext_hex")));
188
+ if (!NIL_P(ciphertext) && !NIL_P(ciphertext_hex)) {
189
+ rb_raise(rb_eCryptoPP_Error, "can't set both ciphertext and ciphertext_hex in options");
190
+ }
191
+ else if (!NIL_P(ciphertext)) {
192
+ cipher_ciphertext_eq(self, ciphertext, false);
193
+ }
194
+ else if (!NIL_P(ciphertext_hex)) {
195
+ cipher_ciphertext_eq(self, ciphertext_hex, true);
196
+ }
197
+ }
198
+
199
+ {
200
+ VALUE key = rb_hash_aref(options, ID2SYM(rb_intern("key")));
201
+ VALUE key_hex = rb_hash_aref(options, ID2SYM(rb_intern("key_hex")));
202
+ if (!NIL_P(key) && !NIL_P(key_hex)) {
203
+ rb_raise(rb_eCryptoPP_Error, "can't set both key and key_hex in options");
204
+ }
205
+ else if (!NIL_P(key)) {
206
+ cipher_key_eq(self, key, false);
207
+ }
208
+ else if (!NIL_P(key_hex)) {
209
+ cipher_key_eq(self, key_hex, true);
210
+ }
211
+ }
212
+
213
+ {
214
+ VALUE key_length = rb_hash_aref(options, ID2SYM(rb_intern("key_length")));
215
+ if (!NIL_P(key_length)) {
216
+ rb_cipher_key_length_eq(self, key_length);
217
+ }
218
+ }
219
+
220
+ # if ENABLED_RC2_CIPHER
221
+ {
222
+ VALUE effective_key_length = rb_hash_aref(options, ID2SYM(rb_intern("effective_key_length")));
223
+ if (!NIL_P(effective_key_length)) {
224
+ rb_cipher_effective_key_length_eq(self, effective_key_length);
225
+ }
226
+ }
227
+ # endif
228
+
229
+ {
230
+ VALUE rounds = rb_hash_aref(options, ID2SYM(rb_intern("rounds")));
231
+ if (!NIL_P(rounds)) {
232
+ rb_cipher_rounds_eq(self, rounds);
233
+ }
234
+ }
235
+
236
+ {
237
+ VALUE rng = rb_hash_aref(options, ID2SYM(rb_intern("rng")));
238
+ if (!NIL_P(rng)) {
239
+ rb_cipher_rng_eq(self, rng);
240
+ }
241
+ }
242
+
243
+ {
244
+ VALUE rand_iv = rb_hash_aref(options, ID2SYM(rb_intern("rand_iv")));
245
+ VALUE iv = rb_hash_aref(options, ID2SYM(rb_intern("iv")));
246
+ VALUE iv_hex = rb_hash_aref(options, ID2SYM(rb_intern("iv_hex")));
247
+
248
+ if (!NIL_P(rand_iv) && (!NIL_P(iv) || !NIL_P(iv_hex))) {
249
+ rb_raise(rb_eCryptoPP_Error, "can't set both rand_iv and iv or iv_hex in options");
250
+ }
251
+ else if (!NIL_P(iv) && !NIL_P(iv_hex)) {
252
+ rb_raise(rb_eCryptoPP_Error, "can't set both iv and iv_hex in options");
253
+ }
254
+ else if (!NIL_P(rand_iv)) {
255
+ cipher_rand_iv(self, rand_iv);
256
+ }
257
+ else if (!NIL_P(iv)) {
258
+ cipher_iv_eq(self, iv, false);
259
+ }
260
+ else if (!NIL_P(iv_hex)) {
261
+ cipher_iv_eq(self, iv_hex, true);
262
+ }
263
+ }
264
+
265
+ {
266
+ VALUE block_mode = rb_hash_aref(options, ID2SYM(rb_intern("block_mode")));
267
+ if (!NIL_P(block_mode)) {
268
+ rb_cipher_block_mode_eq(self, block_mode);
269
+ }
270
+ }
271
+
272
+ {
273
+ VALUE padding = rb_hash_aref(options, ID2SYM(rb_intern("padding")));
274
+ if (!NIL_P(padding)) {
275
+ rb_cipher_padding_eq(self, padding);
276
+ }
277
+ }
278
+ }
279
+
280
+
281
+ /* Creates a new Crypto++ cipher. May throw a JException if no suitable cipher
282
+ * is found. May throw a JException if no suitable cipher is found. */
283
+ static JBase* cipher_factory(VALUE algorithm)
284
+ {
285
+ try {
286
+ switch (cipher_sym_to_const(algorithm)) {
287
+ default:
288
+ throw JException("the requested algorithm cannot be found");
289
+ break;
290
+
291
+ # define CIPHER_ALGORITHM_X(klass, r, c, s) \
292
+ case r ## _CIPHER: \
293
+ return static_cast<c*>(new c);
294
+ # include "defs/ciphers.def"
295
+ }
296
+ }
297
+ catch (Exception e) {
298
+ throw JException("Crypto++ exception: " + e.GetWhat());
299
+ }
300
+ }
301
+
302
+ /* Wraps a Cipher object into a Ruby object. May throw a JException if no
303
+ * suitable Cipher is found. */
304
+ static VALUE wrap_cipher_in_ruby(JBase* cipher)
305
+ {
306
+ const type_info& info = typeid(*cipher);
307
+ # define CIPHER_ALGORITHM_X(klass, r, c, s) \
308
+ if (info == typeid(c)) { \
309
+ return Data_Wrap_Struct(rb_cCryptoPP_Cipher_## r, cipher_mark, cipher_free, cipher); \
310
+ } \
311
+ else
312
+ # include "defs/ciphers.def"
313
+ {
314
+ throw JException("the requested algorithm has been disabled");
315
+ }
316
+ }
317
+
318
+ /**
319
+ * call-seq:
320
+ * cipher_factory(algorithm) => Cipher
321
+ * cipher_factory(algorithm, options) => Cipher
322
+ *
323
+ * Creates a new Cipher object.
324
+ *
325
+ * See the Cipher class for available options.
326
+ */
327
+ VALUE rb_module_cipher_factory(int argc, VALUE *argv, VALUE self)
328
+ {
329
+ VALUE algorithm, options, retval;
330
+ rb_scan_args(argc, argv, "11", &algorithm, &options);
331
+ try {
332
+ retval = wrap_cipher_in_ruby(cipher_factory(algorithm));
333
+ }
334
+ catch (Exception& e) {
335
+ rb_raise(rb_eCryptoPP_Error, e.GetWhat().c_str());
336
+ }
337
+ if (!NIL_P(options)) {
338
+ cipher_options(retval, options);
339
+ }
340
+ return retval;
341
+ }
342
+
343
+ #define CIPHER_ALGORITHM_X(klass, r, n, s) \
344
+ VALUE rb_cipher_ ## r ##_new(int argc, VALUE *argv, VALUE self) \
345
+ { \
346
+ VALUE options, retval; \
347
+ rb_scan_args(argc, argv, "01", &options); \
348
+ try { \
349
+ retval = wrap_cipher_in_ruby(cipher_factory(ID2SYM(rb_intern(# s)))); \
350
+ } \
351
+ catch (Exception& e) { \
352
+ rb_raise(rb_eCryptoPP_Error, e.GetWhat().c_str()); \
353
+ } \
354
+ if (!NIL_P(options)) { \
355
+ cipher_options(retval, options); \
356
+ } \
357
+ return retval; \
358
+ }
359
+ #include "defs/ciphers.def"
360
+
361
+
362
+ /* Creates a random initialization vector on the cipher. */
363
+ static void cipher_rand_iv(VALUE self, VALUE l)
364
+ {
365
+ JBase *cipher = NULL;
366
+ unsigned int length = NUM2UINT(rb_funcall(l, rb_intern("to_i"), 0));
367
+ Data_Get_Struct(self, JBase, cipher);
368
+ cipher->setRandIV(length);
369
+ }
370
+
371
+ /**
372
+ * call-seq:
373
+ * rand_iv(length) => nil
374
+ *
375
+ * Sets a random initialization vector on the Cipher. This method uses the
376
+ * random number generator set on the Cipher to produce the IV, so be sure to
377
+ * set the RNG before you try creating a random IV.
378
+ *
379
+ * The random IV created will is returned in binary.
380
+ */
381
+ VALUE rb_cipher_rand_iv(VALUE self, VALUE l)
382
+ {
383
+ JBase *cipher = NULL;
384
+ unsigned int length = NUM2UINT(rb_funcall(l, rb_intern("to_i"), 0));
385
+ Data_Get_Struct(self, JBase, cipher);
386
+ cipher->setRandIV(length);
387
+ return l;
388
+ }
389
+
390
+
391
+ /* Sets an IV on the cipher. */
392
+ static string cipher_iv_eq(VALUE self, VALUE iv, bool hex)
393
+ {
394
+ JBase *cipher = NULL;
395
+ Check_Type(iv, T_STRING);
396
+ Data_Get_Struct(self, JBase, cipher);
397
+ cipher->setIV(string(StringValuePtr(iv), RSTRING(iv)->len), hex);
398
+ return cipher->getIV(hex);
399
+ }
400
+
401
+ /**
402
+ * call-seq:
403
+ * iv=(iv) => String
404
+ *
405
+ * Set an initialization vector on the Cipher.
406
+ */
407
+ VALUE rb_cipher_iv_eq(VALUE self, VALUE iv)
408
+ {
409
+ cipher_iv_eq(self, iv, false);
410
+ return iv;
411
+ }
412
+
413
+ /**
414
+ * call-seq:
415
+ * iv_hex=(iv) => String
416
+ *
417
+ * Set an initialization vector on the Cipher. This method uses hex data and
418
+ * returns the IV as set.
419
+ */
420
+ VALUE rb_cipher_iv_hex_eq(VALUE self, VALUE iv)
421
+ {
422
+ cipher_iv_eq(self, iv, true);
423
+ return iv;
424
+ }
425
+
426
+
427
+ /* Gets the IV. */
428
+ static string cipher_iv(VALUE self, bool hex)
429
+ {
430
+ JBase *cipher = NULL;
431
+ Data_Get_Struct(self, JBase, cipher);
432
+ return cipher->getIV(hex);
433
+ }
434
+
435
+ /**
436
+ * call-seq:
437
+ * iv => String
438
+ *
439
+ * Returns the Cipher's IV in binary.
440
+ */
441
+ VALUE rb_cipher_iv(VALUE self)
442
+ {
443
+ string retval = cipher_iv(self, false);
444
+ return rb_tainted_str_new(retval.data(), retval.length());
445
+ }
446
+
447
+ /**
448
+ * call-seq:
449
+ * iv => String
450
+ *
451
+ * Returns the Cipher's IV in hex.
452
+ */
453
+ VALUE rb_cipher_iv_hex(VALUE self)
454
+ {
455
+ string retval = cipher_iv(self, true);
456
+ return rb_tainted_str_new(retval.data(), retval.length());
457
+ }
458
+
459
+
460
+ /**
461
+ * call-seq:
462
+ * block_mode=(mode) => Symbol
463
+ *
464
+ * Set the block mode on block ciphers. Returns the mode as set and may raise
465
+ * a CryptoPPError if the mode is invalid or you are using a stream cipher.
466
+ */
467
+ VALUE rb_cipher_block_mode_eq(VALUE self, VALUE m)
468
+ {
469
+ JBase *cipher = NULL;
470
+ ModeEnum mode = mode_sym_to_const(m);
471
+
472
+ if (!VALID_MODE(mode)) {
473
+ rb_raise(rb_eCryptoPP_Error, "invalid cipher mode");
474
+ }
475
+ Data_Get_Struct(self, JBase, cipher);
476
+ if (IS_STREAM_CIPHER(cipher->getCipherType())) {
477
+ rb_raise(rb_eCryptoPP_Error, "can't set mode on stream ciphers");
478
+ }
479
+ else {
480
+ ((JCipher*) cipher)->setMode(mode);
481
+ return m;
482
+ }
483
+ }
484
+
485
+
486
+ /**
487
+ * call-seq:
488
+ * block_mode => Fixnum
489
+ *
490
+ * Get the block mode. Returns <tt>nil</tt> if you try to use this on a stream
491
+ * cipher.
492
+ */
493
+ VALUE rb_cipher_block_mode(VALUE self)
494
+ {
495
+ JBase *cipher = NULL;
496
+ Data_Get_Struct(self, JBase, cipher);
497
+ ModeEnum mode = ((JCipher*) cipher)->getMode();
498
+ if (IS_STREAM_CIPHER(cipher->getCipherType())) {
499
+ return Qnil;
500
+ }
501
+ # define BLOCK_MODE_X(c, s) \
502
+ else if (mode == c ## _MODE) { \
503
+ return ID2SYM(rb_intern(# s)); \
504
+ }
505
+ # include "defs/block_modes.def"
506
+ }
507
+
508
+
509
+ /**
510
+ * call-seq:
511
+ * padding=(padding) => Symbol
512
+ *
513
+ * Set the padding on block ciphers.
514
+ *
515
+ * Note that not all block cipher modes can use all of the padding types.
516
+ * A CryptoPPError will be raised if you try to set an invalid padding. Also
517
+ * note that the padding should be set <i>AFTER</i> the block mode, as setting
518
+ * the mode causes the padding to revert to its default setting.
519
+ *
520
+ * Returns the padding as set.
521
+ */
522
+ VALUE rb_cipher_padding_eq(VALUE self, VALUE p)
523
+ {
524
+ JBase *cipher = NULL;
525
+ PaddingEnum padding = padding_sym_to_const(p);
526
+
527
+ if (!VALID_PADDING(padding)) {
528
+ rb_raise(rb_eCryptoPP_Error, "invalid cipher padding");
529
+ }
530
+ Data_Get_Struct(self, JBase, cipher);
531
+ if (IS_STREAM_CIPHER(cipher->getCipherType())) {
532
+ rb_raise(rb_eCryptoPP_Error, "can't set padding on stream ciphers");
533
+ }
534
+ else {
535
+ ((JCipher*) cipher)->setPadding(padding);
536
+ if (((JCipher*) cipher)->getPadding() != padding) {
537
+ rb_raise(rb_eCryptoPP_Error, "Padding '%s' cannot be used with mode '%s'", JCipher::getPaddingName(padding).c_str(), ((JCipher*) cipher)->getModeName().c_str());
538
+ }
539
+ else {
540
+ return p;
541
+ }
542
+ }
543
+ }
544
+
545
+
546
+ /**
547
+ * call-seq:
548
+ * padding => Fixnum
549
+ *
550
+ * Get the cipher padding being used. Returns <tt>nil</tt> if you try to use
551
+ * this on a stream cipher.
552
+ */
553
+ VALUE rb_cipher_padding(VALUE self)
554
+ {
555
+ JBase *cipher = NULL;
556
+ Data_Get_Struct(self, JBase, cipher);
557
+ PaddingEnum padding = ((JCipher*) cipher)->getPadding();
558
+ if (IS_STREAM_CIPHER(cipher->getCipherType())) {
559
+ return Qnil;
560
+ }
561
+ # define PADDING_X(c, s) \
562
+ else if (padding == c ## _PADDING) { \
563
+ return ID2SYM(rb_intern(# s)); \
564
+ }
565
+ # include "defs/paddings.def"
566
+ }
567
+
568
+
569
+ /**
570
+ * call-seq:
571
+ * rng=(rng) => Symbol
572
+ *
573
+ * Set the random number generator to use for IVs. A CryptoPPError will be
574
+ * raised if an RNG is not available on the system.
575
+ *
576
+ * RNGs are used to create random initialization vectors using
577
+ * <tt>rand_iv</tt>. The default is a non-blocking RNG, such as
578
+ * <tt>/dev/urandom</tt> on UNIX-alikes or CryptoAPI on Microsoft systems.
579
+ */
580
+ VALUE rb_cipher_rng_eq(VALUE self, VALUE r)
581
+ {
582
+ JBase *cipher = NULL;
583
+ RNGEnum rng = rng_sym_to_const(r);
584
+
585
+ if (!VALID_RNG(rng)) {
586
+ rb_raise(rb_eCryptoPP_Error, "invalid cipher RNG");
587
+ }
588
+ Data_Get_Struct(self, JBase, cipher);
589
+ ((JCipher*) cipher)->setRNG(rng);
590
+ if (((JCipher*) cipher)->getRNG() != rng) {
591
+ rb_raise(rb_eCryptoPP_Error, "RNG '%s' is unavailable", JBase::getRNGName(rng).c_str());
592
+ }
593
+ else {
594
+ return r;
595
+ }
596
+ }
597
+
598
+
599
+ /**
600
+ * call-seq:
601
+ * rng => Fixnum
602
+ *
603
+ * Get the RNG being used.
604
+ */
605
+ VALUE rb_cipher_rng(VALUE self)
606
+ {
607
+ JBase *cipher = NULL;
608
+ Data_Get_Struct(self, JBase, cipher);
609
+ RNGEnum rng = ((JCipher*) cipher)->getRNG();
610
+ if (false) {
611
+ // no-op so we can use our x-macro
612
+ }
613
+ # define RNG_X(c, s) \
614
+ else if (rng == c ## _RNG) { \
615
+ return ID2SYM(rb_intern(# s)); \
616
+ }
617
+ # include "defs/rngs.def"
618
+ }
619
+
620
+
621
+ /* Set the plaintext. */
622
+ static string cipher_plaintext_eq(VALUE self, VALUE plaintext, bool hex)
623
+ {
624
+ JBase *cipher = NULL;
625
+ Check_Type(plaintext, T_STRING);
626
+ Data_Get_Struct(self, JBase, cipher);
627
+ cipher->setPlaintext(string(StringValuePtr(plaintext), RSTRING(plaintext)->len), hex);
628
+ return cipher->getPlaintext(hex);
629
+ }
630
+
631
+ /**
632
+ * call-seq:
633
+ * plaintext=(string) => String
634
+ *
635
+ * Sets the plaintext on the Cipher in binary and returns the same.
636
+ */
637
+ VALUE rb_cipher_plaintext_eq(VALUE self, VALUE plaintext)
638
+ {
639
+ cipher_plaintext_eq(self, plaintext, false);
640
+ return plaintext;
641
+ }
642
+
643
+ /**
644
+ * call-seq:
645
+ * plaintext_hex=(string) => String
646
+ *
647
+ * Sets the plaintext on the Cipher in hex and returns the same.
648
+ */
649
+ VALUE rb_cipher_plaintext_hex_eq(VALUE self, VALUE plaintext)
650
+ {
651
+ cipher_plaintext_eq(self, plaintext, true);
652
+ return plaintext;
653
+ }
654
+
655
+
656
+ /* Get the plaintext. */
657
+ static string cipher_plaintext(VALUE self, bool hex)
658
+ {
659
+ JBase *cipher = NULL;
660
+ Data_Get_Struct(self, JBase, cipher);
661
+ return cipher->getPlaintext(hex);
662
+ }
663
+
664
+ /**
665
+ * call-seq:
666
+ * plaintext => String
667
+ *
668
+ * Gets the plaintext from the Cipher in binary.
669
+ */
670
+ VALUE rb_cipher_plaintext(VALUE self)
671
+ {
672
+ string retval = cipher_plaintext(self, false);
673
+ return rb_tainted_str_new(retval.data(), retval.length());
674
+ }
675
+
676
+ /**
677
+ * call-seq:
678
+ * plaintext_hex => String
679
+ *
680
+ * Gets the plaintext from the Cipher in hex.
681
+ */
682
+ VALUE rb_cipher_plaintext_hex(VALUE self)
683
+ {
684
+ string retval = cipher_plaintext(self, true);
685
+ return rb_tainted_str_new(retval.data(), retval.length());
686
+ }
687
+
688
+
689
+ /* Set the ciphertext. */
690
+ static string cipher_ciphertext_eq(VALUE self, VALUE ciphertext, bool hex)
691
+ {
692
+ JBase *cipher = NULL;
693
+ Check_Type(ciphertext, T_STRING);
694
+ Data_Get_Struct(self, JBase, cipher);
695
+ cipher->setCiphertext(string(StringValuePtr(ciphertext), RSTRING(ciphertext)->len), hex);
696
+ return cipher->getCiphertext(hex);
697
+ }
698
+
699
+ /**
700
+ * call-seq:
701
+ * ciphertext=(string) => String
702
+ *
703
+ * Sets the ciphertext on the Cipher in binary and returns the same.
704
+ */
705
+ VALUE rb_cipher_ciphertext_eq(VALUE self, VALUE ciphertext)
706
+ {
707
+ cipher_ciphertext_eq(self, ciphertext, false);
708
+ return ciphertext;
709
+ }
710
+
711
+ /**
712
+ * call-seq:
713
+ * ciphertext_hex=(string) => String
714
+ *
715
+ * Sets the ciphertext on the Cipher in hex and returns the same.
716
+ */
717
+ VALUE rb_cipher_ciphertext_hex_eq(VALUE self, VALUE ciphertext)
718
+ {
719
+ cipher_ciphertext_eq(self, ciphertext, true);
720
+ return ciphertext;
721
+ }
722
+
723
+
724
+ /* Get the ciphertext. */
725
+ static string cipher_ciphertext(VALUE self, bool hex)
726
+ {
727
+ JBase *cipher = NULL;
728
+ Data_Get_Struct(self, JBase, cipher);
729
+ return cipher->getCiphertext(hex);
730
+ }
731
+
732
+ /**
733
+ * call-seq:
734
+ * ciphertext => String
735
+ *
736
+ * Gets the ciphertext from the Cipher in binary.
737
+ */
738
+ VALUE rb_cipher_ciphertext(VALUE self)
739
+ {
740
+ string retval = cipher_ciphertext(self, false);
741
+ return rb_tainted_str_new(retval.data(), retval.length());
742
+ }
743
+
744
+ /**
745
+ * call-seq:
746
+ * ciphertext_hex => String
747
+ *
748
+ * Gets the ciphertext from the Cipher in hex.
749
+ */
750
+ VALUE rb_cipher_ciphertext_hex(VALUE self)
751
+ {
752
+ string retval = cipher_ciphertext(self, true);
753
+ return rb_tainted_str_new(retval.data(), retval.length());
754
+ }
755
+
756
+
757
+ /* Set the key. The true length of the key might not be what you expect,
758
+ * as different algorithms behave differently, i.e. 3Way has a fixed keylength
759
+ * of 12 bytes, while Blowfish can use keys of 1 to 72 bytes. */
760
+ static string cipher_key_eq(VALUE self, VALUE key, bool hex)
761
+ {
762
+ JBase *cipher = NULL;
763
+ Check_Type(key, T_STRING);
764
+ Data_Get_Struct(self, JBase, cipher);
765
+ cipher->setKey(string(StringValuePtr(key), RSTRING(key)->len), hex);
766
+ return cipher->getKey(hex);
767
+ }
768
+
769
+ /**
770
+ * call-seq:
771
+ * key=(string) => String
772
+ *
773
+ * Sets the key on the Cipher in binary and returns the same. Note that the
774
+ * key try to set may be truncated or padded depending on its length. Some
775
+ * ciphers have fixed key lengths while others have specific requirements on
776
+ * their size. For instance, the Threeway cipher has a fixed key length of 12
777
+ * bytes, while Blowfish can use keys of 1 to 72 bytes.
778
+ *
779
+ * When the key being used is shorter than an allowed key length, the key
780
+ * will be padded with \0's before being set. When the key is longer than
781
+ * an allowed key length, the key will be truncated before being set.
782
+ *
783
+ * In both cases, this happens automatically. You should check the actual
784
+ * key that is set using <tt>#key</tt>.
785
+ */
786
+ VALUE rb_cipher_key_eq(VALUE self, VALUE key)
787
+ {
788
+ cipher_key_eq(self, key, false);
789
+ return key;
790
+ }
791
+
792
+ /**
793
+ * call-seq:
794
+ * key_hex=(string) => String
795
+ *
796
+ * Sets the key on the Cipher in hex and returns the same. Note that the
797
+ * key try to set may be truncated or padded depending on its length. Some
798
+ * ciphers have fixed key lengths while others have specific requirements on
799
+ * their size. For instance, the Threeway cipher has a fixed key length of 12
800
+ * bytes, while Blowfish can use keys of 1 to 72 bytes.
801
+ *
802
+ * When the key being used is shorter than an allowed key length, the key
803
+ * will be padded with \0's before being set. When the key is longer than
804
+ * an allowed key length, the key will be truncated before being set.
805
+ *
806
+ * In both cases, this happens automatically. You should check the actual
807
+ * key that is set using <tt>#key</tt>.
808
+ */
809
+ VALUE rb_cipher_key_hex_eq(VALUE self, VALUE key)
810
+ {
811
+ cipher_key_eq(self, key, true);
812
+ return key;
813
+ }
814
+
815
+
816
+ /* Get the key. */
817
+ static string cipher_key(VALUE self, bool hex)
818
+ {
819
+ JBase *cipher = NULL;
820
+ Data_Get_Struct(self, JBase, cipher);
821
+ return cipher->getKey(hex);
822
+ }
823
+
824
+ /**
825
+ * call-seq:
826
+ * key => String
827
+ *
828
+ * Returns the key set on the Cipher in binary.
829
+ */
830
+ VALUE rb_cipher_key(VALUE self)
831
+ {
832
+ string retval = cipher_key(self, false);
833
+ return rb_tainted_str_new(retval.data(), retval.length());
834
+ }
835
+
836
+ /**
837
+ * call-seq:
838
+ * key => String
839
+ *
840
+ * Returns the key set on the Cipher in hex.
841
+ */
842
+ VALUE rb_cipher_key_hex(VALUE self)
843
+ {
844
+ string retval = cipher_key(self, true);
845
+ return rb_tainted_str_new(retval.data(), retval.length());
846
+ }
847
+
848
+
849
+ /**
850
+ * call-seq:
851
+ * key_length=(length) => Fixnum
852
+ *
853
+ * Sets the key length. Some ciphers require rather specific key lengths,
854
+ * and if the key length you attempt to set is invalid, an exception will
855
+ * be thrown. The key length being set is set in terms of bytes in binary, not
856
+ * hex characters.
857
+ */
858
+ VALUE rb_cipher_key_length_eq(VALUE self, VALUE l)
859
+ {
860
+ JBase *cipher = NULL;
861
+ unsigned int length = NUM2UINT(rb_funcall(l, rb_intern("to_i"), 0));
862
+ Data_Get_Struct(self, JBase, cipher);
863
+ cipher->setKeylength(length);
864
+ if (cipher->getKeylength() != length) {
865
+ rb_raise(rb_eCryptoPP_Error, "tried to set a key length of %d but %d was used", length, cipher->getKeylength());
866
+ }
867
+ else {
868
+ return l;
869
+ }
870
+ }
871
+
872
+
873
+ /**
874
+ * call-seq:
875
+ * key_length => Fixnum
876
+ *
877
+ * Gets the key length. The key length being returned in terms of bytes
878
+ * in binary, not hex characters.
879
+ */
880
+ VALUE rb_cipher_key_length(VALUE self)
881
+ {
882
+ JBase *cipher = NULL;
883
+ Data_Get_Struct(self, JBase, cipher);
884
+ return rb_fix_new(cipher->getKeylength());
885
+ }
886
+
887
+
888
+ /**
889
+ * Returns the default key length.
890
+ */
891
+ VALUE rb_cipher_default_key_length(VALUE self)
892
+ {
893
+ JBase *cipher = NULL;
894
+ Data_Get_Struct(self, JBase, cipher);
895
+ return rb_fix_new(cipher->getDefaultKeylength());
896
+ }
897
+
898
+ /**
899
+ * Returns the minimum key length.
900
+ */
901
+ VALUE rb_cipher_min_key_length(VALUE self)
902
+ {
903
+ JBase *cipher = NULL;
904
+ Data_Get_Struct(self, JBase, cipher);
905
+ return rb_fix_new(cipher->getMinKeylength());
906
+ }
907
+
908
+ /**
909
+ * Returns the maximum key length.
910
+ */
911
+ VALUE rb_cipher_max_key_length(VALUE self)
912
+ {
913
+ JBase *cipher = NULL;
914
+ Data_Get_Struct(self, JBase, cipher);
915
+ return rb_fix_new(cipher->getMaxKeylength());
916
+ }
917
+
918
+ /**
919
+ * Returns the multiplier used for the key length.
920
+ */
921
+ VALUE rb_cipher_mult_key_length(VALUE self)
922
+ {
923
+ JBase *cipher = NULL;
924
+ Data_Get_Struct(self, JBase, cipher);
925
+ return rb_fix_new(cipher->getMultKeylength());
926
+ }
927
+
928
+ /**
929
+ * Returns the closest valid key length without actually setting it.
930
+ */
931
+ VALUE rb_cipher_valid_key_length(VALUE self, VALUE l)
932
+ {
933
+ JBase *cipher = NULL;
934
+ unsigned int length = NUM2UINT(l);
935
+ Data_Get_Struct(self, JBase, cipher);
936
+ return rb_fix_new(cipher->getValidKeylength(length));
937
+ }
938
+
939
+
940
+ #if ENABLED_RC2_CIPHER
941
+ /**
942
+ * call-seq:
943
+ * effect_key_length=(length) => Fixnum
944
+ *
945
+ * Set the effective keylength on the RC2 algorithm. This function can
946
+ * only be used with RC2. Returns the actual effective keylength set. The
947
+ * default is 1024, which is also the maximum.
948
+ */
949
+ VALUE rb_cipher_effective_key_length_eq(VALUE self, VALUE l)
950
+ {
951
+ JBase *cipher = NULL;
952
+ unsigned int length = NUM2UINT(rb_funcall(l, rb_intern("to_i"), 0));
953
+ Data_Get_Struct(self, JBase, cipher);
954
+ if (cipher->getCipherType() != RC2_CIPHER) {
955
+ rb_raise(rb_eCryptoPP_Error, "effective key lengths can only be used with the RC2 cipher");
956
+ }
957
+ else {
958
+ ((JRC2*) cipher)->setEffectiveKeylength(length);
959
+ if (((JRC2*) cipher)->getEffectiveKeylength() != length) {
960
+ rb_raise(rb_eCryptoPP_Error, "tried to set an effective key length of %d but %d was used", length, ((JRC2*) cipher)->getEffectiveKeylength());
961
+ }
962
+ else {
963
+ return l;
964
+ }
965
+ }
966
+ }
967
+
968
+
969
+ /**
970
+ * Gets the key length. The key length being returned in terms of bytes in
971
+ * binary, not hex characters.
972
+ */
973
+ VALUE rb_cipher_effective_key_length(VALUE self)
974
+ {
975
+ JBase *cipher = NULL;
976
+ Data_Get_Struct(self, JBase, cipher);
977
+ return rb_fix_new(((JRC2*) cipher)->getEffectiveKeylength());
978
+ }
979
+ #endif
980
+
981
+
982
+ /**
983
+ * call-seq:
984
+ * block_size => Fixnum
985
+ *
986
+ * Gets the block size.
987
+ */
988
+ VALUE rb_cipher_block_size(VALUE self)
989
+ {
990
+ JBase *cipher = NULL;
991
+ Data_Get_Struct(self, JBase, cipher);
992
+ return rb_fix_new(cipher->getBlockSize());
993
+ }
994
+
995
+
996
+ /**
997
+ * call-seq:
998
+ * rounds=(rounds) => Fixnum
999
+ *
1000
+ * Sets the number of rounds to perform on block ciphers. Some block ciphers
1001
+ * have different requirements for their rounds than others. An exception
1002
+ * will be raised on invalid round settings.
1003
+ */
1004
+ VALUE rb_cipher_rounds_eq(VALUE self, VALUE r)
1005
+ {
1006
+ JBase *cipher = NULL;
1007
+ unsigned int rounds = NUM2UINT(rb_funcall(r, rb_intern("to_i"), 0));
1008
+ Data_Get_Struct(self, JBase, cipher);
1009
+ if (IS_STREAM_CIPHER(cipher->getCipherType())) {
1010
+ rb_raise(rb_eCryptoPP_Error, "can't set rounds on stream ciphers");
1011
+ }
1012
+ else {
1013
+ ((JCipher*) cipher)->setRounds(rounds);
1014
+ if (((JCipher*) cipher)->getRounds() != rounds) {
1015
+ rb_raise(rb_eCryptoPP_Error, "tried set the number of rounds to %d but %d was used instead", rounds, ((JCipher*) cipher)->getRounds());
1016
+ }
1017
+ else {
1018
+ return r;
1019
+ }
1020
+ }
1021
+ }
1022
+
1023
+
1024
+ /**
1025
+ * call-seq:
1026
+ * rounts => Fixnum
1027
+ *
1028
+ * Gets the number of rounds to perform on block ciphers. Returns nil if you
1029
+ * try to use this on a stream cipher.
1030
+ */
1031
+ VALUE rb_cipher_rounds(VALUE self)
1032
+ {
1033
+ JBase *cipher = NULL;
1034
+ Data_Get_Struct(self, JBase, cipher);
1035
+ if (IS_STREAM_CIPHER(cipher->getCipherType())) {
1036
+ return Qnil;
1037
+ }
1038
+ else {
1039
+ return rb_fix_new(((JCipher*) cipher)->getRounds());
1040
+ }
1041
+ }
1042
+
1043
+
1044
+ /* Encrypt the plaintext using the options set on the Cipher. This method will
1045
+ * return the ciphertext in binary or hex accordingly, but the raw ciphertext
1046
+ * will always be available through the ciphertext methods regardless. */
1047
+ static VALUE cipher_encrypt(VALUE self, bool hex)
1048
+ {
1049
+ JBase *cipher = NULL;
1050
+ Data_Get_Struct(self, JBase, cipher);
1051
+ try {
1052
+ cipher->encrypt();
1053
+ return rb_tainted_str_new(cipher->getCiphertext(hex).data(), cipher->getCiphertext(hex).length());
1054
+ }
1055
+ catch (Exception e) {
1056
+ rb_raise(rb_eCryptoPP_Error, string("Crypto++ exception: " + e.GetWhat()).c_str());
1057
+ }
1058
+ }
1059
+
1060
+ /**
1061
+ * call-seq:
1062
+ * encrypt => String
1063
+ *
1064
+ * Encrypt the plaintext using the options set on the Cipher. This method will
1065
+ * return the ciphertext in binary. The raw ciphertext will always be available
1066
+ * through the ciphertext and ciphertext_hex afterwards.
1067
+ */
1068
+ VALUE rb_cipher_encrypt(VALUE self)
1069
+ {
1070
+ return cipher_encrypt(self, false);
1071
+ }
1072
+
1073
+ /**
1074
+ * call-seq:
1075
+ * encrypt_hex => String
1076
+ *
1077
+ * Encrypt the plaintext using the options set on the Cipher. This method will
1078
+ * return the ciphertext in hex. The raw ciphertext will always be available
1079
+ * through the ciphertext and ciphertext_hex afterwards.
1080
+ */
1081
+ VALUE rb_cipher_encrypt_hex(VALUE self)
1082
+ {
1083
+ return cipher_encrypt(self, true);
1084
+ }
1085
+
1086
+
1087
+ /* Decrypt the ciphertext using the options set on the Cipher and store
1088
+ * it in the plaintext attribute. This method will return the plaintext
1089
+ * in binary or hex accordingly, but the raw plaintext will always be
1090
+ * available through the plaintext methods regardless. */
1091
+ static VALUE cipher_decrypt(VALUE self, bool hex)
1092
+ {
1093
+ JBase *cipher = NULL;
1094
+ Data_Get_Struct(self, JBase, cipher);
1095
+ try {
1096
+ cipher->decrypt();
1097
+ string retval = cipher->getPlaintext(hex);
1098
+ return rb_tainted_str_new(retval.data(), retval.length());
1099
+ }
1100
+ catch (Exception e) {
1101
+ rb_raise(rb_eCryptoPP_Error, "Crypto++ exception: %s", e.GetWhat().c_str());
1102
+ }
1103
+ }
1104
+
1105
+ /**
1106
+ * call-seq:
1107
+ * decrypt => String
1108
+ *
1109
+ * Decrypt the ciphertext using the options set on the Cipher. This method
1110
+ * will return the plaintext in binary. The raw plaintext will always be
1111
+ * available through the plaintext and plaintext_hex methods afterwards.
1112
+ */
1113
+ VALUE rb_cipher_decrypt(VALUE self)
1114
+ {
1115
+ return cipher_decrypt(self, false);
1116
+ }
1117
+
1118
+ /**
1119
+ * call-seq:
1120
+ * decrypt_hex => String
1121
+ *
1122
+ * Decrypt the ciphertext using the options set on the Cipher. This method
1123
+ * will return the plaintext in hex. The raw plaintext will always be
1124
+ * available through the plaintext and plaintext_hex methods afterwards.
1125
+ */
1126
+ VALUE rb_cipher_decrypt_hex(VALUE self)
1127
+ {
1128
+ return cipher_decrypt(self, true);
1129
+ }
1130
+
1131
+
1132
+ /**
1133
+ * call-seq:
1134
+ * encrypt_io(in, out) => true
1135
+ *
1136
+ * Encrypts a Ruby IO object and spits the result into another one. You can use
1137
+ * any sort of Ruby object as long as it implements <tt>eof?</tt>,
1138
+ * <tt>read</tt>, <tt>write</tt> and <tt>flush</tt>.
1139
+ *
1140
+ * Examples:
1141
+ *
1142
+ * cipher.encrypt_io(File.open("http://example.com/"), File.open("test.out", 'w'))
1143
+ *
1144
+ * output = StringIO.new
1145
+ * cipher.encrypt_io(File.open('test.enc'), output)
1146
+ */
1147
+ VALUE rb_cipher_encrypt_io(VALUE self, VALUE in, VALUE out)
1148
+ {
1149
+ JBase *cipher = NULL;
1150
+ Data_Get_Struct(self, JBase, cipher);
1151
+ try {
1152
+ cipher->encryptRubyIO(&in, &out);
1153
+ return Qtrue;
1154
+ }
1155
+ catch (Exception e) {
1156
+ rb_raise(rb_eCryptoPP_Error, "Crypto++ exception: %s in %s()", e.GetWhat().c_str());
1157
+ }
1158
+ }
1159
+
1160
+
1161
+ /**
1162
+ * call-seq:
1163
+ * decrypt_io(in, out) => true
1164
+ *
1165
+ * Decrypts a Ruby IO object and spits the result into another one. You can use
1166
+ * any sort of Ruby object as long as it implements <tt>eof?</tt>,
1167
+ * <tt>read</tt>, <tt>write</tt> and <tt>flush</tt>.
1168
+ *
1169
+ * Examples:
1170
+ *
1171
+ * cipher.decrypt_io(File.open("http://example.com/"), File.open("test.out", 'w'))
1172
+ *
1173
+ * output = StringIO.new
1174
+ * cipher.decrypt_io(File.open('test.enc'), output)
1175
+ */
1176
+ VALUE rb_cipher_decrypt_io(VALUE self, VALUE in, VALUE out)
1177
+ {
1178
+ JBase *cipher = NULL;
1179
+ Data_Get_Struct(self, JBase, cipher);
1180
+ try {
1181
+ cipher->decryptRubyIO(&in, &out);
1182
+ return Qtrue;
1183
+ }
1184
+ catch (Exception e) {
1185
+ rb_raise(rb_eCryptoPP_Error, "Crypto++ exception: %s in %s()", e.GetWhat().c_str());
1186
+ }
1187
+ }
1188
+
1189
+
1190
+ /**
1191
+ * call-seq:
1192
+ * cipher_name(algorithm) => String
1193
+ *
1194
+ * Returns the name of a Cipher.
1195
+ */
1196
+ VALUE rb_module_cipher_name(VALUE self, VALUE c)
1197
+ {
1198
+ switch (cipher_sym_to_const(c)) {
1199
+ default:
1200
+ rb_raise(rb_eCryptoPP_Error, "could not find a valid cipher type");
1201
+ break;
1202
+
1203
+ # define CIPHER_ALGORITHM_X(klass, r, c, s) \
1204
+ case r ## _CIPHER: \
1205
+ return rb_tainted_str_new2(c::getStaticCipherName().c_str());
1206
+ # include "defs/ciphers.def"
1207
+ }
1208
+ }
1209
+
1210
+
1211
+ /**
1212
+ * call-seq:
1213
+ * algorithm_name() => String
1214
+ *
1215
+ * Returns the name of the cipher algorithm being used.
1216
+ */
1217
+ VALUE rb_cipher_algorithm_name(VALUE self)
1218
+ {
1219
+ JBase *cipher = NULL;
1220
+ Data_Get_Struct(self, JBase, cipher);
1221
+ return rb_tainted_str_new2(cipher->getCipherName().c_str());
1222
+ }
1223
+
1224
+
1225
+ /**
1226
+ * call-seq:
1227
+ * block_mode_name(block_mode) => String
1228
+ *
1229
+ * Singleton method to return the name of a block cipher mode.
1230
+ */
1231
+ VALUE rb_module_block_mode_name(VALUE self, VALUE m)
1232
+ {
1233
+ return rb_tainted_str_new2(JCipher::getModeName(mode_sym_to_const(m)).c_str());
1234
+ }
1235
+
1236
+
1237
+ /**
1238
+ * call-seq:
1239
+ * block_mode_name() => String
1240
+ *
1241
+ * Returns the name of the mode being used.
1242
+ */
1243
+ VALUE rb_cipher_block_mode_name(VALUE self)
1244
+ {
1245
+ JBase *cipher = NULL;
1246
+ Data_Get_Struct(self, JBase, cipher);
1247
+ if (IS_STREAM_CIPHER(cipher->getCipherType())) {
1248
+ return Qnil;
1249
+ }
1250
+ else {
1251
+ return rb_tainted_str_new2(JCipher::getModeName(((JCipher*) cipher)->getMode()).c_str());
1252
+ }
1253
+ }
1254
+
1255
+
1256
+ /**
1257
+ * call-seq:
1258
+ * padding_name(padding) => String
1259
+ *
1260
+ * Singleton method to return the name of the a block cipher padding mode.
1261
+ */
1262
+ VALUE rb_module_padding_name(VALUE self, VALUE p)
1263
+ {
1264
+ return rb_tainted_str_new2(JCipher::getPaddingName(padding_sym_to_const(p)).c_str());
1265
+ }
1266
+
1267
+
1268
+ /**
1269
+ * call-seq:
1270
+ * padding_name() => String
1271
+ *
1272
+ * Returns the name of the padding being used.
1273
+ */
1274
+ VALUE rb_cipher_padding_name(VALUE self)
1275
+ {
1276
+ JBase *cipher = NULL;
1277
+ Data_Get_Struct(self, JBase, cipher);
1278
+ if (IS_STREAM_CIPHER(cipher->getCipherType())) {
1279
+ return Qnil;
1280
+ }
1281
+ else {
1282
+ return rb_tainted_str_new2(JCipher::getPaddingName(((JCipher*) cipher)->getPadding()).c_str());
1283
+ }
1284
+ }
1285
+
1286
+
1287
+ /**
1288
+ * call-seq:
1289
+ * rng_name(rng) => String
1290
+ *
1291
+ * Singleton method to return the name of the random number generator being
1292
+ * used.
1293
+ */
1294
+ VALUE rb_module_rng_name(VALUE self, VALUE r)
1295
+ {
1296
+ return rb_tainted_str_new2(JCipher::getRNGName(rng_sym_to_const(r)).c_str());
1297
+ }
1298
+
1299
+
1300
+ /**
1301
+ * call-seq:
1302
+ * rng_name() => String
1303
+ *
1304
+ * Returns the name of the random number generator being used.
1305
+ */
1306
+ VALUE rb_cipher_rng_name(VALUE self)
1307
+ {
1308
+ JBase *cipher = NULL;
1309
+ Data_Get_Struct(self, JBase, cipher);
1310
+ return rb_tainted_str_new2(JCipher::getRNGName(cipher->getRNG()).c_str());
1311
+ }
1312
+
1313
+
1314
+ /**
1315
+ * call-seq:
1316
+ * cipher_type() => Symbol
1317
+ *
1318
+ * Returns the type of cipher being used as a Symbol.
1319
+ */
1320
+ VALUE rb_cipher_cipher_type(VALUE self)
1321
+ {
1322
+ JBase *cipher = NULL;
1323
+ Data_Get_Struct(self, JBase, cipher);
1324
+
1325
+ switch (cipher->getCipherType()) {
1326
+ # define CIPHER_ALGORITHM_X(klass, r, c, s) \
1327
+ case r ## _CIPHER: \
1328
+ return ID2SYM(rb_intern(# s));
1329
+ # include "defs/ciphers.def"
1330
+
1331
+ default:
1332
+ return Qnil;
1333
+ }
1334
+ }
1335
+
1336
+
1337
+ /**
1338
+ * call-seq:
1339
+ * cipher_enabled?(algorithm) => boolean
1340
+ *
1341
+ * Singleton method to check for the availability of a cipher algorithm.
1342
+ */
1343
+ VALUE rb_module_cipher_enabled(VALUE self, VALUE c)
1344
+ {
1345
+ switch (cipher_sym_to_const(c)) {
1346
+ default:
1347
+ return Qfalse;
1348
+
1349
+ # define CIPHER_ALGORITHM_X(klass, r, c, s) \
1350
+ case r ## _CIPHER:
1351
+ # include "defs/ciphers.def"
1352
+ return Qtrue;
1353
+ }
1354
+ }
1355
+
1356
+
1357
+ /**
1358
+ * call-seq:
1359
+ * rng_available?(rng) => boolean
1360
+ *
1361
+ * Singleton method to check for the availability of a random number generator.
1362
+ */
1363
+ VALUE rb_module_rng_available(VALUE self, VALUE r)
1364
+ {
1365
+ ID id = SYM2ID(r);
1366
+ if (id == rb_intern("rand")) {
1367
+ return Qtrue;
1368
+ }
1369
+ # ifdef NONBLOCKING_RNG_AVAILABLE
1370
+ else if (id == rb_intern("non_blocking")) {
1371
+ return Qtrue;
1372
+ }
1373
+ # endif
1374
+
1375
+ # ifdef BLOCKING_RNG_AVAILABLE
1376
+ else if (id == rb_intern("blocking")) {
1377
+ return Qtrue;
1378
+ }
1379
+ # endif
1380
+
1381
+ else {
1382
+ return Qfalse;
1383
+ }
1384
+ }
1385
+
1386
+
1387
+ /**
1388
+ * call-seq:
1389
+ * cipher_list() => Array
1390
+ *
1391
+ * Returns an Array of available ciphers.
1392
+ */
1393
+ VALUE rb_module_cipher_list(VALUE self)
1394
+ {
1395
+ VALUE ary = rb_ary_new();
1396
+
1397
+ # define CIPHER_ALGORITHM_X(klass, r, c, s) \
1398
+ rb_ary_push(ary, ID2SYM(rb_intern(# s)));
1399
+ # include "defs/ciphers.def"
1400
+
1401
+ return ary;
1402
+ }