digest 3.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
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: []