class Omnibus::Packager::WindowsBase

Public Instance Methods

algorithm() click to toggle source
# File lib/omnibus/packagers/windows_base.rb, line 98
def algorithm
  signing_identity[:algorithm]
end
cert_store_name() click to toggle source
# File lib/omnibus/packagers/windows_base.rb, line 102
def cert_store_name
  signing_identity[:store]
end
certificate_subject() click to toggle source

Get the certificate subject of the signing identity

@return [String]

# File lib/omnibus/packagers/windows_base.rb, line 165
def certificate_subject
  return "CN=#{project.package_name}" unless signing_identity

  store = machine_store? ? "LocalMachine" : "CurrentUser"
  cmd = [].tap do |arr|
    arr << "powershell.exe"
    arr << "-ExecutionPolicy Bypass"
    arr << "-NoProfile"
    arr << "-Command (Get-Item Cert:/#{store}/#{cert_store_name}/#{thumbprint}).Subject"
  end.join(" ")

  shellout!(cmd).stdout.strip
end
is_signed?(package_file) click to toggle source
# File lib/omnibus/packagers/windows_base.rb, line 123
    def is_signed?(package_file)
      cmd = [].tap do |arr|
        arr << "smctl.exe"
        arr << "sign"
        arr << "--fingerprint #{thumbprint}"
        arr << "--input #{package_file}"
      end.join(" ")

      status = shellout(cmd)

      log.debug(log_key) { "#{self.class}##{__method__} - package_file: #{package_file}" }
      log.debug(log_key) { "#{self.class}##{__method__} - cmd: #{cmd}" }
      log.debug(log_key) { "#{self.class}##{__method__} - status: #{status}" }
      log.debug(log_key) { "#{self.class}##{__method__} - status.exitstatus: #{status.exitstatus}" }
      log.debug(log_key) { "#{self.class}##{__method__} - status.stdout: #{status.stdout}" }
      log.debug(log_key) { "#{self.class}##{__method__} - status.stderr: #{status.stderr}" }

      # log the error if the signing failed
      if status.exitstatus != 0
        log.warn(log_key) do
          <<-EOH.strip
                Failed to verify signature of #{package_file}

                STDOUT
                ------
                #{status.stdout}

                STDERR
                ------
                #{status.stderr}
          EOH
        end
      end

      status.exitstatus == 0
    end
keypair_alias() click to toggle source
# File lib/omnibus/packagers/windows_base.rb, line 110
def keypair_alias
  signing_identity[:keypair_alias]
end
machine_store?() click to toggle source
# File lib/omnibus/packagers/windows_base.rb, line 114
def machine_store?
  signing_identity[:machine_store]
end
sign_package(package_file) click to toggle source

signs the package with the given certificate

# File lib/omnibus/packagers/windows_base.rb, line 119
def sign_package(package_file)
  raise FailedToSignWindowsPackage.new unless is_signed?(package_file)
end
signing_identity(thumbprint = NULL, params = NULL) click to toggle source

Set the signing certificate name

@example

signing_identity 'FooCert'
signing_identity 'FooCert', store: 'BarStore'

@param [String] thumbprint

the thumbprint of the certificate in the certificate store

@param [Hash<Symbol, String>] params

an optional hash that defines the parameters for the singing identity

@option params [String] :store (My)

The name of the certificate store which contains the certificate

@option params [Array<String>, String] :timestamp_servers

A trusted timestamp server or a list of truested timestamp servers to
be tried. They are tried in the order provided.

@option params [TrueClass, FalseClass] :machine_store (false)

If set to true, the local machine store will be searched for a valid
certificate. Otherwise, the current user store is used

Setting nothing will default to trying ['http://timestamp.digicert.com',
'http://timestamp.verisign.com/scripts/timestamp.dll']

@return [Hash{:thumbprint => String, :store => String, :timestamp_servers => Array}]

# File lib/omnibus/packagers/windows_base.rb, line 45
def signing_identity(thumbprint = NULL, params = NULL)
  unless null?(thumbprint)
    @signing_identity = {}
    unless thumbprint.is_a?(String)
      raise InvalidValue.new(:signing_identity, "be a String")
    end

    @signing_identity[:thumbprint] = thumbprint

    if !null?(params)
      unless params.is_a?(Hash)
        raise InvalidValue.new(:params, "be a Hash")
      end

      valid_keys = %i{store machine_store algorithm keypair_alias}
      invalid_keys = params.keys - valid_keys
      unless invalid_keys.empty?

        # log a deprecated warning if timestamp_server is used
        if invalid_keys.include?(:timestamp_servers)
          log.deprecated(log_key) do
            "The signing_identity is updated to use smctl.exe. which does not require timestamp_servers" \
            "Please remove timestamp_servers from your signing_identity"
          end
        end

        raise InvalidValue.new(:params, "contain keys from [#{valid_keys.join(", ")}]. "\
                               "Found invalid keys [#{invalid_keys.join(", ")}]")
      end

      if !params[:machine_store].nil? && !(
         params[:machine_store].is_a?(TrueClass) ||
         params[:machine_store].is_a?(FalseClass))
        raise InvalidValue.new(:params, "contain key :machine_store of type TrueClass or FalseClass")
      end
    else
      params = {}
    end

    @signing_identity[:store] = params[:store] || "My"
    @signing_identity[:algorithm] = params[:algorithm] || "SHA256"
    @signing_identity[:machine_store] = params[:machine_store] || false
    @signing_identity[:keypair_alias] = params[:keypair_alias]
  end

  @signing_identity
end
thumbprint() click to toggle source
# File lib/omnibus/packagers/windows_base.rb, line 94
def thumbprint
  signing_identity[:thumbprint]
end
timestamp_servers() click to toggle source
# File lib/omnibus/packagers/windows_base.rb, line 106
def timestamp_servers
  signing_identity[:timestamp_servers]
end
windows_package_version() click to toggle source

Parse and return the version from the {Project#build_version}.

A project’s build_version looks something like:

dev builds => 11.14.0-alpha.1+20140501194641.git.94.561b564
           => 0.0.0+20140506165802.1

rel builds => 11.14.0.alpha.1 || 11.14.0

The appx and msi version specs expects a version that looks like X.Y.Z.W where X, Y, Z & W are all 32 bit integers.

@return [String]

# File lib/omnibus/packagers/windows_base.rb, line 194
def windows_package_version
  major, minor, patch = project.build_version.split(/[.+-]/)
  [major, minor, patch, project.build_iteration].join(".")
end