blob: 5dca3f7955907bccf20e25e403dfbba1199b6cb2 [file] [log] [blame]
Paul Kehrer0839aa82014-02-11 22:36:51 -06001Submitting Patches
2==================
3
4* Always make a new branch for your work.
5* Patches should be small to facilitate easier review. `Studies have shown`_
6 that review quality falls off as patch size grows. Sometimes this will result
7 in many small PRs to land a single large feature.
8* Larger changes should be discussed on `our mailing list`_ before submission.
9* New features and significant bug fixes should be documented in the
10 :doc:`/changelog`.
11
12If you believe you've identified a security issue in ``cryptography``, please
13follow the directions on the :doc:`security page </security>`.
14
15Code
16----
17
18When in doubt, refer to :pep:`8` for Python code.
19
20`Write comments as complete sentences.`_
21
22Every code file must start with the boilerplate notice of the Apache License.
23Additionally, every Python code file must contain
24
25.. code-block:: python
26
27 from __future__ import absolute_import, division, print_function
28
29API Considerations
30~~~~~~~~~~~~~~~~~~
31
32Most projects' APIs are designed with a philosophy of "make easy things easy,
33and make hard things possible". One of the perils of writing cryptographic code
34is that secure code looks just like insecure code, and its results are almost
35always indistinguishable. As a result ``cryptography`` has, as a design
36philosophy: "make it hard to do insecure things". Here are a few strategies for
37API design that should be both followed, and should inspire other API choices:
38
39If it is necessary to compare a user provided value with a computed value (for
40example, verifying a signature), there should be an API provided that performs
41the verification in a secure way (for example, using a constant time
42comparison), rather than requiring the user to perform the comparison
43themselves.
44
45If it is incorrect to ignore the result of a method, it should raise an
46exception, and not return a boolean ``True``/``False`` flag. For example, a
47method to verify a signature should raise ``InvalidSignature``, and not return
48whether the signature was valid.
49
50.. code-block:: python
51
52 # This is bad.
53 def verify(sig):
54 # ...
55 return is_valid
56
57 # Good!
58 def verify(sig):
59 # ...
60 if not is_valid:
61 raise InvalidSignature
62
63Every recipe should include a version or algorithmic marker of some sort in its
64output in order to allow transparent upgrading of the algorithms in use, as
65the algorithms or parameters needed to achieve a given security margin evolve.
66
67APIs at the :doc:`/hazmat/primitives/index` layer should always take an
68explicit backend, APIs at the recipes layer should automatically use the
69:func:`~cryptography.hazmat.backends.default_backend`, but optionally allow
70specifying a different backend.
71
72C bindings
73~~~~~~~~~~
74
75When binding C code with ``cffi`` we have our own style guide, it's pretty
76simple.
77
78Don't name parameters:
79
80.. code-block:: c
81
82 // Good
83 long f(long);
84 // Bad
85 long f(long x);
86
87...unless they're inside a struct:
88
89.. code-block:: c
90
91 struct my_struct {
92 char *name;
93 int number;
94 ...;
95 };
96
97Include ``void`` if the function takes no arguments:
98
99.. code-block:: c
100
101 // Good
102 long f(void);
103 // Bad
104 long f();
105
106Wrap lines at 80 characters like so:
107
108.. code-block:: c
109
110 // Pretend this went to 80 characters
111 long f(long, long,
112 int *)
113
114Include a space after commas between parameters:
115
116.. code-block:: c
117
118 // Good
119 long f(int, char *)
120 // Bad
121 long f(int,char *)
122
123Values set by ``#define`` should be assigned the appropriate type. If you see
124this:
125
126.. code-block:: c
127
128 #define SOME_INTEGER_LITERAL 0x0;
129 #define SOME_UNSIGNED_INTEGER_LITERAL 0x0001U;
130 #define SOME_STRING_LITERAL "hello";
131
132...it should be added to the bindings like so:
133
134.. code-block:: c
135
136 static const int SOME_INTEGER_LITERAL;
137 static const unsigned int SOME_UNSIGNED_INTEGER_LITERAL;
138 static const char *const SOME_STRING_LITERAL;
139
140Tests
141-----
142
143All code changes must be accompanied by unit tests with 100% code coverage (as
144measured by the combined metrics across our build matrix).
145
146When implementing a new primitive or recipe ``cryptography`` requires that you
Paul Kehrer1681a692014-02-11 23:43:51 -0600147provide a set of test vectors. See :doc:`/development/test-vectors` for more
148details.
Paul Kehrer0839aa82014-02-11 22:36:51 -0600149
150Documentation
151-------------
152
153All features should be documented with prose in the ``docs`` section.
154
155Because of the inherent challenges in implementing correct cryptographic
156systems, we want to make our documentation point people in the right directions
157as much as possible. To that end:
158
159* When documenting a generic interface, use a strong algorithm in examples.
160 (e.g. when showing a hashing example, don't use
161 :class:`~cryptography.hazmat.primitives.hashes.MD5`)
162* When giving prescriptive advice, always provide references and supporting
163 material.
164* When there is real disagreement between cryptographic experts, represent both
165 sides of the argument and describe the trade-offs clearly.
166
167When documenting a new module in the ``hazmat`` package, its documentation
168should begin with the "Hazardous Materials" warning:
169
170.. code-block:: rest
171
172 .. hazmat::
173
174When referring to a hypothetical individual (such as "a person receiving an
175encrypted message") use gender neutral pronouns (they/them/their).
176
177Docstrings are typically only used when writing abstract classes, but should
178be written like this if required:
179
180.. code-block:: python
181
182 def some_function(some_arg):
183 """
184 Does some things.
185
186 :param some_arg: Some argument.
187 """
188
189So, specifically:
190
191* Always use three double quotes.
192* Put the three double quotes on their own line.
193* No blank line at the end.
194* Use Sphinx parameter/attribute documentation `syntax`_.
195
196
197.. _`Write comments as complete sentences.`: http://nedbatchelder.com/blog/201401/comments_should_be_sentences.html
198.. _`syntax`: http://sphinx-doc.org/domains.html#info-field-lists
199.. _`Studies have shown`: http://www.ibm.com/developerworks/rational/library/11-proven-practices-for-peer-review/
200.. _`our mailing list`: https://mail.python.org/mailman/listinfo/cryptography-dev