Module: Syndi::IRC::SASL::Mech::DHBlowfish

Defined in:
lib/syndi/irc/sasl/mech/dh_blowfish.rb

Overview

Module which implements the SASL DH-BLOWFISH mechanism.

Author:

  • noxgirl

Class Method Summary collapse

Class Method Details

.encrypt(username, password, provision) ⇒ Object

Create an SASL-encrypted hash.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/syndi/irc/sasl/mech/dh_blowfish.rb', line 26

def self.encrypt username, password, provision
  # This is a fairly complex process. Duplicate +username+ and
  # +password+ for safety.
  user = username.dup
  pass = password.dup

  # Decode the key from base64.
  key = Base64.decode64(provision).force_encoding('ASCII-8BIT')

  # Unpack it.
  p, g, y = unpack_key key

  dh     = DiffieHellman.new(p, g, 23)
  pkey   = dh.generate
  secret = OpenSSL::BN.new(dh.secret(y).to_s).to_s(2)
  pub    = OpenSSL::BN.new(pkey.to_s).to_s(2)

  pass.concat "\0"
  pass.concat('.' * (8 - (password.size % 8)))

  cipher         = OpenSSL::Cipher::Cipher.new 'BF-ECB'
  cipher.key_len = 32
  cipher.encrypt
  cipher.key     = secret

  enc    = cipher.update(pass).to_s
  answer = [pub.bytesize, pub, user, enc].pack('na*Z*a*')

  Base64.strict_encode64(answer) # finally, return the hash
end

.unpack_key(key) ⇒ Array(Numeric, Numeric, Numeric)



59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/syndi/irc/sasl/mech/dh_blowfish.rb', line 59

def self.unpack_key key
  key = key.dup
  pgy = []

  3.times do
    size = key.unpack('n').first
    key.slice! 0, 2
    pgy << key.unpack("a#{size}").first
    key.slice!(0, size)
  end
  
  pgy.map { |int| OpenSSL::BN.new(int, 2).to_i }
end