Skip to content
This repository has been archived by the owner on Oct 28, 2024. It is now read-only.

passkey calculation as a C extension #76

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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