mirror of
https://codeberg.org/Toasterson/ips.git
synced 2026-04-10 21:30:41 +00:00
362 lines
15 KiB
Text
362 lines
15 KiB
Text
|
|
.. CDDL HEADER START
|
|||
|
|
|
|||
|
|
.. The contents of this file are subject to the terms of the
|
|||
|
|
Common Development and Distribution License (the "License").
|
|||
|
|
You may not use this file except in compliance with the License.
|
|||
|
|
|
|||
|
|
.. You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
|||
|
|
or http://www.opensolaris.org/os/licensing.
|
|||
|
|
See the License for the specific language governing permissions
|
|||
|
|
and limitations under the License.
|
|||
|
|
|
|||
|
|
.. When distributing Covered Code, include this CDDL HEADER in each
|
|||
|
|
file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
|||
|
|
If applicable, add the following below this CDDL HEADER, with the
|
|||
|
|
fields enclosed by brackets "[]" replaced with your own identifying
|
|||
|
|
information: Portions Copyright [yyyy] [name of copyright owner]
|
|||
|
|
|
|||
|
|
.. CDDL HEADER END
|
|||
|
|
|
|||
|
|
.. Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
|||
|
|
|
|||
|
|
Chapter 11
|
|||
|
|
----------
|
|||
|
|
|
|||
|
|
Signing Packages
|
|||
|
|
................
|
|||
|
|
|
|||
|
|
One important consideration in the design of IPS was being able to
|
|||
|
|
validate that the software installed on the customer's machine was
|
|||
|
|
actually as originally specified by the publisher. This ability to
|
|||
|
|
validate the installed system is key for both the customer and the
|
|||
|
|
support engineering staff.
|
|||
|
|
|
|||
|
|
To support this validation, manifests can be signed in IPS with the
|
|||
|
|
signatures becoming part of the manifest. Signatures are represented
|
|||
|
|
as actions like all other manifest content. Since manifests contain
|
|||
|
|
all the package metadata - file permissions, ownership, content
|
|||
|
|
hashes, etc., a ``signature`` action that validates that the manifest has
|
|||
|
|
not be altered since it was published is an important part of system
|
|||
|
|
validation.
|
|||
|
|
|
|||
|
|
The ``signature`` actions form a tree that includes the delivered binaries
|
|||
|
|
such that complete verification of the installed software is possible.
|
|||
|
|
|
|||
|
|
There are other uses for manifest signing beyond validation; signatures
|
|||
|
|
can also be used to indicate approval by other organizations or parties.
|
|||
|
|
|
|||
|
|
For example, the internal QA organization could sign manifests of packages
|
|||
|
|
once it was determined the packages were qualified for production use.
|
|||
|
|
Policy could mandate such approvals prior to installation.
|
|||
|
|
|
|||
|
|
As a result, a useful characteristic for signatures is to be
|
|||
|
|
independent of other signatures in a manifest. Signatures can be
|
|||
|
|
added or removed without invalidating the other signatures
|
|||
|
|
that might be present. This feature also facilitates production
|
|||
|
|
hand offs, with signatures used along the path to indicate completion
|
|||
|
|
along the way. Subsequent steps can optionally remove previous
|
|||
|
|
signatures at any time without ill effect.
|
|||
|
|
|
|||
|
|
``signature`` actions look like this::
|
|||
|
|
|
|||
|
|
signature <hash of certificate> algorithm=<signature algorithm> \
|
|||
|
|
value=<signature value> \
|
|||
|
|
chain="<hashes of certs needed to validate primary certificate>" \
|
|||
|
|
version=<pkg version of signature>
|
|||
|
|
|
|||
|
|
The payload and ``chain`` attributes represent the packaging
|
|||
|
|
hash of the PEM (Privacy Enhanced Mail) files, containing the
|
|||
|
|
x.509 certificates downloadable from the originating repository.
|
|||
|
|
The value is the signed hash of the manifest's message text, prepared
|
|||
|
|
as discussed below. The payload certificate is the certificate which
|
|||
|
|
verifies the value in ``value``.
|
|||
|
|
|
|||
|
|
The other certificates presented needs to form a
|
|||
|
|
certificate path that leads from the payload certificate to the trust
|
|||
|
|
anchors that were established as part of the publisher configuration.
|
|||
|
|
|
|||
|
|
Two types of signature algorithms are currently supported. The first
|
|||
|
|
is the RSA group of signature algorithms; an example is ``rsa-sha256``.
|
|||
|
|
The bit after the dash specifies the hash algorithm to use to change
|
|||
|
|
the message text into a single value the RSA algorithm can use.
|
|||
|
|
|
|||
|
|
The second type of signature algorithm is compute the hash only. This
|
|||
|
|
type of algorithm exists primarily for testing and process
|
|||
|
|
verification purposes and presents the hash as the signature value. A
|
|||
|
|
signature action of this type is indicated by the lack of a payload
|
|||
|
|
certificate hash. This type of signature action is verified if the
|
|||
|
|
image is configured to check signatures. Its presence however does
|
|||
|
|
not count as a signature if signatures are required::
|
|||
|
|
|
|||
|
|
signature algorithm=<hash algorithm> value=<hash> \
|
|||
|
|
version=<pkg version of signature>
|
|||
|
|
|
|||
|
|
|
|||
|
|
Additional metadata can be added to a signature if desired, as with
|
|||
|
|
any other action. Such metadata is protected by that signature.
|
|||
|
|
|
|||
|
|
Policies can be set for the image or for specific publishers. The
|
|||
|
|
policies include ignoring signatures, verifying existing signatures,
|
|||
|
|
requiring signatures, and requiring that specific common names must be
|
|||
|
|
seen in the chain of trust. Other policies might be added in the
|
|||
|
|
future.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Publishing a signed manifest is a two step process:
|
|||
|
|
|
|||
|
|
1. Publish the package unsigned to a repository.
|
|||
|
|
2. Update the package in place, using |pkgsign| to append
|
|||
|
|
a signature action to the manifest in the repository.
|
|||
|
|
|
|||
|
|
This process leaves the package intact, including its timestamp.
|
|||
|
|
|
|||
|
|
This process enables a signature action to be added
|
|||
|
|
by someone other than the publisher without invalidating the original
|
|||
|
|
publisher's signature. For example, the QA department of a company
|
|||
|
|
might want to sign all packages that are installed internally to
|
|||
|
|
indicate they have been approved for use, but not republish the
|
|||
|
|
packages, which would create a new timestamp and invalidate the
|
|||
|
|
signature of the original publisher.
|
|||
|
|
|
|||
|
|
Note that |pkgsign| is the only way to publish a signed package. If one
|
|||
|
|
attempts to publish a package already containing a signature, that
|
|||
|
|
signature is removed and a warning is emitted. The |pkgsign| man page
|
|||
|
|
contains examples of how to use |pkgsign|.
|
|||
|
|
|
|||
|
|
One current restriction to be aware of is that signature actions with variants
|
|||
|
|
are ignored. That means that doing a |pkgmerge| on a pair of manifests will
|
|||
|
|
invalidate any signatures which were previously applied. Signing the package
|
|||
|
|
should be the last step of the package development before the package is tested.
|
|||
|
|
|
|||
|
|
|pkgsign| does not perform all the possible checks for its inputs when signing
|
|||
|
|
packages. This means it's important to check signed packages to ensure that
|
|||
|
|
they can be properly installed after being signed. What follows are some of the
|
|||
|
|
errors that can appear when attempting to install or update a signed package
|
|||
|
|
along with explanations of what the errors mean and how to solve the problem.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Errors Involving Signed Packages
|
|||
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
|
|
|||
|
|
A signed package can fail to install or update for reasons that are unique to
|
|||
|
|
signed packages. For example, if a package's signature fails to verify, or if
|
|||
|
|
its chain of trust can't be verified or anchored to a trusted certificate, the
|
|||
|
|
package will fail to install.
|
|||
|
|
|
|||
|
|
When installing signed packages, certain image properties will influence the
|
|||
|
|
checks that are performed on packages. These properties are:
|
|||
|
|
|
|||
|
|
* ``signature-policy``
|
|||
|
|
* ``signature-required-names``
|
|||
|
|
* ``trust-anchor-directory``
|
|||
|
|
|
|||
|
|
See the |pkg| man page for further information about these properties, and their
|
|||
|
|
permitted values.
|
|||
|
|
|
|||
|
|
What follows are some examples of different failure paths and what can
|
|||
|
|
be done to resolve them.
|
|||
|
|
|
|||
|
|
Example 1: Chain Certificate Not Found
|
|||
|
|
``````````````````````````````````````
|
|||
|
|
::
|
|||
|
|
|
|||
|
|
pkg install: The certificate which issued this certificate:
|
|||
|
|
/C=US/ST=California/L=Menlo Park/O=pkg5/CN=cs1_ch1_ta3/emailAddress=cs1_ch1_ta3
|
|||
|
|
could not be found. The issuer is:
|
|||
|
|
/C=US/ST=California/L=Menlo Park/O=pkg5/CN=ch1_ta3/emailAddress=ch1_ta3
|
|||
|
|
|
|||
|
|
The package involved is:pkg://test/example_pkg@1.0,5.11-0:20110919T184152Z
|
|||
|
|
|
|||
|
|
The error shown above happens when a certificate in the chain of trust is
|
|||
|
|
missing or otherwise erroneous.
|
|||
|
|
|
|||
|
|
In this case, there were three certificates in the chain of trust when the
|
|||
|
|
package was signed. It was rooted in the trust anchor, a certificate named
|
|||
|
|
``ta3``. ``ta3`` signed a chain cert named ``ch1_ta3``.
|
|||
|
|
|
|||
|
|
``ch1_ta3`` signed a code signing certificate named ``cs1_ch1_ta3``. When |pkg|
|
|||
|
|
tried to install the package, it was able to locate the code signing
|
|||
|
|
certificate, ``cs1_ch1_ta3``, but it couldn't locate the chain certificate,
|
|||
|
|
``ch1_ta3``, so the chain of trust could not be established.
|
|||
|
|
|
|||
|
|
The most common cause of this problem is failing to provide the right
|
|||
|
|
certificate(s) to the ``-i`` option of |pkgsign|.
|
|||
|
|
|
|||
|
|
Example 2: Authorized Certificate Not Found
|
|||
|
|
```````````````````````````````````````````
|
|||
|
|
|
|||
|
|
::
|
|||
|
|
|
|||
|
|
pkg install: The certificate which issued this certificate:
|
|||
|
|
/C=US/ST=California/L=Menlo Park/O=pkg5/CN=cs1_cs8_ch1_ta3/emailAddress=cs1_cs8_ch1_ta3
|
|||
|
|
could not be found. The issuer is:
|
|||
|
|
/C=US/ST=California/L=Menlo Park/O=pkg5/CN=cs8_ch1_ta3/emailAddress=cs8_ch1_ta3
|
|||
|
|
The package involved is:pkg://test/example_pkg@1.0,5.11-0:20110919T201101Z
|
|||
|
|
|
|||
|
|
The error shown above is similar to the error in *Example 1* but has a different
|
|||
|
|
cause.
|
|||
|
|
|
|||
|
|
In this case, the package was signed using the ``cs1_cs8_ch1_ta3``
|
|||
|
|
certificate, which was signed by the ``cs8_ch1_ta3`` certificate.
|
|||
|
|
|
|||
|
|
The problem is that the ``cs8_ch1_ta3`` certificate wasn't authorized to sign
|
|||
|
|
other certificates. (To be specific, the ``cs8_ch1_ta3`` certificate had the
|
|||
|
|
``basicConstraints`` extension set to ``CA:false`` and marked critical.)
|
|||
|
|
|
|||
|
|
When |pkg| verifies the chain of trust, it doesn't find a certificate which was
|
|||
|
|
allowed to sign the ``cs1_cs8_ch1_ta3`` certificate. Since the chain of trust
|
|||
|
|
can't be verified from the leaf to the root, |pkg| prevents the package from
|
|||
|
|
being installed.
|
|||
|
|
|
|||
|
|
|
|||
|
|
Example 3: Untrusted Self-Signed Certificate
|
|||
|
|
````````````````````````````````````````````
|
|||
|
|
|
|||
|
|
::
|
|||
|
|
|
|||
|
|
pkg install: Chain was rooted in an untrusted self-signed certificate.
|
|||
|
|
The package involved is:pkg://test/example_pkg@1.0,5.11-0:20110919T185335Z
|
|||
|
|
|
|||
|
|
The error shown above happens when a chain of trust ends in a self-signed
|
|||
|
|
certificate which isn't trusted by the system.
|
|||
|
|
|
|||
|
|
When a developer creates a chain of certificates using ``openssl`` for testing,
|
|||
|
|
the root certificate is usually self-signed, since there's little reason to have
|
|||
|
|
an outside company verify a certificate only used for testing.
|
|||
|
|
|
|||
|
|
In a test situation, there are two solutions.
|
|||
|
|
|
|||
|
|
The first is to add the self-signed certificate which is the root of the chain
|
|||
|
|
of trust into ``/etc/certs/CA`` and refresh the ``system/ca-certificates``
|
|||
|
|
service.
|
|||
|
|
|
|||
|
|
This mirrors the likely situation customers will encounter where a production
|
|||
|
|
package is signed with a certificate that's ultimately rooted in a certificate
|
|||
|
|
that's delivered with the operating system as a trust anchor.
|
|||
|
|
|
|||
|
|
The second solution is to approve the self-signed certificate for the publisher
|
|||
|
|
which offers the package for testing by using the ``--approve-ca-cert``
|
|||
|
|
option for the ``set-publisher`` subcommand to |pkg|.
|
|||
|
|
|
|||
|
|
Example 4: Signature Value Does Not Match Expected Value
|
|||
|
|
````````````````````````````````````````````````````````
|
|||
|
|
|
|||
|
|
::
|
|||
|
|
|
|||
|
|
pkg install: A signature in pkg://test/example_pkg@1.0,5.11-0:20110919T195801Z
|
|||
|
|
could not be verified for this reason:
|
|||
|
|
The signature value did not match the expected value. Res: 0
|
|||
|
|
The signature's hash is 0ce15c572961b7a0413b8390c90b7cac18ee9010
|
|||
|
|
|
|||
|
|
The error shown above happens when the value on the signature action could not
|
|||
|
|
be verified using the certificate which the action claims was paired with the
|
|||
|
|
key used to sign the package.
|
|||
|
|
|
|||
|
|
There are two possible causes for an error like this.
|
|||
|
|
|
|||
|
|
The first is that the package has been changed since it was signed. This
|
|||
|
|
is unlikely to happen since |pkgsend| will strip existing signature actions
|
|||
|
|
during publication (since the new timestamp the package will get will invalidate
|
|||
|
|
the old signature) but is possible if the package's manifest has been hand
|
|||
|
|
edited since signing.
|
|||
|
|
|
|||
|
|
The second, and most likely cause, is that the key and certificate used to the
|
|||
|
|
sign the package weren't a matched pair. If the certificate given to the
|
|||
|
|
``-c`` option of |pkgsign| wasn't created with the key given to the
|
|||
|
|
``-k`` option of |pkgsign|, the package is signed, but its signature won't
|
|||
|
|
be verified.
|
|||
|
|
|
|||
|
|
Example 5: Unknown Critical Extension
|
|||
|
|
`````````````````````````````````````
|
|||
|
|
|
|||
|
|
::
|
|||
|
|
|
|||
|
|
pkg install: The certificate whose subject is
|
|||
|
|
/C=US/ST=California/L=Menlo Park/O=pkg5/CN=cs2_ch1_ta3/emailAddress=cs2_ch1_ta3
|
|||
|
|
could not be verified because it uses a critical extension that pkg5 cannot
|
|||
|
|
handle yet. Extension name:issuerAltName
|
|||
|
|
Extension value:<EMPTY>
|
|||
|
|
|
|||
|
|
The error above happens when a certificate in the chain of trust uses a critical
|
|||
|
|
extension which |pkg| doesn't understand.
|
|||
|
|
|
|||
|
|
Until |pkg| learns how to process that critical extension, the only solution is
|
|||
|
|
to regenerate the certificate without the problematic critical extension.
|
|||
|
|
|
|||
|
|
Example 6: Unknown Extension Value
|
|||
|
|
``````````````````````````````````
|
|||
|
|
|
|||
|
|
::
|
|||
|
|
|
|||
|
|
pkg install: The certificate whose subject is
|
|||
|
|
/C=US/ST=California/L=Menlo Park/O=pkg5/CN=cs5_ch1_ta3/emailAddress=cs5_ch1_ta3
|
|||
|
|
could not be verified because it has an extension with a value that pkg(5)
|
|||
|
|
does not understand.
|
|||
|
|
Extension name:keyUsage
|
|||
|
|
Extension value:Encipher Only
|
|||
|
|
|
|||
|
|
The error above is similar to the error in *Example 5* except that the problem is
|
|||
|
|
not with an unfamiliar critical extension but with a value that |pkg| doesn't
|
|||
|
|
understand for an extension which |pkg| does understand.
|
|||
|
|
|
|||
|
|
In this case, |pkg| understands the ``keyUsage`` extension, but doesn't
|
|||
|
|
understand the value ‘``Encipher Only``.’ The error will look the same whether
|
|||
|
|
the extension in question is critical or not.
|
|||
|
|
|
|||
|
|
The solution, until |pkg| learns about the value in question, is to remove the
|
|||
|
|
value from the extension, or remove the extension entirely.
|
|||
|
|
|
|||
|
|
Example 7: Unauthorized Use of Certificate
|
|||
|
|
``````````````````````````````````````````
|
|||
|
|
|
|||
|
|
::
|
|||
|
|
|
|||
|
|
pkg install: The certificate whose subject is
|
|||
|
|
/C=US/ST=California/L=Menlo Park/O=pkg5/CN=ch1_ta3/emailAddress=ch1_ta3
|
|||
|
|
could not be verified because it has been used inappropriately.
|
|||
|
|
The way it is used means that the value for extension keyUsage must include
|
|||
|
|
'DIGITAL SIGNATURE' but the value was 'Certificate Sign, CRL Sign'.
|
|||
|
|
|
|||
|
|
The error above occurs when a certificate has been used for a purpose for which
|
|||
|
|
it was not authorized.
|
|||
|
|
|
|||
|
|
In this case, the certificate ``ch1_ta3`` has been used to sign the package.
|
|||
|
|
It's ``keyUsage`` extension means that it's only valid to use that certificate
|
|||
|
|
to sign other certificates and CRL's.
|
|||
|
|
|
|||
|
|
Example 8: Unexpected Hash Value
|
|||
|
|
````````````````````````````````
|
|||
|
|
|
|||
|
|
::
|
|||
|
|
|
|||
|
|
pkg install: Certificate
|
|||
|
|
/tmp/ips.test.7149/0/image0/var/pkg/publisher/test/certs/0ce15c572961b7a0413b8390c90b7cac18ee9010
|
|||
|
|
has been modified on disk. Its hash value is not what was expected.
|
|||
|
|
|
|||
|
|
The error above means what it says.
|
|||
|
|
|
|||
|
|
The certificate at the provided path is used to verify the package being
|
|||
|
|
installed but the hash of the contents on disk don't match what the signature
|
|||
|
|
action thought they should be.
|
|||
|
|
|
|||
|
|
This indicates that the certificate has been changed since it was last retrieved
|
|||
|
|
from the publisher.
|
|||
|
|
|
|||
|
|
The simple solution is to remove the certificate and allow |pkg| to download
|
|||
|
|
the certificate again.
|
|||
|
|
|
|||
|
|
Example 9: Revoked Certificate
|
|||
|
|
``````````````````````````````
|
|||
|
|
|
|||
|
|
::
|
|||
|
|
|
|||
|
|
pkg install: This certificate was revoked:
|
|||
|
|
/C=US/ST=California/L=Menlo Park/O=pkg5/CN=cs1_ch1_ta4/emailAddress=cs1_ch1_ta4
|
|||
|
|
for this reason: None
|
|||
|
|
The package involved is: pkg://test/example_pkg@1.0,5.11-0:20110919T205539Z
|
|||
|
|
|
|||
|
|
The error above indicates the certificate in question, which was in the chain of
|
|||
|
|
trust for the package to be installed, was revoked by the issuer of the
|
|||
|
|
certificate.
|
|||
|
|
|