From 333fb1024e20fa10ec3e85cbd196cbdff059000d Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 31 Oct 2013 10:27:35 -0700 Subject: Docs --- docs/fernet.rst | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 1 + 2 files changed, 49 insertions(+) create mode 100644 docs/fernet.rst (limited to 'docs') diff --git a/docs/fernet.rst b/docs/fernet.rst new file mode 100644 index 00000000..938ba0cb --- /dev/null +++ b/docs/fernet.rst @@ -0,0 +1,48 @@ +Fernet +====== + +.. currentmodule:: cryptography.fernet + +.. testsetup:: + + import binascii + key = binascii.unhexlify(b"0" * 32) + + +`Fernet`_ is an implementation of symmetric (also known as "secret key") +authenticated cryptography. Fernet provides guarntees that a message encrypted +using it cannot be manipulated or read without the key. + +.. class:: Fernet(key) + + This class provides both encryption and decryption facilities. + + .. doctest:: + + >>> from cryptography.fernet import Fernet + >>> f = Fernet(key) + >>> ciphertext = f.encrypt(b"my deep dark secret") + >>> f.decrypt(ciphertext) + 'my deep dark secret' + + :param bytes key: A 32-byte key. This **must** be kept secret. Anyone with + this key is able to create and read messages. + + + .. method:: encrypt(plaintext) + + :param bytes plaintext: The message you would like to encrypt. + :returns bytes: A secure message which cannot be read or altered + without the key. + + .. method:: decrypt(ciphertext, ttl=None) + + :param bytes ciphertext: An encrypted message. + :param int ttl: Optionally, the number of seconds old a message may be + for it to be valid. If the message is older than + ``ttl`` seconds (from the time it was originally + created) an exception will be raised. + :returns bytes: The original plaintext. + + +.. _`Fernet`: https://github.com/fernet/spec/ diff --git a/docs/index.rst b/docs/index.rst index 4fd5d3be..b9c5b5fb 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -30,6 +30,7 @@ Contents .. toctree:: :maxdepth: 2 + fernet architecture contributing security -- cgit v1.2.3 From de475eb9f56a34868c7debb707427ab5678eda6c Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 31 Oct 2013 10:35:19 -0700 Subject: Improve the docs --- docs/fernet.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/fernet.rst b/docs/fernet.rst index 938ba0cb..ac610eb8 100644 --- a/docs/fernet.rst +++ b/docs/fernet.rst @@ -22,6 +22,9 @@ using it cannot be manipulated or read without the key. >>> from cryptography.fernet import Fernet >>> f = Fernet(key) >>> ciphertext = f.encrypt(b"my deep dark secret") + # Secret bytes. + >>> ciphertext + '...' >>> f.decrypt(ciphertext) 'my deep dark secret' @@ -33,7 +36,7 @@ using it cannot be manipulated or read without the key. :param bytes plaintext: The message you would like to encrypt. :returns bytes: A secure message which cannot be read or altered - without the key. + without the key. It is URL safe base64-encoded. .. method:: decrypt(ciphertext, ttl=None) -- cgit v1.2.3 From 13e0d54510d3f939c749d3efc810bad675f4f908 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 31 Oct 2013 10:38:04 -0700 Subject: Be explicit --- docs/fernet.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/fernet.rst b/docs/fernet.rst index ac610eb8..d44e737b 100644 --- a/docs/fernet.rst +++ b/docs/fernet.rst @@ -44,7 +44,9 @@ using it cannot be manipulated or read without the key. :param int ttl: Optionally, the number of seconds old a message may be for it to be valid. If the message is older than ``ttl`` seconds (from the time it was originally - created) an exception will be raised. + created) an exception will be raised. If ``ttl`` is not + provided (or is ``None``), the age of the message is + not considered. :returns bytes: The original plaintext. -- cgit v1.2.3 From 36e2df0955aa1c6534049be21868c24e93569b8b Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 31 Oct 2013 10:40:17 -0700 Subject: Fixed keylength in example --- docs/fernet.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/fernet.rst b/docs/fernet.rst index d44e737b..33488891 100644 --- a/docs/fernet.rst +++ b/docs/fernet.rst @@ -6,7 +6,7 @@ Fernet .. testsetup:: import binascii - key = binascii.unhexlify(b"0" * 32) + key = binascii.unhexlify(b"0" * 64) `Fernet`_ is an implementation of symmetric (also known as "secret key") -- cgit v1.2.3 From 5ac6524f790713090754572fb775405f64a87df2 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 31 Oct 2013 11:28:13 -0700 Subject: fix --- docs/fernet.rst | 1 - 1 file changed, 1 deletion(-) (limited to 'docs') diff --git a/docs/fernet.rst b/docs/fernet.rst index 33488891..02b99705 100644 --- a/docs/fernet.rst +++ b/docs/fernet.rst @@ -22,7 +22,6 @@ using it cannot be manipulated or read without the key. >>> from cryptography.fernet import Fernet >>> f = Fernet(key) >>> ciphertext = f.encrypt(b"my deep dark secret") - # Secret bytes. >>> ciphertext '...' >>> f.decrypt(ciphertext) -- cgit v1.2.3 From 9626b5a50460d2f90baa1f1b8c6a09ccc900c178 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 19 Nov 2013 16:49:26 -0800 Subject: Validate the IV/nonce length for a given algorithm. Fixes #159 --- docs/hazmat/primitives/interfaces.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'docs') diff --git a/docs/hazmat/primitives/interfaces.rst b/docs/hazmat/primitives/interfaces.rst index 11cff51a..e798c0e6 100644 --- a/docs/hazmat/primitives/interfaces.rst +++ b/docs/hazmat/primitives/interfaces.rst @@ -56,6 +56,18 @@ Interfaces used by the symmetric cipher modes described in The name may be used by a backend to influence the operation of a cipher in conjunction with the algorithm's name. + .. method:: validate_for_algorithm(algorithm) + + :param CipherAlgorithm algorithm: + + Checks that the combination of this mode with the provided algorithm + meets any necessary invariants. This should raise an exception if they + are not met. + + For example, the :class:`~cryptography.hazmat.primitives.modes.CBC` + mode uses this method to check that the provided initialization + vector's length matches the block size of the algorithm. + .. class:: ModeWithInitializationVector -- cgit v1.2.3 From 43307c7b57b5d2cbee01f1a89eae212d2325ca40 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 21 Nov 2013 21:50:14 -0800 Subject: Fixed a typo --- docs/fernet.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'docs') diff --git a/docs/fernet.rst b/docs/fernet.rst index 02b99705..e4756c09 100644 --- a/docs/fernet.rst +++ b/docs/fernet.rst @@ -5,12 +5,13 @@ Fernet .. testsetup:: + import base64 import binascii - key = binascii.unhexlify(b"0" * 64) + key = base64.urlsafe_b64encode(binascii.unhexlify(b"0" * 64)) `Fernet`_ is an implementation of symmetric (also known as "secret key") -authenticated cryptography. Fernet provides guarntees that a message encrypted +authenticated cryptography. Fernet provides guarantees that a message encrypted using it cannot be manipulated or read without the key. .. class:: Fernet(key) @@ -27,8 +28,9 @@ using it cannot be manipulated or read without the key. >>> f.decrypt(ciphertext) 'my deep dark secret' - :param bytes key: A 32-byte key. This **must** be kept secret. Anyone with - this key is able to create and read messages. + :param bytes key: A base64 encoded 32-byte key. This **must** be kept + secret. Anyone with this key is able to create and read + messages. .. method:: encrypt(plaintext) -- cgit v1.2.3 From 7a121fce784efb6d436816d84ed01e873f251490 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 22 Nov 2013 10:18:30 -0800 Subject: More info in the docs --- docs/fernet.rst | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'docs') diff --git a/docs/fernet.rst b/docs/fernet.rst index e4756c09..c95077bb 100644 --- a/docs/fernet.rst +++ b/docs/fernet.rst @@ -28,16 +28,16 @@ using it cannot be manipulated or read without the key. >>> f.decrypt(ciphertext) 'my deep dark secret' - :param bytes key: A base64 encoded 32-byte key. This **must** be kept - secret. Anyone with this key is able to create and read - messages. + :param bytes key: A URL-safe base64-encoded 32-byte key. This **must** be + kept secret. Anyone with this key is able to create and + read messages. .. method:: encrypt(plaintext) :param bytes plaintext: The message you would like to encrypt. :returns bytes: A secure message which cannot be read or altered - without the key. It is URL safe base64-encoded. + without the key. It is URL-safe base64-encoded. .. method:: decrypt(ciphertext, ttl=None) @@ -49,6 +49,16 @@ using it cannot be manipulated or read without the key. provided (or is ``None``), the age of the message is not considered. :returns bytes: The original plaintext. + :raises InvalidToken: If the ``ciphertext`` is in any way invalid, this + exception is raised. A ciphertext may be invalid + for a number of reasons: it is older than the + ``ttl``, it is malformed, or it does not have a + valid signature. + + +.. class:: InvalidToken + + See :meth:`Fernet.decrypt` for more information. .. _`Fernet`: https://github.com/fernet/spec/ -- cgit v1.2.3 From 36597b4379bd62e520b9076072a030c73b85f471 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 22 Nov 2013 10:25:13 -0800 Subject: An API for generating keys --- docs/fernet.rst | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'docs') diff --git a/docs/fernet.rst b/docs/fernet.rst index c95077bb..241bf1ea 100644 --- a/docs/fernet.rst +++ b/docs/fernet.rst @@ -3,13 +3,6 @@ Fernet .. currentmodule:: cryptography.fernet -.. testsetup:: - - import base64 - import binascii - key = base64.urlsafe_b64encode(binascii.unhexlify(b"0" * 64)) - - `Fernet`_ is an implementation of symmetric (also known as "secret key") authenticated cryptography. Fernet provides guarantees that a message encrypted using it cannot be manipulated or read without the key. @@ -21,6 +14,7 @@ using it cannot be manipulated or read without the key. .. doctest:: >>> from cryptography.fernet import Fernet + >>> key = Fernet.generate_key() >>> f = Fernet(key) >>> ciphertext = f.encrypt(b"my deep dark secret") >>> ciphertext @@ -32,6 +26,11 @@ using it cannot be manipulated or read without the key. kept secret. Anyone with this key is able to create and read messages. + .. classmethod:: generate_key() + + Generates a fresh fernet key. Keep this some place safe! If you lose it + you'll no longer be able to decrypt messages; if anyone else gains + access to it, they'll be able to decrypt all of your messages. .. method:: encrypt(plaintext) -- cgit v1.2.3 From 6cf242bee212b5b6069865a48c6bdc4836f78ff6 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 16 Dec 2013 11:17:07 -0800 Subject: Document the other consequence of losing your key --- docs/contributing.rst | 3 ++- docs/fernet.rst | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/contributing.rst b/docs/contributing.rst index cb9c7283..036043f5 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -244,7 +244,8 @@ Use `tox`_ to build the documentation. For example: docs: commands succeeded congratulations :) -The HTML documentation index can now be found at ``docs/_build/html/index.html`` +The HTML documentation index can now be found at +``docs/_build/html/index.html``. .. _`GitHub`: https://github.com/pyca/cryptography diff --git a/docs/fernet.rst b/docs/fernet.rst index 241bf1ea..3f0cdded 100644 --- a/docs/fernet.rst +++ b/docs/fernet.rst @@ -30,7 +30,9 @@ using it cannot be manipulated or read without the key. Generates a fresh fernet key. Keep this some place safe! If you lose it you'll no longer be able to decrypt messages; if anyone else gains - access to it, they'll be able to decrypt all of your messages. + access to it, they'll be able to decrypt all of your messages, and + they'll also be able forge arbitrary messages which will be + authenticated and decrypted. .. method:: encrypt(plaintext) -- cgit v1.2.3 From e9083291b9dac1c1ab7b0a2da38f9455536a807d Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 17 Dec 2013 16:56:29 -0800 Subject: Include more info in the title --- docs/fernet.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/fernet.rst b/docs/fernet.rst index 3f0cdded..287c991b 100644 --- a/docs/fernet.rst +++ b/docs/fernet.rst @@ -1,5 +1,5 @@ -Fernet -====== +Fernet (Symmetric encryption) +============================= .. currentmodule:: cryptography.fernet -- cgit v1.2.3 From 0d0896319f59fe7b03d8ef6a153275f87816976b Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 17 Dec 2013 20:23:43 -0800 Subject: Use the term fernet token --- docs/fernet.rst | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'docs') diff --git a/docs/fernet.rst b/docs/fernet.rst index 287c991b..0122e364 100644 --- a/docs/fernet.rst +++ b/docs/fernet.rst @@ -16,10 +16,10 @@ using it cannot be manipulated or read without the key. >>> from cryptography.fernet import Fernet >>> key = Fernet.generate_key() >>> f = Fernet(key) - >>> ciphertext = f.encrypt(b"my deep dark secret") - >>> ciphertext + >>> token = f.encrypt(b"my deep dark secret") + >>> token '...' - >>> f.decrypt(ciphertext) + >>> f.decrypt(token) 'my deep dark secret' :param bytes key: A URL-safe base64-encoded 32-byte key. This **must** be @@ -38,11 +38,13 @@ using it cannot be manipulated or read without the key. :param bytes plaintext: The message you would like to encrypt. :returns bytes: A secure message which cannot be read or altered - without the key. It is URL-safe base64-encoded. + without the key. It is URL-safe base64-encoded. This is + refered to as a "Fernet token". - .. method:: decrypt(ciphertext, ttl=None) + .. method:: decrypt(token, ttl=None) - :param bytes ciphertext: An encrypted message. + :param bytes token: The Fernet token. This is the result of calling + :meth:`encrypt`. :param int ttl: Optionally, the number of seconds old a message may be for it to be valid. If the message is older than ``ttl`` seconds (from the time it was originally @@ -50,11 +52,11 @@ using it cannot be manipulated or read without the key. provided (or is ``None``), the age of the message is not considered. :returns bytes: The original plaintext. - :raises InvalidToken: If the ``ciphertext`` is in any way invalid, this - exception is raised. A ciphertext may be invalid - for a number of reasons: it is older than the - ``ttl``, it is malformed, or it does not have a - valid signature. + :raises InvalidToken: If the ``token`` is in any way invalid, this + exception is raised. A token may be invalid for a + number of reasons: it is older than the ``ttl``, + it is malformed, or it does not have a valid + signature. .. class:: InvalidToken -- cgit v1.2.3 From 05515723738870170b05b47ee260564b9ebe62f9 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 17 Dec 2013 20:43:59 -0800 Subject: Mention that the timestamp is plaintext --- docs/fernet.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/fernet.rst b/docs/fernet.rst index 0122e364..a47ae2e3 100644 --- a/docs/fernet.rst +++ b/docs/fernet.rst @@ -39,7 +39,10 @@ using it cannot be manipulated or read without the key. :param bytes plaintext: The message you would like to encrypt. :returns bytes: A secure message which cannot be read or altered without the key. It is URL-safe base64-encoded. This is - refered to as a "Fernet token". + refered to as a "Fernet token". Note that this *does* + contain the current time when it was generated in + plaintext, the time a message was created will + therefore be visible to a possible attacker. .. method:: decrypt(token, ttl=None) -- cgit v1.2.3 From 3ef458ac7dc021378d8ca14bfcf654c0d51d9a0d Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 20 Dec 2013 13:19:43 -0800 Subject: Reword slightly --- docs/fernet.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs') diff --git a/docs/fernet.rst b/docs/fernet.rst index a47ae2e3..4e618f59 100644 --- a/docs/fernet.rst +++ b/docs/fernet.rst @@ -39,10 +39,10 @@ using it cannot be manipulated or read without the key. :param bytes plaintext: The message you would like to encrypt. :returns bytes: A secure message which cannot be read or altered without the key. It is URL-safe base64-encoded. This is - refered to as a "Fernet token". Note that this *does* - contain the current time when it was generated in - plaintext, the time a message was created will - therefore be visible to a possible attacker. + refered to as a "Fernet token". Note that this contains + the current time when it was generated in *plaintext*, + the time a message was created will therefore be + visible to a possible attacker. .. method:: decrypt(token, ttl=None) -- cgit v1.2.3 From 32dc4e4e9f3036f04598134369af50fd70143dae Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 20 Dec 2013 13:26:12 -0800 Subject: Make into a warning as suggested by @dstufft --- docs/fernet.rst | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'docs') diff --git a/docs/fernet.rst b/docs/fernet.rst index 4e618f59..68184b3a 100644 --- a/docs/fernet.rst +++ b/docs/fernet.rst @@ -39,10 +39,13 @@ using it cannot be manipulated or read without the key. :param bytes plaintext: The message you would like to encrypt. :returns bytes: A secure message which cannot be read or altered without the key. It is URL-safe base64-encoded. This is - refered to as a "Fernet token". Note that this contains - the current time when it was generated in *plaintext*, - the time a message was created will therefore be - visible to a possible attacker. + refered to as a "Fernet token". + + .. warning:: + + The encrypted message contains the current time when it was + generated in *plaintext*, the time a message was created will + therefore be visible to a possible attacker. .. method:: decrypt(token, ttl=None) -- cgit v1.2.3 From 719eb6a412b5d3eab3ca84a9d4e8af76955bcbcc Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 20 Dec 2013 13:35:57 -0800 Subject: Linkify this --- docs/fernet.rst | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'docs') diff --git a/docs/fernet.rst b/docs/fernet.rst index 68184b3a..2fe2b860 100644 --- a/docs/fernet.rst +++ b/docs/fernet.rst @@ -41,7 +41,7 @@ using it cannot be manipulated or read without the key. without the key. It is URL-safe base64-encoded. This is refered to as a "Fernet token". - .. warning:: + .. note:: The encrypted message contains the current time when it was generated in *plaintext*, the time a message was created will @@ -58,11 +58,14 @@ using it cannot be manipulated or read without the key. provided (or is ``None``), the age of the message is not considered. :returns bytes: The original plaintext. - :raises InvalidToken: If the ``token`` is in any way invalid, this - exception is raised. A token may be invalid for a - number of reasons: it is older than the ``ttl``, - it is malformed, or it does not have a valid - signature. + :raises cryptography.fernet.InvalidToken: If the ``token`` is in any + way invalid, this exception + is raised. A token may be + invalid for a number of + reasons: it is older than the + ``ttl``, it is malformed, or + it does not have a valid + signature. .. class:: InvalidToken -- cgit v1.2.3 From 2724ff6af8ba5f8dfd1f0f511ed95fab5cd8abd8 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 20 Dec 2013 13:51:42 -0800 Subject: Link from symmetric encryption to fernet --- docs/cryptography-docs.py | 17 +++++++++++++++-- docs/hazmat/primitives/symmetric-encryption.rst | 2 +- 2 files changed, 16 insertions(+), 3 deletions(-) (limited to 'docs') diff --git a/docs/cryptography-docs.py b/docs/cryptography-docs.py index ea7e8eef..f07c18bb 100644 --- a/docs/cryptography-docs.py +++ b/docs/cryptography-docs.py @@ -6,17 +6,30 @@ from sphinx.util.compat import Directive, make_admonition DANGER_MESSAGE = """ This is a "Hazardous Materials" module. You should **ONLY** use it if you're 100% absolutely sure that you know what you're doing because this module is -full of land mines, dragons, and dinosaurs with laser guns. """ +full of land mines, dragons, and dinosaurs with laser guns. +""" + +DANGER_ALTERNATE = """ + +You may instead be interested in :doc:`{alternate}`. +""" + class HazmatDirective(Directive): + has_content = True + def run(self): + message = DANGER_MESSAGE + if self.content: + message += DANGER_ALTERNATE.format(alternate=self.content[0]) + ad = make_admonition( Hazmat, self.name, [], self.options, - nodes.paragraph("", DANGER_MESSAGE), + nodes.paragraph("", message), self.lineno, self.content_offset, self.block_text, diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index f4d0457a..7b012975 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -1,4 +1,4 @@ -.. hazmat:: +.. hazmat:: /fernet Symmetric Encryption -- cgit v1.2.3 From 3ac297e4c9b655b3222da1830e9677c9d03a3926 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 20 Dec 2013 14:16:34 -0800 Subject: flake8 fix --- docs/cryptography-docs.py | 1 - 1 file changed, 1 deletion(-) (limited to 'docs') diff --git a/docs/cryptography-docs.py b/docs/cryptography-docs.py index f07c18bb..0252d693 100644 --- a/docs/cryptography-docs.py +++ b/docs/cryptography-docs.py @@ -15,7 +15,6 @@ You may instead be interested in :doc:`{alternate}`. """ - class HazmatDirective(Directive): has_content = True -- cgit v1.2.3 From 681fca8f43f9cbed97ce2df0b871447953c7edda Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 31 Dec 2013 14:13:39 -0800 Subject: Rearange sentence on recommendation of @jacobian --- docs/cryptography-docs.py | 3 +++ docs/fernet.rst | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'docs') diff --git a/docs/cryptography-docs.py b/docs/cryptography-docs.py index 0252d693..f27a8467 100644 --- a/docs/cryptography-docs.py +++ b/docs/cryptography-docs.py @@ -23,6 +23,9 @@ class HazmatDirective(Directive): if self.content: message += DANGER_ALTERNATE.format(alternate=self.content[0]) + import pdb + pdb.set_trace() + ad = make_admonition( Hazmat, self.name, diff --git a/docs/fernet.rst b/docs/fernet.rst index 2fe2b860..4e94e212 100644 --- a/docs/fernet.rst +++ b/docs/fernet.rst @@ -3,9 +3,9 @@ Fernet (Symmetric encryption) .. currentmodule:: cryptography.fernet -`Fernet`_ is an implementation of symmetric (also known as "secret key") -authenticated cryptography. Fernet provides guarantees that a message encrypted -using it cannot be manipulated or read without the key. +Fernet provides guarantees that a message encrypted using it cannot be +manipulated or read without the key. `Fernet`_ is an implementation of +symmetric (also known as "secret key") authenticated cryptography. .. class:: Fernet(key) -- cgit v1.2.3 From 09aa74635f54ace5480a6d502b0da92651f516b6 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 31 Dec 2013 15:18:34 -0800 Subject: Remove this one weird debugger --- docs/cryptography-docs.py | 3 --- 1 file changed, 3 deletions(-) (limited to 'docs') diff --git a/docs/cryptography-docs.py b/docs/cryptography-docs.py index f27a8467..0252d693 100644 --- a/docs/cryptography-docs.py +++ b/docs/cryptography-docs.py @@ -23,9 +23,6 @@ class HazmatDirective(Directive): if self.content: message += DANGER_ALTERNATE.format(alternate=self.content[0]) - import pdb - pdb.set_trace() - ad = make_admonition( Hazmat, self.name, -- cgit v1.2.3 From 1225270be8af862a82e45342f086419dbedce0fb Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 2 Jan 2014 11:10:35 -0800 Subject: Correct spelling, fix phrasing, line wrap. --- docs/hazmat/bindings/index.rst | 2 +- docs/hazmat/primitives/hmac.rst | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'docs') diff --git a/docs/hazmat/bindings/index.rst b/docs/hazmat/bindings/index.rst index 809eddfc..e2a17591 100644 --- a/docs/hazmat/bindings/index.rst +++ b/docs/hazmat/bindings/index.rst @@ -6,7 +6,7 @@ Bindings .. currentmodule:: cryptography.hazmat.bindings ``cryptography`` aims to provide low-level CFFI based bindings to multiple -native C libraries. These provide no automatic initialisation of the library +native C libraries. These provide no automatic initialization of the library and may not provide complete wrappers for its API. Using these functions directly is likely to require you to be careful in diff --git a/docs/hazmat/primitives/hmac.rst b/docs/hazmat/primitives/hmac.rst index b8f94fd2..dc5c54f8 100644 --- a/docs/hazmat/primitives/hmac.rst +++ b/docs/hazmat/primitives/hmac.rst @@ -74,8 +74,11 @@ message. .. method:: verify(signature) - Finalize the current context and securely compare digest to ``signature``. + Finalize the current context and securely compare digest to + ``signature``. - :param bytes signature: The bytes of the HMAC signature recieved. + :param bytes signature: The bytes to compare the current digest + against. :raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize` - :raises cryptography.exceptions.InvalidSignature: If signature does not match digest + :raises cryptography.exceptions.InvalidSignature: If signature does not + match digest -- cgit v1.2.3 From 3aa243cddc5cbe4e4205b019946dc6c4f271f589 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 6 Jan 2014 13:13:18 -0800 Subject: Spell a word correctly --- docs/fernet.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/fernet.rst b/docs/fernet.rst index 4e94e212..13295c0c 100644 --- a/docs/fernet.rst +++ b/docs/fernet.rst @@ -39,7 +39,7 @@ symmetric (also known as "secret key") authenticated cryptography. :param bytes plaintext: The message you would like to encrypt. :returns bytes: A secure message which cannot be read or altered without the key. It is URL-safe base64-encoded. This is - refered to as a "Fernet token". + referred to as a "Fernet token". .. note:: -- cgit v1.2.3 From 2b22fae990513eeb4026cd0883bc2e244af8b56a Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 6 Jan 2014 13:19:33 -0800 Subject: Compute the version in the same way as setup.py does --- docs/conf.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'docs') diff --git a/docs/conf.py b/docs/conf.py index 5dbcdab8..00660314 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -60,10 +60,13 @@ copyright = '2013-2014, Individual Contributors' # |version| and |release|, also used in various other places throughout the # built documents. # -# The short X.Y version. -version = '0.1dev' -# The full version, including alpha/beta/rc tags. -release = '0.1dev' + +base_dir = os.path.join(os.path.dirname(__file__), os.pardir) +about = {} +with open(os.path.join(base_dir, "cryptography", "__about__.py")) as f: + exec(f.read(), about) + +version = release = about["__version__"] # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -- cgit v1.2.3 From 89063f687893417e1e5dac2e854a02d92037b6a0 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 6 Jan 2014 15:52:38 -0800 Subject: Update procedure --- docs/doing-a-release.rst | 27 +++++++++++++++++++++++++++ docs/index.rst | 1 + 2 files changed, 28 insertions(+) create mode 100644 docs/doing-a-release.rst (limited to 'docs') diff --git a/docs/doing-a-release.rst b/docs/doing-a-release.rst new file mode 100644 index 00000000..81349a70 --- /dev/null +++ b/docs/doing-a-release.rst @@ -0,0 +1,27 @@ +Doing a Release +=============== + +Doing a release of ``cryptography`` is a two part process. + +Bumping the version number +-------------------------- + +The first step in doing a release is bumping the version number in the +software. + +* Update the version number in ``cryptography/__about__.py`` and + ``docs/conf.py``. +* Do a commit indicating this. +* Send a pull request with this. +* Wait for it to be merged. + +Performing the release +---------------------- + +The commit which merged the version number bump is now the official release +commit for this release. Once this has happened: + +* Run ``invoke release {version}``. + +That's all, the release should now be available on PyPI and a tag should be +available in the repository. diff --git a/docs/index.rst b/docs/index.rst index 5eb3de7d..24d6d204 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -78,4 +78,5 @@ The ``cryptography`` open source project contributing security api-stability + doing-a-release community -- cgit v1.2.3 From ce0b5a3a8a5d2bb9de1680a9e9ea6e488d33da27 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 6 Jan 2014 16:53:31 -0800 Subject: Update release docs --- docs/doing-a-release.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/doing-a-release.rst b/docs/doing-a-release.rst index 81349a70..d790523b 100644 --- a/docs/doing-a-release.rst +++ b/docs/doing-a-release.rst @@ -9,8 +9,7 @@ Bumping the version number The first step in doing a release is bumping the version number in the software. -* Update the version number in ``cryptography/__about__.py`` and - ``docs/conf.py``. +* Update the version number in ``cryptography/__about__.py``. * Do a commit indicating this. * Send a pull request with this. * Wait for it to be merged. -- cgit v1.2.3 From b3794dbe97a6f4e088244adfdd6a06b2d4e185e0 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 7 Jan 2014 09:25:54 -0800 Subject: You need a gpg key to do a release --- docs/doing-a-release.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/doing-a-release.rst b/docs/doing-a-release.rst index d790523b..77582a48 100644 --- a/docs/doing-a-release.rst +++ b/docs/doing-a-release.rst @@ -18,7 +18,8 @@ Performing the release ---------------------- The commit which merged the version number bump is now the official release -commit for this release. Once this has happened: +commit for this release. You will need to have ``gpg`` installed and a ``gpg`` +key in order to do a release. Once this has happened: * Run ``invoke release {version}``. -- cgit v1.2.3 From fea893c7060c57fe5ed9e0f9df58fee5c306681b Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 7 Jan 2014 11:06:51 -0800 Subject: More stuff --- docs/doing-a-release.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/doing-a-release.rst b/docs/doing-a-release.rst index 77582a48..e52c2728 100644 --- a/docs/doing-a-release.rst +++ b/docs/doing-a-release.rst @@ -23,5 +23,6 @@ key in order to do a release. Once this has happened: * Run ``invoke release {version}``. -That's all, the release should now be available on PyPI and a tag should be -available in the repository. +The release should now be available on PyPI and a tag should be available in +the repository. You should verify that ``pip install cryptography`` works +correctly. -- cgit v1.2.3 From 41c14d55ea2d17e3e9968acfa93d442615f7cda0 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 7 Jan 2014 11:19:08 -0800 Subject: How to verify that your released correctly --- docs/doing-a-release.rst | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/doing-a-release.rst b/docs/doing-a-release.rst index e52c2728..0f382064 100644 --- a/docs/doing-a-release.rst +++ b/docs/doing-a-release.rst @@ -25,4 +25,12 @@ key in order to do a release. Once this has happened: The release should now be available on PyPI and a tag should be available in the repository. You should verify that ``pip install cryptography`` works -correctly. +correctly: + +.. code-block:: pycon + + >>> import cryptography + >>> cryptography.__version__ + '...' + +Verify that this is the version you just released. -- cgit v1.2.3 From bb996d7e06fe539cbddee880a1af22df334cd5db Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 7 Jan 2014 17:34:48 -0600 Subject: also remove CAST5 docs --- docs/hazmat/primitives/symmetric-encryption.rst | 9 --------- 1 file changed, 9 deletions(-) (limited to 'docs') diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index e05248ff..a1a3ec0d 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -189,15 +189,6 @@ Algorithms ``56`` bits long), they can simply be concatenated to produce the full key. This must be kept secret. -.. class:: CAST5(key) - - CAST5 (also known as CAST-128) is a block cipher approved for use in the - Canadian government by their Communications Security Establishment. It is a - variable key length cipher and supports keys from 40-128 bits in length. - - :param bytes key: The secret key, 40-128 bits in length (in increments of - 8). This must be kept secret. - Weak Ciphers ------------ -- cgit v1.2.3 From 78569d68de24bc56dd799c262f3dd2d522bcdcd1 Mon Sep 17 00:00:00 2001 From: David Reid Date: Tue, 7 Jan 2014 15:42:17 -0800 Subject: Try making the AEAD examples less dense. --- docs/hazmat/primitives/symmetric-encryption.rst | 51 ++++++++++++++++++------- 1 file changed, 38 insertions(+), 13 deletions(-) (limited to 'docs') diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index e05248ff..d3ba731a 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -365,20 +365,45 @@ Modes :param bytes tag: The tag bytes to verify during decryption. When encrypting this must be None. - .. doctest:: + .. code-block:: python - >>> from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes - >>> from cryptography.hazmat.backends import default_backend - >>> cipher = Cipher(algorithms.AES(key), modes.GCM(iv), backend=default_backend()) - >>> encryptor = cipher.encryptor() - >>> encryptor.authenticate_additional_data(b"authenticated but not encrypted payload") - >>> ct = encryptor.update(b"a secret message") + encryptor.finalize() - >>> tag = encryptor.tag - >>> cipher = Cipher(algorithms.AES(key), modes.GCM(iv, tag), backend) - >>> decryptor = cipher.decryptor() - >>> decryptor.authenticate_additional_data(b"authenticated but not encrypted payload") - >>> decryptor.update(ct) + decryptor.finalize() - 'a secret message' + def encrypt(key, plaintext, associated_data): + iv = os.urandom(12) + cipher = Cipher( + algorithms.AES(key), + modes.GCM(iv), + backend=default_backend() + ) + + encryptor = cipher.encryptor() + encryptor.authenticate_additional_data(associated_data) + ciphertext = encryptor.update(plaintext) + encryptor.finalize() + + return (associated_data, iv, ciphertext, encryptor.tag) + + def decrypt(key, associated_data, iv, ciphertext, tag): + cipher = Cipher( + algorithms.AES(key), + modes.GCM(iv, tag), + backend=default_backend() + ) + + decryptor = cipher.decryptor() + decryptor.authenticate_additional_data(associated_data) + + return decryptor.update(ciphertext) + decryptor.finalize() + + associated_data, iv, ciphertext, tag = encrypt( + key, + b"a secret message", + b"authenticated but not encrypted payload" + ) + + print(decrypt(key, associated_data, iv, ciphertext, tag)) + + .. testoutput:: + + a secret message Insecure Modes -- cgit v1.2.3 From abb72d23118fb63a8601d2036b7c2cef2598f408 Mon Sep 17 00:00:00 2001 From: David Reid Date: Tue, 7 Jan 2014 16:06:18 -0800 Subject: Make the example more complete and add some comments walking the user through some stuff. --- docs/hazmat/primitives/symmetric-encryption.rst | 63 +++++++++++++++++++------ 1 file changed, 49 insertions(+), 14 deletions(-) (limited to 'docs') diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index d3ba731a..59aff99b 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -365,45 +365,80 @@ Modes :param bytes tag: The tag bytes to verify during decryption. When encrypting this must be None. - .. code-block:: python + .. testcode:: + + import os + + from cryptography.hazmat.primitives.ciphers import ( + Cipher, algorithms, modes + ) + + from cryptography.hazmat.primitives.padding import PKCS7 def encrypt(key, plaintext, associated_data): + # Generate a random 96-bit IV. iv = os.urandom(12) - cipher = Cipher( + + # Construct a AES-GCM Cipher object with the given and our randomly + # generated IV. + encryptor = Cipher( algorithms.AES(key), modes.GCM(iv), backend=default_backend() - ) + ).encryptor() - encryptor = cipher.encryptor() + # We have to pad our plaintext because it may not be a + # multiple of the block size. + padder = PKCS7(algorithms.AES.block_size).padder() + padded_plaintext = padder.update(plaintext) + padder.finalize() + + # associated_data will be authenticated but not encrypted, + # it must also be passed in on decryption. encryptor.authenticate_additional_data(associated_data) - ciphertext = encryptor.update(plaintext) + encryptor.finalize() - return (associated_data, iv, ciphertext, encryptor.tag) + # Encrypt the plaintext and get the associated ciphertext. + ciphertext = encryptor.update(padded_plaintext) + encryptor.finalize() + + return (iv, ciphertext, encryptor.tag) def decrypt(key, associated_data, iv, ciphertext, tag): - cipher = Cipher( + # Construct a Cipher object, with the key, iv, and additionally the + # GCM tag used for authenticating the message. + decryptor = Cipher( algorithms.AES(key), modes.GCM(iv, tag), backend=default_backend() - ) + ).decryptor() + + # We will need to unpad the plaintext. + unpadder = PKCS7(algorithms.AES.block_size).unpadder() - decryptor = cipher.decryptor() + # We put associated_data back in or the tag will fail to verify + # when we finalize the decryptor. decryptor.authenticate_additional_data(associated_data) - return decryptor.update(ciphertext) + decryptor.finalize() + # Decryption gets us the authenticated padded plaintext. + padded_plaintext = decryptor.update(ciphertext) + decryptor.finalize() - associated_data, iv, ciphertext, tag = encrypt( + return unpadder.update(padded_plaintext) + unpadder.finalize() + + iv, ciphertext, tag = encrypt( key, - b"a secret message", + b"a secret message!", b"authenticated but not encrypted payload" ) - print(decrypt(key, associated_data, iv, ciphertext, tag)) + print(decrypt( + key, + b"authenticated but not encrypted payload", + iv, + ciphertext, + tag + )) .. testoutput:: - a secret message + a secret message! Insecure Modes -- cgit v1.2.3 From ad6d164a93352a9f6ddb57fd98152ba929e35d34 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 7 Jan 2014 19:10:12 -0600 Subject: move ciphercontext/aeadciphercontext to bottom of symmetric encryption Add a bit of additional text to try to make the convoluted AEAD explanation better. --- docs/hazmat/primitives/symmetric-encryption.rst | 156 +++++++++++++----------- 1 file changed, 83 insertions(+), 73 deletions(-) (limited to 'docs') diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index a683bb98..c1f7bb64 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -74,79 +74,6 @@ an "encrypt-then-MAC" formulation as `described by Colin Percival`_. and ``mode`` an :class:`cryptography.exceptions.UnsupportedAlgorithm` will be raised. - -.. currentmodule:: cryptography.hazmat.primitives.interfaces - -.. class:: CipherContext - - When calling ``encryptor()`` or ``decryptor()`` on a ``Cipher`` object - you will receive a return object conforming to the ``CipherContext`` - interface. You can then call ``update(data)`` with data until you have fed - everything into the context. Once that is done call ``finalize()`` to - finish the operation and obtain the remainder of the data. - - Block ciphers require that plaintext or ciphertext always be a multiple of - their block size, because of that **padding** is often required to make a - message the correct size. ``CipherContext`` will not automatically apply - any padding; you'll need to add your own. For block ciphers the recommended - padding is :class:`cryptography.hazmat.primitives.padding.PKCS7`. If you - are using a stream cipher mode (such as - :class:`cryptography.hazmat.primitives.modes.CTR`) you don't have to worry - about this. - - .. method:: update(data) - - :param bytes data: The data you wish to pass into the context. - :return bytes: Returns the data that was encrypted or decrypted. - :raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize` - - When the ``Cipher`` was constructed in a mode that turns it into a - stream cipher (e.g. - :class:`cryptography.hazmat.primitives.ciphers.modes.CTR`), this will - return bytes immediately, however in other modes it will return chunks, - whose size is determined by the cipher's block size. - - .. method:: finalize() - - :return bytes: Returns the remainder of the data. - :raises ValueError: This is raised when the data provided isn't - correctly padded to be a multiple of the - algorithm's block size. - - Once ``finalize`` is called this object can no longer be used and - :meth:`update` and :meth:`finalize` will raise - :class:`~cryptography.exceptions.AlreadyFinalized`. - -.. class:: AEADCipherContext - - When calling ``encryptor()`` or ``decryptor()`` on a ``Cipher`` object - with an AEAD mode you will receive a return object conforming to the - ``AEADCipherContext`` interface (in addition to the ``CipherContext`` - interface). If it is an encryption context it will additionally be an - ``AEADEncryptionContext`` interface. ``AEADCipherContext`` contains an - additional method ``authenticate_additional_data`` for adding additional - authenticated but unencrypted data. You should call this before calls to - ``update``. When you are done call ``finalize()`` to finish the operation. - - .. method:: authenticate_additional_data(data) - - :param bytes data: The data you wish to authenticate but not encrypt. - :raises: :class:`~cryptography.exceptions.AlreadyFinalized` - -.. class:: AEADEncryptionContext - - When creating an encryption context using ``encryptor()`` on a ``Cipher`` - object with an AEAD mode you will receive a return object conforming to the - ``AEADEncryptionContext`` interface (as well as ``AEADCipherContext``). - This interface provides one additional attribute ``tag``. ``tag`` can only - be obtained after ``finalize()``. - - .. attribute:: tag - - :return bytes: Returns the tag value as bytes. - :raises: :class:`~cryptography.exceptions.NotYetFinalized` if called - before the context is finalized. - .. _symmetric-encryption-algorithms: Algorithms @@ -448,6 +375,89 @@ Insecure Modes identical plaintext blocks will always result in identical ciphertext blocks, and thus result in information leakage +Interfaces +---------- + +.. class:: CipherContext + + When calling ``encryptor()`` or ``decryptor()`` on a ``Cipher`` object + you will receive a return object conforming to the ``CipherContext`` + interface. You can then call ``update(data)`` with data until you have fed + everything into the context. Once that is done call ``finalize()`` to + finish the operation and obtain the remainder of the data. + + Block ciphers require that plaintext or ciphertext always be a multiple of + their block size, because of that **padding** is often required to make a + message the correct size. ``CipherContext`` will not automatically apply + any padding; you'll need to add your own. For block ciphers the recommended + padding is :class:`cryptography.hazmat.primitives.padding.PKCS7`. If you + are using a stream cipher mode (such as + :class:`cryptography.hazmat.primitives.modes.CTR`) you don't have to worry + about this. + + .. method:: update(data) + + :param bytes data: The data you wish to pass into the context. + :return bytes: Returns the data that was encrypted or decrypted. + :raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize` + + When the ``Cipher`` was constructed in a mode that turns it into a + stream cipher (e.g. + :class:`cryptography.hazmat.primitives.ciphers.modes.CTR`), this will + return bytes immediately, however in other modes it will return chunks, + whose size is determined by the cipher's block size. + + .. method:: finalize() + + :return bytes: Returns the remainder of the data. + :raises ValueError: This is raised when the data provided isn't + correctly padded to be a multiple of the + algorithm's block size. + + Once ``finalize`` is called this object can no longer be used and + :meth:`update` and :meth:`finalize` will raise + :class:`~cryptography.exceptions.AlreadyFinalized`. + +.. class:: AEADCipherContext + + When calling ``encryptor()`` or ``decryptor()`` on a ``Cipher`` object + with an AEAD mode (e.g. + :class:`~cryptography.hazmat.primitives.ciphers.modes.GCM`) you will receive + a return object conforming to the ``AEADCipherContext`` and + ``CipherContext`` interfaces. If it is an encryption context it will + additionally be an ``AEADEncryptionContext`` interface. + ``AEADCipherContext`` contains an additional method + ``authenticate_additional_data`` for adding additional authenticated but + unencrypted data (see note below). You should call this before calls to + ``update``. When you are done call ``finalize()`` to finish the operation. + + .. note:: + + In AEAD modes all data passed to ``update()`` will be both encrypted + and authenticated. Do not pass encrypted data to the + ``authenticate_additional_data()`` method. It is meant solely for + additional data you may want to authenticate but leave unencrypted. + + .. method:: authenticate_additional_data(data) + + :param bytes data: Any data you wish to authenticate but not encrypt. + :raises: :class:`~cryptography.exceptions.AlreadyFinalized` + +.. class:: AEADEncryptionContext + + When creating an encryption context using ``encryptor()`` on a ``Cipher`` + object with an AEAD mode (e.g. + :class:`~cryptography.hazmat.primitives.ciphers.modes.GCM`) you will receive + a return object conforming to the ``AEADEncryptionContext`` interface (as + well as ``AEADCipherContext``). This interface provides one additional + attribute ``tag``. ``tag`` can only be obtained after ``finalize()``. + + .. attribute:: tag + + :return bytes: Returns the tag value as bytes. + :raises: :class:`~cryptography.exceptions.NotYetFinalized` if called + before the context is finalized. + .. _`described by Colin Percival`: http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html .. _`recommends 96-bit IV length`: http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf -- cgit v1.2.3 From af0b9f56e761353593a0b33b1f4797169a716dec Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 7 Jan 2014 19:21:49 -0600 Subject: GCM does not require padding (removing from docs example) --- docs/hazmat/primitives/symmetric-encryption.rst | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) (limited to 'docs') diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index a683bb98..86267a25 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -364,8 +364,6 @@ Modes Cipher, algorithms, modes ) - from cryptography.hazmat.primitives.padding import PKCS7 - def encrypt(key, plaintext, associated_data): # Generate a random 96-bit IV. iv = os.urandom(12) @@ -378,17 +376,13 @@ Modes backend=default_backend() ).encryptor() - # We have to pad our plaintext because it may not be a - # multiple of the block size. - padder = PKCS7(algorithms.AES.block_size).padder() - padded_plaintext = padder.update(plaintext) + padder.finalize() - # associated_data will be authenticated but not encrypted, # it must also be passed in on decryption. encryptor.authenticate_additional_data(associated_data) # Encrypt the plaintext and get the associated ciphertext. - ciphertext = encryptor.update(padded_plaintext) + encryptor.finalize() + # GCM does not require padding. + ciphertext = encryptor.update(plaintext) + encryptor.finalize() return (iv, ciphertext, encryptor.tag) @@ -401,17 +395,13 @@ Modes backend=default_backend() ).decryptor() - # We will need to unpad the plaintext. - unpadder = PKCS7(algorithms.AES.block_size).unpadder() - # We put associated_data back in or the tag will fail to verify # when we finalize the decryptor. decryptor.authenticate_additional_data(associated_data) - # Decryption gets us the authenticated padded plaintext. - padded_plaintext = decryptor.update(ciphertext) + decryptor.finalize() - - return unpadder.update(padded_plaintext) + unpadder.finalize() + # Decryption gets us the authenticated plaintext. + # If the tag does not match an InvalidTag exception will be raised. + return decryptor.update(ciphertext) + decryptor.finalize() iv, ciphertext, tag = encrypt( key, -- cgit v1.2.3 From fe2e3c2827f2776e8e4116b3aec50d4409476cd9 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 7 Jan 2014 20:55:20 -0600 Subject: add padding info to docs --- docs/hazmat/primitives/symmetric-encryption.rst | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index 2233d525..83165690 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -169,6 +169,8 @@ Modes CBC (Cipher block chaining) is a mode of operation for block ciphers. It is considered cryptographically strong. + **Padding is required when using this mode.** + :param bytes initialization_vector: Must be random bytes. They do not need to be kept secret (they can be included in a transmitted message). Must be the @@ -211,6 +213,8 @@ Modes cryptographically strong. It transforms a block cipher into a stream cipher. + **This mode does not require padding.** + :param bytes nonce: Should be random bytes. It is critical to never reuse a ``nonce`` with a given key. Any reuse of a nonce with the same key compromises the security of every @@ -224,6 +228,8 @@ Modes OFB (Output Feedback) is a mode of operation for block ciphers. It transforms a block cipher into a stream cipher. + **This mode does not require padding.** + :param bytes initialization_vector: Must be random bytes. They do not need to be kept secret (they can be included in a transmitted message). Must be the @@ -237,6 +243,8 @@ Modes CFB (Cipher Feedback) is a mode of operation for block ciphers. It transforms a block cipher into a stream cipher. + **This mode does not require padding.** + :param bytes initialization_vector: Must be random bytes. They do not need to be kept secret (they can be included in a transmitted message). Must be the @@ -261,6 +269,8 @@ Modes Additional means of verifying integrity (like :doc:`HMAC `) are not necessary. + **This mode does not require padding.** + :param bytes initialization_vector: Must be random bytes. They do not need to be kept secret (they can be included in a transmitted message). NIST @@ -365,6 +375,8 @@ Insecure Modes identical plaintext blocks will always result in identical ciphertext blocks, and thus result in information leakage + **Padding is required when using this mode.** + Interfaces ---------- @@ -377,8 +389,8 @@ Interfaces finish the operation and obtain the remainder of the data. Block ciphers require that plaintext or ciphertext always be a multiple of - their block size, because of that **padding** is often required to make a - message the correct size. ``CipherContext`` will not automatically apply + their block size, because of that **padding** is sometimes required to make + a message the correct size. ``CipherContext`` will not automatically apply any padding; you'll need to add your own. For block ciphers the recommended padding is :class:`cryptography.hazmat.primitives.padding.PKCS7`. If you are using a stream cipher mode (such as -- cgit v1.2.3 From 3f23040fca700b9e15c528ebdebd67764e7cec2c Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 8 Jan 2014 09:21:57 -0800 Subject: Fixed #428 -- added a changelog --- docs/changelog.rst | 9 +++++++++ docs/contributing.rst | 2 ++ docs/doing-a-release.rst | 1 + docs/index.rst | 1 + 4 files changed, 13 insertions(+) create mode 100644 docs/changelog.rst (limited to 'docs') diff --git a/docs/changelog.rst b/docs/changelog.rst new file mode 100644 index 00000000..e46d8c9b --- /dev/null +++ b/docs/changelog.rst @@ -0,0 +1,9 @@ +Changelog +========= + +0.1 +~~~ + +**Released on XXX** + +* Initial released. diff --git a/docs/contributing.rst b/docs/contributing.rst index 657c4359..8e32c368 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -29,6 +29,8 @@ devastating, ``cryptography`` has a strict code review policy: backwards incompatible release of a dependency) no pull requests may be merged until this is rectified. * All merged patches must have 100% test coverage. +* New features and significant bug fixes should be documented in the + :doc:`/changelog`. The purpose of these policies is to minimize the chances we merge a change which jeopardizes our users' security. diff --git a/docs/doing-a-release.rst b/docs/doing-a-release.rst index 0f382064..194e82f4 100644 --- a/docs/doing-a-release.rst +++ b/docs/doing-a-release.rst @@ -10,6 +10,7 @@ The first step in doing a release is bumping the version number in the software. * Update the version number in ``cryptography/__about__.py``. +* Set the release date in the :doc:`/changelog`. * Do a commit indicating this. * Send a pull request with this. * Wait for it to be merged. diff --git a/docs/index.rst b/docs/index.rst index 4bbfe7fd..9967075a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -80,4 +80,5 @@ The ``cryptography`` open source project security api-stability doing-a-release + changelog community -- cgit v1.2.3 From 7c6d7d6b71743457fe7d7c7f5cd607ca46b187f8 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 8 Jan 2014 09:46:27 -0800 Subject: Typo fix --- docs/changelog.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/changelog.rst b/docs/changelog.rst index e46d8c9b..52fcbfe3 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -6,4 +6,4 @@ Changelog **Released on XXX** -* Initial released. +* Initial release. -- cgit v1.2.3 From 924599e267250bb5f1bb80d6b0345918e3d52094 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 8 Jan 2014 09:47:05 -0800 Subject: Reformat --- docs/changelog.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'docs') diff --git a/docs/changelog.rst b/docs/changelog.rst index 52fcbfe3..4d782216 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,9 +1,7 @@ Changelog ========= -0.1 -~~~ - -**Released on XXX** +0.1 - YYYY-MM-DD +~~~~~~~~~~~~~~~~ * Initial release. -- cgit v1.2.3 From d873b4cf3f53f7dee8ed68722e9c413d9f60881c Mon Sep 17 00:00:00 2001 From: David Reid Date: Wed, 8 Jan 2014 11:42:45 -0800 Subject: Prepare to release. --- docs/changelog.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/changelog.rst b/docs/changelog.rst index 4d782216..b2d24c58 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,7 +1,7 @@ Changelog ========= -0.1 - YYYY-MM-DD +0.1 - 2014-01-08 ~~~~~~~~~~~~~~~~ * Initial release. -- cgit v1.2.3 From 292902e259029cea91bdf2e725861462db223057 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 8 Jan 2014 15:18:52 -0800 Subject: Document that we're on PyPI --- docs/index.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'docs') diff --git a/docs/index.rst b/docs/index.rst index 9967075a..e17b4f9f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -8,12 +8,11 @@ needs in Python. Installing ---------- -We don't yet have a release on PyPI, for now you can install ``cryptography`` -directly from Github: +You can install ``cryptography`` with ``pip``: .. code-block:: console - $ pip install git+https://github.com/pyca/cryptography + $ pip install cryptography Why a new crypto library for Python? ------------------------------------ -- cgit v1.2.3 From 2b64fe2222e383bd6f68203b9bbcd9d8af7ec1fd Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 8 Jan 2014 19:59:28 -0600 Subject: add 0.2 changelog section --- docs/changelog.rst | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'docs') diff --git a/docs/changelog.rst b/docs/changelog.rst index b2d24c58..41db635e 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,5 +1,9 @@ Changelog ========= +0.2 - 2014-XX-XX +~~~~~~~~~~~~~~~~ + +* In development. 0.1 - 2014-01-08 ~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 5bbcf7660b07f5a77ce9ff5666bede3c3377dfc7 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 8 Jan 2014 18:36:57 -0800 Subject: Make verify on HMAC more prominent --- docs/hazmat/primitives/hmac.rst | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'docs') diff --git a/docs/hazmat/primitives/hmac.rst b/docs/hazmat/primitives/hmac.rst index dc5c54f8..f4f5daa1 100644 --- a/docs/hazmat/primitives/hmac.rst +++ b/docs/hazmat/primitives/hmac.rst @@ -37,6 +37,17 @@ message. If the backend doesn't support the requested ``algorithm`` an :class:`~cryptography.exceptions.UnsupportedAlgorithm` will be raised. + If you've been given a signature and need to check that it's correct, this + can be done with the :meth:`verify` method, you'll get an exception if the + signature is wrong: + + .. code-block:: pycon + + >>> h.verify(b"an incorrect signature") + Traceback (most recent call last): + ... + cryptography.exceptions.InvalidSignature: Signature did not match digest. + :param key: Secret key as ``bytes``. :param algorithm: A :class:`~cryptography.hazmat.primitives.interfaces.HashAlgorithm` @@ -61,17 +72,6 @@ message. and finalized independently of the original instance. :raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize` - .. method:: finalize() - - Finalize the current context and return the message digest as bytes. - - Once ``finalize`` is called this object can no longer be used and - :meth:`update`, :meth:`copy`, and :meth:`finalize` will raise - :class:`~cryptography.exceptions.AlreadyFinalized`. - - :return bytes: The message digest as bytes. - :raises cryptography.exceptions.AlreadyFinalized: - .. method:: verify(signature) Finalize the current context and securely compare digest to @@ -82,3 +82,14 @@ message. :raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize` :raises cryptography.exceptions.InvalidSignature: If signature does not match digest + + .. method:: finalize() + + Finalize the current context and return the message digest as bytes. + + Once ``finalize`` is called this object can no longer be used and + :meth:`update`, :meth:`copy`, and :meth:`finalize` will raise + :class:`~cryptography.exceptions.AlreadyFinalized`. + + :return bytes: The message digest as bytes. + :raises cryptography.exceptions.AlreadyFinalized: -- cgit v1.2.3 From 288bae7ede180812c1229fc82eda76e47aa73f58 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 8 Jan 2014 21:46:18 -0600 Subject: rewrite some text about the hmac verify method --- docs/hazmat/primitives/hmac.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'docs') diff --git a/docs/hazmat/primitives/hmac.rst b/docs/hazmat/primitives/hmac.rst index f4f5daa1..a21799be 100644 --- a/docs/hazmat/primitives/hmac.rst +++ b/docs/hazmat/primitives/hmac.rst @@ -37,9 +37,8 @@ message. If the backend doesn't support the requested ``algorithm`` an :class:`~cryptography.exceptions.UnsupportedAlgorithm` will be raised. - If you've been given a signature and need to check that it's correct, this - can be done with the :meth:`verify` method, you'll get an exception if the - signature is wrong: + To check that a given signature is correct use the :meth:`verify` method. + You will receive an exception if the signature is wrong: .. code-block:: pycon -- cgit v1.2.3 From 7fccf4c38e1bb63066232198b9aa4551e4da660f Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 4 Jan 2014 21:51:31 -0600 Subject: add CommonCrypto binding docs --- docs/hazmat/bindings/commoncrypto.rst | 28 ++++++++++++++++++++++++++++ docs/hazmat/bindings/index.rst | 1 + 2 files changed, 29 insertions(+) create mode 100644 docs/hazmat/bindings/commoncrypto.rst (limited to 'docs') diff --git a/docs/hazmat/bindings/commoncrypto.rst b/docs/hazmat/bindings/commoncrypto.rst new file mode 100644 index 00000000..a4423365 --- /dev/null +++ b/docs/hazmat/bindings/commoncrypto.rst @@ -0,0 +1,28 @@ +.. hazmat:: + +CommonCrypto Binding +==================== + +.. currentmodule:: cryptography.hazmat.bindings.commoncrypto.binding + +These are `CFFI`_ bindings to the `CommonCrypto`_ C library. It is available on +Mac OS X. + +.. class:: cryptography.hazmat.bindings.commoncrypto.binding.Binding() + + This is the exposed API for the CommonCrypto bindings. It has two public + attributes: + + .. attribute:: ffi + + This is a :class:`cffi.FFI` instance. It can be used to allocate and + otherwise manipulate OpenSSL structures. + + .. attribute:: lib + + This is a ``cffi`` library. It can be used to call OpenSSL functions, + and access constants. + + +.. _`CFFI`: https://cffi.readthedocs.org/ +.. _`CommonCrypto`: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/Common%20Crypto.3cc.html#//apple_ref/doc/man/3cc/CommonCrypto diff --git a/docs/hazmat/bindings/index.rst b/docs/hazmat/bindings/index.rst index e2a17591..caab8d6a 100644 --- a/docs/hazmat/bindings/index.rst +++ b/docs/hazmat/bindings/index.rst @@ -20,3 +20,4 @@ Individual Bindings :maxdepth: 1 openssl + commoncrypto -- cgit v1.2.3 From 9180ba525c440ef7c8ef814f59aef4e57bc241b0 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 9 Jan 2014 18:06:52 -0800 Subject: Fix up a mistaken copy paste --- docs/hazmat/bindings/commoncrypto.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs') diff --git a/docs/hazmat/bindings/commoncrypto.rst b/docs/hazmat/bindings/commoncrypto.rst index a4423365..25535e02 100644 --- a/docs/hazmat/bindings/commoncrypto.rst +++ b/docs/hazmat/bindings/commoncrypto.rst @@ -16,12 +16,12 @@ Mac OS X. .. attribute:: ffi This is a :class:`cffi.FFI` instance. It can be used to allocate and - otherwise manipulate OpenSSL structures. + otherwise manipulate CommonCrypto structures. .. attribute:: lib - This is a ``cffi`` library. It can be used to call OpenSSL functions, - and access constants. + This is a ``cffi`` library. It can be used to call CommonCrypto + functions, and access constants. .. _`CFFI`: https://cffi.readthedocs.org/ -- cgit v1.2.3 From 9cd4b21fd91016040658f1ee0fb095fc11541651 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 10 Jan 2014 06:54:21 -0800 Subject: Use a normal quote here, not sure where the smart quote came from --- docs/security.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/security.rst b/docs/security.rst index 88959709..2b96d589 100644 --- a/docs/security.rst +++ b/docs/security.rst @@ -7,6 +7,6 @@ identified a security issue in it, please report it to fingerprint ``E27D 4AA0 1651 72CB C5D2 AF2B 125F 5C67 DFE9 4084`` (this public key is available from most commonly-used key servers). -Once you’ve submitted an issue via email, you should receive an acknowledgment +Once you've submitted an issue via email, you should receive an acknowledgment within 48 hours, and depending on the action to be taken, you may receive further followup emails. -- cgit v1.2.3 From fc4e2b740feba8d38ad9900e6203f619a31b71f3 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 10 Jan 2014 07:30:51 -0800 Subject: Try to run the spellchecker on travis --- docs/conf.py | 1 + docs/spelling_wordlist.txt | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 docs/spelling_wordlist.txt (limited to 'docs') diff --git a/docs/conf.py b/docs/conf.py index 00660314..a42dcb22 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -38,6 +38,7 @@ extensions = [ 'sphinx.ext.intersphinx', 'sphinx.ext.viewcode', 'cryptography-docs', + 'sphinxcontrib.spelling', ] # Add any paths that contain templates here, relative to this directory. diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt new file mode 100644 index 00000000..97356c24 --- /dev/null +++ b/docs/spelling_wordlist.txt @@ -0,0 +1,28 @@ +backend +backends +boolean +ciphertext +committer +crypto +cryptographic +cryptographically +decrypt +decrypted +decrypting +fernet +hazmat +indistinguishability +introspectability +invariants +pickleable +plaintext +testability +unencrypted +unpadded +unpadding +Backends +Blowfish +Changelog +Docstrings +Fernet +Schneier -- cgit v1.2.3 From 59075dfd1bc18ad778d04425d8941e07352d7bba Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 10 Jan 2014 11:40:03 -0800 Subject: Spelling! --- docs/security.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/security.rst b/docs/security.rst index 2b96d589..4dadc847 100644 --- a/docs/security.rst +++ b/docs/security.rst @@ -9,4 +9,4 @@ key is available from most commonly-used key servers). Once you've submitted an issue via email, you should receive an acknowledgment within 48 hours, and depending on the action to be taken, you may receive -further followup emails. +further follow-up emails. -- cgit v1.2.3