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

Commit d62907e

Browse files
passkey calculation as a C extension
given the string overhead involved in the calculation.
1 parent bed5e38 commit d62907e

File tree

9 files changed

+92
-11
lines changed

9 files changed

+92
-11
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
/Gemfile.lock
99
/vendor
1010
.env
11+
/ext/Makefile
1112

1213
*.DS_Store
1314
*.sw[po]

Gemfile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ ruby RUBY_VERSION
55

66
gemspec
77

8-
gem "rake", "~> 12.3"
8+
gem "rake", "~> 13"
99
gem "rspec", "~> 3.5"
1010

1111
gem "pry"
@@ -36,3 +36,8 @@ else
3636
end
3737

3838
end
39+
40+
gem "jruby-openssl", "~> 0.14", platform: :jruby
41+
gem "ruby-prof"
42+
gem "rake-compiler"
43+
gem "benchmark-ips"

Rakefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# frozen_string_literal: true
22

33
require "bundler/gem_tasks"
4+
require 'rake/extensiontask'
5+
6+
Rake::ExtensionTask.new('netsnmp_ext')
47

58
begin
69
require "rspec/core/rake_task"

ext/netsnmp_ext/extconf.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
require 'mkmf'
2+
create_makefile 'netsnmp_ext'

ext/netsnmp_ext/netsnmp_ext.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#include <ruby.h>
2+
3+
#define USM_LENGTH_EXPANDED_PASSPHRASE (1024 * 1024) /* 1Meg. */
4+
#define USM_LENGTH_KU_HASHBLOCK 64
5+
6+
static VALUE mNETSNMP;
7+
static VALUE cNETSNMP_Sec_Params;
8+
9+
static VALUE NETSNMP_expand_passphrase(VALUE self, VALUE password)
10+
{
11+
char *P;
12+
size_t P_len;
13+
int nbytes = USM_LENGTH_EXPANDED_PASSPHRASE;
14+
u_int pindex = 0;
15+
u_char buf[USM_LENGTH_EXPANDED_PASSPHRASE], *bufp;
16+
17+
StringValue(password);
18+
P = RSTRING_PTR(password);
19+
P_len = RSTRING_LEN(password);
20+
21+
bufp = buf;
22+
while (nbytes > 0) {
23+
*bufp++ = P[pindex++ % P_len];
24+
// if (!EVP_DigestUpdate(ctx, buf, USM_LENGTH_KU_HASHBLOCK))
25+
// ossl_raise(eDigestError, "EVP_DigestUpdate");
26+
27+
nbytes--;
28+
}
29+
30+
// if (!EVP_DigestFinal_ex(ctx, &Ku, &kulen))
31+
// ossl_raise(eDigestError, "EVP_DigestFinal_ex");
32+
33+
// memset(buf, 0, sizeof(buf));
34+
35+
// TODO: trim to 16 bytes if auth protocol is md5
36+
37+
return rb_usascii_str_new((const char *) buf, USM_LENGTH_EXPANDED_PASSPHRASE);
38+
}
39+
40+
void Init_netsnmp_ext( void )
41+
{
42+
mNETSNMP = rb_define_module("NETSNMP");
43+
cNETSNMP_Sec_Params = rb_define_class_under(mNETSNMP, "SecurityParameters", rb_cObject);
44+
// rb_define_method(cNETSNMP_Sec_Params, "passkey", NETSNMP_passkey, 1);
45+
rb_define_method(cNETSNMP_Sec_Params, "expand_passphrase", NETSNMP_expand_passphrase, 1);
46+
}

lib/netsnmp.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ def xor(other)
5151
require "netsnmp/message"
5252
require "netsnmp/encryption/des"
5353
require "netsnmp/encryption/aes"
54+
require "netsnmp_ext" if RUBY_ENGINE == "ruby"
5455

5556
require "netsnmp/client"
5657

lib/netsnmp/security_parameters.rb

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -191,22 +191,24 @@ def localize_key(key)
191191

192192
def passkey(password)
193193
digest.reset
194-
password_index = 0
194+
digest << expand_passphrase(password)
195+
196+
dig = digest.digest
197+
dig = dig[0, 16] if @auth_protocol == :md5
198+
dig || ""
199+
end
195200

196-
# buffer = +""
201+
def expand_passphrase(password)
202+
password_index = 0
203+
buffer = "".b
197204
password_length = password.length
198205
while password_index < 1048576
199206
initial = password_index % password_length
200-
rotated = String(password[initial..-1]) + String(password[0, initial])
201-
buffer = (rotated * (64 / rotated.length)) + String(rotated[0, 64 % rotated.length])
207+
rotated = String(password.byteslice(initial..-1)) + String(password.byteslice(0, initial))
208+
buffer << (rotated * (64 / rotated.length)) + String(rotated.byteslice(0, 64 % rotated.length))
202209
password_index += 64
203-
digest << buffer
204-
buffer.clear
205210
end
206-
207-
dig = digest.digest
208-
dig = dig[0, 16] if @auth_protocol == :md5
209-
dig || ""
211+
buffer
210212
end
211213

212214
def digest

netsnmp.gemspec

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ Gem::Specification.new do |gem|
2121
# Manifest
2222
gem.files = Dir["LICENSE.txt", "README.md", "AUTHORS", "lib/**/*.rb", "sig/**/*.rbs"]
2323
gem.require_paths = ["lib"]
24+
if RUBY_ENGINE == "ruby"
25+
gem.extensions = ["ext/extconf.rb"]
26+
end
2427

2528
gem.add_runtime_dependency "parslet"
2629
gem.metadata["rubygems_mfa_required"] = "true"

spec/support/specs.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,24 @@ cd /home
2323
bundle -v
2424
bundle install
2525

26+
cat <<EOT >> /etc/ssl/openssl.cnf
27+
28+
[provider_sect]
29+
default = default_sect
30+
legacy = legacy_sect
31+
32+
[default_sect]
33+
activate = 1
34+
35+
[legacy_sect]
36+
activate = 1
37+
38+
EOT
39+
40+
if [[ "$RUBY_ENGINE" = "ruby" ]]; then
41+
bundle exec rake compile
42+
fi
43+
2644
if [[ ${RUBY_VERSION:0:1} = "3" ]]; then
2745
export RUBYOPT='-rbundler/setup -rrbs/test/setup'
2846
export RBS_TEST_RAISE=true

0 commit comments

Comments
 (0)