chpt11.txt revision 2573
.. 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
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, and insures that the package has not be altered.
The signature actions form a Merkle, or hash, 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 Solaris packages once they had be
determined to be qualified for production use; policy settings 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; it was decided
necessary to support the addition (or removal) of signatures (but not
other actions) in a manifest without invalidating the other signatures
that might be present. This feature also facilitates production
handoffs, 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 pkg.chain_certs attributes represent the packaging
hash of the pem file(s) containing the x.509 certificate(s)
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
pkg.sigval. The other certificates presented need to form a
certificate path that leads from the payload certificate to the trust
anchor(s) that was 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 signature types (pgp, for example) may be added in the
future.
Additional metadata can be added to a signature if desired, as with
any other action; such metadata is protected by that signature.
Policies may 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 may be added in the
future.
Publishing a signed manifest is a two step process. First, the
package is published unsigned, to a repository. The package is then
updated in place, using pkgsign, appending a signature action to the
manifest in the repository but leaving the package, including its
timestamp, intact. This process allows 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
may 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 with a warning. The pkgsign man page contains
examples of how to use pkgsign.
One current restriction to be aware of is that varianted signatures are ignored.
That means that doing a pkgmerge on a pair of manifests will invalidate any
signatures which were previously applied. It's safest if signing the package is
the last thing done to the package before it's made available to users.
Pkgsign does not perform all the possible checks for its inputs when signing
packages. This means it's important to check signed packages to insure 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. For
example, if a package's signature fails to verify, or if it's chain of trust
can't be verified or anchored to a trusted certificate, the package will fail to
install. What follows are some examples of different failure paths and what can
be done to resolve them.
Example 1::
pkg install: The certificate which issued this certificate:
could not be found. The issuer is:
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 1a::
pkg install: The certificate which issued this certificate:
could not be found. The issuer is:
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 2::
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 often
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 3::
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 three 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 is that there's a bug in pkg. The third, 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, pkgsign will sign
the package but the package's signature won't be verified.
Example 4::
pkg install: The certificate whose subject is
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 4a::
pkg install: The certificate whose subject is
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 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 5::
pkg install: The certificate whose subject is
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 happens 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 6::
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
redownload the certificate.
Example 7:
pkg install: This certificate was revoked:
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.