2573N/A.. CDDL HEADER START
2525N/A
2573N/A.. The contents of this file are subject to the terms of the
2573N/A Common Development and Distribution License (the "License").
2573N/A You may not use this file except in compliance with the License.
2573N/A
2573N/A.. You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2573N/A or http://www.opensolaris.org/os/licensing.
2573N/A See the License for the specific language governing permissions
2573N/A and limitations under the License.
2573N/A
2573N/A.. When distributing Covered Code, include this CDDL HEADER in each
2573N/A file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2573N/A If applicable, add the following below this CDDL HEADER, with the
2573N/A fields enclosed by brackets "[]" replaced with your own identifying
2573N/A information: Portions Copyright [yyyy] [name of copyright owner]
2525N/A
2573N/A.. CDDL HEADER END
2573N/A
2573N/A.. Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
2573N/A
2573N/AChapter 11
2573N/A----------
2573N/A
2585N/ASigning Packages
2573N/A................
2573N/A
2585N/AOne important consideration in the design of IPS was being able to
2585N/Avalidate that the software installed on the customer's machine was
2585N/Aactually as originally specified by the publisher. This ability to
2585N/Avalidate the installed system is key for both the customer and the
2585N/Asupport engineering staff.
2585N/A
2585N/ATo support this validation, manifests can be signed in IPS with the
2573N/Asignatures becoming part of the manifest. Signatures are represented
2585N/Aas actions like all other manifest content. Since manifests contain
2585N/Aall the package metadata - file permissions, ownership, content
2585N/Ahashes, etc., a ``signature`` action that validates that the manifest has
2585N/Anot be altered since it was published is an important part of system
2585N/Avalidation.
2585N/A
2585N/AThe ``signature`` actions form a tree that includes the delivered binaries
2525N/Asuch that complete verification of the installed software is possible.
2585N/A
2525N/AThere are other uses for manifest signing beyond validation; signatures
2525N/Acan also be used to indicate approval by other organizations or parties.
2525N/A
2525N/AFor example, the internal QA organization could sign manifests of packages
2525N/Aonce it was determined the packages were qualified for production use.
2585N/APolicy could mandate such approvals prior to installation.
2585N/A
2585N/AAs a result, a useful characteristic for signatures is to be
2585N/Aindependent of other signatures in a manifest. Signatures can be
2525N/Aadded or removed without invalidating the other signatures
2585N/Athat might be present. This feature also facilitates production
2585N/Ahand offs, with signatures used along the path to indicate completion
2585N/Aalong the way. Subsequent steps can optionally remove previous
2525N/Asignatures at any time without ill effect.
2585N/A
2585N/A``signature`` actions look like this::
2525N/A
2585N/A signature <hash of certificate> algorithm=<signature algorithm> \
2585N/A value=<signature value> \
2585N/A chain="<hashes of certs needed to validate primary certificate>" \
2585N/A version=<pkg version of signature>
2525N/A
2573N/AThe payload and ``chain`` attributes represent the packaging
2573N/Ahash of the PEM (Privacy Enhanced Mail) files, containing the
2585N/Ax.509 certificates downloadable from the originating repository.
2585N/AThe value is the signed hash of the manifest's message text, prepared
2573N/Aas discussed below. The payload certificate is the certificate which
2573N/Averifies the value in ``value``.
2585N/A
2585N/AThe other certificates presented needs to form a
2585N/Acertificate path that leads from the payload certificate to the trust
2585N/Aanchors that were established as part of the publisher configuration.
2585N/A
2525N/ATwo types of signature algorithms are currently supported. The first
2585N/Ais the RSA group of signature algorithms; an example is ``rsa-sha256``.
2585N/AThe bit after the dash specifies the hash algorithm to use to change
2585N/Athe message text into a single value the RSA algorithm can use.
2585N/A
2585N/AThe second type of signature algorithm is compute the hash only. This
2585N/Atype of algorithm exists primarily for testing and process
2585N/Averification purposes and presents the hash as the signature value. A
2573N/Asignature action of this type is indicated by the lack of a payload
2525N/Acertificate hash. This type of signature action is verified if the
2573N/Aimage is configured to check signatures. Its presence however does
2573N/Anot count as a signature if signatures are required::
2573N/A
2573N/A signature algorithm=<hash algorithm> value=<hash> \
2573N/A version=<pkg version of signature>
2573N/A
2573N/A
2573N/AAdditional metadata can be added to a signature if desired, as with
2573N/Aany other action. Such metadata is protected by that signature.
2573N/A
2573N/APolicies can be set for the image or for specific publishers. The
2573N/Apolicies include ignoring signatures, verifying existing signatures,
2573N/Arequiring signatures, and requiring that specific common names must be
2573N/Aseen in the chain of trust. Other policies might be added in the
2573N/Afuture.
2585N/A
2585N/A
2585N/APublishing a signed manifest is a two step process:
2585N/A
2585N/A1. Publish the package unsigned to a repository.
2585N/A2. Update the package in place, using |pkgsign| to append
2585N/A a signature action to the manifest in the repository.
2585N/A
2585N/AThis process leaves the package intact, including its timestamp.
2585N/A
2585N/AThis process enables a signature action to be added
2585N/Aby someone other than the publisher without invalidating the original
2585N/Apublisher's signature. For example, the QA department of a company
2585N/Amight want to sign all packages that are installed internally to
2585N/Aindicate they have been approved for use, but not republish the
2585N/Apackages, which would create a new timestamp and invalidate the
2585N/Asignature of the original publisher.
2585N/A
2585N/ANote that |pkgsign| is the only way to publish a signed package. If one
2585N/Aattempts to publish a package already containing a signature, that
2585N/Asignature is removed and a warning is emitted. The |pkgsign| man page
2585N/Acontains examples of how to use |pkgsign|.
2585N/A
2585N/AOne current restriction to be aware of is that signature actions with variants
2585N/Aare ignored. That means that doing a |pkgmerge| on a pair of manifests will
2585N/Ainvalidate any signatures which were previously applied. Signing the package
2585N/Ashould be the last step of the package development before the package is tested.
2585N/A
2585N/A|pkgsign| does not perform all the possible checks for its inputs when signing
2585N/Apackages. This means it's important to check signed packages to ensure that
2585N/Athey can be properly installed after being signed. What follows are some of the
2585N/Aerrors that can appear when attempting to install or update a signed package
2585N/Aalong with explanations of what the errors mean and how to solve the problem.
2585N/A
2585N/A
2585N/AErrors Involving Signed Packages
2585N/A~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2585N/A
2585N/AA signed package can fail to install or update for reasons that are unique to
2585N/Asigned packages. For example, if a package's signature fails to verify, or if
2585N/Aits chain of trust can't be verified or anchored to a trusted certificate, the
2585N/Apackage will fail to install.
2585N/A
2585N/AWhen installing signed packages, certain image properties will influence the
2585N/Achecks 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.