Class: SecureHeaders::PublicKeyPins

Inherits:
Object
  • Object
show all
Defined in:
lib/secure_headers/headers/public_key_pins.rb

Constant Summary collapse

HEADER_NAME =
"Public-Key-Pins".freeze
REPORT_ONLY =
"Public-Key-Pins-Report-Only".freeze
HASH_ALGORITHMS =
[:sha256].freeze
CONFIG_KEY =
:hpkp

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ PublicKeyPins

Returns a new instance of PublicKeyPins.



36
37
38
39
40
41
42
# File 'lib/secure_headers/headers/public_key_pins.rb', line 36

def initialize(config)
  @max_age = config.fetch(:max_age, nil)
  @pins = config.fetch(:pins, nil)
  @report_uri = config.fetch(:report_uri, nil)
  @report_only = !!config.fetch(:report_only, nil)
  @include_subdomains = !!config.fetch(:include_subdomains, nil)
end

Class Method Details

.make_header(config) ⇒ Object

Public: make an hpkp header name, value pair

Returns nil if not configured, returns header name and value if configured.



15
16
17
18
19
# File 'lib/secure_headers/headers/public_key_pins.rb', line 15

def make_header(config)
  return if config.nil?
  header = new(config)
  [header.name, header.value]
end

.validate_config!(config) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/secure_headers/headers/public_key_pins.rb', line 21

def validate_config!(config)
  return if config.nil? || config == OPT_OUT
  raise PublicKeyPinsConfigError.new("config must be a hash.") unless config.is_a? Hash

  if !config[:max_age]
    raise PublicKeyPinsConfigError.new("max-age is a required directive.")
  elsif config[:max_age].to_s !~ /\A\d+\z/
    raise PublicKeyPinsConfigError.new("max-age must be a number.
                                      #{config[:max_age]} was supplied.")
  elsif config[:pins] && config[:pins].length < 2
    raise PublicKeyPinsConfigError.new("A minimum of 2 pins are required.")
  end
end

Instance Method Details

#max_age_directiveObject



70
71
72
# File 'lib/secure_headers/headers/public_key_pins.rb', line 70

def max_age_directive
  "max-age=#{@max_age}" if @max_age
end

#nameObject



44
45
46
47
48
49
50
# File 'lib/secure_headers/headers/public_key_pins.rb', line 44

def name
  if @report_only
    REPORT_ONLY
  else
    HEADER_NAME
  end
end

#pin_directivesObject



61
62
63
64
65
66
67
68
# File 'lib/secure_headers/headers/public_key_pins.rb', line 61

def pin_directives
  return nil if @pins.nil?
  @pins.collect do |pin|
    pin.map do |token, hash|
      "pin-#{token}=\"#{hash}\"" if HASH_ALGORITHMS.include?(token)
    end
  end.join("; ")
end

#report_uri_directiveObject



74
75
76
# File 'lib/secure_headers/headers/public_key_pins.rb', line 74

def report_uri_directive
  "report-uri=\"#{@report_uri}\"" if @report_uri
end

#subdomain_directiveObject



78
79
80
# File 'lib/secure_headers/headers/public_key_pins.rb', line 78

def subdomain_directive
  @include_subdomains ? "includeSubDomains" : nil
end

#valueObject



52
53
54
55
56
57
58
59
# File 'lib/secure_headers/headers/public_key_pins.rb', line 52

def value
  [
    max_age_directive,
    pin_directives,
    report_uri_directive,
    subdomain_directive
  ].compact.join("; ").strip
end