(#23349) Create autosign setting for input validation

This commit adds adds a new 'autosign' setting for the autosign command.
There are two reasons we're doing this: first, setting validation is
best done with a new setting class, and second, defining a hook for a
setting that might interpolate an application setting can cause the
interpolation to fail. By moving validation to a setting class, we can
sidestep this issue for now.

Jira issue: PUP-932
(#23349) Defer setting hooks to post app init when needed

Defining a hook for settings can force that setting to be interpolated
before all settings are loaded, which will fail. This commit allows
setting hooks to be deferred after application initialization, so that
values can be properly interpolated before invoking the hook.

Jira issue: PUP-932
(#23366) Ensure we require ffi before using it

We use ffi on windows in 4 files, but only required it in 3, which could
prevent puppet on windows from running with the error:

    uninitialized constant Puppet::Util::Windows::Security::API::FFI (NameError)

This commit ensure we require ffi before using it.
Merge remote-tracking branch 'joshcooper/ticket/stable/23366-require-ffi' into stable

* joshcooper/ticket/stable/23366-require-ffi:
  (#23366) Ensure we require ffi before using it
Merge branch 'pr/2127' into stable

* pr/2127:
  (#23349) Defer setting hooks to post app init when needed
  (#23349) Create autosign setting for input validation
(Maint) Expand paths for windows

The path /path/to/file is not absolute on windows, causing the specs to fail.
(#23369) Allow caller to override YAML.load_file returning false

According to https://github.com/tenderlove/psych/issues/149, Syck and
Psych return false when ::YAML.load_file tries to parse an empty file.

Since Puppet::Indirector::Yaml#find calls Puppet::Util::Yaml.load_file
directly, we can't change the semantics of what it returns.

Instead we allow the caller to explicitly specify what the default value
should be.
(maint) Add f20 to default mocks
(#23369) Handle invalid CSR attribute contents

Previously, Puppet::Util::Yaml.load_file returned false when the file
was empty, causing the CSR attributes code to call non-existent methods
on `false`.

In addition, the code assumed that the YAML file contained a Hash, and
attempted to invoke non-existent methods on the loaded object.

This commit passes in a fallback value for the load_file invocation,
so that if the file is empty or contains only whitespace, we still
generate the CSR.

But if the file contains something other than a Hash, e.g. Arrray, then
we raise an exception so we don't generate a CSR with unexpected data.

Tests based on work by Josh Partlow <joshua.partlow@puppetlabs.com>
Paired-with: Adrien Thebo <adrien@puppetlabs.com>
Merge pull request #2131 from joshcooper/ticket/stable/23369-empty-csr-attributes

(#23369) Handle invalid csr attributes
Merge pull request #2125 from melissaanne/ticket/stable/re-597-add-f20

(maint) Add f20 to default mocks