Skip to content

Commit

Permalink
Merge pull request #1139 from herwinw/openssl_digest
Browse files Browse the repository at this point in the history
  • Loading branch information
seven1m authored Aug 15, 2023
2 parents d96c66c + 205fbbd commit 7f2b7cd
Show file tree
Hide file tree
Showing 10 changed files with 213 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/digest.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require 'digest/sha1'
require 'digest/sha2'
5 changes: 5 additions & 0 deletions lib/digest/sha1.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require 'openssl'

module Digest
SHA1 = OpenSSL::Digest::SHA1
end
7 changes: 7 additions & 0 deletions lib/digest/sha2.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require 'openssl'

module Digest
SHA256 = OpenSSL::Digest::SHA256
SHA384 = OpenSSL::Digest::SHA384
SHA512 = OpenSSL::Digest::SHA512
end
29 changes: 29 additions & 0 deletions lib/openssl.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/sha.h>

#include "natalie.hpp"

Expand Down Expand Up @@ -42,3 +43,31 @@ Value OpenSSL_Random_random_bytes(Env *env, Value self, Args args, Block *) {

return new StringObject { reinterpret_cast<char *>(buf), static_cast<size_t>(num), EncodingObject::get(Encoding::ASCII_8BIT) };
}

template <size_t LENGTH, class F>
static Value digest_wrapper(Env *env, Args args, F f) {
args.ensure_argc_is(env, 1);
Value data = args[0];
data->assert_type(env, Object::Type::String, "String");

unsigned char md[LENGTH];
f(reinterpret_cast<const unsigned char *>(data->as_string()->c_str()), data->as_string()->string().size(), md);

return new StringObject { reinterpret_cast<const char *>(md), LENGTH };
}

Value OpenSSL_Digest_SHA1_digest(Env *env, Value self, Args args, Block *) {
return digest_wrapper<SHA_DIGEST_LENGTH>(env, args, SHA1);
}

Value OpenSSL_Digest_SHA256_digest(Env *env, Value self, Args args, Block *) {
return digest_wrapper<SHA256_DIGEST_LENGTH>(env, args, SHA256);
}

Value OpenSSL_Digest_SHA384_digest(Env *env, Value self, Args args, Block *) {
return digest_wrapper<SHA384_DIGEST_LENGTH>(env, args, SHA384);
}

Value OpenSSL_Digest_SHA512_digest(Env *env, Value self, Args args, Block *) {
return digest_wrapper<SHA512_DIGEST_LENGTH>(env, args, SHA512);
}
34 changes: 34 additions & 0 deletions lib/openssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,38 @@ module OpenSSL
module Random
__bind_static_method__ :random_bytes :OpenSSL_Random_random_bytes
end

class Digest
def self.digest(digest, data)
klass = const_get(digest.to_s.upcase.to_sym)
raise NameError unless klass.ancestors[1] == self
klass.new.digest(data)
rescue NameError
raise "Unsupported digest algorithm (#{digest}).: unknown object name"
end

def self.base64digest(digest, data)
[digest(digest, data)].pack('m0')
end

def self.hexdigest(digest, data)
digest(digest, data).unpack1('H*')
end

class SHA1 < Digest
__bind_method__ :digest, :OpenSSL_Digest_SHA1_digest
end

class SHA256 < Digest
__bind_method__ :digest, :OpenSSL_Digest_SHA256_digest
end

class SHA384 < Digest
__bind_method__ :digest, :OpenSSL_Digest_SHA384_digest
end

class SHA512 < Digest
__bind_method__ :digest, :OpenSSL_Digest_SHA512_digest
end
end
end
18 changes: 18 additions & 0 deletions spec/library/digest/sha1/shared/constants.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# -*- encoding: binary -*-

require 'digest/sha1'

module SHA1Constants

Contents = "Ipsum is simply dummy text of the printing and typesetting industry. \nLorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. \nIt has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. \nIt was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."

Klass = ::Digest::SHA1
BlockLength = 64
DigestLength = 20
BlankDigest = "\3329\243\356^kK\r2U\277\357\225`\030\220\257\330\a\t"
Digest = "X!\255b\323\035\352\314a|q\344+\376\317\361V9\324\343"
BlankHexdigest = "da39a3ee5e6b4b0d3255bfef95601890afd80709"
Hexdigest = "5821ad62d31deacc617c71e42bfecff15639d4e3"
Base64digest = "WCGtYtMd6sxhfHHkK/7P8VY51OM="

end
18 changes: 18 additions & 0 deletions spec/library/digest/sha256/shared/constants.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# -*- encoding: binary -*-

require 'digest/sha2'

module SHA256Constants

Contents = "Ipsum is simply dummy text of the printing and typesetting industry. \nLorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. \nIt has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. \nIt was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."

Klass = ::Digest::SHA256
BlockLength = 64
DigestLength = 32
BlankDigest = "\343\260\304B\230\374\034\024\232\373\364\310\231o\271$'\256A\344d\233\223L\244\225\231\exR\270U"
Digest = "\230b\265\344_\337\357\337\242\004\314\311A\211jb\350\373\254\370\365M\230B\002\372\020j\as\270\376"
BlankHexdigest = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
Hexdigest = "9862b5e45fdfefdfa204ccc941896a62e8fbacf8f54d984202fa106a0773b8fe"
Base64digest = "mGK15F/f79+iBMzJQYlqYuj7rPj1TZhCAvoQagdzuP4="

end
19 changes: 19 additions & 0 deletions spec/library/digest/sha384/shared/constants.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# -*- encoding: binary -*-

require 'digest/sha2'

module SHA384Constants

Contents = "Ipsum is simply dummy text of the printing and typesetting industry. \nLorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. \nIt has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. \nIt was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."


Klass = ::Digest::SHA384
BlockLength = 128
DigestLength = 48
BlankDigest = "8\260`\247Q\254\2268L\3312~\261\261\343j!\375\267\021\024\276\aCL\f\307\277c\366\341\332'N\336\277\347oe\373\325\032\322\361H\230\271["
Digest = "B&\266:\314\216z\361!TD\001{`\355\323\320MW%\270\272\0034n\034\026g\a\217\"\333s\202\275\002Y*\217]\207u\f\034\244\231\266f"
BlankHexdigest = "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b"
Hexdigest = "4226b63acc8e7af1215444017b60edd3d04d5725b8ba03346e1c1667078f22db7382bd02592a8f5d87750c1ca499b666"
Base64digest = "Qia2OsyOevEhVEQBe2Dt09BNVyW4ugM0bhwWZwePIttzgr0CWSqPXYd1DBykmbZm"

end
18 changes: 18 additions & 0 deletions spec/library/digest/sha512/shared/constants.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# -*- encoding: binary -*-

require 'digest/sha2'

module SHA512Constants

Contents = "Ipsum is simply dummy text of the printing and typesetting industry. \nLorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. \nIt has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. \nIt was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."

Klass = ::Digest::SHA512
BlockLength = 128
DigestLength = 64
BlankDigest = "\317\203\3415~\357\270\275\361T(P\326m\200\a\326 \344\005\vW\025\334\203\364\251!\323l\351\316G\320\321<]\205\362\260\377\203\030\322\207~\354/c\2711\275GAz\201\24582z\371'\332>"
Digest = "\241\231\232\365\002z\241\331\242\310=\367F\272\004\326\331g\315n\251Q\222\250\374E\257\254=\325\225\003SM\350\244\234\220\233=\031\230A;\000\203\233\340\323t\333\271\222w\266\307\2678\344\255j\003\216\300"
BlankHexdigest = "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"
Hexdigest = "a1999af5027aa1d9a2c83df746ba04d6d967cd6ea95192a8fc45afac3dd59503534de8a49c909b3d1998413b00839be0d374dbb99277b6c7b738e4ad6a038ec0"
Base64digest = "oZma9QJ6odmiyD33RroE1tlnzW6pUZKo/EWvrD3VlQNTTeiknJCbPRmYQTsAg5vg03TbuZJ3tse3OOStagOOwA=="

end
63 changes: 63 additions & 0 deletions spec/library/openssl/digest_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
require_relative '../../spec_helper'
require_relative '../../library/digest/sha1/shared/constants'
require_relative '../../library/digest/sha256/shared/constants'
require_relative '../../library/digest/sha384/shared/constants'
require_relative '../../library/digest/sha512/shared/constants'
require 'openssl'

describe "OpenSSL::Digest" do

describe ".digest" do
it "returns a SHA1 digest" do
OpenSSL::Digest.digest('sha1', SHA1Constants::Contents).should == SHA1Constants::Digest
end

it "returns a SHA256 digest" do
OpenSSL::Digest.digest('sha256', SHA256Constants::Contents).should == SHA256Constants::Digest
end

it "returns a SHA384 digest" do
OpenSSL::Digest.digest('sha384', SHA384Constants::Contents).should == SHA384Constants::Digest
end

it "returns a SHA512 digest" do
OpenSSL::Digest.digest('sha512', SHA512Constants::Contents).should == SHA512Constants::Digest
end
end

describe ".hexdigest" do
it "returns a SHA1 hexdigest" do
OpenSSL::Digest.hexdigest('sha1', SHA1Constants::Contents).should == SHA1Constants::Hexdigest
end

it "returns a SHA256 hexdigest" do
OpenSSL::Digest.hexdigest('sha256', SHA256Constants::Contents).should == SHA256Constants::Hexdigest
end

it "returns a SHA384 hexdigest" do
OpenSSL::Digest.hexdigest('sha384', SHA384Constants::Contents).should == SHA384Constants::Hexdigest
end

it "returns a SHA512 hexdigest" do
OpenSSL::Digest.hexdigest('sha512', SHA512Constants::Contents).should == SHA512Constants::Hexdigest
end
end

describe ".base64digest" do
it "returns a SHA1 base64digest" do
OpenSSL::Digest.base64digest('sha1', SHA1Constants::Contents).should == SHA1Constants::Base64digest
end

it "returns a SHA256 base64digest" do
OpenSSL::Digest.base64digest('sha256', SHA256Constants::Contents).should == SHA256Constants::Base64digest
end

it "returns a SHA384 base64digest" do
OpenSSL::Digest.base64digest('sha384', SHA384Constants::Contents).should == SHA384Constants::Base64digest
end

it "returns a SHA512 base64digest" do
OpenSSL::Digest.base64digest('sha512', SHA512Constants::Contents).should == SHA512Constants::Base64digest
end
end
end

0 comments on commit 7f2b7cd

Please sign in to comment.