digest 3.1.0-java

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a175b98d1a4a7d66bac0148da4d3516a70e125646e9b867bacd154fb05e4b4ef
4
+ data.tar.gz: 938ffb653c44c018d9f7c74703f5ee8a885e1f7dbf94270969e2c4c3ac959ba0
5
+ SHA512:
6
+ metadata.gz: 610b1874d03ed4c45c7a0bc5706506021c8676393e70db96c0bc5e1f46c8f3fb1d1a99a4828ecbd32fea9459b52e4aba52113c0df09926c52b66c4c60015ffd5
7
+ data.tar.gz: 99d7714c5cf4f4e08331b920bc70efec0413384fb1e930125d238293d104c90421d4dbb12a12eb36026c5a10dc1bc40573930e761948ce7b9e09e7b0a94bdf75
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions
5
+ are met:
6
+ 1. Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ 2. Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+
12
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22
+ SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # Digest
2
+
3
+ ![CI](https://github.com/ruby/digest/workflows/CI/badge.svg?branch=master&event=push)
4
+
5
+ This module provides a framework for message digest libraries.
6
+
7
+ You may want to look at OpenSSL::Digest as it supports more algorithms.
8
+
9
+ A cryptographic hash function is a procedure that takes data and returns a fixed bit string: the hash value, also known as _digest_. Hash functions are also called one-way functions, it is easy to compute a digest from a message, but it is infeasible to generate a message from a digest.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'digest'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install digest
26
+
27
+ ## Usage
28
+
29
+ ```ruby
30
+ require 'digest'
31
+
32
+ # Compute a complete digest
33
+ Digest::SHA256.digest 'message' #=> "\xABS\n\x13\xE4Y..."
34
+
35
+ sha256 = Digest::SHA256.new
36
+ sha256.digest 'message' #=> "\xABS\n\x13\xE4Y..."
37
+
38
+ # Other encoding formats
39
+ Digest::SHA256.hexdigest 'message' #=> "ab530a13e459..."
40
+ Digest::SHA256.base64digest 'message' #=> "q1MKE+RZFJgr..."
41
+
42
+ # Compute digest by chunks
43
+ md5 = Digest::MD5.new
44
+ md5.update 'message1'
45
+ md5 << 'message2' # << is an alias for update
46
+
47
+ md5.hexdigest #=> "94af09c09bb9..."
48
+
49
+ # Compute digest for a file
50
+ sha256 = Digest::SHA256.file 'testfile'
51
+ sha256.hexdigest
52
+ ```
53
+
54
+ Additionally digests can be encoded in "bubble babble" format as a sequence of consonants and vowels which is more recognizable and comparable than a hexadecimal digest.
55
+
56
+ ```ruby
57
+ require 'digest/bubblebabble'
58
+
59
+ Digest::SHA256.bubblebabble 'message' #=> "xopoh-fedac-fenyh-..."
60
+ ```
61
+
62
+ See the bubble babble specification at http://web.mit.edu/kenta/www/one/bubblebabble/spec/jrtrjwzi/draft-huima-01.txt.
63
+
64
+ ## Digest algorithms
65
+
66
+ Different digest algorithms (or hash functions) are available:
67
+
68
+ ```
69
+ MD5::
70
+ See RFC 1321 The MD5 Message-Digest Algorithm
71
+ RIPEMD-160::
72
+ As Digest::RMD160.
73
+ See http://homes.esat.kuleuven.be/~bosselae/ripemd160.html.
74
+ SHA1::
75
+ See FIPS 180 Secure Hash Standard.
76
+ SHA2 family::
77
+ See FIPS 180 Secure Hash Standard which defines the following algorithms:
78
+ SHA512
79
+ SHA384
80
+ SHA256
81
+ ```
82
+
83
+ The latest versions of the FIPS publications can be found here: http://csrc.nist.gov/publications/PubsFIPS.html.
84
+
85
+ ## Development
86
+
87
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
88
+
89
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
90
+
91
+ ## Contributing
92
+
93
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/digest.
94
+
95
+ ## License
96
+
97
+ The gem is available as open source under the terms of the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause).
@@ -0,0 +1,119 @@
1
+ /*
2
+ **** BEGIN LICENSE BLOCK *****
3
+ * BSD 2-Clause License
4
+ *
5
+ * Copyright (c) 2010, Charles Oliver Nutter <headius@headius.com>
6
+ * All rights reserved.
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions are met:
10
+ *
11
+ * 1. Redistributions of source code must retain the above copyright notice, this
12
+ * list of conditions and the following disclaimer.
13
+ *
14
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
15
+ * this list of conditions and the following disclaimer in the documentation
16
+ * and/or other materials provided with the distribution.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ ***** END LICENSE BLOCK *****/
29
+
30
+ package org.jruby.ext.digest;
31
+
32
+ import org.jruby.Ruby;
33
+ import org.jruby.runtime.load.Library;
34
+ import org.jruby.util.ByteList;
35
+
36
+ import java.io.IOException;
37
+
38
+ public class BubbleBabble implements Library {
39
+
40
+ public void load(final Ruby runtime, boolean wrap) throws IOException {
41
+ RubyDigest.createDigestBubbleBabble(runtime);
42
+ }
43
+
44
+ /**
45
+ * Ported from OpenSSH (https://github.com/openssh/openssh-portable/blob/957fbceb0f3166e41b76fdb54075ab3b9cc84cba/sshkey.c#L942-L987)
46
+ *
47
+ * OpenSSH License Notice
48
+ *
49
+ * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
50
+ * Copyright (c) 2008 Alexander von Gernler. All rights reserved.
51
+ * Copyright (c) 2010,2011 Damien Miller. All rights reserved.
52
+ *
53
+ * Redistribution and use in source and binary forms, with or without
54
+ * modification, are permitted provided that the following conditions
55
+ * are met:
56
+ * 1. Redistributions of source code must retain the above copyright
57
+ * notice, this list of conditions and the following disclaimer.
58
+ * 2. Redistributions in binary form must reproduce the above copyright
59
+ * notice, this list of conditions and the following disclaimer in the
60
+ * documentation and/or other materials provided with the distribution.
61
+ *
62
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
63
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
64
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
65
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
66
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
67
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
68
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
69
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
71
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72
+ */
73
+ public static ByteList bubblebabble(byte[] message, int begin, int length) {
74
+ char[] vowels = new char[]{'a', 'e', 'i', 'o', 'u', 'y'};
75
+ char[] consonants = new char[]{'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
76
+ 'n', 'p', 'r', 's', 't', 'v', 'z', 'x'};
77
+
78
+ long seed = 1;
79
+
80
+ ByteList retval = new ByteList();
81
+
82
+ int rounds = (length / 2) + 1;
83
+ retval.append('x');
84
+ for (int i = 0; i < rounds; i++) {
85
+ int idx0, idx1, idx2, idx3, idx4;
86
+
87
+ if ((i + 1 < rounds) || (length % 2 != 0)) {
88
+ long b = message[begin + 2 * i] & 0xFF;
89
+ idx0 = (int) ((((b >> 6) & 3) + seed) % 6) & 0xFFFFFFFF;
90
+ idx1 = (int) (((b) >> 2) & 15) & 0xFFFFFFFF;
91
+ idx2 = (int) (((b & 3) + (seed / 6)) % 6) & 0xFFFFFFFF;
92
+ retval.append(vowels[idx0]);
93
+ retval.append(consonants[idx1]);
94
+ retval.append(vowels[idx2]);
95
+ if ((i + 1) < rounds) {
96
+ long b2 = message[begin + (2 * i) + 1] & 0xFF;
97
+ idx3 = (int) ((b2 >> 4) & 15) & 0xFFFFFFFF;
98
+ idx4 = (int) ((b2) & 15) & 0xFFFFFFFF;
99
+ retval.append(consonants[idx3]);
100
+ retval.append('-');
101
+ retval.append(consonants[idx4]);
102
+ seed = ((seed * 5) +
103
+ ((b * 7) +
104
+ b2)) % 36;
105
+ }
106
+ } else {
107
+ idx0 = (int) (seed % 6) & 0xFFFFFFFF;
108
+ idx1 = 16;
109
+ idx2 = (int) (seed / 6) & 0xFFFFFFFF;
110
+ retval.append(vowels[idx0]);
111
+ retval.append(consonants[idx1]);
112
+ retval.append(vowels[idx2]);
113
+ }
114
+ }
115
+ retval.append('x');
116
+
117
+ return retval;
118
+ }
119
+ }
@@ -0,0 +1,44 @@
1
+ /*
2
+ **** BEGIN LICENSE BLOCK *****
3
+ * BSD 2-Clause License
4
+ *
5
+ * Copyright (C) 2006 Ola Bini <ola@ologix.com>
6
+ * All rights reserved.
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions are met:
10
+ *
11
+ * 1. Redistributions of source code must retain the above copyright notice, this
12
+ * list of conditions and the following disclaimer.
13
+ *
14
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
15
+ * this list of conditions and the following disclaimer in the documentation
16
+ * and/or other materials provided with the distribution.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ ***** END LICENSE BLOCK *****/
29
+
30
+ package org.jruby.ext.digest;
31
+
32
+ import java.io.IOException;
33
+
34
+ import org.jruby.Ruby;
35
+ import org.jruby.runtime.load.Library;
36
+
37
+ /**
38
+ * @author <a href="mailto:ola.bini@ki.se">Ola Bini</a>
39
+ */
40
+ public class DigestLibrary implements Library {
41
+ public void load(final Ruby runtime, boolean wrap) throws IOException {
42
+ org.jruby.ext.digest.RubyDigest.createDigest(runtime);
43
+ }
44
+ }// DigestLibrary
@@ -0,0 +1,41 @@
1
+ /*
2
+ **** BEGIN LICENSE BLOCK *****
3
+ * BSD 2-Clause License
4
+ *
5
+ * Copyright (c) 2010, Charles Oliver Nutter <headius@headius.com>
6
+ * All rights reserved.
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions are met:
10
+ *
11
+ * 1. Redistributions of source code must retain the above copyright notice, this
12
+ * list of conditions and the following disclaimer.
13
+ *
14
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
15
+ * this list of conditions and the following disclaimer in the documentation
16
+ * and/or other materials provided with the distribution.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ ***** END LICENSE BLOCK *****/
29
+
30
+ package org.jruby.ext.digest;
31
+
32
+ import java.io.IOException;
33
+ import org.jruby.Ruby;
34
+ import org.jruby.runtime.load.Library;
35
+
36
+ public class MD5 implements Library {
37
+
38
+ public void load(final Ruby runtime, boolean wrap) throws IOException {
39
+ org.jruby.ext.digest.RubyDigest.createDigestMD5(runtime);
40
+ }
41
+ }
@@ -0,0 +1,41 @@
1
+ /*
2
+ **** BEGIN LICENSE BLOCK *****
3
+ * BSD 2-Clause License
4
+ *
5
+ * Copyright (c) 2010, Charles Oliver Nutter <headius@headius.com>
6
+ * All rights reserved.
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions are met:
10
+ *
11
+ * 1. Redistributions of source code must retain the above copyright notice, this
12
+ * list of conditions and the following disclaimer.
13
+ *
14
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
15
+ * this list of conditions and the following disclaimer in the documentation
16
+ * and/or other materials provided with the distribution.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ ***** END LICENSE BLOCK *****/
29
+
30
+ package org.jruby.ext.digest;
31
+
32
+ import java.io.IOException;
33
+ import org.jruby.Ruby;
34
+ import org.jruby.runtime.load.Library;
35
+
36
+ public class RMD160 implements Library {
37
+
38
+ public void load(final Ruby runtime, boolean wrap) throws IOException {
39
+ org.jruby.ext.digest.RubyDigest.createDigestRMD160(runtime);
40
+ }
41
+ }
@@ -0,0 +1,498 @@
1
+ /*
2
+ **** BEGIN LICENSE BLOCK *****
3
+ * BSD 2-Clause License
4
+ *
5
+ * Copyright (C) 2006, 2007 Ola Bini <ola@ologix.com>
6
+ * Copyright (C) 2007 Nick Sieger <nicksieger@gmail.com>
7
+ * Copyright (C) 2008 Vladimir Sizikov <vsizikov@gmail.com>
8
+ * Copyright (C) 2009 Joseph LaFata <joe@quibb.org>
9
+ * All rights reserved.
10
+ *
11
+ * Redistribution and use in source and binary forms, with or without
12
+ * modification, are permitted provided that the following conditions are met:
13
+ *
14
+ * 1. Redistributions of source code must retain the above copyright notice, this
15
+ * list of conditions and the following disclaimer.
16
+ *
17
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
18
+ * this list of conditions and the following disclaimer in the documentation
19
+ * and/or other materials provided with the distribution.
20
+ *
21
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ ***** END LICENSE BLOCK *****/
32
+
33
+ package org.jruby.ext.digest;
34
+
35
+ import java.security.MessageDigest;
36
+ import java.security.NoSuchAlgorithmException;
37
+ import java.security.Provider;
38
+ import java.util.HashMap;
39
+ import java.util.Map;
40
+
41
+ import org.jcodings.specific.USASCIIEncoding;
42
+ import org.jruby.Ruby;
43
+ import org.jruby.RubyClass;
44
+ import org.jruby.RubyFixnum;
45
+ import org.jruby.RubyModule;
46
+ import org.jruby.RubyObject;
47
+ import org.jruby.RubyString;
48
+
49
+ import org.jruby.anno.JRubyClass;
50
+ import org.jruby.anno.JRubyMethod;
51
+ import org.jruby.anno.JRubyModule;
52
+ import org.jruby.exceptions.RaiseException;
53
+ import org.jruby.runtime.Block;
54
+ import org.jruby.runtime.ThreadContext;
55
+ import org.jruby.runtime.Visibility;
56
+ import org.jruby.runtime.builtin.IRubyObject;
57
+ import org.jruby.util.ArraySupport;
58
+ import org.jruby.util.ByteList;
59
+ import org.jruby.util.log.Logger;
60
+ import org.jruby.util.log.LoggerFactory;
61
+
62
+ /**
63
+ * @author <a href="mailto:ola.bini@ki.se">Ola Bini</a>
64
+ */
65
+ @JRubyModule(name="Digest")
66
+ public class RubyDigest {
67
+
68
+ private static final Map<String, MessageDigest> CLONEABLE_DIGESTS = new HashMap<String, MessageDigest>(8, 1);
69
+ static {
70
+ // standard digests from JCA specification; if we can retrieve and clone, save them
71
+ for (String name : new String[] {"MD2", "MD5", "SHA-1", "SHA-256", "SHA-384", "SHA-512"}) {
72
+ try {
73
+ MessageDigest digest = MessageDigest.getInstance(name);
74
+ digest.clone();
75
+ CLONEABLE_DIGESTS.put(name, digest);
76
+ }
77
+ catch (Exception e) {
78
+ logger().debug(name + " not clonable", e);
79
+ }
80
+ }
81
+ }
82
+
83
+ private static Logger logger() { return LoggerFactory.getLogger(RubyDigest.class); }
84
+
85
+ private static final String PROVIDER = "org.bouncycastle.jce.provider.BouncyCastleProvider";
86
+ private static Provider provider = null;
87
+
88
+ public static void createDigest(Ruby runtime) {
89
+ try {
90
+ provider = (Provider) Class.forName(PROVIDER).getConstructor().newInstance();
91
+ }
92
+ catch (Throwable t) { /* provider is not available */ }
93
+
94
+ RubyModule mDigest = runtime.defineModule("Digest");
95
+ mDigest.defineAnnotatedMethods(RubyDigest.class);
96
+ RubyModule mDigestInstance = mDigest.defineModuleUnder("Instance");
97
+ mDigestInstance.defineAnnotatedMethods(DigestInstance.class);
98
+ RubyClass cDigestClass = mDigest.defineClassUnder("Class", runtime.getObject(), DigestClass::new);
99
+ cDigestClass.defineAnnotatedMethods(DigestClass.class);
100
+ cDigestClass.includeModule(mDigestInstance);
101
+ RubyClass cDigestBase = mDigest.defineClassUnder("Base", cDigestClass, DigestBase::new);
102
+ cDigestBase.defineAnnotatedMethods(DigestBase.class);
103
+ }
104
+
105
+ private static MessageDigest createMessageDigest(final String name) throws NoSuchAlgorithmException {
106
+ MessageDigest cloneable = CLONEABLE_DIGESTS.get(name);
107
+ if (cloneable != null) {
108
+ try {
109
+ return (MessageDigest) cloneable.clone();
110
+ }
111
+ catch (CloneNotSupportedException e) {
112
+ // should never happen, since we tested it in static init
113
+ }
114
+ }
115
+
116
+ // fall back on JCA mechanisms for getting a digest
117
+ if (provider != null) {
118
+ try {
119
+ return MessageDigest.getInstance(name, provider);
120
+ }
121
+ catch (NoSuchAlgorithmException e) {
122
+ // bouncy castle doesn't support algorithm
123
+ }
124
+ }
125
+
126
+ // fall back to default JCA providers
127
+ return MessageDigest.getInstance(name);
128
+ }
129
+
130
+ private final static byte[] digits = {
131
+ '0', '1', '2', '3', '4', '5',
132
+ '6', '7', '8', '9', 'a', 'b',
133
+ 'c', 'd', 'e', 'f', 'g', 'h',
134
+ 'i', 'j', 'k', 'l', 'm', 'n',
135
+ 'o', 'p', 'q', 'r', 's', 't',
136
+ 'u', 'v', 'w', 'x', 'y', 'z'
137
+ };
138
+
139
+ private static ByteList toHex(byte[] val) {
140
+ ByteList byteList = new ByteList(val.length * 2);
141
+ for (int i = 0, j = val.length; i < j; i++) {
142
+ int b = val[i] & 0xFF;
143
+ byteList.append(digits[b >> 4]);
144
+ byteList.append(digits[b & 0xF]);
145
+ }
146
+ return byteList;
147
+ }
148
+
149
+ private static RubyString toHexString(Ruby runtime, byte[] val) {
150
+ return RubyString.newStringNoCopy(runtime, new ByteList(ByteList.plain(toHex(val)), USASCIIEncoding.INSTANCE));
151
+ }
152
+
153
+ @JRubyMethod(name = "hexencode", required = 1, meta = true)
154
+ public static RubyString hexencode(IRubyObject self, IRubyObject arg) {
155
+ return toHexString(self.getRuntime(), arg.convertToString().getBytes());
156
+ }
157
+
158
+ @JRubyMethod(name = "bubblebabble", required = 1, meta = true)
159
+ public static RubyString bubblebabble(IRubyObject recv, IRubyObject arg) {
160
+ final ByteList bytes = arg.convertToString().getByteList();
161
+ return RubyString.newString(recv.getRuntime(), BubbleBabble.bubblebabble(bytes.unsafeBytes(), bytes.begin(), bytes.length()));
162
+ }
163
+
164
+ private static class Metadata {
165
+
166
+ private final String name;
167
+ private final int blockLength;
168
+
169
+ Metadata(String name, int blockLength) {
170
+ this.name = name;
171
+ this.blockLength = blockLength;
172
+ }
173
+
174
+ String getName() {
175
+ return name;
176
+ }
177
+
178
+ int getBlockLength() {
179
+ return blockLength;
180
+ }
181
+ }
182
+
183
+
184
+ @JRubyClass(name="Digest::MD5", parent="Digest::Base")
185
+ public static class MD5 {}
186
+ @JRubyClass(name="Digest::RMD160", parent="Digest::Base")
187
+ public static class RMD160 {}
188
+ @JRubyClass(name="Digest::SHA1", parent="Digest::Base")
189
+ public static class SHA1 {}
190
+ @JRubyClass(name="Digest::SHA256", parent="Digest::Base")
191
+ public static class SHA256 {}
192
+ @JRubyClass(name="Digest::SHA384", parent="Digest::Base")
193
+ public static class SHA384 {}
194
+ @JRubyClass(name="Digest::SHA512", parent="Digest::Base")
195
+ public static class SHA512 {}
196
+
197
+ public static void createDigestMD5(Ruby runtime) {
198
+ runtime.getLoadService().require("digest");
199
+ RubyModule Digest = runtime.getModule("Digest");
200
+ RubyClass Base = Digest.getClass("Base");
201
+ RubyClass MD5 = Digest.defineClassUnder("MD5", Base, Base.getAllocator());
202
+ MD5.setInternalVariable("metadata", new Metadata("MD5", 64));
203
+ }
204
+
205
+ public static void createDigestRMD160(Ruby runtime) {
206
+ runtime.getLoadService().require("digest");
207
+ if(provider == null) {
208
+ throw runtime.newLoadError("RMD160 not supported without BouncyCastle");
209
+ }
210
+ RubyModule Digest = runtime.getModule("Digest");
211
+ RubyClass Base = Digest.getClass("Base");
212
+ RubyClass RMD160 = Digest.defineClassUnder("RMD160", Base, Base.getAllocator());
213
+ RMD160.setInternalVariable("metadata", new Metadata("RIPEMD160", 64));
214
+ }
215
+
216
+ public static void createDigestSHA1(Ruby runtime) {
217
+ runtime.getLoadService().require("digest");
218
+ RubyModule Digest = runtime.getModule("Digest");
219
+ RubyClass Base = Digest.getClass("Base");
220
+ RubyClass SHA1 = Digest.defineClassUnder("SHA1", Base, Base.getAllocator());
221
+ SHA1.setInternalVariable("metadata", new Metadata("SHA1", 64));
222
+ }
223
+
224
+ public static void createDigestSHA2(Ruby runtime) {
225
+ runtime.getLoadService().require("digest");
226
+ try {
227
+ createMessageDigest("SHA-256");
228
+ }
229
+ catch (NoSuchAlgorithmException e) {
230
+ RaiseException ex = runtime.newLoadError("SHA2 not supported");
231
+ ex.initCause(e);
232
+ throw ex;
233
+ }
234
+ final RubyModule Digest = runtime.getModule("Digest");
235
+ final RubyClass Base = Digest.getClass("Base");
236
+ RubyClass SHA256 = Digest.defineClassUnder("SHA256", Base, Base.getAllocator());
237
+ SHA256.setInternalVariable("metadata", new Metadata("SHA-256", 64));
238
+ RubyClass SHA384 = Digest.defineClassUnder("SHA384", Base, Base.getAllocator());
239
+ SHA384.setInternalVariable("metadata", new Metadata("SHA-384", 128));
240
+ RubyClass SHA512 = Digest.defineClassUnder("SHA512", Base, Base.getAllocator());
241
+ SHA512.setInternalVariable("metadata", new Metadata("SHA-512", 128));
242
+ }
243
+
244
+ public static void createDigestBubbleBabble(Ruby runtime) {
245
+ runtime.getLoadService().require("digest");
246
+ RubyModule Digest = runtime.getModule("Digest");
247
+ RubyClass Base = Digest.getClass("Base");
248
+ RubyClass MD5 = Digest.defineClassUnder("BubbleBabble", Base, Base.getAllocator());
249
+ MD5.setInternalVariable("metadata", new Metadata("BubbleBabble", 64));
250
+ }
251
+
252
+ @JRubyModule(name = "Digest::Instance")
253
+ public static class DigestInstance {
254
+
255
+ private static IRubyObject throwUnimplError(IRubyObject self, String name) {
256
+ throw self.getRuntime().newRuntimeError(String.format("%s does not implement %s()", self.getMetaClass().getRealClass().getName(), name));
257
+ }
258
+
259
+ /* instance methods that should be overridden */
260
+ @JRubyMethod(name = {"update", "<<"}, required = 1)
261
+ public static IRubyObject update(ThreadContext context, IRubyObject self, IRubyObject arg) {
262
+ return throwUnimplError(self, "update");
263
+ }
264
+
265
+ @JRubyMethod()
266
+ public static IRubyObject finish(ThreadContext context, IRubyObject self) {
267
+ return throwUnimplError(self, "finish");
268
+ }
269
+
270
+ @JRubyMethod()
271
+ public static IRubyObject reset(ThreadContext context, IRubyObject self) {
272
+ return throwUnimplError(self, "reset");
273
+ }
274
+
275
+ @JRubyMethod()
276
+ public static IRubyObject digest_length(ThreadContext context, IRubyObject self) {
277
+ return digest(context, self, null).convertToString().bytesize();
278
+ }
279
+
280
+ @JRubyMethod()
281
+ public static IRubyObject block_length(ThreadContext context, IRubyObject self) {
282
+ return throwUnimplError(self, "block_length");
283
+ }
284
+
285
+ /* instance methods that may be overridden */
286
+ @JRubyMethod(name = "==", required = 1)
287
+ public static IRubyObject op_equal(ThreadContext context, IRubyObject self, IRubyObject oth) {
288
+ if(oth.isNil()) return context.fals;
289
+
290
+ RubyString str1, str2;
291
+ RubyModule instance = (RubyModule)context.runtime.getModule("Digest").getConstantAt("Instance");
292
+ if (oth.getMetaClass().getRealClass().hasModuleInHierarchy(instance)) {
293
+ str1 = digest(context, self, null).convertToString();
294
+ str2 = digest(context, oth, null).convertToString();
295
+ } else {
296
+ str1 = to_s(context, self).convertToString();
297
+ str2 = oth.convertToString();
298
+ }
299
+ boolean ret = str1.bytesize().eql(str2.bytesize()) && (str1.eql(str2));
300
+ return ret ? context.tru : context.fals;
301
+ }
302
+
303
+ @JRubyMethod()
304
+ public static IRubyObject inspect(ThreadContext context, IRubyObject self) {
305
+ return RubyString.newStringNoCopy(self.getRuntime(), ByteList.plain("#<" + self.getMetaClass().getRealClass().getName() + ": " + hexdigest(context, self, null) + ">"));
306
+ }
307
+
308
+ /* instance methods that need not usually be overridden */
309
+ @JRubyMethod(name = "new")
310
+ public static IRubyObject newObject(ThreadContext context, IRubyObject self) {
311
+ return self.rbClone().callMethod(context, "reset");
312
+ }
313
+
314
+ @JRubyMethod(optional = 1)
315
+ public static IRubyObject digest(ThreadContext context, IRubyObject self, IRubyObject[] args) {
316
+ final IRubyObject value;
317
+ if (args != null && args.length > 0) {
318
+ self.callMethod(context, "reset");
319
+ self.callMethod(context, "update", args[0]);
320
+ value = self.callMethod(context, "finish");
321
+ self.callMethod(context, "reset");
322
+ } else {
323
+ IRubyObject clone = self.rbClone();
324
+ value = clone.callMethod(context, "finish");
325
+ clone.callMethod(context, "reset");
326
+ }
327
+ return value;
328
+ }
329
+
330
+ @JRubyMethod(name = "digest!")
331
+ public static IRubyObject digest_bang(ThreadContext context, IRubyObject self) {
332
+ IRubyObject value = self.callMethod(context, "finish");
333
+ self.callMethod(context, "reset");
334
+ return value;
335
+ }
336
+
337
+ @JRubyMethod(optional = 1)
338
+ public static IRubyObject hexdigest(ThreadContext context, IRubyObject self, IRubyObject[] args) {
339
+ return toHexString(context.runtime, digest(context, self, args).convertToString().getBytes());
340
+ }
341
+
342
+ @JRubyMethod(name = "hexdigest!")
343
+ public static IRubyObject hexdigest_bang(ThreadContext context, IRubyObject self) {
344
+ return toHexString(context.runtime, digest_bang(context, self).convertToString().getBytes());
345
+ }
346
+
347
+ @JRubyMethod(name = "bubblebabble", required = 1, optional = 1, meta = true)
348
+ public static IRubyObject bubblebabble(ThreadContext context, IRubyObject recv, IRubyObject[] args, Block unusedBlock) {
349
+ byte[] digest = recv.callMethod(context, "digest", args, Block.NULL_BLOCK).convertToString().getBytes();
350
+ return RubyString.newString(recv.getRuntime(), BubbleBabble.bubblebabble(digest, 0, digest.length));
351
+ }
352
+
353
+ @JRubyMethod()
354
+ public static IRubyObject to_s(ThreadContext context, IRubyObject self) {
355
+ return self.callMethod(context, "hexdigest");
356
+ }
357
+
358
+ @JRubyMethod(name = {"length", "size"})
359
+ public static IRubyObject length(ThreadContext context, IRubyObject self) {
360
+ return self.callMethod(context, "digest_length");
361
+ }
362
+ }
363
+
364
+
365
+ @JRubyClass(name="Digest::Class")
366
+ public static class DigestClass extends RubyObject {
367
+ public DigestClass(Ruby runtime, RubyClass type) {
368
+ super(runtime, type);
369
+ }
370
+
371
+ @JRubyMethod(name = "digest", required = 1, rest = true, meta = true)
372
+ public static IRubyObject s_digest(ThreadContext context, IRubyObject recv, IRubyObject[] args, Block unusedBlock) {
373
+ final Ruby runtime = context.runtime;
374
+ if (args.length < 1) {
375
+ throw runtime.newArgumentError("no data given");
376
+ }
377
+ RubyString str = args[0].convertToString();
378
+ args = ArraySupport.newCopy(args, 1, args.length - 1); // skip first arg
379
+ IRubyObject obj = ((RubyClass) recv).newInstance(context, args, Block.NULL_BLOCK);
380
+ return obj.callMethod(context, "digest", str);
381
+ }
382
+
383
+ @JRubyMethod(name = "hexdigest", required = 1, optional = 1, meta = true)
384
+ public static IRubyObject s_hexdigest(ThreadContext context, IRubyObject recv, IRubyObject[] args, Block unusedBlock) {
385
+ Ruby runtime = recv.getRuntime();
386
+ byte[] digest = recv.callMethod(context, "digest", args, Block.NULL_BLOCK).convertToString().getBytes();
387
+ return RubyDigest.toHexString(runtime, digest);
388
+ }
389
+
390
+ @JRubyMethod(name = "bubblebabble", required = 1, meta = true)
391
+ public static RubyString bubblebabble(IRubyObject recv, IRubyObject arg) {
392
+ byte[] digest = recv.callMethod(recv.getRuntime().getCurrentContext(), "digest", arg).convertToString().getBytes();
393
+ return RubyString.newString(recv.getRuntime(), BubbleBabble.bubblebabble(digest, 0, digest.length));
394
+ }
395
+ }
396
+
397
+
398
+ @JRubyClass(name="Digest::Base")
399
+ public static class DigestBase extends RubyObject {
400
+ private MessageDigest algo;
401
+ private int blockLength = 0;
402
+
403
+ public DigestBase(Ruby runtime, RubyClass type) {
404
+ super(runtime,type);
405
+
406
+ if(type == runtime.getModule("Digest").getClass("Base")) {
407
+ throw runtime.newNotImplementedError("Digest::Base is an abstract class");
408
+ }
409
+
410
+ Metadata metadata = getMetadata(type);
411
+ if(metadata == null) {
412
+ throw runtime.newNotImplementedError("the " + type + "() function is unimplemented on this machine");
413
+ }
414
+
415
+ try {
416
+ setAlgorithm(metadata);
417
+ } catch(NoSuchAlgorithmException e) {
418
+ throw runtime.newNotImplementedError("the " + type + "() function is unimplemented on this machine");
419
+ }
420
+
421
+ }
422
+
423
+ // if subclass extends particular digest we need to walk to find it...we should rearchitect digest to avoid walking type systems
424
+ private Metadata getMetadata(RubyModule type) {
425
+ for (RubyModule current = type; current != null; current = current.getSuperClass()) {
426
+ Metadata metadata = (Metadata) current.getInternalVariable("metadata");
427
+
428
+ if (metadata != null) return metadata;
429
+ }
430
+
431
+ return null;
432
+ }
433
+
434
+ @JRubyMethod(required = 1, visibility = Visibility.PRIVATE)
435
+ @Override
436
+ public IRubyObject initialize_copy(IRubyObject obj) {
437
+ if (this == obj) return this;
438
+
439
+ DigestBase from = (DigestBase) obj;
440
+ from.checkFrozen();
441
+
442
+ try {
443
+ this.algo = (MessageDigest) from.algo.clone();
444
+ }
445
+ catch (CloneNotSupportedException e) {
446
+ String name = from.algo.getAlgorithm();
447
+ throw getRuntime().newTypeError("Could not initialize copy of digest (" + name + ")");
448
+ }
449
+ return this;
450
+ }
451
+
452
+ @JRubyMethod(name = {"update", "<<"}, required = 1)
453
+ public IRubyObject update(IRubyObject obj) {
454
+ ByteList bytes = obj.convertToString().getByteList();
455
+ algo.update(bytes.getUnsafeBytes(), bytes.getBegin(), bytes.getRealSize());
456
+ return this;
457
+ }
458
+
459
+ @JRubyMethod()
460
+ public IRubyObject finish() {
461
+ IRubyObject digest = RubyString.newStringNoCopy(getRuntime(), algo.digest());
462
+ algo.reset();
463
+ return digest;
464
+ }
465
+
466
+ @JRubyMethod()
467
+ public IRubyObject digest_length() {
468
+ return RubyFixnum.newFixnum(getRuntime(), algo.getDigestLength());
469
+ }
470
+
471
+ @JRubyMethod()
472
+ public IRubyObject block_length() {
473
+ if (blockLength == 0) {
474
+ throw getRuntime().newRuntimeError(
475
+ this.getMetaClass() + " doesn't implement block_length()");
476
+ }
477
+ return RubyFixnum.newFixnum(getRuntime(), blockLength);
478
+ }
479
+
480
+ @JRubyMethod()
481
+ public IRubyObject reset() {
482
+ algo.reset();
483
+ return this;
484
+ }
485
+
486
+ @JRubyMethod()
487
+ public IRubyObject bubblebabble(ThreadContext context) {
488
+ final byte[] digest = algo.digest();
489
+ return RubyString.newString(context.runtime, BubbleBabble.bubblebabble(digest, 0, digest.length));
490
+ }
491
+
492
+ private void setAlgorithm(Metadata metadata) throws NoSuchAlgorithmException {
493
+ this.algo = createMessageDigest(metadata.getName());
494
+ this.blockLength = metadata.getBlockLength();
495
+ }
496
+
497
+ }
498
+ }// RubyDigest
@@ -0,0 +1,41 @@
1
+ /*
2
+ **** BEGIN LICENSE BLOCK *****
3
+ * BSD 2-Clause License
4
+ *
5
+ * Copyright (c) 2010, Charles Oliver Nutter <headius@headius.com>
6
+ * All rights reserved.
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions are met:
10
+ *
11
+ * 1. Redistributions of source code must retain the above copyright notice, this
12
+ * list of conditions and the following disclaimer.
13
+ *
14
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
15
+ * this list of conditions and the following disclaimer in the documentation
16
+ * and/or other materials provided with the distribution.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ ***** END LICENSE BLOCK *****/
29
+
30
+ package org.jruby.ext.digest;
31
+
32
+ import java.io.IOException;
33
+ import org.jruby.Ruby;
34
+ import org.jruby.runtime.load.Library;
35
+
36
+ public class SHA1 implements Library {
37
+
38
+ public void load(final Ruby runtime, boolean wrap) throws IOException {
39
+ org.jruby.ext.digest.RubyDigest.createDigestSHA1(runtime);
40
+ }
41
+ }
@@ -0,0 +1,41 @@
1
+ /*
2
+ **** BEGIN LICENSE BLOCK *****
3
+ * BSD 2-Clause License
4
+ *
5
+ * Copyright (c) 2010, Charles Oliver Nutter <headius@headius.com>
6
+ * All rights reserved.
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions are met:
10
+ *
11
+ * 1. Redistributions of source code must retain the above copyright notice, this
12
+ * list of conditions and the following disclaimer.
13
+ *
14
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
15
+ * this list of conditions and the following disclaimer in the documentation
16
+ * and/or other materials provided with the distribution.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ ***** END LICENSE BLOCK *****/
29
+
30
+ package org.jruby.ext.digest;
31
+
32
+ import java.io.IOException;
33
+ import org.jruby.Ruby;
34
+ import org.jruby.runtime.load.Library;
35
+
36
+ public class SHA2 implements Library {
37
+
38
+ public void load(final Ruby runtime, boolean wrap) throws IOException {
39
+ org.jruby.ext.digest.RubyDigest.createDigestSHA2(runtime);
40
+ }
41
+ }
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ JRuby::Util.load_ext("org.jruby.ext.digest.BubbleBabble")
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ JRuby::Util.load_ext('org.jruby.ext.digest.DigestLibrary')
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ JRuby::Util.load_ext("org.jruby.ext.digest.MD5")
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ JRuby::Util.load_ext("org.jruby.ext.digest.RMD160")
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ JRuby::Util.load_ext("org.jruby.ext.digest.SHA1")
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ JRuby::Util.load_ext('org.jruby.ext.digest.SHA2')
@@ -0,0 +1,142 @@
1
+ # frozen_string_literal: false
2
+ #--
3
+ # sha2.rb - defines Digest::SHA2 class which wraps up the SHA256,
4
+ # SHA384, and SHA512 classes.
5
+ #++
6
+ # Copyright (c) 2006 Akinori MUSHA <knu@iDaemons.org>
7
+ #
8
+ # All rights reserved. You can redistribute and/or modify it under the same
9
+ # terms as Ruby.
10
+ #
11
+ # $Id$
12
+
13
+ require 'digest'
14
+ require 'digest/sha2/loader'
15
+
16
+ module Digest
17
+ #
18
+ # A meta digest provider class for SHA256, SHA384 and SHA512.
19
+ #
20
+ # FIPS 180-2 describes SHA2 family of digest algorithms. It defines
21
+ # three algorithms:
22
+ # * one which works on chunks of 512 bits and returns a 256-bit
23
+ # digest (SHA256),
24
+ # * one which works on chunks of 1024 bits and returns a 384-bit
25
+ # digest (SHA384),
26
+ # * and one which works on chunks of 1024 bits and returns a 512-bit
27
+ # digest (SHA512).
28
+ #
29
+ # ==Examples
30
+ # require 'digest'
31
+ #
32
+ # # Compute a complete digest
33
+ # Digest::SHA2.hexdigest 'abc' # => "ba7816bf8..."
34
+ # Digest::SHA2.new(256).hexdigest 'abc' # => "ba7816bf8..."
35
+ # Digest::SHA256.hexdigest 'abc' # => "ba7816bf8..."
36
+ #
37
+ # Digest::SHA2.new(384).hexdigest 'abc' # => "cb00753f4..."
38
+ # Digest::SHA384.hexdigest 'abc' # => "cb00753f4..."
39
+ #
40
+ # Digest::SHA2.new(512).hexdigest 'abc' # => "ddaf35a19..."
41
+ # Digest::SHA512.hexdigest 'abc' # => "ddaf35a19..."
42
+ #
43
+ # # Compute digest by chunks
44
+ # sha2 = Digest::SHA2.new # =>#<Digest::SHA2:256>
45
+ # sha2.update "ab"
46
+ # sha2 << "c" # alias for #update
47
+ # sha2.hexdigest # => "ba7816bf8..."
48
+ #
49
+ # # Use the same object to compute another digest
50
+ # sha2.reset
51
+ # sha2 << "message"
52
+ # sha2.hexdigest # => "ab530a13e..."
53
+ #
54
+ class SHA2 < Digest::Class
55
+ # call-seq:
56
+ # Digest::SHA2.new(bitlen = 256) -> digest_obj
57
+ #
58
+ # Create a new SHA2 hash object with a given bit length.
59
+ #
60
+ # Valid bit lengths are 256, 384 and 512.
61
+ def initialize(bitlen = 256)
62
+ case bitlen
63
+ when 256
64
+ @sha2 = Digest::SHA256.new
65
+ when 384
66
+ @sha2 = Digest::SHA384.new
67
+ when 512
68
+ @sha2 = Digest::SHA512.new
69
+ else
70
+ raise ArgumentError, "unsupported bit length: %s" % bitlen.inspect
71
+ end
72
+ @bitlen = bitlen
73
+ end
74
+
75
+ # call-seq:
76
+ # digest_obj.reset -> digest_obj
77
+ #
78
+ # Reset the digest to the initial state and return self.
79
+ def reset
80
+ @sha2.reset
81
+ self
82
+ end
83
+
84
+ # call-seq:
85
+ # digest_obj.update(string) -> digest_obj
86
+ # digest_obj << string -> digest_obj
87
+ #
88
+ # Update the digest using a given _string_ and return self.
89
+ def update(str)
90
+ @sha2.update(str)
91
+ self
92
+ end
93
+ alias << update
94
+
95
+ def finish # :nodoc:
96
+ @sha2.digest!
97
+ end
98
+ private :finish
99
+
100
+
101
+ # call-seq:
102
+ # digest_obj.block_length -> Integer
103
+ #
104
+ # Return the block length of the digest in bytes.
105
+ #
106
+ # Digest::SHA256.new.block_length * 8
107
+ # # => 512
108
+ # Digest::SHA384.new.block_length * 8
109
+ # # => 1024
110
+ # Digest::SHA512.new.block_length * 8
111
+ # # => 1024
112
+ def block_length
113
+ @sha2.block_length
114
+ end
115
+
116
+ # call-seq:
117
+ # digest_obj.digest_length -> Integer
118
+ #
119
+ # Return the length of the hash value (the digest) in bytes.
120
+ #
121
+ # Digest::SHA256.new.digest_length * 8
122
+ # # => 256
123
+ # Digest::SHA384.new.digest_length * 8
124
+ # # => 384
125
+ # Digest::SHA512.new.digest_length * 8
126
+ # # => 512
127
+ #
128
+ # For example, digests produced by Digest::SHA256 will always be 32 bytes
129
+ # (256 bits) in size.
130
+ def digest_length
131
+ @sha2.digest_length
132
+ end
133
+
134
+ def initialize_copy(other) # :nodoc:
135
+ @sha2 = other.instance_eval { @sha2.clone }
136
+ end
137
+
138
+ def inspect # :nodoc:
139
+ "#<%s:%d %s>" % [self.class.name, @bitlen, hexdigest]
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Digest
4
+ VERSION = "3.1.0"
5
+ end
data/lib/digest.jar ADDED
Binary file
data/lib/digest.rb ADDED
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: false
2
+
3
+ if defined?(Digest) &&
4
+ /\A(?:2\.|3\.0\.[0-2]\z)/.match?(RUBY_VERSION) &&
5
+ caller_locations.any? { |l|
6
+ %r{/(rubygems/gem_runner|bundler/cli)\.rb}.match?(l.path)
7
+ }
8
+ # Before Ruby 3.0.3/3.1.0, the gem and bundle commands used to load
9
+ # the digest library before loading additionally installed gems, so
10
+ # you will get constant redefinition warnings and unexpected
11
+ # implementation overwriting if we proceed here. Avoid that.
12
+ return
13
+ end
14
+
15
+ require 'digest/version'
16
+ require 'digest/loader'
17
+
18
+ module Digest
19
+ # A mutex for Digest().
20
+ REQUIRE_MUTEX = Thread::Mutex.new
21
+
22
+ def self.const_missing(name) # :nodoc:
23
+ case name
24
+ when :SHA256, :SHA384, :SHA512
25
+ lib = 'digest/sha2'
26
+ else
27
+ lib = File.join('digest', name.to_s.downcase)
28
+ end
29
+
30
+ begin
31
+ require lib
32
+ rescue LoadError
33
+ raise LoadError, "library not found for class Digest::#{name} -- #{lib}", caller(1)
34
+ end
35
+ unless Digest.const_defined?(name)
36
+ raise NameError, "uninitialized constant Digest::#{name}", caller(1)
37
+ end
38
+ Digest.const_get(name)
39
+ end
40
+
41
+ class ::Digest::Class
42
+ # Creates a digest object and reads a given file, _name_.
43
+ # Optional arguments are passed to the constructor of the digest
44
+ # class.
45
+ #
46
+ # p Digest::SHA256.file("X11R6.8.2-src.tar.bz2").hexdigest
47
+ # # => "f02e3c85572dc9ad7cb77c2a638e3be24cc1b5bea9fdbb0b0299c9668475c534"
48
+ def self.file(name, *args)
49
+ new(*args).file(name)
50
+ end
51
+
52
+ # Returns the base64 encoded hash value of a given _string_. The
53
+ # return value is properly padded with '=' and contains no line
54
+ # feeds.
55
+ def self.base64digest(str, *args)
56
+ [digest(str, *args)].pack('m0')
57
+ end
58
+ end
59
+
60
+ module Instance
61
+ # Updates the digest with the contents of a given file _name_ and
62
+ # returns self.
63
+ def file(name)
64
+ File.open(name, "rb") {|f|
65
+ buf = ""
66
+ while f.read(16384, buf)
67
+ update buf
68
+ end
69
+ }
70
+ self
71
+ end
72
+
73
+ # If none is given, returns the resulting hash value of the digest
74
+ # in a base64 encoded form, keeping the digest's state.
75
+ #
76
+ # If a +string+ is given, returns the hash value for the given
77
+ # +string+ in a base64 encoded form, resetting the digest to the
78
+ # initial state before and after the process.
79
+ #
80
+ # In either case, the return value is properly padded with '=' and
81
+ # contains no line feeds.
82
+ def base64digest(str = nil)
83
+ [str ? digest(str) : digest].pack('m0')
84
+ end
85
+
86
+ # Returns the resulting hash value and resets the digest to the
87
+ # initial state.
88
+ def base64digest!
89
+ [digest!].pack('m0')
90
+ end
91
+ end
92
+ end
93
+
94
+ # call-seq:
95
+ # Digest(name) -> digest_subclass
96
+ #
97
+ # Returns a Digest subclass by +name+ in a thread-safe manner even
98
+ # when on-demand loading is involved.
99
+ #
100
+ # require 'digest'
101
+ #
102
+ # Digest("MD5")
103
+ # # => Digest::MD5
104
+ #
105
+ # Digest(:SHA256)
106
+ # # => Digest::SHA256
107
+ #
108
+ # Digest(:Foo)
109
+ # # => LoadError: library not found for class Digest::Foo -- digest/foo
110
+ def Digest(name)
111
+ const = name.to_sym
112
+ Digest::REQUIRE_MUTEX.synchronize {
113
+ # Ignore autoload's because it is void when we have #const_missing
114
+ Digest.const_missing(const)
115
+ }
116
+ rescue LoadError
117
+ # Constants do not necessarily rely on digest/*.
118
+ if Digest.const_defined?(const)
119
+ Digest.const_get(const)
120
+ else
121
+ raise
122
+ end
123
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: digest
3
+ version: !ruby/object:Gem::Version
4
+ version: 3.1.0
5
+ platform: java
6
+ authors:
7
+ - Akinori MUSHA
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-12-24 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Provides a framework for message digest libraries.
14
+ email:
15
+ - knu@idaemons.org
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - LICENSE.txt
21
+ - README.md
22
+ - ext/java/org/jruby/ext/digest/BubbleBabble.java
23
+ - ext/java/org/jruby/ext/digest/DigestLibrary.java
24
+ - ext/java/org/jruby/ext/digest/MD5.java
25
+ - ext/java/org/jruby/ext/digest/RMD160.java
26
+ - ext/java/org/jruby/ext/digest/RubyDigest.java
27
+ - ext/java/org/jruby/ext/digest/SHA1.java
28
+ - ext/java/org/jruby/ext/digest/SHA2.java
29
+ - ext/java/org/jruby/ext/digest/lib/digest/bubblebabble.rb
30
+ - ext/java/org/jruby/ext/digest/lib/digest/loader.rb
31
+ - ext/java/org/jruby/ext/digest/lib/digest/md5.rb
32
+ - ext/java/org/jruby/ext/digest/lib/digest/rmd160.rb
33
+ - ext/java/org/jruby/ext/digest/lib/digest/sha1.rb
34
+ - ext/java/org/jruby/ext/digest/lib/digest/sha2/loader.rb
35
+ - lib/digest.jar
36
+ - lib/digest.rb
37
+ - lib/digest/sha2.rb
38
+ - lib/digest/version.rb
39
+ homepage: https://github.com/ruby/digest
40
+ licenses:
41
+ - Ruby
42
+ - BSD-2-Clause
43
+ metadata:
44
+ msys2_mingw_dependencies: openssl
45
+ post_install_message:
46
+ rdoc_options: []
47
+ require_paths:
48
+ - lib
49
+ - ext/java/org/jruby/ext/digest/lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 2.5.0
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubygems_version: 3.2.14
62
+ signing_key:
63
+ specification_version: 4
64
+ summary: Provides a framework for message digest libraries.
65
+ test_files: []