Skip to content
This repository has been archived by the owner on Apr 21, 2023. It is now read-only.

Commit

Permalink
passkey calculation as a C extension
Browse files Browse the repository at this point in the history
given the string overhead involved in the calculation.
  • Loading branch information
HoneyryderChuck committed Apr 3, 2023
1 parent bed5e38 commit d62907e
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 11 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
/Gemfile.lock
/vendor
.env
/ext/Makefile

*.DS_Store
*.sw[po]
Expand Down
7 changes: 6 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ ruby RUBY_VERSION

gemspec

gem "rake", "~> 12.3"
gem "rake", "~> 13"
gem "rspec", "~> 3.5"

gem "pry"
Expand Down Expand Up @@ -36,3 +36,8 @@ else
end

end

gem "jruby-openssl", "~> 0.14", platform: :jruby
gem "ruby-prof"
gem "rake-compiler"
gem "benchmark-ips"
3 changes: 3 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# frozen_string_literal: true

require "bundler/gem_tasks"
require 'rake/extensiontask'

Rake::ExtensionTask.new('netsnmp_ext')

begin
require "rspec/core/rake_task"
Expand Down
2 changes: 2 additions & 0 deletions ext/netsnmp_ext/extconf.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require 'mkmf'
create_makefile 'netsnmp_ext'
46 changes: 46 additions & 0 deletions ext/netsnmp_ext/netsnmp_ext.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include <ruby.h>

#define USM_LENGTH_EXPANDED_PASSPHRASE (1024 * 1024) /* 1Meg. */
#define USM_LENGTH_KU_HASHBLOCK 64

static VALUE mNETSNMP;
static VALUE cNETSNMP_Sec_Params;

static VALUE NETSNMP_expand_passphrase(VALUE self, VALUE password)
{
char *P;
size_t P_len;
int nbytes = USM_LENGTH_EXPANDED_PASSPHRASE;
u_int pindex = 0;
u_char buf[USM_LENGTH_EXPANDED_PASSPHRASE], *bufp;

StringValue(password);
P = RSTRING_PTR(password);
P_len = RSTRING_LEN(password);

bufp = buf;
while (nbytes > 0) {
*bufp++ = P[pindex++ % P_len];
// if (!EVP_DigestUpdate(ctx, buf, USM_LENGTH_KU_HASHBLOCK))
// ossl_raise(eDigestError, "EVP_DigestUpdate");

nbytes--;
}

// if (!EVP_DigestFinal_ex(ctx, &Ku, &kulen))
// ossl_raise(eDigestError, "EVP_DigestFinal_ex");

// memset(buf, 0, sizeof(buf));

// TODO: trim to 16 bytes if auth protocol is md5

return rb_usascii_str_new((const char *) buf, USM_LENGTH_EXPANDED_PASSPHRASE);
}

void Init_netsnmp_ext( void )
{
mNETSNMP = rb_define_module("NETSNMP");
cNETSNMP_Sec_Params = rb_define_class_under(mNETSNMP, "SecurityParameters", rb_cObject);
// rb_define_method(cNETSNMP_Sec_Params, "passkey", NETSNMP_passkey, 1);
rb_define_method(cNETSNMP_Sec_Params, "expand_passphrase", NETSNMP_expand_passphrase, 1);
}
1 change: 1 addition & 0 deletions lib/netsnmp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def xor(other)
require "netsnmp/message"
require "netsnmp/encryption/des"
require "netsnmp/encryption/aes"
require "netsnmp_ext" if RUBY_ENGINE == "ruby"

require "netsnmp/client"

Expand Down
22 changes: 12 additions & 10 deletions lib/netsnmp/security_parameters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -191,22 +191,24 @@ def localize_key(key)

def passkey(password)
digest.reset
password_index = 0
digest << expand_passphrase(password)

dig = digest.digest
dig = dig[0, 16] if @auth_protocol == :md5
dig || ""
end

# buffer = +""
def expand_passphrase(password)
password_index = 0
buffer = "".b
password_length = password.length
while password_index < 1048576
initial = password_index % password_length
rotated = String(password[initial..-1]) + String(password[0, initial])
buffer = (rotated * (64 / rotated.length)) + String(rotated[0, 64 % rotated.length])
rotated = String(password.byteslice(initial..-1)) + String(password.byteslice(0, initial))
buffer << (rotated * (64 / rotated.length)) + String(rotated.byteslice(0, 64 % rotated.length))
password_index += 64
digest << buffer
buffer.clear
end

dig = digest.digest
dig = dig[0, 16] if @auth_protocol == :md5
dig || ""
buffer
end

def digest
Expand Down
3 changes: 3 additions & 0 deletions netsnmp.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ Gem::Specification.new do |gem|
# Manifest
gem.files = Dir["LICENSE.txt", "README.md", "AUTHORS", "lib/**/*.rb", "sig/**/*.rbs"]
gem.require_paths = ["lib"]
if RUBY_ENGINE == "ruby"
gem.extensions = ["ext/extconf.rb"]
end

gem.add_runtime_dependency "parslet"
gem.metadata["rubygems_mfa_required"] = "true"
Expand Down
18 changes: 18 additions & 0 deletions spec/support/specs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,24 @@ cd /home
bundle -v
bundle install

cat <<EOT >> /etc/ssl/openssl.cnf
[provider_sect]
default = default_sect
legacy = legacy_sect
[default_sect]
activate = 1
[legacy_sect]
activate = 1
EOT

if [[ "$RUBY_ENGINE" = "ruby" ]]; then
bundle exec rake compile
fi

if [[ ${RUBY_VERSION:0:1} = "3" ]]; then
export RUBYOPT='-rbundler/setup -rrbs/test/setup'
export RBS_TEST_RAISE=true
Expand Down

0 comments on commit d62907e

Please sign in to comment.