diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | TODO | 157 | ||||
-rw-r--r-- | lang/python/docs/GPGMEpythonHOWTOen.org | 456 | ||||
-rw-r--r-- | lang/python/docs/TODO.org | 51 | ||||
-rw-r--r-- | src/gpgme-tool.c | 2 |
5 files changed, 625 insertions, 42 deletions
@@ -52,4 +52,3 @@ nosetests.xml default.profraw .DS_Store ._.DS_Store -default.profraw
\ No newline at end of file @@ -14,23 +14,46 @@ Hey Emacs, this is -*- org -*- mode! tracked through the [[https://dev.gnupg.org/][dev.gnupg.org]] site. -* TODO Document all the new stuff. +* Documentation :PROPERTIES: - :CUSTOM_ID: more-docs-is-better + :CUSTOM_ID: documentation :END: -** STARTED Fix this TODO list. +** Document all the new stuff. :PROPERTIES: - :CUSTOM_ID: fix-todo + :CUSTOM_ID: more-docs-is-better :END: - - State "STARTED" from "TODO" [2018-03-09 Fri 08:31] - Clean up the current TODO list. Include properties as relevant (so - if someone does make a PDF or HTML version the TOC will work). - Also check ans see if some of these ancient things can be removed - (e.g. do we really need to fix things that were broken in GPG - 1.3.x? I'm thinking not so much). +*** TODO Fix this TODO list. + :PROPERTIES: + :CUSTOM_ID: fix-todo + :END: + + Clean up the current TODO list. Include properties as relevant (so + if someone does make a PDF or HTML version the TOC will work). + + Also check ans see if some of these ancient things can be removed + (e.g. do we really need to fix things that were broken in GPG + 1.3.x? I'm thinking not so much). + +**** DONE fix TODO items + CLOSED: [2018-03-04 Sun 08:55] + :PROPERTIES: + :CUSTOM_ID: fix-todo-items + :END: + + Adjust todo items so each can now be referenced by custom-id and + checked off as necessary. +** TODO Document validity and trust issues. + :PROPERTIES: + :CUSTOM_ID: valid-trust-issues + :END: + +** In gpgme.texi: Register callbacks under the right letter in the index. + :PROPERTIES: + :CUSTOM_ID: gpgme-texi + :END: * Fix the remaining UI Server problems: @@ -63,10 +86,12 @@ Hey Emacs, this is -*- org -*- mode! :END: Right now we block reading the next line with assuan. + * Before release: :PROPERTIES: :CUSTOM_ID: pre-release :END: + ** CANCELLED Some gpg tests fail with gpg 1.3.4-cvs (gpg/t-keylist-sig) CLOSED: [2018-03-09 Fri 08:16] :PROPERTIES: @@ -75,100 +100,123 @@ Hey Emacs, this is -*- org -*- mode! - State "CANCELLED" from "TODO" [2018-03-09 Fri 08:16] \\ WON'T FIX — too old or no longer applies. The test is currently disabled there and in gpg/t-import. + ** When gpg supports it, write binary subpackets directly, :PROPERTIES: :CUSTOM_ID: binary-subpackets :END: and parse SUBPACKET status lines. + * ABI's to break: :PROPERTIES: :CUSTOM_ID: abi-breakage-apparently-on-purpose :END: + ** Old opassuan interface. :PROPERTIES: :CUSTOM_ID: old-opassuan :END: + ** Implementation: Remove support for old style error codes in :PROPERTIES: :CUSTOM_ID: remove-old-error-codes :END: conversion.c::_gpgme_map_gnupg_error. + ** gpgme_edit_cb_t: Add "processed" return argument :PROPERTIES: :CUSTOM_ID: add-processed-return :END: (see edit.c::command_handler). + ** I/O and User Data could be made extensible. But this can be done :PROPERTIES: :CUSTOM_ID: add-io-user-data :END: without breaking the ABI hopefully. + ** All enums should be replaced by ints and simple macros for :PROPERTIES: :CUSTOM_ID: enums-should-be-ints :END: maximum compatibility. + ** Compatibility interfaces that can be removed in future versions: :PROPERTIES: :CUSTOM_ID: compat-interfaces-to-go :END: + *** gpgme_data_new_from_filepart :PROPERTIES: :CUSTOM_ID: gpgme-data-new-from-filepart :END: + *** gpgme_data_new_from_file :PROPERTIES: :CUSTOM_ID: gpgme-data-new-from-file :END: + *** gpgme_data_new_with_read_cb :PROPERTIES: :CUSTOM_ID: gpgme-data-new-with-read-cb :END: + *** gpgme_data_rewind :PROPERTIES: :CUSTOM_ID: gpgme-data-rewind :END: + *** gpgme_op_import_ext :PROPERTIES: :CUSTOM_ID: gpgme-op-import-ext :END: + *** gpgme_get_sig_key :PROPERTIES: :CUSTOM_ID: gpgme-get-sig-key :END: + *** gpgme_get_sig_ulong_attr :PROPERTIES: :CUSTOM_ID: gpgme-get-sig-ulong-attr :END: + *** gpgme_get_sig_string_attr :PROPERTIES: :CUSTOM_ID: gpgme-get-sig-string-attr :END: + *** GPGME_SIG_STAT_* :PROPERTIES: :CUSTOM_ID: gpgme-sig-stat :END: + *** gpgme_get_sig_status :PROPERTIES: :CUSTOM_ID: gpgme-get-sig-status :END: + *** gpgme_trust_item_release :PROPERTIES: :CUSTOM_ID: gpgme-trust-item-release :END: + *** gpgme_trust_item_get_string_attr :PROPERTIES: :CUSTOM_ID: gpgme-trust-item-get-string-attr :END: + *** gpgme_trust_item_get_ulong_attr :PROPERTIES: :CUSTOM_ID: gpgme-trust-item-get-ulong-attr :END: + *** gpgme_attr_t :PROPERTIES: :CUSTOM_ID: gpgme-attr-t :END: + *** All Gpgme* typedefs. :PROPERTIES: :CUSTOM_ID: all-gpgme-typedefs @@ -179,20 +227,24 @@ Hey Emacs, this is -*- org -*- mode! :PROPERTIES: :CUSTOM_ID: threads :END: + ** When GNU Pth supports sendmsg/recvmsg, wrap them properly. :PROPERTIES: :CUSTOM_ID: wrap-oth :END: + ** Without timegm (3) support our ISO time parser is not thread safe. :PROPERTIES: :CUSTOM_ID: time-threads :END: There is a configure time warning, though. + * New features: :PROPERTIES: :CUSTOM_ID: new-features :END: + ** Flow control for data objects. :PROPERTIES: :CUSTOM_ID: flow-control-is-not-a-euphemism-for-an-s-bend @@ -205,11 +257,13 @@ Hey Emacs, this is -*- org -*- mode! respective event loop. or (B) a way for gpgme data objects to be associated with a waitable object, that can be registered with the user event loop. Neither is particularly simple. + ** Extended notation support. When gpg supports arbitrary binary :PROPERTIES: :CUSTOM_ID: extended-notation :END: notation data, provide a user interface for that. + ** notification system :PROPERTIES: :CUSTOM_ID: notification-system @@ -236,25 +290,30 @@ Hey Emacs, this is -*- org -*- mode! :PROPERTIES: :CUSTOM_ID: stat-data :END: + ** Implement support for photo ids. :PROPERTIES: :CUSTOM_ID: photo-id :END: + ** Allow selection of subkeys :PROPERTIES: :CUSTOM_ID: subkey-selection :END: + ** Allow to return time stamps in ISO format :PROPERTIES: :CUSTOM_ID: iso-format-datetime :END: - This allows us to handle years later than 2037 properly. With the - time_t interface they are all mapped to 2037-12-31 + This allows us to handle years later than 2037 properly. With the + time_t interface they are all mapped to 2037-12-31 + ** New features requested by our dear users, but rejected or left for :PROPERTIES: :CUSTOM_ID: feature-requests :END: later consideration: + *** Allow to export secret keys. :PROPERTIES: :CUSTOM_ID: export-secret-keys @@ -262,6 +321,7 @@ Hey Emacs, this is -*- org -*- mode! Rejected because this is conceptually flawed. Secret keys on a smart card can not be exported, for example. May eventually e supproted with a keywrapping system. + *** Selecting the key ring, setting the version or comment in output. :PROPERTIES: :CUSTOM_ID: select-keyring-version @@ -269,46 +329,23 @@ Hey Emacs, this is -*- org -*- mode! Rejected because the naive implementation is engine specific, the configuration is part of the engine's configuration or readily worked around in a different way + *** Selecting the symmetric cipher. :PROPERTIES: :CUSTOM_ID: symmetric-cipher-selection :END: + *** Exchanging keys with key servers. :PROPERTIES: :CUSTOM_ID: key-server-exchange :END: -* Documentation - :PROPERTIES: - :CUSTOM_ID: documentation - :END: -** TODO Document validity and trust issues. - :PROPERTIES: - :CUSTOM_ID: valid-trust-issues - :END: -** In gpgme.texi: Register callbacks under the right letter in the index. - :PROPERTIES: - :CUSTOM_ID: gpgme-texi - :END: -** TODO Update TODO file - :PROPERTIES: - :CUSTOM_ID: todo-update - :END: - -*** DONE fix TODO items - CLOSED: [2018-03-04 Sun 08:55] - :PROPERTIES: - :CUSTOM_ID: fix-todo-items - :END: - - Adjust todo items so each can now be referenced by custom-id and - checked off as necessary. - * Engines :PROPERTIES: :CUSTOM_ID: engines :END: + ** Do not create/destroy engines, but create engine and then reset it. :PROPERTIES: :CUSTOM_ID: reset-engine-is-not-quite-just-ignition @@ -321,26 +358,31 @@ Hey Emacs, this is -*- org -*- mode! Note that we need support in gpgsm to set include-certs to default as RESET does not reset it, also for no_encrypt_to and probably other options. + ** Optimize the case where a data object has an underlying fd we can pass :PROPERTIES: :CUSTOM_ID: optimus-data-cousin-of-optimus-prime :END: directly to the engine. This will be automatic with socket I/O and descriptor passing. + ** Move code common to all engines up from gpg to engine. :PROPERTIES: :CUSTOM_ID: move-code-common-to-engines-out-of-gpg :END: + ** engine operations can return General Error on unknown protocol :PROPERTIES: :CUSTOM_ID: general-error-looking-to-be-court-martialled :END: (it's an internal error, as select_protocol checks already). + ** When server mode is implemented properly, more care has to be taken to :PROPERTIES: :CUSTOM_ID: server-mode :END: release all resources on error (for example to free assuan_cmd). + ** op_import_keys and op_export_keys have a limit in the number of keys. :PROPERTIES: :CUSTOM_ID: import-export-problems @@ -354,6 +396,7 @@ Hey Emacs, this is -*- org -*- mode! :PROPERTIES: :CUSTOM_ID: gpg-breakage :END: + ** CANCELLED gpg 1.4.2 lacks error reporting if sign/encrypt with revoked key. CLOSED: [2018-03-09 Fri 08:19] :PROPERTIES: @@ -361,6 +404,7 @@ Hey Emacs, this is -*- org -*- mode! :END: - State "CANCELLED" from "TODO" [2018-03-09 Fri 08:19] \\ WON'T FIX. + ** CANCELLED gpg 1.4.2 does crappy error reporting (namely none at all) when CLOSED: [2018-03-09 Fri 08:20] :PROPERTIES: @@ -374,6 +418,7 @@ Hey Emacs, this is -*- org -*- mode! gpg: signing failed: general error [GNUPG:] BEGIN_ENCRYPTION 2 10 gpg: test: sign+encrypt failed: general error + ** DONE Without agent and with wrong passphrase, gpg 1.4.2 enters into an CLOSED: [2018-03-09 Fri 08:20] :PROPERTIES: @@ -382,6 +427,7 @@ Hey Emacs, this is -*- org -*- mode! - State "DONE" from "TODO" [2018-03-09 Fri 08:20] \\ Must have been fixed in a subsequent release. infinite loop. + ** CANCELLED Use correct argv[0] CLOSED: [2018-03-09 Fri 08:24] :PROPERTIES: @@ -402,71 +448,86 @@ Hey Emacs, this is -*- org -*- mode! :PROPERTIES: :CUSTOM_ID: operations-are-not-surgical :END: + ** Include cert values -2, -1, 0 and 1 should be defined as macros. :PROPERTIES: :CUSTOM_ID: certified-macros :END: + ** If an operation failed, make sure that the result functions don't return :PROPERTIES: :CUSTOM_ID: operation-failure :END: corrupt partial information. !!! NOTE: The EOF status handler is not called in this case !!! + ** Verify must not fail on NODATA premature if auto-key-retrieval failed. :PROPERTIES: :CUSTOM_ID: autobot-key-retrieval :END: It should not fail silently if it knows there is an error. !!! + ** All operations: Better error reporting. !! :PROPERTIES: :CUSTOM_ID: better-reporting-not-like-fox-news :END: + ** Export status handler need much more work. !!! :PROPERTIES: :CUSTOM_ID: export-status-handler :END: + ** Import should return a useful error when one happened. :PROPERTIES: :CUSTOM_ID: import-useful-stuff-even-wrong-stuff :END: + *** Import does not take notice of NODATA status report. :PROPERTIES: :CUSTOM_ID: import-no-data :END: + *** When GPGSM does issue IMPORT_OK status reports, make sure to check for :PROPERTIES: :CUSTOM_ID: gpgsm-import-ok :END: them in tests/gpgs m/t-import.c. + ** Verify can include info about version/algo/class, but currently :PROPERTIES: :CUSTOM_ID: verify-class :END: this is only available for gpg, not gpgsm. + ** Return ENC_TO output in verify result. Again, this is not available :PROPERTIES: :CUSTOM_ID: return-to-enc :END: for gpgsm. + ** Genkey should return something more useful than General_Error. :PROPERTIES: :CUSTOM_ID: general-key-assumed-command-from-general-error :END: + ** If possible, use --file-setsize to set the file size for proper progress :PROPERTIES: :CUSTOM_ID: file-setsize :END: callback handling. Write data interface for file size. + ** Optimize the file descriptor list, so the number of open fds is :PROPERTIES: :CUSTOM_ID: optimus-descriptus-younger-brother-of-optimus-prime :END: always known easily. + ** Encryption: It should be verified that the behaviour for partially untrusted :PROPERTIES: :CUSTOM_ID: only-mostly-dead-means-partially-alive :END: recipients is correct. + ** When GPG issues INV_something for invalid signers, catch them. :PROPERTIES: :CUSTOM_ID: invalid-sig @@ -477,15 +538,18 @@ Hey Emacs, this is -*- org -*- mode! :PROPERTIES: :CUSTOM_ID: error-value :END: + ** Map ASSUAN/GpgSM ERR error values in a better way than is done now. !! :PROPERTIES: :CUSTOM_ID: map-ass-error :END: + ** Some error values should identify the source more correctly (mostly error :PROPERTIES: :CUSTOM_ID: source-errors :END: values derived from status messages). + ** In rungpg.c we need to check the version of the engine :PROPERTIES: :CUSTOM_ID: rungpg-c-engine-ver @@ -498,6 +562,7 @@ Hey Emacs, this is -*- org -*- mode! :PROPERTIES: :CUSTOM_ID: tests :END: + ** TODO Write a fake gpg-agent so that we can supply known passphrases to :PROPERTIES: :CUSTOM_ID: test-fake-gpg-agent @@ -505,23 +570,28 @@ Hey Emacs, this is -*- org -*- mode! gpgsm and setup the configuration files to use the agent. Without this we are testing a currently running gpg-agent which is not a clever idea. ! + ** t-data :PROPERTIES: :CUSTOM_ID: test-data :END: + *** Test gpgme_data_release_and_get_mem. :PROPERTIES: :CUSTOM_ID: test-gpgme-data-release-mem :END: + *** Test gpgme_data_seek for invalid types. :PROPERTIES: :CUSTOM_ID: test-gpgme-data-seek :END: + ** t-keylist :PROPERTIES: :CUSTOM_ID: test-keylist :END: Write a test for ext_keylist. + ** Test reading key signatures. :PROPERTIES: :CUSTOM_ID: test-key-sig @@ -532,6 +602,7 @@ Hey Emacs, this is -*- org -*- mode! :PROPERTIES: :CUSTOM_ID: debug :END: + ** Tracepoints should be added at: Every public interface enter/leave, :PROPERTIES: :CUSTOM_ID: tracepoint-pub-int @@ -547,6 +618,7 @@ Hey Emacs, this is -*- org -*- mode! decrypt-verify.c delete.c edit.c encrypt.c encrypt-sign.c export.c genkey.c import.c key.c keylist.c passphrase.c progress.c signers.c sig-notation.c trust-item.c trustlist.c verify.c + ** TODO Handle malloc and vasprintf errors. But decide first if they should be :PROPERTIES: :CUSTOM_ID: malloc-vasprintf @@ -559,10 +631,12 @@ Hey Emacs, this is -*- org -*- mode! :PROPERTIES: :CUSTOM_ID: build-suite :END: + ** TODO Make sure everything is cleaned correctly (esp. test area). :PROPERTIES: :CUSTOM_ID: clean-tests :END: + ** TODO Enable AC_CONFIG_MACRO_DIR and bump up autoconf version requirement. :PROPERTIES: :CUSTOM_ID: autoconf-macros @@ -575,6 +649,7 @@ Hey Emacs, this is -*- org -*- mode! :PROPERTIES: :CUSTOM_ID: error-checking :END: + ** TODO engine-gpgsm, with-validation :PROPERTIES: :CUSTOM_ID: gpgsm-validation @@ -615,7 +690,11 @@ Hey Emacs, this is -*- org -*- mode! Write a guide/best practices for maintainers of GPGME packages with third party package management systems. -Copyright 2004, 2005, 2018 g10 Code GmbH + +* Copyright 2004, 2005, 2018 g10 Code GmbH + :PROPERTIES: + :CUSTOM_ID: copyright-and-license + :END: This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org new file mode 100644 index 00000000..17ec428e --- /dev/null +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -0,0 +1,456 @@ +#+TITLE: GNU Privacy Guard (GnuPG) Made Easy Python Bindings HOWTO (English) +#+LATEX_COMPILER: xelatex +#+LATEX_CLASS: article +#+LATEX_CLASS_OPTIONS: [12pt] +#+LATEX_HEADER: \usepackage{xltxtra} +#+LATEX_HEADER: \usepackage[margin=1in]{geometry} +#+LATEX_HEADER: \setmainfont[Ligatures={Common}]{Times New Roman} +#+LATEX_HEADER: \author{Ben McGinnes <[email protected]>} + + +* Introduction + :PROPERTIES: + :CUSTOM_ID: intro + :END: + +Version: 0.0.1-alpha [2018-03-07 Wed] +Author: Ben McGinnes <[email protected]> +Author GPG Key: DB4724E6FA4286C92B4E55C4321E4E2373590E5D + +This document provides basic instruction in how to use the GPGME +Python bindings to programmatically leverage the GPGME library. + + +* GPGME Concepts + :PROPERTIES: + :CUSTOM_ID: gpgme-concepts + :END: + +** A C API + :PROPERTIES: + :CUSTOM_ID: gpgme-c-api + :END: + + Unlike many modern APIs with which programmers will be more + familiar with these days, the GPGME API is a C API. The API is + intended for use by C coders who would be able to access its + features by including the =gpgme.h= header file eith their own C + source code and then access its functions just as they would any + other C headers. + + This is a very effective method of gaining complete access to the + API and in the most efficient manner possible. It does, however, + have the drawback that it cannot be directly used by other + languages without some means of providing an interface to those + languages. This is where the need for bindings in various + languages stems. + +** Python bindings + :PROPERTIES: + :CUSTOM_ID: gpgme-python-bindings + :END: + + The Python bindings for GPGME provide a higher level means of + accessing the complete feature set of GPGME itself. It also + provides a more pythonic means of calling these API functions. + + The bindings are generated dynamically with SWIG and the copy of + =gpgme.h= generated when GPGME is compiled. + + This means that a version of the Python bindings is fundamentally + tied to the exact same version of GPGME used to gemerate that copy + of =gpgme.h=. + +** Difference between the Python bindings and other GnuPG Python packages + :PROPERTIES: + :CUSTOM_ID: gpgme-python-bindings-diffs + :END: + + There have been numerous attempts to add GnuPG support to Python + over the years. Some of the most well known are listed here, along + with what differentiates them. + +*** The python-gnupg package maintained by Vinay Sajip + :PROPERTIES: + :CUSTOM_ID: diffs-python-gnupg + :END: + + This is arguably the most popular means of integrating GPG with + Python. The package utilises the =subprocess= module to implement + wrappers for the =gpg= and =gpg2= executables normally invoked on + the command line (=gpg.exe= and =gpg2.exe= on Windows). + + The popularity of this package stemmed from its ease of use and + capability in providing the most commonly required features. + + Unfortunately it has been beset by a number of security issues, + most of which stemmed from using unsafe methods of accessing the + command line via the =subprocess= calls. + + The python-gnupg package is available under the MIT license. + +*** The gnupg package created and maintained by Isis Lovecruft + :PROPERTIES: + :CUSTOM_ID: diffs-isis-gnupg + :END: + + In 2015 Isis Lovecruft from the Tor Project forked and then + re-implemented the python-gnupg package as just gnupg. This new + package also relied on subprocess to call the =gpg= or =gpg2= + binaries, but did so somewhat more securely. + + However the naming and version numbering selected for this package + resulted in conflicts with the original python-gnupg and since its + functions were called in a different manner, the release of this + package also resulted in a great deal of consternation when people + installed what they thought was an upgrade that subsequently broke + the code relying on it. + + The gnupg package is available under the GNU General Public + License version 3.0 (or later). + +*** The PyME package maintained by Martin Albrecht + :PROPERTIES: + :CUSTOM_ID: diffs-pyme + :END: + + This package is the origin of these bindings, though they are + somewhat different now. For details of when and how the PyME + package was folded back into GPGME itself see the [[Short_History.org][Short History]] + document in this Python bindings =docs= directory. + + The PyME package was first released in 2002 and was also the first + attempt to implement a low level binding to GPGME. In doing so it + provided access to considerably more functionality than either the + =python-gnupg= or =gnupg= packages. + + The PyME package is only available for Python 2.6 and 2.7. + + Porting the PyME package to Python 3.4 in 2015 is what resulted in + it being folded into the GPGME project and the current bindings + are the end result of that effort. + + The PyME package is available under the same dual licensing as + GPGME itself: the GNU General Public License version 2.0 (or any + later version) and the GNU Lesser Public License version 2.1 (or + any later version). + + +* GPGME Python bindings installation + :PROPERTIES: + :CUSTOM_ID: gpgme-python-install + :END: + +** No PyPI + :PROPERTIES: + :CUSTOM_ID: do-not-use-pypi + :END: + + Most third-party Python packages and modules are available and + distributed through the Python Package Installer, known as PyPI. + + Due to the nature of what these bindings are and how they work, it + is infeasible to install the GPGME Python bindings in the same way. + +** Requirements + :PROPERTIES: + :CUSTOM_ID: gpgme-python-requirements + :END: + + The GPGME Python bindings only have three requirements: + + 1. A suitable version of Python 2 or Python 3. With Python 2 that + means Python 2.7 and with Python 3 that means Python 3.4 or + higher. + 2. SWIG. + 3. GPGME itself. Which also means that all of GPGME's dependencies + must be installed too. + +** Installation + :PROPERTIES: + :CUSTOM_ID: installation + :END: + + Installing the Python bindings is effectively achieved by compiling + and installing GPGME itself. + + Once SWIG is installed with Python and all the dependencies for + GPGME are installed you only need to confirm that the version(s) of + Python you want the bindings installed for are in your =$PATH=. + + By default GPGME will attempt to install the bindings for the most + recent or highest version number of Python 2 and Python 3 it + detects in =$PATH=. It specifically checks for the =python= and + =python3= executabled first and then checks for specific version + numbers. + + For Python 2 it checks for these executables in this order: + =python=, =python2= and =python2.7=. + + For Python 3 it checks for these executables in this order: + =python3=, =python3.6=, =python3.5= and =python3.4=. + +*** Installing GPGME + :PROPERTIES: + :CUSTOM_ID: install-gpgme + :END: + + See the [[../../../README][GPGME README file]] for details of how to install GPGME from + source. + + +* Fundamentals + :PROPERTIES: + :CUSTOM_ID: howto-fund-a-mental + :END: + + Before we can get to the fun stuff, there are a few matters + regarding GPGME's design which hold true whether you're dealing with + the C code directly or these Python bindings. + +** No REST + :PROPERTIES: + :CUSTOM_ID: no-rest-for-the-wicked + :END: + + The first part of which is or will be fairly blatantly obvious upon + viewing the first example, but it's worth reiterating anyway. That + being that this API is /*not*/ a REST API. Nor indeed could it + ever be one. + + Most, if not all, Python programmers (and not just Python + programmers) know how easy it is to work with a RESTful API. In + fact they've become so popular that many other APIs attempt to + emulate REST-like behaviour as much as they are able. Right down + to the use of JSON formatted output to facilitate the use of their + API without having to retrain developers. + + This API does not do that. It would not be able to do that and + also provide access to the entire C API on which it's built. It + does, however, provide a very pythonic interface on top of the + direct bindings and it's this pythonic layer with which this HOWTO + deals with. + +** Context + :PROPERTIES: + :CUSTOM_ID: howto-get-context + :END: + + One of the reasons which prevents this API from being RESTful is + that most operations require more than one instruction to the API + to perform the task. Sure, there are certain functions which can + be performed simultaneously, particularly if the result known or + strongly anticipated (e.g selecting and encrypting to a key known + to be in the public keybox). + + There are many more, however, which cannot be manipulated so + readily: they must be performed in a specific sequence and the + result of one operation has a direct bearing on the outcome of + subsequent operations. Not merely by generating an error either. + + When dealing with this type of persistant state on the web, full of + both the RESTful and REST-like, it's most commonly referred to as a + session. In GPGME, however, it is called a context and every + operation type has one. + + +* Basic Functions + :PROPERTIES: + :CUSTOM_ID: howto-the-basics + :END: + +** Encryption + :PROPERTIES: + :CUSTOM_ID: howto-basic-encryption + :END: + + Encrypting to one key: + + #+begin_src python + import gpg + import os + + rkey = "0x12345678DEADBEEF" + text = """ + Some plain text to test with. Obtained from any input source Python can read. + + It makes no difference whether it is string or bytes, but the bindings always + produce byte output data. Which is useful to know when writing out either the + encrypted or decrypted results. + + """ + + plain = gpg.core.Data(text) + cipher = gpg.core.Data() + c = gpg.core.Context() + c.set_armor(1) + + c.op_keylist_start(rkey, 0) + r = c.op_keylist_next() + + if r == None: + print("""The key for user "{0}" was not found""".format(rkey)) + else: + try: + c.op_encrypt([r], 1, plain, cipher) + cipher.seek(0, os.SEEK_SET) + del(text) + del(plain) + afile = open("secret_plans.org.asc", "wb") + afile.write(cipher.read()) + afile.close() + except gpg.errors.GPGMEError as ex: + print(ex.getstring()) + #+end_src + +** Decryption + :PROPERTIES: + :CUSTOM_ID: howto-basic-encryption + :END: + + Decrypting something encrypted to a key in one's secret keyring + (will display some extra data you normally wouldn't show, but which + may be of use): + + #+begin_src python + import os.path + import gpg + + if os.path.exists("/path/to/secret_plans.org.asc") is True: + ciphertext = "/path/to/secret_plans.org.asc" + elif os.path.exists("/path/to/secret_plans.org.gpg") is True: + ciphertext = "/path/to/secret_plans.org.gpg" + else: + ciphertext = None + + if ciphertext is not None: + afile = open(ciphertext, "rb") + plaintext = gpg.Context().decrypt(afile) + afile.close() + newfile = open("/path/to/secret_plans.org", "wb") + newfile.write(plaintext[0]) + newfile.close() + print(plaintext[0]) + plaintext[1] + plaintext[2] + del(plaintext) + else: + pass + #+end_src + +** Signing text + :PROPERTIES: + :CUSTOM_ID: howto-basic-signing + :END: + + Need to determine whether or not to include clearsigning and + detached signing here or give them separate sections. + + #+begin_src python + import gpg + + text = """Declaration of ... something. + + """ + + c = gpg.Context() + c.armor = True + signed = c.sign(text, mode=mode.NORMAL) + + afile = open("/path/to/statement.txt.asc", "w") + for i in range(len(signed[0].splitlines())): + afile.write("{0}\n".format(signed[0].splitlines()[i].decode('utf-8'))) + afile.close() + #+end_src + + Clearsigning: + + #+begin_src python + import gpg + + text = """Declaration of ... something. + + """ + + c = gpg.Context() + c.armor = True + signed = c.sign(text, mode=mode.CLEAR) + + afile = open("/path/to/statement.txt.asc", "w") + for i in range(len(signed[0].splitlines())): + afile.write("{0}\n".format(signed[0].splitlines()[i].decode('utf-8'))) + afile.close() + #+end_src + + Detached ASCII Armoured signing: + + #+begin_src python + import gpg + + text = """Declaration of ... something. + + """ + + c = gpg.Context() + c.armor = True + signed = c.sign(text, mode=mode.DETACH) + + afile = open("/path/to/statement.txt.asc", "w") + for i in range(len(signed[0].splitlines())): + afile.write("{0}\n".format(signed[0].splitlines()[i].decode('utf-8'))) + afile.close() + #+end_src + + Detached binary signing (maybe change text to be reading a file's + content): + + #+begin_src python +import gpg + +text = """Declaration of ... something. + +""" + +c = gpg.Context() +c.armor = True +signed = c.sign(text, mode=mode.DETACH) + +afile = open("/path/to/statement.txt.sig", "wb") +afile.write(signed[0]) +afile.close() + #+end_src + + +** Signature verification + :PROPERTIES: + :CUSTOM_ID: howto-basic-verification + :END: + +x + + +* Copyright and Licensing + :PROPERTIES: + :CUSTOM_ID: copyright-and-license + :END: + +** Copyright (C) The GnuPG Project, 2018 + :PROPERTIES: + :CUSTOM_ID: copyright + :END: + + Copyright © The GnuPG Project, 2018. + +** License GPL compatible + :PROPERTIES: + :CUSTOM_ID: license + :END: + + This file is free software; as a special exception the author gives + unlimited permission to copy and/or distribute it, with or without + modifications, as long as this notice is preserved. + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY, to the extent permitted by law; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. diff --git a/lang/python/docs/TODO.org b/lang/python/docs/TODO.org index 9f039d81..897c617a 100644 --- a/lang/python/docs/TODO.org +++ b/lang/python/docs/TODO.org @@ -28,13 +28,61 @@ to produce reST versions via Pandoc and DITA XML can be reached through converting to either Markdown or XHTML first. -** TODO Documentation HOWTO +** STARTED Documentation HOWTO :PROPERTIES: :CUSTOM_ID: todo-docs-howto :END: + - State "STARTED" from "TODO" [2018-03-08 Thu 13:59] \\ + Started yesterday. Write a HOWTO style guide for the current Python bindings. +*** DONE Start python bindings HOWTO + CLOSED: [2018-03-07 Wed 18:14] + :PROPERTIES: + :CUSTOM_ID: howto-start + :END: + +*** TODO Include certain specific instructions in the HOWTO + :PROPERTIES: + :CUSTOM_ID: howto-requests + :END: + + Some functions can be worked out from the handful of examples + available, but many more can't and I've already begun receiving + requests for certain functions to be explained. + +**** TODO Standard scenarios + :PROPERTIES: + :CUSTOM_ID: howto-the-basics + :END: + + What everyone expects: encryption, decryption, signing and verifying. + +**** TODO Key control + :PROPERTIES: + :CUSTOM_ID: howto-key-control + :END: + + Generating keys, adding subkeys, revoking subkeys (and keeping + the cert key), adding and revoking UIDs, signing/certifying keys. + +**** TODO Key control + :PROPERTIES: + :CUSTOM_ID: howto-key-selection + :END: + + Selecting keys to encrypt to or manipulate in other ways (e.g. as + with key control or the basics). + +**** TODO S/MIME + :PROPERTIES: + :CUSTOM_ID: howto-s-mime + :END: + + Eventually add some of this, but it the OpenPGP details are far + more important at the moment. + ** TODO Documentation SWIG :PROPERTIES: :CUSTOM_ID: todo-docs-swig @@ -94,6 +142,7 @@ available or for which it is too difficult to create proper bindings. + * Project Task Details :PROPERTIES: :CUSTOM_ID: detailed-tasks diff --git a/src/gpgme-tool.c b/src/gpgme-tool.c index 3e2dc785..e7a7a6f3 100644 --- a/src/gpgme-tool.c +++ b/src/gpgme-tool.c @@ -3101,7 +3101,7 @@ cmd_hash_algo_name (assuan_context_t ctx, char *line) static const char hlp_identify[] = - "IDENTIY\n" + "IDENTIFY\n" "\n" "Identify the type of data set with the INPUT command."; static gpg_error_t |