]> git.donarmstrong.com Git - dsa-puppet.git/blob - modules/puppetmaster/lib/puppet/parser/functions/hkdf.rb
Always remove acpi packages from jessie hosts
[dsa-puppet.git] / modules / puppetmaster / lib / puppet / parser / functions / hkdf.rb
1 # a RFC5869 implementation:
2 # HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
3 #
4 # function John Downey, downloaded from https://rubygems.org/gems/hkdf
5 # and distributed under the MIT license.
6
7
8 require 'openssl'
9
10 class HKDF
11   def initialize(source, options = {})
12     options = {:algorithm => 'SHA256', :info => '', :salt => nil}.merge(options)
13
14     @digest = OpenSSL::Digest.new(options[:algorithm])
15     @info = options[:info]
16
17     salt = options[:salt]
18     salt = 0.chr * @digest.digest_length if salt.nil? or salt.empty?
19
20     @prk = OpenSSL::HMAC.digest(@digest, salt, source)
21     @position = 0
22     @blocks = []
23     @blocks << ''
24   end
25
26   def algorithm
27     @digest.name
28   end
29
30   def max_length
31     @digest.digest_length * 255
32   end
33
34   def seek(position)
35     raise RangeError.new("cannot seek past #{max_length}") if position > max_length
36
37     @position = position
38   end
39
40   def rewind
41     seek(0)
42   end
43
44   def next_bytes(length)
45     new_position = length + @position
46     raise RangeError.new("requested #{length} bytes, only #{max_length} available") if new_position > max_length
47
48     _generate_blocks(new_position)
49
50     start = @position
51     @position = new_position
52
53     @blocks.join('').slice(start, length)
54   end
55
56   def next_hex_bytes(length)
57     next_bytes(length).unpack('H*').first
58   end
59
60   def _generate_blocks(length)
61     start = @blocks.size
62     block_count = (length.to_f / @digest.digest_length).ceil
63     start.upto(block_count) do |n|
64       @blocks << OpenSSL::HMAC.digest(@digest, @prk, @blocks[n - 1] + @info + n.chr)
65     end
66   end
67 end
68
69 # puppetization by weasel
70 module Puppet::Parser::Functions
71   newfunction(:hkdf, :type => :rvalue) do |args|
72     secretfile = args.shift()
73     data = args.shift()
74
75     require 'openssl'
76     secret = ""
77     begin
78       secret = File.new(secretfile, "r").read
79     rescue => e
80       raise Puppet::ParseError, "Error loading secret from #{secretfile}: #{e.message}\n#{e.backtrace}"
81     end
82
83     hkdf = HKDF.new(secret, :info => data)
84     return hkdf.next_hex_bytes(32)
85   end
86 end
87 # vim:set ts=2:
88 # vim:set et:
89 # vim:set shiftwidth=2: