pep-0427 edits
This commit is contained in:
parent
c42dc66be1
commit
f1535d9c8c
138
pep-0427.txt
138
pep-0427.txt
|
@ -93,7 +93,7 @@ Recommended installer features
|
|||
Rewrite ``#!python``.
|
||||
In wheel, scripts are packaged in
|
||||
``{distribution}-{version}.data/scripts/``. If the first line of
|
||||
a file in ``scripts/`` starts with exactly b'#!python', rewrite to
|
||||
a file in ``scripts/`` starts with exactly ``b'#!python'``, rewrite to
|
||||
point to the correct interpreter. Unix installers may need to add
|
||||
the +x bit to these files if the archive was created on Windows.
|
||||
|
||||
|
@ -146,12 +146,26 @@ package's basic interpreter requirements and are detailed in PEP 425.
|
|||
File contents
|
||||
'''''''''''''
|
||||
|
||||
#. Wheel files contain a folder {distribution}-{version}.dist-info/
|
||||
with the PEP 426 metadata (Metadata version 1.3 or greater) and an
|
||||
additional file WHEEL with metadata about the archive itself.
|
||||
#. The root of a .whl is installed into one of purelib or platlib.
|
||||
#. Wheel files contain metadata about the wheel format itself in
|
||||
``{distribution}-{version}.dist-info/WHEEL``::
|
||||
The conents of a wheel file, where {distribution} is replaced with the
|
||||
name of the package, e.g. ``beaglevote`` and {version} is replaced with
|
||||
its version, e.g. ``1.0.0``, consist of:
|
||||
|
||||
#. ``/``, the root of the archive, contains all files to be installed in
|
||||
``purelib`` or ``platlib`` as specified in ``WHEEL``. ``purelib`` and
|
||||
``platlib`` are usually both ``site-packages``.
|
||||
#. ``{distribution}-{version}.dist-info/`` contains metadata.
|
||||
#. ``{distribution}-{version}.data/`` contains one subdirectory
|
||||
for each non-empty install scheme key not already covered, where
|
||||
the subdirectory name is an index into a dictionary of install paths
|
||||
(e.g. ``data``, ``scripts``, ``include``, ``purelib`, ``platlib``).
|
||||
#. Python scripts must appear in ``scripts`` and begin with exactly
|
||||
``b'#!python'`` in order to enjoy script wrapper generation and
|
||||
``#!python`` rewriting at install time. They may have any or no
|
||||
extension.
|
||||
#. ``{distribution}-{version}.dist-info/METADATA`` is Metadata version 1.3
|
||||
(PEP 426) or greater format metadata.
|
||||
#. ``{distribution}-{version}.dist-info/WHEEL`` is metadata about the archive
|
||||
itself::
|
||||
|
||||
Wheel-Version: 0.1
|
||||
Generator: bdist_wheel 0.7
|
||||
|
@ -163,16 +177,17 @@ File contents
|
|||
directory of the archive should be installed into purelib;
|
||||
otherwise the root should be installed into platlib.
|
||||
#. A wheel installer should warn if Wheel-Version is greater than the
|
||||
version it supports, and fail if Wheel-Version has a greater major
|
||||
version than the version it supports.
|
||||
#. If a .whl contains scripts, both purelib and platlib, or any other
|
||||
files that are not installed on ``sys.path``, they are found in
|
||||
``{distribution}-{version}.data/{key}``, where ``{key}`` is an
|
||||
index into a dictionary of install paths.
|
||||
version it supports, and must fail if Wheel-Version has a greater
|
||||
major version than the version it supports.
|
||||
#. Wheel, being an installation format that is intended to work across
|
||||
multiple versions of Python, does not generally include .pyc files.
|
||||
#. Wheel does not contain setup.py or setup.cfg.
|
||||
|
||||
This version of the wheel specification is based on the distutils install
|
||||
schemes and does not define how to install files to other locations.
|
||||
The layout offers a superset of the functionality provided by the existing
|
||||
wininst and egg binary formats.
|
||||
|
||||
|
||||
The .dist-info directory
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -232,10 +247,11 @@ RECORD.jws is not mentioned in RECORD at all. Every other file in the
|
|||
archive must have a correct hash in RECORD, or the installation will
|
||||
fail.
|
||||
|
||||
The signature is one or more JSON Web Signature JSON Serialization
|
||||
(JWS-JS) signatures stored in a file RECORD.jws adjacent to RECORD.
|
||||
The signature format is derived from the JSON Web Signatures (JWS)
|
||||
specification. One or more JSON Web Signature JSON Serialization (JWS-JS)
|
||||
signatures may be stored in a file RECORD.jws adjacent to RECORD.
|
||||
|
||||
A signature-aware installer can be instructed to check for a
|
||||
A signature-aware installer could be instructed to check for a
|
||||
particular Ed25519 public key by using an extended "extras" syntax.::
|
||||
|
||||
# request a normal optional feature "extra", and indicate
|
||||
|
@ -243,43 +259,36 @@ particular Ed25519 public key by using an extended "extras" syntax.::
|
|||
# urlsafe-b64encode-nopad encoded ed25519 public key:
|
||||
package[extra, ed25519=ouBJlTJJ4SJXoy8Bi1KRlewWLU6JW7HUXTgvU1YRuiA]
|
||||
|
||||
An application could distribute a requires.txt file with many such
|
||||
lines for all its dependencies and their public keys. By installing
|
||||
from this file an application's users would know whether the
|
||||
application's dependencies came from the correct publishers.
|
||||
An application could distribute a requires.txt file with many such lines
|
||||
for all its dependencies and their public keys. By installing from this
|
||||
file an application's users can know they are getting packages from the
|
||||
same publishers.
|
||||
|
||||
Applications that wish to "fail open" for backwards compatibility with
|
||||
non-signature-aware installers should specify that their package
|
||||
provides the extra ``ed25519=(key)`` with no associated dependencies.
|
||||
|
||||
Key distribution is outside the scope of this spec. Public wheel
|
||||
signing keys could be signed with the packager's GPG key or stored at
|
||||
an ``https://`` protected URL.
|
||||
|
||||
|
||||
JSON Web Signatures Extensions
|
||||
''''''''''''''''''''''''''''''
|
||||
|
||||
The Ed25519 algorithm is used as an extension to the JSON Web
|
||||
Signatures specification. Wheel uses ``alg="Ed25519"`` in the header.
|
||||
The key attribute holds the signature's public JSON Web Key. For JSON
|
||||
Web Key / JSON Private Key the verifying (public) key is called vk and
|
||||
The Ed25519 algorithm is used as an extension to the JSON Web Signatures
|
||||
specification. Wheel uses ``alg="Ed25519"`` in the header. The key
|
||||
attribute holds the signature's public JSON Web Key. In JSON Web Key
|
||||
/ JSON Private Key the Ed25519 verifying (public) key is called vk and
|
||||
the signing (private) key is called sk.
|
||||
|
||||
Example header::
|
||||
|
||||
{
|
||||
"alg": "Ed25519",
|
||||
"typ": "JWT",
|
||||
"key": {
|
||||
"alg": "Ed25519",
|
||||
"vk": "tmAYCrSfj8gtJ10v3VkvW7jOndKmQIYE12hgnFu3cvk"
|
||||
}
|
||||
"alg": "Ed25519",
|
||||
"jwk": {
|
||||
"alg": "Ed25519",
|
||||
"vk": "tmAYCrSfj8gtJ10v3VkvW7jOndKmQIYE12hgnFu3cvk"
|
||||
}
|
||||
}
|
||||
|
||||
A future version of wheel may omit ``typ``.
|
||||
|
||||
Example payload::
|
||||
Example payload, always the SHA-256 hash of RECORD::
|
||||
|
||||
{ "hash": "sha256=ADD-r2urObZHcxBW3Cr-vDCu5RJwT4CaRTHiFmbcIYY" }
|
||||
|
||||
|
@ -292,6 +301,7 @@ See
|
|||
- http://self-issued.info/docs/draft-jones-jose-jws-json-serialization.html
|
||||
- http://self-issued.info/docs/draft-ietf-jose-json-web-key.html
|
||||
- http://self-issued.info/docs/draft-jones-jose-json-private-key.html
|
||||
- http://ed25519.cr.yp.to/
|
||||
|
||||
|
||||
Comparison to .egg
|
||||
|
@ -328,29 +338,47 @@ Wheel defines a .data directory. Should I put all my data there?
|
|||
This specification does not have an opinion on how you should organize
|
||||
your code. The .data directory is just a place for any files that are
|
||||
not normally installed inside ``site-packages`` or on the PYTHONPATH.
|
||||
In other words, you may continue to use ``pkgutil.get_data(package,
|
||||
resource)`` even though *those* files will usually not be distributed
|
||||
in *wheel's* ``.data`` directory.
|
||||
|
||||
Why are you using Ed25519 and JWS instead of PGP, S/MIME, or ECDSA?
|
||||
Wheel's signing scheme is designed to protect against cryptography
|
||||
that is not used. Wheel tries to encourage signing by making it very
|
||||
fast and easy. Signature verification is encouraged by including
|
||||
the signature in the archive itself rather than making it a separate
|
||||
download, and by including a Python implementation of the entire
|
||||
signing system in the reference implementation.
|
||||
that is not used. The system yields a tiny, performant pure-Python
|
||||
implementation that can just be included with the reference installer.
|
||||
The 32-byte public keys are convienent to share directly in the
|
||||
same way you would share a SHA-256 digest. Since the signatures
|
||||
are inside the archive itself, they are more likely to be present
|
||||
at install time compared to detached signatures.
|
||||
|
||||
JWS and Ed25519 yield small, pure-Python implementations. Ed25519
|
||||
is fast enough that public-key cryptography can be considered for
|
||||
applications where it was traditionally too slow to be used, so
|
||||
wheels can be signed without worrying about performance. In Ed25519,
|
||||
unlike ECDSA, only key generation, but not signing, depends on
|
||||
a continuing high-quality source of entropy. The combination of
|
||||
increased performance, convenience, and availability compared to
|
||||
using a separate program means digital signatures can always be
|
||||
enabled in wheel.
|
||||
Wheel's signing system is designed to be used more like an md5 sum
|
||||
or a secure hash used to verify the integrity of an archive than
|
||||
something like PGP or X.509 signatures. A secure hash can verify
|
||||
the integrity of a single archive, but a wheel signing key verifies
|
||||
the signer of all packages signed with that key. Once you know to
|
||||
expect a particular signing key, a signature-verifying installer
|
||||
protects you from installing anything but intact packages from the
|
||||
expected signers. It makes no difference whether the wrong packages
|
||||
come from choosing the wrong package index, disk corruption, or an
|
||||
actual attack; if a package is not signed with the expected key,
|
||||
with its file contents matching their hashes in RECORD, then it will
|
||||
not be installed.
|
||||
|
||||
Appendix
|
||||
========
|
||||
|
||||
Example urlsafe-base64-nopad implementation::
|
||||
|
||||
# urlsafe-base64-nopad for Python 3
|
||||
import base64
|
||||
|
||||
def urlsafe_b64encode_nopad(data):
|
||||
return base64.urlsafe_b64encode(data).rstrip(b'=')
|
||||
|
||||
def urlsafe_b64decode_nopad(data):
|
||||
pad = b'=' * (4 - (len(data) & 3))
|
||||
return base64.urlsafe_b64decode(data + pad)
|
||||
|
||||
Wheel uses simplified keys and a signature system where key generation
|
||||
is about as fast as signing, making it possible to consider signing
|
||||
keys an abundant resource. Keys could represent a build server or
|
||||
a package rather than the publisher's entire digital identity.
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
|
Loading…
Reference in New Issue