From 7d2c74e4d36de4b70e72f2f8d6a7a60e86f80e60 Mon Sep 17 00:00:00 2001 From: Laurens Van Houtven <_@lvh.cc> Date: Mon, 23 Jun 2014 13:49:58 +0200 Subject: Add C binding documentation page --- docs/development/c-bindings.rst | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 docs/development/c-bindings.rst (limited to 'docs/development/c-bindings.rst') diff --git a/docs/development/c-bindings.rst b/docs/development/c-bindings.rst new file mode 100644 index 00000000..9106e59c --- /dev/null +++ b/docs/development/c-bindings.rst @@ -0,0 +1,8 @@ +C bindings +========== + +C bindings are bindings to C libraries, using cffi_ whenever possible. + +.. _cffi:: http://cffi.readthedocs.org + +Bindings live in :py:mod:`cryptography.hazmat.bindings`. -- cgit v1.2.3 From efa5cfbe1eecc59bbce709dd43d0aa5b4cb6bf12 Mon Sep 17 00:00:00 2001 From: Laurens Van Houtven <_@lvh.cc> Date: Mon, 23 Jun 2014 13:51:35 +0200 Subject: Add docs about exposing features in C bindings --- docs/development/c-bindings.rst | 112 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) (limited to 'docs/development/c-bindings.rst') diff --git a/docs/development/c-bindings.rst b/docs/development/c-bindings.rst index 9106e59c..1c134ad4 100644 --- a/docs/development/c-bindings.rst +++ b/docs/development/c-bindings.rst @@ -6,3 +6,115 @@ C bindings are bindings to C libraries, using cffi_ whenever possible. .. _cffi:: http://cffi.readthedocs.org Bindings live in :py:mod:`cryptography.hazmat.bindings`. + +Adding constant, types, functions... +------------------------------------ + +You can create bindings for any name that exists in some version of +the library you're binding against. However, the project also has to +keep supporting older versions of the library. In order to acchieve +this, binding modules have ``CUSTOMIZATIONS`` and +``CONDITIONAL_NAMES`` constants. + +Let's say you want to enable quantum transmogrification. The upstream +library implements this as the following API:: + + static const int QM_TRANSMOGRIFICATION_ALIGNMENT_LEFT; + static const int QM_TRANSMOGRIFICATION_ALIGNMENT_RIGHT; + typedef ... QM_TRANSMOGRIFICATION_CTX; + int QM_transmogrify(QM_TRANSMOGRIFICATION_CTX *, int); + +To start, create a new constant that defines if the *actual* library +has the feature you want, and add it to ``TYPES``:: + + static const long Cryptography_HAS_QUANTUM_TRANSMOGRIFICATION; + +This should start with ``Cryptography_``, since we're adding it in +this library. This prevents namespace collisions. + +Then, define the actual features (constants, types, functions...) you +want to expose. If it's a constant, just add it to ``TYPES``:: + + static const int QM_TRANSMOGRIFICATION_ALIGNMENT_LEFT; + static const int QM_TRANSMOGRIFICATION_ALIGNMENT_RIGHT; + +If it's a struct, add it to ``TYPES`` as well. The following is an +opaque struct:: + + typedef ... QM_TRANSMOGRIFICATION_CTX; + +... but you can also make some or all items in the struct accessible:: + + typedef struct { + /* Fundamental constant k for your particular universe */ + BIGNUM *k; + ...; + } QM_TRANSMOGRIFICATION_CTX; + +Confusingly, functions that aren't always available on all supported +versions of the library, should be defined in ``MACROS`` and *not* in +``FUNCTIONS``. Fortunately, you just have to copy the signature:: + + int QM_transmogrify(QM_TRANSMOGRIFICATION_CTX *, int); + +Then, we define the ``CUSTOMIZATIONS`` entry. To do that, we have to +come up with a C preprocessor expression that decides whether or not a +feature exists in the library. For example:: + + #ifdef QM_transmogrify + +Then, we set the flag that signifies the feature exists:: + + static const long Cryptography_HAS_QUANTUM_TRANSMOGRIFICATION = 1; + +Otherwise, we set that flag to 0:: + + #else + static const long Cryptography_HAS_QUANTUM_TRANSMOGRIFICATION = 0; + +Then, in that ``#else`` block, we define a number of fallbacks. For an +integer constant, just define it as 0:: + + static const int QM_TRANSMOGRIFICATION_ALIGNMENT_LEFT = 0; + static const int QM_TRANSMOGRIFICATION_ALIGNMENT_RIGHT = 0; + +For a function, it's a bit trickier. You have to define a function +pointer of the appropriate type to be NULL:: + + int (*QM_transmogrify)(QM_TRANSMOGRIFICATION_CTX *, int) = NULL; + +(That is, copy the signature, put a ``*`` in front of the function +name and wrap it in parens, and then put ``= NULL`` at the end). + +Note how types don't need to be conditionally defined, as long as all +the necessarily typedefs are in place. + +Finally, add an entry to ``CONDITIONAL_NAMES`` with all of the things +you want to conditionally export:: + + CONDITIONAL_NAMES = { + ... + "Cryptography_HAS_QUANTUM_TRANSMOGRIFICATION": [ + "QM_TRANSMOGRIFICATION_ALIGNMENT_LEFT", + "QM_TRANSMOGRIFICATION_ALIGNMENT_RIGHT", + "QM_transmogrify" + ] + } + +Caveats +~~~~~~~ + +Sometimes, a set of loosely related features are added in the same +version, and it's impractical to create ``#ifdef`` statements for each +one. In that case, it may make sense to either check for a particular +version. For example, to check for OpenSSL 1.0.0 or newer: + + #if OPENSSL_VERSION_NUMBER >= 0x10000000L + +Sometimes, the version of a libray on a particular platform will have +features that you thought it wouldn't, based on its version. +Occasionally, packagers appear to ship arbitrary VCS checkouts. As a +result, sometimes you may have to add separate ``#ifdef`` statements +for particular features. This kind of issue is typically only caught +by running the tests on a wide variety of systems, which is the job of +our continuous integration infrastructure. -- cgit v1.2.3 From 1dc0b146636d6a155efa22be220c88ef0c4f9952 Mon Sep 17 00:00:00 2001 From: Laurens Van Houtven <_@lvh.cc> Date: Mon, 23 Jun 2014 13:55:21 +0200 Subject: Improve wording --- docs/development/c-bindings.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/development/c-bindings.rst') diff --git a/docs/development/c-bindings.rst b/docs/development/c-bindings.rst index 1c134ad4..1770e200 100644 --- a/docs/development/c-bindings.rst +++ b/docs/development/c-bindings.rst @@ -83,7 +83,7 @@ pointer of the appropriate type to be NULL:: int (*QM_transmogrify)(QM_TRANSMOGRIFICATION_CTX *, int) = NULL; -(That is, copy the signature, put a ``*`` in front of the function +(To do that, copy the signature, put a ``*`` in front of the function name and wrap it in parens, and then put ``= NULL`` at the end). Note how types don't need to be conditionally defined, as long as all -- cgit v1.2.3 From 1c07ddf6911d3d2810d8d0c26e66862b8e385343 Mon Sep 17 00:00:00 2001 From: Laurens Van Houtven <_@lvh.cc> Date: Mon, 23 Jun 2014 13:55:27 +0200 Subject: Fix ReST syntax for a code block --- docs/development/c-bindings.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/development/c-bindings.rst') diff --git a/docs/development/c-bindings.rst b/docs/development/c-bindings.rst index 1770e200..3fad00ff 100644 --- a/docs/development/c-bindings.rst +++ b/docs/development/c-bindings.rst @@ -107,7 +107,7 @@ Caveats Sometimes, a set of loosely related features are added in the same version, and it's impractical to create ``#ifdef`` statements for each one. In that case, it may make sense to either check for a particular -version. For example, to check for OpenSSL 1.0.0 or newer: +version. For example, to check for OpenSSL 1.0.0 or newer:: #if OPENSSL_VERSION_NUMBER >= 0x10000000L -- cgit v1.2.3 From 4e0061479a0b48d19074d56e0b25879582b97510 Mon Sep 17 00:00:00 2001 From: Laurens Van Houtven <_@lvh.cc> Date: Mon, 23 Jun 2014 14:05:10 +0200 Subject: Fix ReST hyperlink markup --- docs/development/c-bindings.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/development/c-bindings.rst') diff --git a/docs/development/c-bindings.rst b/docs/development/c-bindings.rst index 3fad00ff..910f4d3d 100644 --- a/docs/development/c-bindings.rst +++ b/docs/development/c-bindings.rst @@ -3,7 +3,7 @@ C bindings C bindings are bindings to C libraries, using cffi_ whenever possible. -.. _cffi:: http://cffi.readthedocs.org +.. _cffi: http://cffi.readthedocs.org Bindings live in :py:mod:`cryptography.hazmat.bindings`. -- cgit v1.2.3 From 220a98ddfee87e049ddb91229b05e6f9c82a5ddf Mon Sep 17 00:00:00 2001 From: Laurens Van Houtven <_@lvh.cc> Date: Mon, 23 Jun 2014 14:08:27 +0200 Subject: Move C bindings style guide to C bindings document --- docs/development/c-bindings.rst | 72 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'docs/development/c-bindings.rst') diff --git a/docs/development/c-bindings.rst b/docs/development/c-bindings.rst index 910f4d3d..1349af73 100644 --- a/docs/development/c-bindings.rst +++ b/docs/development/c-bindings.rst @@ -7,6 +7,78 @@ C bindings are bindings to C libraries, using cffi_ whenever possible. Bindings live in :py:mod:`cryptography.hazmat.bindings`. +Style guide +----------- + +Don't name parameters: + +.. code-block:: c + + /* Good */ + long f(long); + /* Bad */ + long f(long x); + +...unless they're inside a struct: + +.. code-block:: c + + struct my_struct { + char *name; + int number; + ...; + }; + +Include ``void`` if the function takes no arguments: + +.. code-block:: c + + /* Good */ + long f(void); + /* Bad */ + long f(); + +Wrap lines at 80 characters like so: + +.. code-block:: c + + /* Pretend this went to 80 characters */ + long f(long, long, + int *) + +Include a space after commas between parameters: + +.. code-block:: c + + /* Good */ + long f(int, char *) + /* Bad */ + long f(int,char *) + +Use C-style ``/* */`` comments instead of C++-style ``//``: + +.. code-block:: c + + // Bad + /* Good */ + +Values set by ``#define`` should be assigned the appropriate type. If you see +this: + +.. code-block:: c + + #define SOME_INTEGER_LITERAL 0x0; + #define SOME_UNSIGNED_INTEGER_LITERAL 0x0001U; + #define SOME_STRING_LITERAL "hello"; + +...it should be added to the bindings like so: + +.. code-block:: c + + static const int SOME_INTEGER_LITERAL; + static const unsigned int SOME_UNSIGNED_INTEGER_LITERAL; + static const char *const SOME_STRING_LITERAL; + Adding constant, types, functions... ------------------------------------ -- cgit v1.2.3 From 260e8870842fb19e29ce69e560f91c683e868771 Mon Sep 17 00:00:00 2001 From: Laurens Van Houtven <_@lvh.cc> Date: Mon, 23 Jun 2014 16:22:32 +0200 Subject: Spelling fix: library --- docs/development/c-bindings.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/development/c-bindings.rst') diff --git a/docs/development/c-bindings.rst b/docs/development/c-bindings.rst index 1349af73..dbcd62f5 100644 --- a/docs/development/c-bindings.rst +++ b/docs/development/c-bindings.rst @@ -183,7 +183,7 @@ version. For example, to check for OpenSSL 1.0.0 or newer:: #if OPENSSL_VERSION_NUMBER >= 0x10000000L -Sometimes, the version of a libray on a particular platform will have +Sometimes, the version of a library on a particular platform will have features that you thought it wouldn't, based on its version. Occasionally, packagers appear to ship arbitrary VCS checkouts. As a result, sometimes you may have to add separate ``#ifdef`` statements -- cgit v1.2.3 From 1159af88ccb1bab81701ce7e48ba7527986c1d2f Mon Sep 17 00:00:00 2001 From: Laurens Van Houtven <_@lvh.cc> Date: Mon, 23 Jun 2014 16:23:24 +0200 Subject: Spelling fix: achieve --- docs/development/c-bindings.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/development/c-bindings.rst') diff --git a/docs/development/c-bindings.rst b/docs/development/c-bindings.rst index dbcd62f5..852896ea 100644 --- a/docs/development/c-bindings.rst +++ b/docs/development/c-bindings.rst @@ -84,7 +84,7 @@ Adding constant, types, functions... You can create bindings for any name that exists in some version of the library you're binding against. However, the project also has to -keep supporting older versions of the library. In order to acchieve +keep supporting older versions of the library. In order to achieve this, binding modules have ``CUSTOMIZATIONS`` and ``CONDITIONAL_NAMES`` constants. -- cgit v1.2.3 From a7b0758a117ee596e4870f44cf70d026a75d94a1 Mon Sep 17 00:00:00 2001 From: Laurens Van Houtven <_@lvh.cc> Date: Mon, 23 Jun 2014 16:23:46 +0200 Subject: Spelling fix: parentheses --- docs/development/c-bindings.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/development/c-bindings.rst') diff --git a/docs/development/c-bindings.rst b/docs/development/c-bindings.rst index 852896ea..a8d71e5c 100644 --- a/docs/development/c-bindings.rst +++ b/docs/development/c-bindings.rst @@ -156,7 +156,7 @@ pointer of the appropriate type to be NULL:: int (*QM_transmogrify)(QM_TRANSMOGRIFICATION_CTX *, int) = NULL; (To do that, copy the signature, put a ``*`` in front of the function -name and wrap it in parens, and then put ``= NULL`` at the end). +name and wrap it in parentheses, and then put ``= NULL`` at the end). Note how types don't need to be conditionally defined, as long as all the necessarily typedefs are in place. -- cgit v1.2.3 From 4e74a7f3f0991e271959a8c4aacc394a1e4ca615 Mon Sep 17 00:00:00 2001 From: Laurens Van Houtven <_@lvh.cc> Date: Mon, 23 Jun 2014 16:29:39 +0200 Subject: typedefs -> type definitions --- docs/development/c-bindings.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/development/c-bindings.rst') diff --git a/docs/development/c-bindings.rst b/docs/development/c-bindings.rst index a8d71e5c..039c081f 100644 --- a/docs/development/c-bindings.rst +++ b/docs/development/c-bindings.rst @@ -159,7 +159,7 @@ pointer of the appropriate type to be NULL:: name and wrap it in parentheses, and then put ``= NULL`` at the end). Note how types don't need to be conditionally defined, as long as all -the necessarily typedefs are in place. +the necessarily type definitions are in place. Finally, add an entry to ``CONDITIONAL_NAMES`` with all of the things you want to conditionally export:: -- cgit v1.2.3 From 316b4fd47896766928289d3785d8c53d1ca32892 Mon Sep 17 00:00:00 2001 From: Laurens Van Houtven <_@lvh.cc> Date: Mon, 23 Jun 2014 16:33:24 +0200 Subject: Dance around the word "fallbacks"" --- docs/development/c-bindings.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/development/c-bindings.rst') diff --git a/docs/development/c-bindings.rst b/docs/development/c-bindings.rst index 039c081f..56963379 100644 --- a/docs/development/c-bindings.rst +++ b/docs/development/c-bindings.rst @@ -144,8 +144,8 @@ Otherwise, we set that flag to 0:: #else static const long Cryptography_HAS_QUANTUM_TRANSMOGRIFICATION = 0; -Then, in that ``#else`` block, we define a number of fallbacks. For an -integer constant, just define it as 0:: +Then, in that ``#else`` block, we define the names that aren't +available as dummy values. For an integer constant, use 0:: static const int QM_TRANSMOGRIFICATION_ALIGNMENT_LEFT = 0; static const int QM_TRANSMOGRIFICATION_ALIGNMENT_RIGHT = 0; -- cgit v1.2.3