ronin-support 0.5.1 → 1.0.0.beta1

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 (517) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +11 -0
  3. data/.github/workflows/ruby.yml +27 -0
  4. data/.gitignore +7 -6
  5. data/.mailmap +1 -0
  6. data/.ruby-version +1 -0
  7. data/.yardopts +1 -2
  8. data/ChangeLog.md +533 -137
  9. data/Gemfile +20 -20
  10. data/README.md +137 -61
  11. data/Rakefile +29 -10
  12. data/data/text/homoglyphs/ascii.txt +8 -0
  13. data/data/text/homoglyphs/cyrillic.txt +33 -0
  14. data/data/text/homoglyphs/full_width.txt +81 -0
  15. data/data/text/homoglyphs/greek.txt +21 -0
  16. data/data/text/homoglyphs/latin_numbers.txt +14 -0
  17. data/data/text/homoglyphs/punctuation.txt +7 -0
  18. data/data/text/patterns/network/public_suffix.rb.erb +44 -0
  19. data/examples/ssl_proxy.rb +38 -0
  20. data/examples/tcp_proxy.rb +41 -0
  21. data/gemspec.yml +25 -15
  22. data/lib/ronin/support/archive/core_ext/file.rb +118 -0
  23. data/lib/ronin/{formatting/sql.rb → support/archive/core_ext.rb} +6 -7
  24. data/lib/ronin/support/archive/mixin.rb +213 -0
  25. data/lib/ronin/support/archive/tar/reader.rb +135 -0
  26. data/lib/ronin/support/archive/tar/writer.rb +197 -0
  27. data/lib/ronin/support/archive/tar.rb +155 -0
  28. data/lib/ronin/support/archive/zip/reader/entry.rb +134 -0
  29. data/lib/ronin/support/archive/zip/reader/statistics.rb +76 -0
  30. data/lib/ronin/support/archive/zip/reader.rb +273 -0
  31. data/lib/ronin/support/archive/zip/writer.rb +175 -0
  32. data/lib/ronin/support/archive/zip.rb +105 -0
  33. data/lib/ronin/support/archive.rb +211 -0
  34. data/lib/ronin/support/binary/array.rb +255 -0
  35. data/lib/ronin/support/binary/bit_flip.rb +147 -0
  36. data/lib/ronin/support/binary/buffer.rb +2027 -0
  37. data/lib/ronin/support/binary/byte_slice.rb +324 -0
  38. data/lib/ronin/support/binary/core_ext/array.rb +75 -0
  39. data/lib/ronin/support/binary/core_ext/float.rb +80 -0
  40. data/lib/ronin/support/binary/core_ext/integer.rb +305 -0
  41. data/lib/ronin/support/binary/core_ext/io.rb +38 -0
  42. data/lib/ronin/support/binary/core_ext/string.rb +115 -0
  43. data/lib/ronin/{formatting/extensions/text.rb → support/binary/core_ext.rb} +9 -9
  44. data/lib/ronin/support/binary/cstring.rb +259 -0
  45. data/lib/ronin/support/binary/ctypes/aggregate_type.rb +98 -0
  46. data/lib/ronin/support/binary/ctypes/arch/arm/big_endian.rb +77 -0
  47. data/lib/ronin/support/binary/ctypes/arch/arm.rb +75 -0
  48. data/lib/ronin/support/binary/ctypes/arch/arm64/big_endian.rb +77 -0
  49. data/lib/ronin/support/binary/ctypes/arch/arm64.rb +75 -0
  50. data/lib/ronin/support/binary/ctypes/arch/mips/little_endian.rb +77 -0
  51. data/lib/ronin/support/binary/ctypes/arch/mips.rb +75 -0
  52. data/lib/ronin/support/binary/ctypes/arch/mips64/little_endian.rb +77 -0
  53. data/lib/ronin/support/binary/ctypes/arch/mips64.rb +75 -0
  54. data/lib/ronin/support/binary/ctypes/arch/ppc.rb +75 -0
  55. data/lib/ronin/support/binary/ctypes/arch/ppc64.rb +75 -0
  56. data/lib/ronin/support/binary/ctypes/arch/x86.rb +75 -0
  57. data/lib/ronin/support/binary/ctypes/arch/x86_64.rb +75 -0
  58. data/lib/ronin/support/binary/ctypes/arch.rb +30 -0
  59. data/lib/ronin/support/binary/ctypes/array_object_type.rb +164 -0
  60. data/lib/ronin/support/binary/ctypes/array_type.rb +232 -0
  61. data/lib/ronin/support/binary/ctypes/big_endian.rb +195 -0
  62. data/lib/ronin/support/binary/ctypes/char_type.rb +59 -0
  63. data/lib/ronin/support/binary/ctypes/char_types.rb +39 -0
  64. data/lib/ronin/support/binary/ctypes/enum_type.rb +181 -0
  65. data/lib/ronin/support/binary/ctypes/float32_type.rb +50 -0
  66. data/lib/ronin/support/binary/ctypes/float64_type.rb +50 -0
  67. data/lib/ronin/support/binary/ctypes/float_type.rb +62 -0
  68. data/lib/ronin/support/binary/ctypes/int16_type.rb +50 -0
  69. data/lib/ronin/support/binary/ctypes/int32_type.rb +50 -0
  70. data/lib/ronin/support/binary/ctypes/int64_type.rb +50 -0
  71. data/lib/ronin/support/binary/ctypes/int8_type.rb +41 -0
  72. data/lib/ronin/support/binary/ctypes/int_type.rb +62 -0
  73. data/lib/ronin/support/binary/ctypes/little_endian.rb +195 -0
  74. data/lib/ronin/support/binary/ctypes/mixin.rb +135 -0
  75. data/lib/ronin/support/binary/ctypes/native.rb +205 -0
  76. data/lib/ronin/support/binary/ctypes/network.rb +29 -0
  77. data/lib/ronin/support/binary/ctypes/object_type.rb +55 -0
  78. data/lib/ronin/support/binary/ctypes/os/bsd.rb +65 -0
  79. data/lib/ronin/support/binary/ctypes/os/freebsd.rb +215 -0
  80. data/lib/ronin/support/binary/ctypes/os/linux.rb +193 -0
  81. data/lib/ronin/support/binary/ctypes/os/macos.rb +151 -0
  82. data/lib/ronin/support/binary/ctypes/os/netbsd.rb +147 -0
  83. data/lib/ronin/support/binary/ctypes/os/openbsd.rb +168 -0
  84. data/lib/ronin/support/binary/ctypes/os/unix.rb +78 -0
  85. data/lib/ronin/support/binary/ctypes/os/windows.rb +125 -0
  86. data/lib/ronin/support/binary/ctypes/os.rb +125 -0
  87. data/lib/ronin/support/binary/ctypes/scalar_type.rb +200 -0
  88. data/lib/ronin/support/binary/ctypes/string_type.rb +143 -0
  89. data/lib/ronin/support/binary/ctypes/struct_object_type.rb +173 -0
  90. data/lib/ronin/support/binary/ctypes/struct_type.rb +359 -0
  91. data/lib/ronin/support/binary/ctypes/type.rb +193 -0
  92. data/lib/ronin/support/binary/ctypes/type_resolver.rb +206 -0
  93. data/lib/ronin/support/binary/ctypes/uint16_type.rb +50 -0
  94. data/lib/ronin/support/binary/ctypes/uint32_type.rb +50 -0
  95. data/lib/ronin/support/binary/ctypes/uint64_type.rb +50 -0
  96. data/lib/ronin/support/binary/ctypes/uint8_type.rb +41 -0
  97. data/lib/ronin/support/binary/ctypes/uint_type.rb +59 -0
  98. data/lib/ronin/support/binary/ctypes/unbounded_array_type.rb +258 -0
  99. data/lib/ronin/support/binary/ctypes/union_object_type.rb +173 -0
  100. data/lib/ronin/support/binary/ctypes/union_type.rb +261 -0
  101. data/lib/ronin/support/binary/ctypes.rb +462 -0
  102. data/lib/ronin/support/binary/hexdump/core_ext/file.rb +118 -0
  103. data/lib/ronin/support/binary/hexdump/core_ext/string.rb +115 -0
  104. data/lib/ronin/support/binary/hexdump/core_ext.rb +20 -0
  105. data/lib/ronin/support/binary/hexdump/parser.rb +492 -0
  106. data/lib/ronin/support/binary/hexdump.rb +20 -0
  107. data/lib/ronin/support/binary/memory.rb +268 -0
  108. data/lib/ronin/support/binary/packet.rb +33 -0
  109. data/lib/ronin/support/binary/stack.rb +256 -0
  110. data/lib/ronin/support/binary/stream/methods.rb +1755 -0
  111. data/lib/ronin/support/binary/stream.rb +151 -0
  112. data/lib/ronin/support/binary/struct/member.rb +86 -0
  113. data/lib/ronin/support/binary/struct.rb +830 -0
  114. data/lib/ronin/support/binary/template.rb +284 -0
  115. data/lib/ronin/support/binary/union.rb +162 -0
  116. data/lib/ronin/support/binary.rb +26 -0
  117. data/lib/ronin/support/cli/ansi.rb +330 -0
  118. data/lib/ronin/support/cli/io_shell/core_ext/io.rb +67 -0
  119. data/lib/ronin/{fuzzing/extensions.rb → support/cli/io_shell/core_ext.rb} +6 -7
  120. data/lib/ronin/support/cli/io_shell.rb +161 -0
  121. data/lib/ronin/support/cli/printing.rb +216 -0
  122. data/lib/ronin/support/cli.rb +20 -0
  123. data/lib/ronin/support/compression/core_ext/file.rb +70 -0
  124. data/lib/ronin/support/compression/core_ext/string.rb +101 -0
  125. data/lib/ronin/{formatting/html.rb → support/compression/core_ext.rb} +6 -7
  126. data/lib/ronin/support/compression/gzip/reader.rb +70 -0
  127. data/lib/ronin/support/compression/gzip/writer.rb +74 -0
  128. data/lib/ronin/support/compression/gzip.rb +105 -0
  129. data/lib/ronin/support/compression/mixin.rb +180 -0
  130. data/lib/ronin/{network/extensions/esmtp/net.rb → support/compression/zlib.rb} +9 -10
  131. data/lib/ronin/support/compression.rb +174 -0
  132. data/lib/ronin/{extensions → support/core_ext}/enumerable.rb +5 -6
  133. data/lib/ronin/{extensions → support/core_ext}/file.rb +11 -34
  134. data/lib/ronin/support/core_ext/integer.rb +37 -0
  135. data/lib/ronin/support/core_ext/ipaddr.rb +65 -0
  136. data/lib/ronin/{extensions → support/core_ext}/kernel.rb +10 -9
  137. data/lib/ronin/{extensions → support/core_ext}/resolv.rb +5 -28
  138. data/lib/ronin/{extensions → support/core_ext}/string.rb +117 -57
  139. data/lib/ronin/support/core_ext.rb +33 -0
  140. data/lib/ronin/support/crypto/cert.rb +522 -0
  141. data/lib/ronin/support/crypto/cert_chain.rb +204 -0
  142. data/lib/ronin/support/crypto/cipher/aes.rb +71 -0
  143. data/lib/ronin/support/crypto/cipher/aes128.rb +54 -0
  144. data/lib/ronin/support/crypto/cipher/aes256.rb +54 -0
  145. data/lib/ronin/support/crypto/cipher.rb +194 -0
  146. data/lib/ronin/support/crypto/core_ext/file.rb +660 -0
  147. data/lib/ronin/support/crypto/core_ext/string.rb +548 -0
  148. data/lib/ronin/{binary.rb → support/crypto/core_ext.rb} +7 -8
  149. data/lib/ronin/support/crypto/hmac.rb +48 -0
  150. data/lib/ronin/support/crypto/key/dh.rb +122 -0
  151. data/lib/ronin/support/crypto/key/dsa.rb +103 -0
  152. data/lib/ronin/support/crypto/key/ec.rb +99 -0
  153. data/lib/ronin/support/crypto/key/methods.rb +163 -0
  154. data/lib/ronin/support/crypto/key/rsa.rb +169 -0
  155. data/lib/ronin/support/crypto/key.rb +105 -0
  156. data/lib/ronin/support/crypto/mixin.rb +620 -0
  157. data/lib/ronin/{network/extensions/http/net.rb → support/crypto/openssl.rb} +9 -10
  158. data/lib/ronin/support/crypto.rb +779 -0
  159. data/lib/ronin/support/encoding/base16/core_ext/string.rb +63 -0
  160. data/lib/ronin/support/encoding/base16/core_ext.rb +19 -0
  161. data/lib/ronin/support/encoding/base16.rb +82 -0
  162. data/lib/ronin/support/encoding/base32/core_ext/string.rb +63 -0
  163. data/lib/ronin/support/encoding/base32/core_ext.rb +19 -0
  164. data/lib/ronin/support/encoding/base32.rb +164 -0
  165. data/lib/ronin/support/encoding/base64/core_ext/string.rb +76 -0
  166. data/lib/ronin/support/encoding/base64/core_ext.rb +19 -0
  167. data/lib/ronin/support/encoding/base64.rb +78 -0
  168. data/lib/ronin/support/encoding/c/core_ext/integer.rb +82 -0
  169. data/lib/ronin/support/encoding/c/core_ext/string.rb +125 -0
  170. data/lib/ronin/support/encoding/c/core_ext.rb +20 -0
  171. data/lib/ronin/support/encoding/c.rb +277 -0
  172. data/lib/ronin/support/encoding/core_ext/string.rb +107 -0
  173. data/lib/ronin/support/encoding/core_ext.rb +33 -0
  174. data/lib/ronin/support/encoding/hex/core_ext/integer.rb +82 -0
  175. data/lib/ronin/support/encoding/hex/core_ext/string.rb +133 -0
  176. data/lib/ronin/support/encoding/hex/core_ext.rb +22 -0
  177. data/lib/ronin/support/encoding/hex.rb +248 -0
  178. data/lib/ronin/support/encoding/html/core_ext/integer.rb +106 -0
  179. data/lib/ronin/support/encoding/html/core_ext/string.rb +130 -0
  180. data/lib/ronin/support/encoding/html/core_ext.rb +20 -0
  181. data/lib/ronin/support/encoding/html.rb +233 -0
  182. data/lib/ronin/support/encoding/http/core_ext/integer.rb +95 -0
  183. data/lib/ronin/support/encoding/http/core_ext/string.rb +129 -0
  184. data/lib/ronin/support/encoding/http/core_ext.rb +20 -0
  185. data/lib/ronin/support/encoding/http.rb +241 -0
  186. data/lib/ronin/support/encoding/js/core_ext/integer.rb +67 -0
  187. data/lib/ronin/support/encoding/js/core_ext/string.rb +125 -0
  188. data/lib/ronin/support/encoding/js/core_ext.rb +20 -0
  189. data/lib/ronin/support/encoding/js.rb +279 -0
  190. data/lib/ronin/support/encoding/powershell/core_ext/integer.rb +87 -0
  191. data/lib/ronin/support/encoding/powershell/core_ext/string.rb +145 -0
  192. data/lib/ronin/support/encoding/powershell/core_ext.rb +20 -0
  193. data/lib/ronin/support/encoding/powershell.rb +297 -0
  194. data/lib/ronin/support/encoding/punycode/core_ext/string.rb +63 -0
  195. data/lib/ronin/support/encoding/punycode/core_ext.rb +19 -0
  196. data/lib/ronin/support/encoding/punycode.rb +76 -0
  197. data/lib/ronin/support/encoding/quoted_printable/core_ext/string.rb +75 -0
  198. data/lib/ronin/support/encoding/quoted_printable/core_ext.rb +19 -0
  199. data/lib/ronin/support/encoding/quoted_printable.rb +102 -0
  200. data/lib/ronin/support/encoding/ruby/core_ext/string.rb +129 -0
  201. data/lib/ronin/{formatting/binary.rb → support/encoding/ruby/core_ext.rb} +6 -7
  202. data/lib/ronin/support/encoding/ruby.rb +235 -0
  203. data/lib/ronin/support/encoding/shell/core_ext/integer.rb +89 -0
  204. data/lib/ronin/support/encoding/shell/core_ext/string.rb +134 -0
  205. data/lib/ronin/support/encoding/shell/core_ext.rb +20 -0
  206. data/lib/ronin/support/encoding/shell.rb +293 -0
  207. data/lib/ronin/{network/extensions → support/encoding}/smtp.rb +7 -7
  208. data/lib/ronin/support/encoding/sql/core_ext/string.rb +114 -0
  209. data/lib/ronin/{formatting/http.rb → support/encoding/sql/core_ext.rb} +6 -7
  210. data/lib/ronin/support/encoding/sql.rb +124 -0
  211. data/lib/ronin/support/encoding/uri/core_ext/integer.rb +149 -0
  212. data/lib/ronin/support/encoding/uri/core_ext/string.rb +195 -0
  213. data/lib/ronin/support/encoding/uri/core_ext.rb +20 -0
  214. data/lib/ronin/support/encoding/uri.rb +424 -0
  215. data/lib/ronin/support/encoding/uuencoding/core_ext/string.rb +73 -0
  216. data/lib/ronin/support/encoding/uuencoding/core_ext.rb +19 -0
  217. data/lib/ronin/support/encoding/uuencoding.rb +70 -0
  218. data/lib/ronin/support/encoding/xml/core_ext/integer.rb +100 -0
  219. data/lib/ronin/support/encoding/xml/core_ext/string.rb +124 -0
  220. data/lib/ronin/support/encoding/xml/core_ext.rb +20 -0
  221. data/lib/ronin/support/encoding/xml.rb +328 -0
  222. data/lib/ronin/support/encoding.rb +46 -0
  223. data/lib/ronin/support/home.rb +88 -0
  224. data/lib/ronin/support/mixin.rb +42 -0
  225. data/lib/ronin/support/network/asn/dns_record.rb +112 -0
  226. data/lib/ronin/support/network/asn/list.rb +269 -0
  227. data/lib/ronin/support/network/asn/record.rb +164 -0
  228. data/lib/ronin/support/network/asn/record_set.rb +226 -0
  229. data/lib/ronin/support/network/asn.rb +88 -0
  230. data/lib/ronin/{binary/hexdump.rb → support/network/core_ext.rb} +6 -7
  231. data/lib/ronin/support/network/dns/idn.rb +38 -0
  232. data/lib/ronin/support/network/dns/mixin.rb +941 -0
  233. data/lib/ronin/support/network/dns/resolver.rb +707 -0
  234. data/lib/ronin/support/network/dns.rb +1109 -0
  235. data/lib/ronin/support/network/domain.rb +70 -0
  236. data/lib/ronin/support/network/email_address.rb +574 -0
  237. data/lib/ronin/support/network/esmtp/mixin.rb +115 -0
  238. data/lib/ronin/support/network/exceptions.rb +43 -0
  239. data/lib/ronin/support/network/ftp/mixin.rb +106 -0
  240. data/lib/ronin/support/network/host.rb +1473 -0
  241. data/lib/ronin/support/network/http/cookie.rb +245 -0
  242. data/lib/ronin/support/network/http/core_ext/uri/http.rb +63 -0
  243. data/lib/ronin/support/network/http/core_ext.rb +19 -0
  244. data/lib/ronin/support/network/http/mixin.rb +890 -0
  245. data/lib/ronin/support/network/http/request.rb +215 -0
  246. data/lib/ronin/support/network/http/set_cookie.rb +210 -0
  247. data/lib/ronin/support/network/http/user_agents.rb +115 -0
  248. data/lib/ronin/support/network/http.rb +2582 -0
  249. data/lib/ronin/support/network/imap/mixin.rb +133 -0
  250. data/lib/ronin/support/network/ip/mixin.rb +114 -0
  251. data/lib/ronin/support/network/ip.rb +540 -0
  252. data/lib/ronin/support/network/ip_range/cidr.rb +252 -0
  253. data/lib/ronin/support/network/ip_range/glob.rb +309 -0
  254. data/lib/ronin/support/network/ip_range/range.rb +249 -0
  255. data/lib/ronin/support/network/ip_range.rb +284 -0
  256. data/lib/ronin/support/network/mixin.rb +58 -0
  257. data/lib/ronin/support/network/packet.rb +27 -0
  258. data/lib/ronin/support/network/pop3/mixin.rb +113 -0
  259. data/lib/ronin/support/network/proxy.rb +602 -0
  260. data/lib/ronin/support/network/public_suffix/list.rb +339 -0
  261. data/lib/ronin/support/network/public_suffix/suffix.rb +118 -0
  262. data/lib/ronin/support/network/public_suffix/suffix_set.rb +150 -0
  263. data/lib/ronin/support/network/public_suffix.rb +41 -0
  264. data/lib/ronin/support/network/smtp/email.rb +190 -0
  265. data/lib/ronin/support/network/smtp/mixin.rb +290 -0
  266. data/lib/ronin/{extensions/meta.rb → support/network/smtp.rb} +6 -7
  267. data/lib/ronin/support/network/ssl/local_cert.rb +114 -0
  268. data/lib/ronin/support/network/ssl/local_key.rb +84 -0
  269. data/lib/ronin/support/network/ssl/mixin.rb +740 -0
  270. data/lib/ronin/{network/extensions/imap/net.rb → support/network/ssl/openssl.rb} +9 -10
  271. data/lib/ronin/support/network/ssl/proxy.rb +296 -0
  272. data/lib/ronin/support/network/ssl.rb +173 -0
  273. data/lib/ronin/support/network/tcp/mixin.rb +400 -0
  274. data/lib/ronin/support/network/tcp/proxy.rb +435 -0
  275. data/lib/ronin/support/network/tcp.rb +443 -0
  276. data/lib/ronin/support/network/telnet/mixin.rb +150 -0
  277. data/lib/ronin/support/network/telnet.rb +90 -0
  278. data/lib/ronin/support/network/tld/list.rb +266 -0
  279. data/lib/ronin/support/network/tld.rb +41 -0
  280. data/lib/ronin/support/network/tls/mixin.rb +670 -0
  281. data/lib/ronin/support/network/tls/proxy.rb +135 -0
  282. data/lib/ronin/support/network/tls.rb +53 -0
  283. data/lib/ronin/support/network/udp/mixin.rb +389 -0
  284. data/lib/ronin/support/network/udp/proxy.rb +192 -0
  285. data/lib/ronin/support/network/udp.rb +435 -0
  286. data/lib/ronin/support/network/unix/mixin.rb +273 -0
  287. data/lib/ronin/support/network.rb +37 -0
  288. data/lib/ronin/support/path.rb +136 -0
  289. data/lib/ronin/{network/extensions/dns/net.rb → support/text/core_ext/regexp.rb} +8 -9
  290. data/lib/ronin/support/text/core_ext/string.rb +46 -0
  291. data/lib/ronin/support/text/core_ext.rb +23 -0
  292. data/lib/ronin/support/text/entropy/core_ext/string.rb +45 -0
  293. data/lib/ronin/support/text/entropy/core_ext.rb +19 -0
  294. data/lib/ronin/support/text/entropy.rb +66 -0
  295. data/lib/ronin/support/text/erb/mixin.rb +44 -0
  296. data/lib/ronin/support/text/erb.rb +19 -0
  297. data/lib/ronin/support/text/homoglyph/core_ext/string.rb +108 -0
  298. data/lib/ronin/{formatting/digest.rb → support/text/homoglyph/core_ext.rb} +6 -7
  299. data/lib/ronin/{network/http/exceptions/unknown_request.rb → support/text/homoglyph/exceptions.rb} +10 -9
  300. data/lib/ronin/support/text/homoglyph/table.rb +228 -0
  301. data/lib/ronin/support/text/homoglyph.rb +142 -0
  302. data/lib/ronin/support/text/mixin.rb +31 -0
  303. data/lib/ronin/support/text/patterns/credentials.rb +75 -0
  304. data/lib/ronin/support/text/patterns/crypto.rb +67 -0
  305. data/lib/ronin/support/text/patterns/file_system.rb +93 -0
  306. data/lib/ronin/support/text/patterns/language.rb +37 -0
  307. data/lib/ronin/support/text/patterns/network/public_suffix.rb +44 -0
  308. data/lib/ronin/support/text/patterns/network.rb +140 -0
  309. data/lib/ronin/support/text/patterns/numeric.rb +52 -0
  310. data/lib/ronin/support/text/patterns/pii.rb +105 -0
  311. data/lib/ronin/support/text/patterns/source_code.rb +148 -0
  312. data/lib/ronin/support/text/patterns.rb +25 -0
  313. data/lib/ronin/support/text/random/mixin.rb +437 -0
  314. data/lib/ronin/support/text/random.rb +419 -0
  315. data/lib/ronin/support/text/typo/core_ext/string.rb +123 -0
  316. data/lib/ronin/support/text/typo/core_ext.rb +19 -0
  317. data/lib/ronin/support/text/typo/exceptions.rb +28 -0
  318. data/lib/ronin/support/text/typo/generator.rb +161 -0
  319. data/lib/ronin/support/text/typo.rb +260 -0
  320. data/lib/ronin/support/text.rb +26 -0
  321. data/lib/ronin/support/version.rb +6 -7
  322. data/lib/ronin/support.rb +20 -15
  323. data/ronin-support.gemspec +3 -1
  324. metadata +462 -369
  325. data/.gemtest +0 -0
  326. data/lib/ronin/binary/hexdump/parser.rb +0 -403
  327. data/lib/ronin/binary/struct.rb +0 -567
  328. data/lib/ronin/binary/template.rb +0 -454
  329. data/lib/ronin/extensions/ip_addr.rb +0 -217
  330. data/lib/ronin/extensions/meta/object.rb +0 -24
  331. data/lib/ronin/extensions/regexp.rb +0 -157
  332. data/lib/ronin/extensions.rb +0 -29
  333. data/lib/ronin/formatting/extensions/binary/array.rb +0 -61
  334. data/lib/ronin/formatting/extensions/binary/base64.rb +0 -106
  335. data/lib/ronin/formatting/extensions/binary/file.rb +0 -77
  336. data/lib/ronin/formatting/extensions/binary/float.rb +0 -65
  337. data/lib/ronin/formatting/extensions/binary/integer.rb +0 -180
  338. data/lib/ronin/formatting/extensions/binary/string.rb +0 -345
  339. data/lib/ronin/formatting/extensions/binary.rb +0 -26
  340. data/lib/ronin/formatting/extensions/digest/file.rb +0 -129
  341. data/lib/ronin/formatting/extensions/digest/string.rb +0 -86
  342. data/lib/ronin/formatting/extensions/digest.rb +0 -21
  343. data/lib/ronin/formatting/extensions/html/integer.rb +0 -142
  344. data/lib/ronin/formatting/extensions/html/string.rb +0 -194
  345. data/lib/ronin/formatting/extensions/html.rb +0 -21
  346. data/lib/ronin/formatting/extensions/http/integer.rb +0 -69
  347. data/lib/ronin/formatting/extensions/http/string.rb +0 -110
  348. data/lib/ronin/formatting/extensions/http.rb +0 -21
  349. data/lib/ronin/formatting/extensions/sql/string.rb +0 -128
  350. data/lib/ronin/formatting/extensions/sql.rb +0 -20
  351. data/lib/ronin/formatting/extensions/text/array.rb +0 -137
  352. data/lib/ronin/formatting/extensions/text/string.rb +0 -297
  353. data/lib/ronin/formatting/extensions.rb +0 -24
  354. data/lib/ronin/formatting/text.rb +0 -20
  355. data/lib/ronin/formatting.rb +0 -25
  356. data/lib/ronin/fuzzing/extensions/string.rb +0 -209
  357. data/lib/ronin/fuzzing/fuzzer.rb +0 -110
  358. data/lib/ronin/fuzzing/fuzzing.rb +0 -360
  359. data/lib/ronin/fuzzing/mutator.rb +0 -161
  360. data/lib/ronin/fuzzing/repeater.rb +0 -81
  361. data/lib/ronin/fuzzing/template.rb +0 -133
  362. data/lib/ronin/fuzzing.rb +0 -21
  363. data/lib/ronin/mixin.rb +0 -89
  364. data/lib/ronin/network/dns.rb +0 -201
  365. data/lib/ronin/network/esmtp.rb +0 -113
  366. data/lib/ronin/network/extensions/dns.rb +0 -20
  367. data/lib/ronin/network/extensions/esmtp.rb +0 -20
  368. data/lib/ronin/network/extensions/http/uri/http.rb +0 -228
  369. data/lib/ronin/network/extensions/http.rb +0 -21
  370. data/lib/ronin/network/extensions/imap.rb +0 -20
  371. data/lib/ronin/network/extensions/pop3/net.rb +0 -24
  372. data/lib/ronin/network/extensions/pop3.rb +0 -20
  373. data/lib/ronin/network/extensions/smtp/net.rb +0 -24
  374. data/lib/ronin/network/extensions/ssl/net.rb +0 -24
  375. data/lib/ronin/network/extensions/ssl.rb +0 -20
  376. data/lib/ronin/network/extensions/tcp/net.rb +0 -24
  377. data/lib/ronin/network/extensions/tcp.rb +0 -20
  378. data/lib/ronin/network/extensions/telnet/net.rb +0 -24
  379. data/lib/ronin/network/extensions/telnet.rb +0 -20
  380. data/lib/ronin/network/extensions/udp/net.rb +0 -24
  381. data/lib/ronin/network/extensions/udp.rb +0 -20
  382. data/lib/ronin/network/extensions.rb +0 -29
  383. data/lib/ronin/network/ftp.rb +0 -149
  384. data/lib/ronin/network/http/exceptions.rb +0 -20
  385. data/lib/ronin/network/http/http.rb +0 -1127
  386. data/lib/ronin/network/http/proxy.rb +0 -330
  387. data/lib/ronin/network/http.rb +0 -22
  388. data/lib/ronin/network/imap.rb +0 -158
  389. data/lib/ronin/network/mixins/dns.rb +0 -55
  390. data/lib/ronin/network/mixins/esmtp.rb +0 -164
  391. data/lib/ronin/network/mixins/ftp.rb +0 -155
  392. data/lib/ronin/network/mixins/http.rb +0 -227
  393. data/lib/ronin/network/mixins/imap.rb +0 -156
  394. data/lib/ronin/network/mixins/mixin.rb +0 -58
  395. data/lib/ronin/network/mixins/pop3.rb +0 -149
  396. data/lib/ronin/network/mixins/smtp.rb +0 -159
  397. data/lib/ronin/network/mixins/ssl.rb +0 -148
  398. data/lib/ronin/network/mixins/tcp.rb +0 -368
  399. data/lib/ronin/network/mixins/telnet.rb +0 -208
  400. data/lib/ronin/network/mixins/udp.rb +0 -381
  401. data/lib/ronin/network/mixins/unix.rb +0 -279
  402. data/lib/ronin/network/mixins.rb +0 -29
  403. data/lib/ronin/network/network.rb +0 -45
  404. data/lib/ronin/network/pop3.rb +0 -124
  405. data/lib/ronin/network/proxy.rb +0 -578
  406. data/lib/ronin/network/smtp/email.rb +0 -174
  407. data/lib/ronin/network/smtp/smtp.rb +0 -230
  408. data/lib/ronin/network/smtp.rb +0 -22
  409. data/lib/ronin/network/ssl.rb +0 -186
  410. data/lib/ronin/network/tcp/proxy.rb +0 -417
  411. data/lib/ronin/network/tcp/tcp.rb +0 -443
  412. data/lib/ronin/network/tcp.rb +0 -21
  413. data/lib/ronin/network/telnet.rb +0 -264
  414. data/lib/ronin/network/udp/proxy.rb +0 -191
  415. data/lib/ronin/network/udp/udp.rb +0 -450
  416. data/lib/ronin/network/udp.rb +0 -21
  417. data/lib/ronin/network/unix.rb +0 -286
  418. data/lib/ronin/network.rb +0 -31
  419. data/lib/ronin/path.rb +0 -137
  420. data/lib/ronin/spec/ui/output.rb +0 -22
  421. data/lib/ronin/support/inflector.rb +0 -92
  422. data/lib/ronin/support/support.rb +0 -42
  423. data/lib/ronin/templates/erb.rb +0 -78
  424. data/lib/ronin/templates/template.rb +0 -169
  425. data/lib/ronin/templates.rb +0 -21
  426. data/lib/ronin/ui/output/helpers.rb +0 -296
  427. data/lib/ronin/ui/output/output.rb +0 -146
  428. data/lib/ronin/ui/output/terminal/color.rb +0 -124
  429. data/lib/ronin/ui/output/terminal/raw.rb +0 -103
  430. data/lib/ronin/ui/output/terminal.rb +0 -21
  431. data/lib/ronin/ui/output.rb +0 -21
  432. data/lib/ronin/ui/shell.rb +0 -286
  433. data/lib/ronin/wordlist.rb +0 -287
  434. data/spec/binary/hexdump/helpers/hexdumps/ascii.bin +0 -0
  435. data/spec/binary/hexdump/helpers/hexdumps/hexdump_decimal_shorts.txt +0 -17
  436. data/spec/binary/hexdump/helpers/hexdumps/hexdump_hex_bytes.txt +0 -17
  437. data/spec/binary/hexdump/helpers/hexdumps/hexdump_hex_shorts.txt +0 -17
  438. data/spec/binary/hexdump/helpers/hexdumps/hexdump_octal_bytes.txt +0 -17
  439. data/spec/binary/hexdump/helpers/hexdumps/hexdump_octal_shorts.txt +0 -17
  440. data/spec/binary/hexdump/helpers/hexdumps/hexdump_repeated.txt +0 -6
  441. data/spec/binary/hexdump/helpers/hexdumps/od_decimal_bytes.txt +0 -17
  442. data/spec/binary/hexdump/helpers/hexdumps/od_decimal_ints.txt +0 -17
  443. data/spec/binary/hexdump/helpers/hexdumps/od_decimal_quads.txt +0 -17
  444. data/spec/binary/hexdump/helpers/hexdumps/od_decimal_shorts.txt +0 -17
  445. data/spec/binary/hexdump/helpers/hexdumps/od_doubles.txt +0 -17
  446. data/spec/binary/hexdump/helpers/hexdumps/od_floats.txt +0 -17
  447. data/spec/binary/hexdump/helpers/hexdumps/od_hex_bytes.txt +0 -17
  448. data/spec/binary/hexdump/helpers/hexdumps/od_hex_ints.txt +0 -17
  449. data/spec/binary/hexdump/helpers/hexdumps/od_hex_quads.txt +0 -17
  450. data/spec/binary/hexdump/helpers/hexdumps/od_hex_shorts.txt +0 -17
  451. data/spec/binary/hexdump/helpers/hexdumps/od_named_chars.txt +0 -17
  452. data/spec/binary/hexdump/helpers/hexdumps/od_octal_bytes.txt +0 -17
  453. data/spec/binary/hexdump/helpers/hexdumps/od_octal_ints.txt +0 -17
  454. data/spec/binary/hexdump/helpers/hexdumps/od_octal_quads.txt +0 -17
  455. data/spec/binary/hexdump/helpers/hexdumps/od_octal_shorts.txt +0 -17
  456. data/spec/binary/hexdump/helpers/hexdumps/od_repeated.txt +0 -6
  457. data/spec/binary/hexdump/helpers/hexdumps/repeated.bin +0 -1
  458. data/spec/binary/hexdump/helpers/hexdumps.rb +0 -13
  459. data/spec/binary/hexdump/parser_spec.rb +0 -302
  460. data/spec/binary/struct_spec.rb +0 -496
  461. data/spec/binary/template_spec.rb +0 -414
  462. data/spec/extensions/enumerable_spec.rb +0 -24
  463. data/spec/extensions/file_spec.rb +0 -63
  464. data/spec/extensions/ip_addr_spec.rb +0 -203
  465. data/spec/extensions/kernel_spec.rb +0 -30
  466. data/spec/extensions/regexp_spec.rb +0 -482
  467. data/spec/extensions/resolv_spec.rb +0 -18
  468. data/spec/extensions/string_spec.rb +0 -179
  469. data/spec/formatting/binary/array_spec.rb +0 -26
  470. data/spec/formatting/binary/base64_spec.rb +0 -50
  471. data/spec/formatting/binary/float_spec.rb +0 -34
  472. data/spec/formatting/binary/integer_spec.rb +0 -166
  473. data/spec/formatting/binary/string_spec.rb +0 -197
  474. data/spec/formatting/digest/string_spec.rb +0 -82
  475. data/spec/formatting/html/integer_spec.rb +0 -66
  476. data/spec/formatting/html/string_spec.rb +0 -103
  477. data/spec/formatting/http/integer_spec.rb +0 -42
  478. data/spec/formatting/http/string_spec.rb +0 -76
  479. data/spec/formatting/sql/string_spec.rb +0 -75
  480. data/spec/formatting/text/array_spec.rb +0 -105
  481. data/spec/formatting/text/string_spec.rb +0 -162
  482. data/spec/fuzzing/extensions/string_spec.rb +0 -87
  483. data/spec/fuzzing/fuzzer_spec.rb +0 -109
  484. data/spec/fuzzing/fuzzing_spec.rb +0 -24
  485. data/spec/fuzzing/mutator_spec.rb +0 -112
  486. data/spec/fuzzing/repeater_spec.rb +0 -57
  487. data/spec/fuzzing/template_spec.rb +0 -54
  488. data/spec/mixin_spec.rb +0 -53
  489. data/spec/network/dns_spec.rb +0 -201
  490. data/spec/network/ftp_spec.rb +0 -81
  491. data/spec/network/http/http_spec.rb +0 -466
  492. data/spec/network/http/proxy_spec.rb +0 -148
  493. data/spec/network/network_spec.rb +0 -8
  494. data/spec/network/proxy_spec.rb +0 -121
  495. data/spec/network/shared/unix_server.rb +0 -31
  496. data/spec/network/smtp/email_spec.rb +0 -100
  497. data/spec/network/ssl_spec.rb +0 -70
  498. data/spec/network/tcp/proxy_spec.rb +0 -116
  499. data/spec/network/tcp/tcp_spec.rb +0 -273
  500. data/spec/network/telnet_spec.rb +0 -67
  501. data/spec/network/udp/udp_spec.rb +0 -271
  502. data/spec/network/unix_spec.rb +0 -183
  503. data/spec/path_spec.rb +0 -86
  504. data/spec/spec_helper.rb +0 -9
  505. data/spec/support/inflector_spec.rb +0 -22
  506. data/spec/support_spec.rb +0 -8
  507. data/spec/templates/classes/example_erb.rb +0 -11
  508. data/spec/templates/classes/example_template.rb +0 -35
  509. data/spec/templates/erb_spec.rb +0 -21
  510. data/spec/templates/helpers/data/includes/_relative.erb +0 -1
  511. data/spec/templates/helpers/data/templates/example.erb +0 -1
  512. data/spec/templates/helpers/data.rb +0 -9
  513. data/spec/templates/template_spec.rb +0 -54
  514. data/spec/ui/classes/test_shell.rb +0 -22
  515. data/spec/ui/output_spec.rb +0 -32
  516. data/spec/ui/shell_spec.rb +0 -83
  517. data/spec/wordlist_spec.rb +0 -151
@@ -0,0 +1,522 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright (c) 2006-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
4
+ #
5
+ # Ronin Support is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as published
7
+ # by the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Ronin Support is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public License
16
+ # along with Ronin Support. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ require 'ronin/support/crypto/openssl'
20
+ require 'ronin/support/crypto/key/rsa'
21
+
22
+ module Ronin
23
+ module Support
24
+ module Crypto
25
+ #
26
+ # Represents a X509 or TLS certificate.
27
+ #
28
+ # @api public
29
+ #
30
+ # @since 1.0.0
31
+ #
32
+ class Cert < OpenSSL::X509::Certificate
33
+
34
+ #
35
+ # Represents the `Subject` and `Issuer` fields in a X509 Certificate.
36
+ #
37
+ # @api semipublic
38
+ #
39
+ class Name < OpenSSL::X509::Name
40
+
41
+ #
42
+ # Builds a X509 `Subject` or `Issuer` string.
43
+ #
44
+ # @param [String, nil] common_name
45
+ # The "common name" for the cert (ex: `github.com`).
46
+ #
47
+ # @param [String, nil] organizational_unit
48
+ # The organizational unit for the cert.
49
+ #
50
+ # @param [String, nil] organization
51
+ # The organization name for the cert (ex: `GitHub, Inc.`).
52
+ #
53
+ # @param [String, nil] locality
54
+ # The locality or city for the cert (ex: `San Francisco`).
55
+ #
56
+ # @param [String, nil] state
57
+ # The state for the cert (ex: `Californa`).
58
+ #
59
+ # @param [String, nil] province
60
+ # The province for the cert.
61
+ #
62
+ # @param [String, nil] country
63
+ # The country for the cert (ex: `US`).
64
+ #
65
+ # @return [Name]
66
+ # The populated name.
67
+ #
68
+ def self.build(common_name: nil, organizational_unit: nil, organization: nil, locality: nil, state: nil, province: nil, country: nil)
69
+ name = new()
70
+ name.add_entry("CN",common_name) if common_name
71
+ name.add_entry("OU",organizational_unit) if organizational_unit
72
+ name.add_entry("O",organization) if organization
73
+ name.add_entry("L",locality) if locality
74
+ name.add_entry("ST",state || province) if (state || province)
75
+ name.add_entry("C",country) if country
76
+
77
+ return name
78
+ end
79
+
80
+ #
81
+ # The parsed entries in the name.
82
+ #
83
+ # @return [Hash{String => String}]
84
+ #
85
+ def entries
86
+ @entries ||= Hash[to_a.map { |(oid,value,type)|
87
+ [oid, value]
88
+ }]
89
+ end
90
+
91
+ alias to_h entries
92
+
93
+ #
94
+ # Finds the entry with the given OID name.
95
+ #
96
+ # @param [String] oid
97
+ #
98
+ # @return [String, nil]
99
+ #
100
+ def [](oid)
101
+ entries[oid]
102
+ end
103
+
104
+ #
105
+ # The common name (`CN`) entry.
106
+ #
107
+ # @return [String, nil]
108
+ #
109
+ def common_name
110
+ self['CN']
111
+ end
112
+
113
+ #
114
+ # The organization (`O`) entry.
115
+ #
116
+ # @return [String, nil]
117
+ #
118
+ def organization
119
+ self['O']
120
+ end
121
+
122
+ #
123
+ # The organizational unit (`OU`) entry.
124
+ #
125
+ # @return [String, nil]
126
+ #
127
+ def organizational_unit
128
+ self['OU']
129
+ end
130
+
131
+ #
132
+ # The locality (`L`) entry.
133
+ #
134
+ # @return [String, nil]
135
+ #
136
+ def locality
137
+ self['L']
138
+ end
139
+
140
+ #
141
+ # The state or province (`ST`) entry.
142
+ #
143
+ # @return [String, nil]
144
+ #
145
+ def state
146
+ self['ST']
147
+ end
148
+
149
+ alias province state
150
+
151
+ #
152
+ # The country (`C`) entry.
153
+ #
154
+ # @return [String, nil]
155
+ #
156
+ def country
157
+ self['C']
158
+ end
159
+
160
+ end
161
+
162
+ #
163
+ # Coerces a value into a {Name} object.
164
+ #
165
+ # @param [String, Hash, OpenSSL::X509::Name] name
166
+ # The name value to coerce.
167
+ #
168
+ # @return [Cert::Name]
169
+ # The name object.
170
+ #
171
+ # @api semipublic
172
+ #
173
+ def self.Name(name)
174
+ case name
175
+ when String then Name.parse(name)
176
+ when Hash then Name.build(**name)
177
+ when OpenSSL::X509::Name
178
+ new_name = Name.allocate
179
+ new_name.send(:initialize_copy,name)
180
+ new_name
181
+ else
182
+ raise(ArgumentError,"value must be either a String, Hash, or a OpenSSL::X509::Name object: #{name.inspect}")
183
+ end
184
+ end
185
+
186
+ #
187
+ # Parses the PEM encoded certificate string.
188
+ #
189
+ # @param [String] string
190
+ # The certificate string.
191
+ #
192
+ # @return [Cert]
193
+ # The parsed certificate.
194
+ #
195
+ def self.parse(string)
196
+ new(string)
197
+ end
198
+
199
+ #
200
+ # Parses the PEM encoded certificate.
201
+ #
202
+ # @param [String] buffer
203
+ # The String containing the certificate.
204
+ #
205
+ # @return [Cert]
206
+ # The parsed certificate.
207
+ #
208
+ def self.load(buffer)
209
+ new(buffer)
210
+ end
211
+
212
+ #
213
+ # Loads the certificate from the file.
214
+ #
215
+ # @param [String] path
216
+ # The path to the file.
217
+ #
218
+ # @return [Cert]
219
+ # The loaded certificate.
220
+ #
221
+ def self.load_file(path)
222
+ new(File.read(path))
223
+ end
224
+
225
+ # One year in seconds
226
+ ONE_YEAR = 60 * 60 * 24 * 365
227
+
228
+ #
229
+ # Generates and signs a new certificate.
230
+ #
231
+ # @param [Integer] version
232
+ # The version of the encoded certificate.
233
+ # See [RFC 5280](https://datatracker.ietf.org/doc/html/rfc5280).
234
+ #
235
+ # @param [Integer] serial
236
+ # The certificate serial number.
237
+ #
238
+ # @param [String, Hash{Symbol => String,nil}, Name, nil] subject
239
+ # The subject field for the certificate. If a `Hash` is given it will
240
+ # be passed to {Name.build}.
241
+ #
242
+ # @param [Time] not_before
243
+ # Beginning time when the certificate is valid.
244
+ #
245
+ # @param [Time] not_after
246
+ # When the certificate expires and is no longer valid.
247
+ #
248
+ # @param [Hash{String => Object}] extensions
249
+ # Additional extensions to add to the new certificate.
250
+ #
251
+ # @param [Key::RSA] key
252
+ # The public/private key pair used with the certificate.
253
+ #
254
+ # @param [Key::RSA, nil] ca_key
255
+ # The optional Certificate Authority (CA) key to use to sign the new
256
+ # certificate.
257
+ #
258
+ # @param [Cert, nil] ca_cert
259
+ # The optional Certificate Authority (CA) certificate to attach to the
260
+ # new certificate.
261
+ #
262
+ # @param [Symbol] signing_hash
263
+ # The hashing algorithm to use to sign the new certificate.
264
+ #
265
+ # @return [Cert]
266
+ # The newly generated and signed certificate.
267
+ #
268
+ # @example Generate a self-signed certificate for `localhost`:
269
+ # key = Ronin::Support::Crypto::Key::RSA.random
270
+ # cert = Ronin::Support::Crypto::Cert.generate(
271
+ # key: key,
272
+ # subject: {
273
+ # common_name: 'localhost',
274
+ # organization: 'Test Co..',
275
+ # organizational_unit: 'Test Dept',
276
+ # locality: 'Test City',
277
+ # state: 'XX',
278
+ # country: 'US'
279
+ # },
280
+ # extensions: {
281
+ # 'subjectAltName' => 'DNS: localhost, IP: 127.0.0.1'
282
+ # }
283
+ # )
284
+ # key.save('cert.key')
285
+ # cert.save('cert.pem')
286
+ #
287
+ # @example Generate a CA certificate:
288
+ # ca_key = Ronin::Support::Crypto::Key::RSA.random
289
+ # ca_cert = Ronin::Support::Crypto::Cert.generate(
290
+ # key: ca_key,
291
+ # subject: {
292
+ # common_name: 'Test CA',
293
+ # organization: 'Test CA, Inc..',
294
+ # organizational_unit: 'Test Dept',
295
+ # locality: 'Test City',
296
+ # state: 'XX',
297
+ # country: 'US'
298
+ # },
299
+ # extensions: {
300
+ # 'basicConstraints' => ['CA:TRUE', true]
301
+ # }
302
+ # )
303
+ # key.save('ca.key')
304
+ # cert.save('ca.pem')
305
+ #
306
+ # @example Generate a sub-certificate from a CA certificate:
307
+ # key = Ronin::Support::Crypto::Key::RSA.random
308
+ # cert = Ronin::Support::Crypto::Cert.generate(
309
+ # key: key,
310
+ # ca_key: ca_key,
311
+ # ca_cert: ca_cert,
312
+ # subject: {
313
+ # common_name: 'test.com',
314
+ # organization: 'Test Co..',
315
+ # organizational_unit: 'Test Dept',
316
+ # locality: 'Test City',
317
+ # state: 'XX',
318
+ # country: 'US'
319
+ # },
320
+ # extensions: {
321
+ # 'subjectAltName' => 'DNS: *.test.com',
322
+ # 'basicConstraints' => ['CA:FALSE', true]
323
+ # }
324
+ # )
325
+ # key.save('cert.key')
326
+ # cert.save('cert.pem')
327
+ #
328
+ def self.generate(version: 2,
329
+ serial: 0,
330
+ not_before: Time.now,
331
+ not_after: not_before+ONE_YEAR,
332
+ subject: nil,
333
+ extensions: nil,
334
+ # signing arguments
335
+ key: ,
336
+ ca_cert: nil,
337
+ ca_key: nil,
338
+ signing_hash: :sha256)
339
+ cert = new()
340
+ cert.version = version
341
+ cert.serial = if ca_cert then ca_cert.serial+1
342
+ else serial
343
+ end
344
+
345
+ cert.not_before = not_before
346
+ cert.not_after = not_after
347
+ cert.public_key = key.public_key
348
+ cert.subject = Name(subject) if subject
349
+ cert.issuer = if ca_cert then ca_cert.subject
350
+ else cert.subject
351
+ end
352
+
353
+ if extensions
354
+ extension_factory = OpenSSL::X509::ExtensionFactory.new()
355
+ extension_factory.subject_certificate = cert
356
+ extension_factory.issuer_certificate = if ca_cert then ca_cert
357
+ else cert
358
+ end
359
+
360
+ extensions.each do |name,(value,critical)|
361
+ ext = extension_factory.create_extension(name,value,critical)
362
+ cert.add_extension(ext)
363
+ end
364
+ end
365
+
366
+ signing_key = if ca_key then ca_key
367
+ else key
368
+ end
369
+ signing_digest = OpenSSL::Digest.const_get(signing_hash.upcase).new
370
+
371
+ cert.sign(signing_key,signing_digest)
372
+ return cert
373
+ end
374
+
375
+ #
376
+ # The issuer of the certificate.
377
+ #
378
+ # @return [Name, nil]
379
+ #
380
+ def issuer
381
+ @issuer ||= if (issuer = super)
382
+ Cert::Name(issuer)
383
+ end
384
+ end
385
+
386
+ #
387
+ # The subject of the certificate.
388
+ #
389
+ # @return [Name, nil]
390
+ #
391
+ def subject
392
+ @subject ||= if (subject = super)
393
+ Cert::Name(subject)
394
+ end
395
+ end
396
+
397
+ #
398
+ # The subjects common name (`CN`) entry.
399
+ #
400
+ # @return [String, nil]
401
+ #
402
+ def common_name
403
+ if (subject = self.subject)
404
+ subject.common_name
405
+ end
406
+ end
407
+
408
+ #
409
+ # The extension OID names.
410
+ #
411
+ # @return [Array<String>]
412
+ #
413
+ def extension_names
414
+ extensions.map(&:oid)
415
+ end
416
+
417
+ #
418
+ # Converts the certificate's extensions into a Hash.
419
+ #
420
+ # @return [Hash{String => OpenSSL::X509::Extension}]
421
+ # The Hash of extension OID names and extension objects.
422
+ #
423
+ def extensions_hash
424
+ Hash[extensions.map { |ext| [ext.oid, ext] }]
425
+ end
426
+
427
+ #
428
+ # Gets the value for the extension with the matching OID.
429
+ #
430
+ # @param [String] oid
431
+ # The OID to search for.
432
+ #
433
+ # @return [String, nil]
434
+ # The value of the matching extension.
435
+ #
436
+ def extension_value(oid)
437
+ if (ext = find_extension(oid))
438
+ ext.value
439
+ end
440
+ end
441
+
442
+ #
443
+ # Retrieves the `subjectAltName` extension and parses it's contents.
444
+ #
445
+ # @return [String, nil]
446
+ # The `subjectAltName` value or `nil` if the certificate does not
447
+ # have the extension.
448
+ #
449
+ def subject_alt_name
450
+ extension_value('subjectAltName')
451
+ end
452
+
453
+ #
454
+ # Retrieves the `subjectAltName` extension and parses it's value.
455
+ #
456
+ # @return [Array<String>, nil]
457
+ # The parsed `subjectAltName` or `nil` if the certificate does not
458
+ # have the extension.
459
+ #
460
+ def subject_alt_names
461
+ if (value = subject_alt_name)
462
+ value.split(', ').map do |name|
463
+ name.split(':',2).last
464
+ end
465
+ end
466
+ end
467
+
468
+ #
469
+ # Saves the certificate to the given path.
470
+ #
471
+ # @param [String] path
472
+ # The path to write the exported certificate to.
473
+ #
474
+ # @param [:pem, :der] encoding
475
+ # The desired encoding of the exported key.
476
+ # * `:pem` - PEM encoding.
477
+ # * `:der` - DER encoding.
478
+ #
479
+ # @raise [ArgumentError]
480
+ # The `endcoding:` value must be either `:pem` or `:der`.
481
+ #
482
+ def save(path, encoding: :pem)
483
+ exported = case encoding
484
+ when :pem then to_pem
485
+ when :der then to_der
486
+ else
487
+ raise(ArgumentError,"encoding: keyword argument (#{encoding.inspect}) must be either :pem or :der")
488
+ end
489
+
490
+ File.write(path,exported)
491
+ end
492
+
493
+ end
494
+
495
+ #
496
+ # Coerces a value into a {Cert} object.
497
+ #
498
+ # @param [String, OpenSSL::X509::Certificate] cert
499
+ # The certificate String or `OpenSSL::X509::Certificate` value.
500
+ #
501
+ # @return [Cert]
502
+ # The coerced certificate.
503
+ #
504
+ # @raise [ArgumentError]
505
+ # The certificate value was not a String or a `OpenSSL::X509::Certificate` object.
506
+ #
507
+ # @api semipublic
508
+ #
509
+ def self.Cert(cert)
510
+ case cert
511
+ when String then Cert.parse(cert)
512
+ when OpenSSL::X509::Certificate
513
+ new_cert = Cert.allocate
514
+ new_cert.send(:initialize_copy,cert)
515
+ new_cert
516
+ else
517
+ raise(ArgumentError,"value must be either a String or a OpenSSL::X509::Certificate object: #{cert.inspect}")
518
+ end
519
+ end
520
+ end
521
+ end
522
+ end
@@ -0,0 +1,204 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright (c) 2006-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
4
+ #
5
+ # Ronin Support is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as published
7
+ # by the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Ronin Support is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public License
16
+ # along with Ronin Support. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ require 'ronin/support/crypto/openssl'
20
+ require 'ronin/support/crypto/cert'
21
+
22
+ module Ronin
23
+ module Support
24
+ module Crypto
25
+ #
26
+ # Represents a X509 or TLS certificate chain.
27
+ #
28
+ # @api public
29
+ #
30
+ # @since 1.0.0
31
+ #
32
+ class CertChain
33
+
34
+ include Enumerable
35
+
36
+ # The certificates in the certificate chain.
37
+ #
38
+ # @return [Array<Cert>]
39
+ attr_reader :certs
40
+
41
+ #
42
+ # The certificates in the certificate chain.
43
+ #
44
+ # @param [Array<Cert>] certs
45
+ # The certificates that make up the certificate chain.
46
+ #
47
+ def initialize(certs)
48
+ @certs = certs
49
+ end
50
+
51
+ #
52
+ # Parses a certificate chain.
53
+ #
54
+ # @param [String] string
55
+ # The string to parse.
56
+ #
57
+ # @return [CertChain]
58
+ # The parsed certificate chain.
59
+ #
60
+ def self.parse(string)
61
+ cert_buffer = String.new
62
+ certs = []
63
+
64
+ string.each_line do |line|
65
+ cert_buffer << line
66
+
67
+ if line.chomp == '-----END CERTIFICATE-----'
68
+ certs << Cert.parse(cert_buffer)
69
+ cert_buffer.clear
70
+ end
71
+ end
72
+
73
+ return new(certs)
74
+ end
75
+
76
+ #
77
+ # Alias for {parse}.
78
+ #
79
+ # @param [String] string
80
+ # The string to parse.
81
+ #
82
+ # @return [CertChain]
83
+ # The parsed certificate chain.
84
+ #
85
+ # @see parse
86
+ #
87
+ def self.load(string)
88
+ parse(string)
89
+ end
90
+
91
+ #
92
+ # Reads and parses the certificate chain from a file.
93
+ #
94
+ # @param [String] path
95
+ # The path to the file to parse.
96
+ #
97
+ # @return [CertChain]
98
+ # The parsed certificate chain.
99
+ #
100
+ def self.load_file(path)
101
+ parse(File.read(path))
102
+ end
103
+
104
+ #
105
+ # Enumerates over the certificates in the certificate chain.
106
+ #
107
+ # @yield [cert]
108
+ # If a block is given, it will be passed each certificate in the
109
+ # certificate chain.
110
+ #
111
+ # @yieldparam [Cert] cert
112
+ # A parsed certificate object in the certificate chain.
113
+ #
114
+ # @return [Enumerator]
115
+ # If no block is given an Enumerator object will be returned.
116
+ #
117
+ def each(&block)
118
+ @certs.each(&block)
119
+ end
120
+
121
+ #
122
+ # Accesses one or more certificates at the index or range/length.
123
+ #
124
+ # @param [Integer, Range<Integer,Integer>] index_or_range
125
+ # The index or range of indices.
126
+ #
127
+ # @param [Integer, nil] length
128
+ # Optional length.
129
+ #
130
+ # @return [Cert, Array<Cert>, nil]
131
+ # The certificate(s) at the index or range of indices.
132
+ #
133
+ def [](index_or_range,length=nil)
134
+ @certs[index_or_range,*length]
135
+ end
136
+
137
+ #
138
+ # The leaf certificate.
139
+ #
140
+ # @return [Cert]
141
+ # The last certificate in the certiificate chain.
142
+ #
143
+ def leaf
144
+ @certs.first
145
+ end
146
+
147
+ #
148
+ # The issuer certificate.
149
+ #
150
+ # @return [Cert]
151
+ # The second-to-last certificate in the certificate chain.
152
+ #
153
+ def issuer
154
+ if @certs.length == 1
155
+ @certs[0]
156
+ else
157
+ @certs[1]
158
+ end
159
+ end
160
+
161
+ #
162
+ # The intermediary certificates.
163
+ #
164
+ # @return [Array<Cert>]
165
+ # The certificates between the {#root} and {#leaf} certificates.
166
+ #
167
+ def intermediates
168
+ @certs[1..-2]
169
+ end
170
+
171
+ #
172
+ # The root certificate.
173
+ #
174
+ # @return [Cert]
175
+ # The first certificate in the certificate chain.
176
+ #
177
+ def root
178
+ @certs.last
179
+ end
180
+
181
+ #
182
+ # The number of certificates in the certificate chain.
183
+ #
184
+ # @return [Integer]
185
+ #
186
+ def length
187
+ @certs.length
188
+ end
189
+
190
+ #
191
+ # Converts the certificate chain to a PEM encoded certificate chain.
192
+ #
193
+ # @return [String]
194
+ #
195
+ def to_pem
196
+ @certs.map(&:to_pem).join
197
+ end
198
+
199
+ alias to_s to_pem
200
+
201
+ end
202
+ end
203
+ end
204
+ end