Skip to content

Commit 5b7ec05

Browse files
committed
Make common byte to int conversion functions
1 parent d0000af commit 5b7ec05

File tree

2 files changed

+27
-14
lines changed

2 files changed

+27
-14
lines changed

lib/rex/crypto.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,27 @@ def self.decrypt_aes256(iv, key, value)
2727
def self.rc4(key, value)
2828
Rc4.rc4(key, value)
2929
end
30+
31+
# Returns an integer represented as a byte array. Useful for certain key-related operations.
32+
#
33+
# @param bytes [String] The bytes to convert
34+
# @return [Integer] The converted value.
35+
def self.bytes_to_int(bytes)
36+
bytes.each_byte.reduce(0) { |acc, byte| (acc << 8) | byte }
37+
end
38+
39+
# Returns a byte array represented as a big-endian integer. Useful for certain key-related operations.
40+
#
41+
# @param bytes [String] The bytes to convert
42+
# @return [Integer] The converted value.
43+
def self.int_to_bytes(num)
44+
bytes = []
45+
46+
while num > 0
47+
bytes.unshift(num & 0xff)
48+
num >>= 8
49+
end
50+
51+
bytes.pack("C*")
52+
end
3053
end

lib/rex/proto/ms_adts/key_credential.rb

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ def set_key(public_key, key_usage)
2525
when KEY_USAGE_NGC
2626
result = Rex::Proto::BcryptPublicKey.new
2727
result.key_length = public_key.n.num_bits
28-
n = self.class.int_to_bytes(public_key.n)
29-
e = self.class.int_to_bytes(public_key.e)
28+
n = Rex::Crypto.int_to_bytes(public_key.n)
29+
e = Rex::Crypto.int_to_bytes(public_key.e)
3030
result.exponent = e
3131
result.modulus = n
3232
result.prime1 = ''
@@ -136,8 +136,8 @@ def public_key
136136
when KEY_USAGE_NGC
137137
if raw_key_material.start_with?([Rex::Proto::BcryptPublicKey::MAGIC].pack('I'))
138138
result = Rex::Proto::BcryptPublicKey.read(raw_key_material)
139-
exponent = OpenSSL::ASN1::Integer.new(bytes_to_int(result.exponent))
140-
modulus = OpenSSL::ASN1::Integer.new(bytes_to_int(result.modulus))
139+
exponent = OpenSSL::ASN1::Integer.new(Rex::Crypto.bytes_to_int(result.exponent))
140+
modulus = OpenSSL::ASN1::Integer.new(Rex::Crypto.bytes_to_int(result.modulus))
141141
# OpenSSL's API has changed over time - constructing from DER has been consistent
142142
data_sequence = OpenSSL::ASN1::Sequence([modulus, exponent])
143143

@@ -165,16 +165,6 @@ def add_entry(struct, identifier, data, insert_at_end: true)
165165
end
166166
end
167167

168-
def self.int_to_bytes(num)
169-
str = num.to_s(16).rjust(2, '0')
170-
171-
[str].pack('H*')
172-
end
173-
174-
def bytes_to_int(num)
175-
num.unpack('H*')[0].to_i(16)
176-
end
177-
178168
# Sets self.key_hash based on the credential_entries value in the provided parameter
179169
# @param struct [MsAdtsKeyCredentialStruct] Its credential_entries value should have only those required to calculate the key_hash value (no key_id or key_hash)
180170
def calculate_key_hash(struct)

0 commit comments

Comments
 (0)