python bindings howto: dita version
* Drafts of instructions for exporting public and secret keys ready, along in addition to the code.
This commit is contained in:
parent
34308fe1fc
commit
dda54cc851
9
lang/python/docs/dita/gpgme-python-howto-footer.xhtml
Normal file
9
lang/python/docs/dita/gpgme-python-howto-footer.xhtml
Normal file
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<div>Copyright © Benjamin D. McGinnes, 2018<br />for the <a href="https://gnupg.org/" target="_blank">GnuPG Project</a></div>
|
||||
</body>
|
||||
</html>
|
@ -58,6 +58,11 @@
|
||||
<topicref id="key-count" href="howto/part03/key-counting.dita"/>
|
||||
</topicref>
|
||||
<topicref id="get-key" href="howto/part03/get-key.dita"/>
|
||||
<topicref id="import-key" href="howto/part03/importing.dita"/>
|
||||
<topicref id="export-key" href="howto/part03/exporting.dita">
|
||||
<topicref id="export-key-pub" href="howto/part03/exporting-pubkeys.dita"/>
|
||||
<topicref id="export-key-sec" href="howto/part03/exporting-seckeys.dita"/>
|
||||
</topicref>
|
||||
</part>
|
||||
<part id="part-4" href="howto/part-4.dita">
|
||||
<topicref id="basics" href="howto/part04/basic-functions.dita"/>
|
||||
@ -87,4 +92,7 @@
|
||||
<part id="part-6" href="howto/part-6.dita">
|
||||
<topicref id="groups" href="howto/part06/group-lines.dita"/>
|
||||
</part>
|
||||
<backmatter>
|
||||
<mapref id="resources" href="resources.ditamap" processing-role="resource-only"/>
|
||||
</backmatter>
|
||||
</bookmap>
|
||||
|
@ -3,4 +3,5 @@
|
||||
<map>
|
||||
<title>GPGME Python Bindings</title>
|
||||
<mapref id="howto-map" href="gpgme-python-howto.ditamap"/>
|
||||
<mapref id="resources" href="resources.ditamap" processing-role="resource-only"/>
|
||||
</map>
|
||||
|
@ -1,20 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="20.0">
|
||||
<project version="20.1">
|
||||
<meta>
|
||||
<filters directoryPatterns="" filePatterns="gpgmePython.xpr" positiveFilePatterns="" showHiddenFiles="false"/>
|
||||
<options>
|
||||
<serialized version="20.0" xml:space="preserve">
|
||||
<serialized version="20.1" xml:space="preserve">
|
||||
<serializableOrderedMap>
|
||||
<entry>
|
||||
<String>scenario.associations</String>
|
||||
<scenarioAssociation-array>
|
||||
<scenarioAssociation>
|
||||
<field name="url">
|
||||
<String>gpgme-python.ditamap</String>
|
||||
</field>
|
||||
<field name="scenarioIds">
|
||||
<list>
|
||||
<String>DITA Map WebHelp - TS/HC - GPGME</String>
|
||||
</list>
|
||||
</field>
|
||||
<field name="scenarioTypes">
|
||||
<list>
|
||||
<String>DITAMAP</String>
|
||||
</list>
|
||||
</field>
|
||||
</scenarioAssociation>
|
||||
<scenarioAssociation>
|
||||
<field name="url">
|
||||
<String>gpgme-python-howto.ditamap</String>
|
||||
</field>
|
||||
<field name="scenarioIds">
|
||||
<list>
|
||||
<String>gpgme-python-howto (WebHelp Responsive)</String>
|
||||
<String>DITA Map WebHelp - TS/HC - GPGME</String>
|
||||
</list>
|
||||
</field>
|
||||
<field name="scenarioTypes">
|
||||
@ -28,6 +43,455 @@
|
||||
<entry>
|
||||
<String>scenarios</String>
|
||||
<scenario-array>
|
||||
<ditaScenario>
|
||||
<field name="useXEP">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="useAntennaHouse">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="baseDir">
|
||||
<String>${cfd}</String>
|
||||
</field>
|
||||
<field name="outputDir">
|
||||
<String>${cfd}/out/webhelp-${ddt}</String>
|
||||
</field>
|
||||
<field name="tempDir">
|
||||
<String>${cfd}/temp/webhelp-${ddt}</String>
|
||||
</field>
|
||||
<field name="transtype">
|
||||
<String>webhelp</String>
|
||||
</field>
|
||||
<field name="filters">
|
||||
<ditavalFilters>
|
||||
<field name="useDitavalFilePath">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="useAppliedConditionSet">
|
||||
<Boolean>true</Boolean>
|
||||
</field>
|
||||
<field name="appliedConditionSet">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="ditavalFilePath">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="simpleFiltersList">
|
||||
<list/>
|
||||
</field>
|
||||
</ditavalFilters>
|
||||
</field>
|
||||
<field name="addOxygenJars">
|
||||
<Boolean>true</Boolean>
|
||||
</field>
|
||||
<field name="skinCssFile">
|
||||
<String>file:/usr/local/oXygenXML/custom/webhelp-skins/high-contrast-skin.css</String>
|
||||
</field>
|
||||
<field name="lastCustomSkinCssPath">
|
||||
<String>file:/usr/local/oXygenXML/custom/webhelp-skins/high-contrast-skin.css</String>
|
||||
</field>
|
||||
<field name="webhelpResponsiveTemplate">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="publishingTemplateDataPO">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="additionalAntArgs">
|
||||
<String></String>
|
||||
</field>
|
||||
<field name="buildTarget">
|
||||
<String></String>
|
||||
</field>
|
||||
<field name="buildFilePath">
|
||||
<String></String>
|
||||
</field>
|
||||
<field name="ditaParams">
|
||||
<list>
|
||||
<ditaParameter>
|
||||
<field name="name">
|
||||
<String>args.xhtml.classattr</String>
|
||||
</field>
|
||||
<field name="description">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="value">
|
||||
<String>yes</String>
|
||||
</field>
|
||||
<field name="defaultValue">
|
||||
<String>yes</String>
|
||||
</field>
|
||||
<field name="type">
|
||||
<Integer>4</Integer>
|
||||
</field>
|
||||
<field name="possibleValues">
|
||||
<String-array>
|
||||
<String>yes</String>
|
||||
<String>no</String>
|
||||
<null/>
|
||||
</String-array>
|
||||
</field>
|
||||
<field name="possibleValuesDescriptions">
|
||||
<String-array>
|
||||
<String></String>
|
||||
<String></String>
|
||||
</String-array>
|
||||
</field>
|
||||
</ditaParameter>
|
||||
<ditaParameter>
|
||||
<field name="name">
|
||||
<String>webhelp.footer.include</String>
|
||||
</field>
|
||||
<field name="description">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="value">
|
||||
<String>yes</String>
|
||||
</field>
|
||||
<field name="defaultValue">
|
||||
<String>yes</String>
|
||||
</field>
|
||||
<field name="type">
|
||||
<Integer>4</Integer>
|
||||
</field>
|
||||
<field name="possibleValues">
|
||||
<String-array>
|
||||
<String>yes</String>
|
||||
<String>no</String>
|
||||
<null/>
|
||||
</String-array>
|
||||
</field>
|
||||
<field name="possibleValuesDescriptions">
|
||||
<String-array>
|
||||
<String>If the "webhelp.footer.file" parameter has a value, the content of that file is used as footer. If "webhelp.footer.file" has no value, the default Oxygen footer is inserted in each Webhelp page.</String>
|
||||
<String>No footer is added to the Webhelp pages.</String>
|
||||
</String-array>
|
||||
</field>
|
||||
</ditaParameter>
|
||||
<ditaParameter>
|
||||
<field name="name">
|
||||
<String>webhelp.footer.file</String>
|
||||
</field>
|
||||
<field name="description">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="value">
|
||||
<String>/Users/ben/dev/hgit/mine/gnupg/dita/gpgme/python/gpgme-python-howto-footer.xhtml</String>
|
||||
</field>
|
||||
<field name="defaultValue">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="type">
|
||||
<Integer>2</Integer>
|
||||
</field>
|
||||
<field name="possibleValues">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="possibleValuesDescriptions">
|
||||
<null/>
|
||||
</field>
|
||||
</ditaParameter>
|
||||
<ditaParameter>
|
||||
<field name="name">
|
||||
<String>webhelp.copyright</String>
|
||||
</field>
|
||||
<field name="description">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="value">
|
||||
<String>Copyright © Benjamin D. McGinnes, 2018</String>
|
||||
</field>
|
||||
<field name="defaultValue">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="type">
|
||||
<Integer>0</Integer>
|
||||
</field>
|
||||
<field name="possibleValues">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="possibleValuesDescriptions">
|
||||
<null/>
|
||||
</field>
|
||||
</ditaParameter>
|
||||
</list>
|
||||
</field>
|
||||
<field name="jvmArgs">
|
||||
<String>-Xmx384m</String>
|
||||
</field>
|
||||
<field name="useCustomJavaHome">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="customJavaHomeDir">
|
||||
<String></String>
|
||||
</field>
|
||||
<field name="useCustomANTHome">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="customANTHomeDir">
|
||||
<String></String>
|
||||
</field>
|
||||
<field name="workingDir">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="showConsoleAlways">
|
||||
<Boolean>true</Boolean>
|
||||
</field>
|
||||
<field name="advancedOptionsMap">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="name">
|
||||
<String>DITA Map WebHelp - TS/HC - GPGME</String>
|
||||
</field>
|
||||
<field name="baseURL">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="footerURL">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="fOPMethod">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="fOProcessorName">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="headerURL">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="inputXSLURL">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="inputXMLURL">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="defaultScenario">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="isFOPPerforming">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="type">
|
||||
<String>DITAMAP</String>
|
||||
</field>
|
||||
<field name="saveAs">
|
||||
<Boolean>true</Boolean>
|
||||
</field>
|
||||
<field name="openInBrowser">
|
||||
<Boolean>true</Boolean>
|
||||
</field>
|
||||
<field name="outputFile">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="outputResource">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="openOtherLocationInBrowser">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="locationToOpenInBrowserURL">
|
||||
<String></String>
|
||||
</field>
|
||||
<field name="openInEditor">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="showInHTMLPane">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="showInXMLPane">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="showInSVGPane">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="showInResultSetPane">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="useXSLTInput">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="xsltParams">
|
||||
<list/>
|
||||
</field>
|
||||
<field name="cascadingStylesheets">
|
||||
<String-array/>
|
||||
</field>
|
||||
<field name="xslTransformer">
|
||||
<String>DITA-OT</String>
|
||||
</field>
|
||||
<field name="extensionURLs">
|
||||
<String-array/>
|
||||
</field>
|
||||
</ditaScenario>
|
||||
<ditaScenario>
|
||||
<field name="useXEP">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="useAntennaHouse">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="baseDir">
|
||||
<String>${cfd}</String>
|
||||
</field>
|
||||
<field name="outputDir">
|
||||
<String>${cfd}/out/html5-${ddt}</String>
|
||||
</field>
|
||||
<field name="tempDir">
|
||||
<String>${cfd}/temp/html5-${ddt}</String>
|
||||
</field>
|
||||
<field name="transtype">
|
||||
<String>html5</String>
|
||||
</field>
|
||||
<field name="filters">
|
||||
<ditavalFilters>
|
||||
<field name="useDitavalFilePath">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="useAppliedConditionSet">
|
||||
<Boolean>true</Boolean>
|
||||
</field>
|
||||
<field name="appliedConditionSet">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="ditavalFilePath">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="simpleFiltersList">
|
||||
<list/>
|
||||
</field>
|
||||
</ditavalFilters>
|
||||
</field>
|
||||
<field name="addOxygenJars">
|
||||
<Boolean>true</Boolean>
|
||||
</field>
|
||||
<field name="skinCssFile">
|
||||
<String>file:/usr/local/oXygenXML/custom/webhelp-skins/high-contrast-skin.css</String>
|
||||
</field>
|
||||
<field name="lastCustomSkinCssPath">
|
||||
<String>file:/usr/local/oXygenXML/custom/webhelp-skins/high-contrast-skin.css</String>
|
||||
</field>
|
||||
<field name="webhelpResponsiveTemplate">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="publishingTemplateDataPO">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="additionalAntArgs">
|
||||
<String></String>
|
||||
</field>
|
||||
<field name="buildTarget">
|
||||
<String></String>
|
||||
</field>
|
||||
<field name="buildFilePath">
|
||||
<String></String>
|
||||
</field>
|
||||
<field name="ditaParams">
|
||||
<list/>
|
||||
</field>
|
||||
<field name="jvmArgs">
|
||||
<String>-Xmx384m</String>
|
||||
</field>
|
||||
<field name="useCustomJavaHome">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="customJavaHomeDir">
|
||||
<String></String>
|
||||
</field>
|
||||
<field name="useCustomANTHome">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="customANTHomeDir">
|
||||
<String></String>
|
||||
</field>
|
||||
<field name="workingDir">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="showConsoleAlways">
|
||||
<Boolean>true</Boolean>
|
||||
</field>
|
||||
<field name="advancedOptionsMap">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="name">
|
||||
<String>gpgme-python (HTML5)</String>
|
||||
</field>
|
||||
<field name="baseURL">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="footerURL">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="fOPMethod">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="fOProcessorName">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="headerURL">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="inputXSLURL">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="inputXMLURL">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="defaultScenario">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="isFOPPerforming">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="type">
|
||||
<String>DITAMAP</String>
|
||||
</field>
|
||||
<field name="saveAs">
|
||||
<Boolean>true</Boolean>
|
||||
</field>
|
||||
<field name="openInBrowser">
|
||||
<Boolean>true</Boolean>
|
||||
</field>
|
||||
<field name="outputFile">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="outputResource">
|
||||
<null/>
|
||||
</field>
|
||||
<field name="openOtherLocationInBrowser">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="locationToOpenInBrowserURL">
|
||||
<String></String>
|
||||
</field>
|
||||
<field name="openInEditor">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="showInHTMLPane">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="showInXMLPane">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="showInSVGPane">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="showInResultSetPane">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="useXSLTInput">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
<field name="xsltParams">
|
||||
<list/>
|
||||
</field>
|
||||
<field name="cascadingStylesheets">
|
||||
<String-array/>
|
||||
</field>
|
||||
<field name="xslTransformer">
|
||||
<String>DITA-OT</String>
|
||||
</field>
|
||||
<field name="extensionURLs">
|
||||
<String-array/>
|
||||
</field>
|
||||
</ditaScenario>
|
||||
<ditaScenario>
|
||||
<field name="useXEP">
|
||||
<Boolean>false</Boolean>
|
||||
|
@ -14,15 +14,16 @@
|
||||
<ol id="ol_k3b_wrx_5db">
|
||||
<li>A <xref href="https://dev.gnupg.org/T3977" format="html" scope="external">bug</xref>
|
||||
in either Org-Mode or Babel prevented the more complex examples included in the HOWTO
|
||||
from displaying correctly.</li>
|
||||
from displaying correctly while also retaining syntax highlighting.</li>
|
||||
<li>To demonstrate some of the advantages of DITA XML over existing documentation
|
||||
production software used in the project (particularly Texinfo and LaTeX).</li>
|
||||
</ol>
|
||||
</p>
|
||||
<p>The XML format definitely supports displaying all the more complex Python code correctly,
|
||||
as well as being designed to produce standards compliant print and HTML output. Whereas
|
||||
currently the existing tools utilised by the GnuPG Project can't display the example code in
|
||||
a way which would actually pass the project's own git commit ruleset.</p>
|
||||
<p>The XML format definitely supports displaying all the more complex Python code correctly
|
||||
with syntax highlighting, as well as being designed to produce standards compliant print and
|
||||
HTML output. Whereas currently the existing tools utilised by the GnuPG Project can't
|
||||
display the example code in a way which would actually pass the project's own git commit
|
||||
ruleset.</p>
|
||||
<p> </p>
|
||||
</body>
|
||||
</topic>
|
||||
|
120
lang/python/docs/dita/howto/part03/exporting-pubkeys.dita
Normal file
120
lang/python/docs/dita/howto/part03/exporting-pubkeys.dita
Normal file
@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE dita PUBLIC "-//OASIS//DTD DITA Composite//EN" "ditabase.dtd">
|
||||
<dita xml:lang="en-GB">
|
||||
<topic id="exporting-pubkeys">
|
||||
<title>Exporting Public Keys</title>
|
||||
<body>
|
||||
<p>There are two methods of exporting public keys, both of which are very similar to the
|
||||
other. The default method, <codeph>key_export()</codeph> will export a public key or keys
|
||||
matching a specified pattern as normal. The alternative, the
|
||||
<codeph>key_export_minimal()</codeph> method will do the same thing except producing a
|
||||
minimised output with extra signatures and third party signatures or certifications
|
||||
removed.</p>
|
||||
<p>
|
||||
<codeblock id="export-pubkey-01" outputclass="language-python">import gpg
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
print("""
|
||||
This script exports one or more public keys.
|
||||
""")
|
||||
|
||||
c = gpg.Context(armor=True)
|
||||
|
||||
if len(sys.argv) >= 4:
|
||||
keyfile = sys.argv[1]
|
||||
logrus = sys.argv[2]
|
||||
homedir = sys.argv[3]
|
||||
elif len(sys.argv) == 3:
|
||||
keyfile = sys.argv[1]
|
||||
logrus = sys.argv[2]
|
||||
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||
elif len(sys.argv) == 2:
|
||||
keyfile = sys.argv[1]
|
||||
logrus = input("Enter the UID matching the key(s) to export: ")
|
||||
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||
else:
|
||||
keyfile = input("Enter the path and filename to save the secret key to: ")
|
||||
logrus = input("Enter the UID matching the key(s) to export: ")
|
||||
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||
|
||||
if homedir.startswith("~"):
|
||||
if os.path.exists(os.path.expanduser(homedir)) is True:
|
||||
c.home_dir = os.path.expanduser(homedir)
|
||||
else:
|
||||
pass
|
||||
elif os.path.exists(homedir) is True:
|
||||
c.home_dir = homedir
|
||||
else:
|
||||
pass
|
||||
|
||||
try:
|
||||
result = c.key_export(pattern=logrus)
|
||||
except:
|
||||
result = c.key_export(pattern=None)
|
||||
|
||||
if result is not None:
|
||||
with open(keyfile, "wb") as f:
|
||||
f.write(result)
|
||||
else:
|
||||
pass
|
||||
</codeblock>
|
||||
</p>
|
||||
<p>It is important to note that the <codeph>result</codeph> will only return
|
||||
<codeph>None</codeph> when a pattern has been entered for <varname>logrus</varname>, but
|
||||
it has not matched any keys. When the search pattern itself is set to <codeph>None</codeph>
|
||||
this triggers the exporting of the entire public keybox.</p>
|
||||
<p>
|
||||
<codeblock id="export-pubkey-02" outputclass="language-python">import gpg
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
print("""
|
||||
This script exports one or more public keys in minimised form.
|
||||
""")
|
||||
|
||||
c = gpg.Context(armor=True)
|
||||
|
||||
if len(sys.argv) >= 4:
|
||||
keyfile = sys.argv[1]
|
||||
logrus = sys.argv[2]
|
||||
homedir = sys.argv[3]
|
||||
elif len(sys.argv) == 3:
|
||||
keyfile = sys.argv[1]
|
||||
logrus = sys.argv[2]
|
||||
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||
elif len(sys.argv) == 2:
|
||||
keyfile = sys.argv[1]
|
||||
logrus = input("Enter the UID matching the key(s) to export: ")
|
||||
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||
else:
|
||||
keyfile = input("Enter the path and filename to save the secret key to: ")
|
||||
logrus = input("Enter the UID matching the key(s) to export: ")
|
||||
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||
|
||||
if homedir.startswith("~"):
|
||||
if os.path.exists(os.path.expanduser(homedir)) is True:
|
||||
c.home_dir = os.path.expanduser(homedir)
|
||||
else:
|
||||
pass
|
||||
elif os.path.exists(homedir) is True:
|
||||
c.home_dir = homedir
|
||||
else:
|
||||
pass
|
||||
|
||||
try:
|
||||
result = c.key_export_minimal(pattern=logrus)
|
||||
except:
|
||||
result = c.key_export_minimal(pattern=None)
|
||||
|
||||
if result is not None:
|
||||
with open(keyfile, "wb") as f:
|
||||
f.write(result)
|
||||
else:
|
||||
pass
|
||||
</codeblock>
|
||||
</p>
|
||||
<p/>
|
||||
</body>
|
||||
</topic>
|
||||
</dita>
|
161
lang/python/docs/dita/howto/part03/exporting-seckeys.dita
Normal file
161
lang/python/docs/dita/howto/part03/exporting-seckeys.dita
Normal file
@ -0,0 +1,161 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE dita PUBLIC "-//OASIS//DTD DITA Composite//EN" "ditabase.dtd">
|
||||
<dita xml:lang="en-GB">
|
||||
<topic id="exporting-seckeys">
|
||||
<title>Exporting Secret Keys</title>
|
||||
<body>
|
||||
<p>Exporting secret keys is, functionally, very similar to exporting public keys; save for the
|
||||
invocation of <cmdname>pinentry</cmdname> via <cmdname>gpg-agent</cmdname> in order to
|
||||
securely enter the key's passphrase and authorise the export.</p>
|
||||
<p>The following example exports the secret key to a file which is then set with the same
|
||||
permissions as the output files created by the command line secret key export options.</p>
|
||||
<p>
|
||||
<codeblock id="export-seckey-01" outputclass="language-python">import gpg
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
print("""
|
||||
This script exports one or more secret keys.
|
||||
|
||||
The gpg-agent and pinentry are invoked to authorise the export.
|
||||
""")
|
||||
|
||||
c = gpg.Context(armor=True)
|
||||
|
||||
if len(sys.argv) >= 4:
|
||||
keyfile = sys.argv[1]
|
||||
logrus = sys.argv[2]
|
||||
homedir = sys.argv[3]
|
||||
elif len(sys.argv) == 3:
|
||||
keyfile = sys.argv[1]
|
||||
logrus = sys.argv[2]
|
||||
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||
elif len(sys.argv) == 2:
|
||||
keyfile = sys.argv[1]
|
||||
logrus = input("Enter the UID matching the secret key(s) to export: ")
|
||||
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||
else:
|
||||
keyfile = input("Enter the path and filename to save the secret key to: ")
|
||||
logrus = input("Enter the UID matching the secret key(s) to export: ")
|
||||
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||
|
||||
if homedir.startswith("~"):
|
||||
if os.path.exists(os.path.expanduser(homedir)) is True:
|
||||
c.home_dir = os.path.expanduser(homedir)
|
||||
else:
|
||||
pass
|
||||
elif os.path.exists(homedir) is True:
|
||||
c.home_dir = homedir
|
||||
else:
|
||||
pass
|
||||
|
||||
try:
|
||||
result = c.key_export_secret(pattern=logrus)
|
||||
except:
|
||||
result = c.key_export_secret(pattern=None)
|
||||
|
||||
if result is not None:
|
||||
with open(keyfile, "wb") as f:
|
||||
f.write(result)
|
||||
os.chmod(keyfile, 0o600)
|
||||
else:
|
||||
pass
|
||||
</codeblock>
|
||||
</p>
|
||||
<p>Alternatively the approach of the following script can be used. This longer example saves
|
||||
the exported secret key(s) in files in the GnuPG home directory, in addition to setting the
|
||||
file permissions as only readable and writable by the user. It also exports the secret
|
||||
key(s) twice in order to output both GPG binary (<codeph>.gpg</codeph>) and ASCII armoured
|
||||
(<codeph>.asc</codeph>) files.</p>
|
||||
<p>
|
||||
<codeblock id="export-seckey-02" outputclass="language-python">import gpg
|
||||
import os
|
||||
import os.path
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
print("""
|
||||
This script exports one or more secret keys as both ASCII armored and binary
|
||||
file formats, saved in files within the user's GPG home directory.
|
||||
|
||||
The gpg-agent and pinentry are invoked to authorise the export.
|
||||
""")
|
||||
|
||||
if sys.platform == "win32":
|
||||
gpgconfcmd = "gpgconf.exe --list-dirs homedir"
|
||||
else:
|
||||
gpgconfcmd = "gpgconf --list-dirs homedir"
|
||||
|
||||
a = gpg.Context(armor=True)
|
||||
b = gpg.Context()
|
||||
c = gpg.Context()
|
||||
|
||||
if len(sys.argv) >= 4:
|
||||
keyfile = sys.argv[1]
|
||||
logrus = sys.argv[2]
|
||||
homedir = sys.argv[3]
|
||||
elif len(sys.argv) == 3:
|
||||
keyfile = sys.argv[1]
|
||||
logrus = sys.argv[2]
|
||||
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||
elif len(sys.argv) == 2:
|
||||
keyfile = sys.argv[1]
|
||||
logrus = input("Enter the UID matching the secret key(s) to export: ")
|
||||
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||
else:
|
||||
keyfile = input("Enter the filename to save the secret key to: ")
|
||||
logrus = input("Enter the UID matching the secret key(s) to export: ")
|
||||
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||
|
||||
if homedir.startswith("~"):
|
||||
if os.path.exists(os.path.expanduser(homedir)) is True:
|
||||
c.home_dir = os.path.expanduser(homedir)
|
||||
else:
|
||||
pass
|
||||
elif os.path.exists(homedir) is True:
|
||||
c.home_dir = homedir
|
||||
else:
|
||||
pass
|
||||
|
||||
if c.home_dir is not None:
|
||||
if c.home_dir.endswith("/"):
|
||||
gpgfile = "{0}{1}.gpg".format(c.home_dir, keyfile)
|
||||
ascfile = "{0}{1}.asc".format(c.home_dir, keyfile)
|
||||
else:
|
||||
gpgfile = "{0}/{1}.gpg".format(c.home_dir, keyfile)
|
||||
ascfile = "{0}/{1}.asc".format(c.home_dir, keyfile)
|
||||
else:
|
||||
if os.path.exists(os.environ["GNUPGHOME"]) is True:
|
||||
hd = os.environ["GNUPGHOME"]
|
||||
else:
|
||||
hd = subprocess.getoutput(gpgconfcmd)
|
||||
gpgfile = "{0}/{1}.gpg".format(hd, keyfile)
|
||||
ascfile = "{0}/{1}.asc".format(hd, keyfile)
|
||||
|
||||
try:
|
||||
a_result = a.key_export_secret(pattern=logrus)
|
||||
b_result = b.key_export_secret(pattern=logrus)
|
||||
except:
|
||||
a_result = a.key_export_secret(pattern=None)
|
||||
b_result = b.key_export_secret(pattern=None)
|
||||
|
||||
if a_result is not None:
|
||||
with open(ascfile, "wb") as f:
|
||||
f.write(a_result)
|
||||
os.chmod(ascfile, 0o600)
|
||||
else:
|
||||
pass
|
||||
|
||||
if b_result is not None:
|
||||
with open(gpgfile, "wb") as f:
|
||||
f.write(b_result)
|
||||
os.chmod(gpgfile, 0o600)
|
||||
else:
|
||||
pass
|
||||
</codeblock>
|
||||
</p>
|
||||
<p/>
|
||||
</body>
|
||||
</topic>
|
||||
</dita>
|
12
lang/python/docs/dita/howto/part03/exporting.dita
Normal file
12
lang/python/docs/dita/howto/part03/exporting.dita
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE dita PUBLIC "-//OASIS//DTD DITA Composite//EN" "ditabase.dtd">
|
||||
<dita xml:lang="en-GB">
|
||||
<topic id="exporting-keys">
|
||||
<title>Exporting Keys</title>
|
||||
<body>
|
||||
<p>Exporting keys remains a reasonably simple task, but has been separated into three
|
||||
different functions for the OpenPGP cryptographic engine. Two of those functions are for
|
||||
exporting public keys and the third is for exporting secret keys.</p>
|
||||
</body>
|
||||
</topic>
|
||||
</dita>
|
67
lang/python/docs/dita/howto/part03/importing.dita
Normal file
67
lang/python/docs/dita/howto/part03/importing.dita
Normal file
@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE dita PUBLIC "-//OASIS//DTD DITA Composite//EN" "ditabase.dtd">
|
||||
<dita xml:lang="en-GB">
|
||||
<topic id="importing-keys">
|
||||
<title>Importing keys</title>
|
||||
<body>
|
||||
<p>Importing keys is possible with the <codeph>key_import()</codeph> method and takes one
|
||||
argument which is a bytes literal object containing either the binary or ASCII armoured key
|
||||
data for one or more keys.</p>
|
||||
<p>The following example retrieves one or more keys from the SKS keyservers via the web using
|
||||
the requests module. Since requests returns the content as a bytes literal object, we can
|
||||
then use that directly to import the resulting data into our keybox.</p>
|
||||
<p>
|
||||
<codeblock id="key-import-01" outputclass="language-python">import gpg
|
||||
import os.path
|
||||
import requests
|
||||
|
||||
c = gpg.Context()
|
||||
url = "https://sks-keyservers.net/pks/lookup"
|
||||
pattern = input("Enter the pattern to search for key or user IDs: ")
|
||||
payload = { "op": "get", "search": pattern }
|
||||
|
||||
r = requests.get(url, verify=True, params=payload)
|
||||
result = c.key_import(r.content)
|
||||
|
||||
if result is not None and hasattr(result, "considered") is False:
|
||||
print(result)
|
||||
elif result is not None and hasattr(result, "considered") is True:
|
||||
num_keys = len(result.imports)
|
||||
new_revs = result.new_revocations
|
||||
new_sigs = result.new_signatures
|
||||
new_subs = result.new_sub_keys
|
||||
new_uids = result.new_user_ids
|
||||
new_scrt = result.secret_imported
|
||||
nochange = result.unchanged
|
||||
print("""
|
||||
The total number of keys considered for import was: {0}
|
||||
|
||||
Number of keys revoked: {1}
|
||||
Number of new signatures: {2}
|
||||
Number of new subkeys: {3}
|
||||
Number of new user IDs: {4}
|
||||
Number of new secret keys: {5}
|
||||
Number of unchanged keys: {6}
|
||||
|
||||
The key IDs for all considered keys were:
|
||||
""".format(num_keys, new_revs, new_sigs, new_subs, new_uids, new_scrt,
|
||||
nochange))
|
||||
for i in range(num_keys):
|
||||
print(result.imports[i].fpr)
|
||||
print("")
|
||||
else:
|
||||
pass
|
||||
</codeblock>
|
||||
</p>
|
||||
<p>
|
||||
<note>When searching for a key ID of any length or a fingerprint (without spaces), the SKS
|
||||
servers require the the leading <codeph>0x</codeph> indicative of hexadecimal be included.
|
||||
Also note that the old short key IDs (e.g. <codeph>0xDEADBEEF</codeph>) should no longer
|
||||
be used due to the relative ease by which such key IDs can be reproduced, as demonstrated
|
||||
by the <xref href="https://evil32.com/" format="html" scope="external">Evil32
|
||||
Project</xref> in 2014 (which was subsequently exploited in 2016).</note>
|
||||
</p>
|
||||
<p/>
|
||||
</body>
|
||||
</topic>
|
||||
</dita>
|
@ -30,9 +30,20 @@ else:
|
||||
pass
|
||||
</codeblock>
|
||||
</p>
|
||||
<p>The data available in <codeph>plaintext</codeph> in this example is the decrypted content
|
||||
as a byte object, the recipient key IDs and algorithms in <codeph>result</codeph> and the
|
||||
results of verifying any signatures of the data in <codeph>verify_result</codeph>.</p>
|
||||
<p>The data available in <codeph>plaintext</codeph> following a successful decryption in this
|
||||
example is the decrypted content as a byte object, the recipient key IDs and algorithms in
|
||||
<codeph>result</codeph> and the results of verifying any signatures of the data in
|
||||
<codeph>verify_result</codeph>.</p>
|
||||
<p>
|
||||
<note>The graceful handling of <codeph>GPGMEError</codeph> with the try/except statement is
|
||||
to handle the decryption error message produced if the file <codeph>ciphertext</codeph>,
|
||||
and thus <codeph>cfile</codeph>, are encrypted with deprecated and insecure methods.
|
||||
Particularly without MDC integrity checks or utilising deprecated encryption algorithms.
|
||||
Messages and files encrypted with these are not decrypted with GPGME at all and any user
|
||||
requiring archival access will need to access it manually with pre-GnuPG 2.3 versions of
|
||||
the software which meets the requirements of the specific use case.</note>
|
||||
</p>
|
||||
<p/>
|
||||
</body>
|
||||
</topic>
|
||||
</dita>
|
||||
|
@ -44,6 +44,10 @@ for i in range(len(group_lists)):
|
||||
<p>
|
||||
<codeblock id="groups-2" outputclass="language-python">from groups import group_lists</codeblock>
|
||||
</p>
|
||||
<p>A demonstration of using the <filepath>groups.py</filepath> module is also available in
|
||||
the form of the executable <cmdname>mutt-groups.py</cmdname> script. This second script
|
||||
reads all the group entries in a user's <filepath>gpg.conf</filepath> file and converts them
|
||||
into crypt-hooks suitable for use with the Mutt and Neomutt mail clients.</p>
|
||||
</body>
|
||||
</topic>
|
||||
</dita>
|
||||
|
@ -4,10 +4,12 @@
|
||||
<topic id="topic_vnz_nn2_vdb">
|
||||
<title>Documentation Version</title>
|
||||
<body>
|
||||
<p><b>Version:</b> 0.1.1</p>
|
||||
<p><b>Version:</b> 0.1.2-DRAFT</p>
|
||||
<p><b>Author:</b> Ben McGinnes <<xref href="mailto:ben@gnupg.org" format="html"
|
||||
scope="external">ben@gnupg.org</xref>></p>
|
||||
<p><b>Author GPG Key ID:</b> DB4724E6FA4286C92B4E55C4321E4E2373590E5D</p>
|
||||
<p><b>Author GPG Key ID:</b>
|
||||
<xref href="http://files.au.adversary.org/crypto/ben-key.asc" format="text" scope="external"
|
||||
>DB4724E6FA4286C92B4E55C4321E4E2373590E5D</xref></p>
|
||||
<p><b>Language:</b> Australian English, British English</p>
|
||||
</body>
|
||||
</topic>
|
||||
|
Loading…
Reference in New Issue
Block a user