summaryrefslogtreecommitdiff
path: root/lib/nickserver/hkp/fetch_key_info.rb
blob: b341aad38e4489e9f4b83de82c1c359d29e1839d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
64
65
66
require 'em-http'

#
# used to fetch an array of KeyInfo objects that match the given uid.
#

module Nickserver; module HKP
  class FetchKeyInfo
    include EM::Deferrable

    # for this regexp to work, the source text must end in a trailing "\n",
    # which the output of sks does.
    MATCH_PUB_KEY = /(^pub:.+?\n(^uid:.+?\n)+)/m

    def search(uid)
      # in practice, exact=on seems to have no effect
      params = {:op => 'vindex', :search => uid, :exact => 'on', :options => 'mr', :fingerprint => 'on'}
      EventMachine::HttpRequest.new(Config.hkp_url).get(:query => params).callback {|http|
        if http.response_header.status != 200
          self.fail http.response_header.status, "Could net fetch keyinfo"
        else
          self.succeed parse(uid, http.response)
        end
      }.errback {|http|
        self.fail 0, http.error
      }
      self
    end

    #
    # input:
    #  uid           -- uid to search for
    #  vindex_result -- raw output from a vindex hkp query (machine readable)
    #
    # returns:
    #   an array of eligible keys (as HKPKeyInfo objects) matching uid.
    #
    # keys are eliminated from eligibility for a number of reasons, including expiration,
    # revocation, uid match, key length, and so on...
    #
    def parse(uid, vindex_result)
      keys = []
      now = Time.now
      vindex_result.scan(MATCH_PUB_KEY).each do |match|
        key_info = KeyInfo.new(match[0])
        if key_info.uids.include?(uid)
          if key_info.keylen <= 1024
            #puts 'key length is too short'
          elsif key_info.expired?
            #puts 'ignoring expired key'
          elsif key_info.revoked?
            #puts 'ignoring revoked key'
          elsif key_info.disabled?
            #puts 'ignoring disabled key'
          elsif key_info.expirationdate && key_info.expirationdate < now
            #puts 'ignoring expired key'
          else
            keys << key_info
          end
        end
      end
      keys
    end
  end

end; end