Puppet Function: tor::generate_onion_key

Defined in:
lib/puppet/functions/tor/generate_onion_key.rb
Function type:
Ruby 4.x API

Summary

Generates or loads an RSA private key for v2 onion service. It will also store the onion address under /tmp/my_secret_key.hostname. If /tmp/my_secret_key.key exists, but not the hostname file. Then the function will be loaded and the onion address will be generated from it. The private key either exists under the supplied path/key_identifier or is being generated on the fly and stored under that path for the next execution.

Overview

tor::generate_onion_key(Any *$args)Array

Examples:

res = tor::generate_onion_key('/tmp','my_secret_key')
notice "Onion Address: ${res[0]}"
notice "Private Key: ${res[1]}"

Parameters:

  • path

    A path (on the puppet master) to load and store the private key from.

  • secret_key

    An identifier, which will be used as a filename in the location.

  • *args (Any)

Returns:

  • (Array)

    The onion address and the private key content.



17
18
19
20
21
22
23
24
25
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
56
57
58
59
60
61
62
63
# File 'lib/puppet/functions/tor/generate_onion_key.rb', line 17

Puppet::Functions.create_function(:'tor::generate_onion_key') do
  #
  # @param path
  #   A path (on the puppet master) to load and store the private key from.
  #
  # @param secret_key
  #   An identifier, which will be used as a filename in the location.
  #
  # @return [Array]
  #   The onion address and the private key content.
  #
  dispatch :default_impl do
    repeated_param 'Any', :args
  end


  def default_impl(*args)
    location = args.shift
    identifier = args.shift

    raise(Puppet::ParseError, "tor::generate_onion_key(): requires 2 arguments") unless [location,identifier].all?{|i| !i.nil? }

    raise(Puppet::ParseError, "tor::generate_onion_key(): requires location (#{location}) to be a directory") unless File.directory?(location)
    path = File.join(location,identifier)

    private_key = if File.exists?(kf="#{path}.key")
      pk = OpenSSL::PKey::RSA.new(File.read(kf))
      raise(Puppet::ParseError, "tor::generate_onion_key(): key in path #{kf} must have a length of 1024bit") unless (pk.n.num_bytes * 8) == 1024
      pk
    else
      # 1024 is hardcoded by tor
      pk = OpenSSL::PKey::RSA.generate(1024)
      File.open(kf,'w'){|f| f << pk.to_s }
      pk
    end
    onion_address = if File.exists?(hf="#{path}.hostname")
      File.read(hf)
    else
      oa = call_function('tor::onion_address', private_key)
      File.open(hf,'w'){|f| f << oa.to_s }
      oa
    end

    [ onion_address,
      Puppet::Pops::Types::PSensitiveType::Sensitive.new(private_key.to_s) ]
  end
end