Repository: privacyidea/privacyidea

Issue:
Automatically create GPG keys in ubuntu package
We can import the key files in an encrypted manner.
For this we need to create GPG keys.

http://privacyidea.readthedocs.io/en/latest/workflows_and_tools/import/index.html

In the postinst of the ubuntu package we should automatically create GPG keys, so that the administrator does not have to do this.

The public GPG key should be downloadable via the webui.

We could add a subcommand:

      pi-manage create-pgp-keys
Automatically create GPG keys in ubuntu package
We can import the key files in an encrypted manner.
For this we need to create GPG keys.

http://privacyidea.readthedocs.io/en/latest/workflows_and_tools/import/index.html

In the postinst of the ubuntu package we should automatically create GPG keys, so that the administrator does not have to do this.

The public GPG key should be downloadable via the webui.

We could add a subcommand:

      pi-manage create-pgp-keys


Discussion:
gpg uses /dev/random. This will not work on headless servers. Thus we can use ``rng-tools``.
See https://serverfault.com/questions/214605/gpg-does-not-have-enough-entropy

The we could run:

    GNUPGHOME=/etc/privacyidea/gpg gpg --gen-key --batch <filename>

With a static file (we are in the privacyidea.postinst!), that looks like this:

    Key-Type: RSA
    Key-Length: 2048
    Subkey-Type: RSA
    Subkey-Length: 2048
    Name-Real: privacyIDEA Server
    Name-Comment: Import GPG Key
    Name-Email: --maybe we can fill this with the machine name--
    Expire-Date: 0
    %commit

gpg uses /dev/random. This will not work on headless servers. Thus we can use ``rng-tools``.
See https://serverfault.com/questions/214605/gpg-does-not-have-enough-entropy

The we could run:

    GNUPGHOME=/etc/privacyidea/gpg gpg --gen-key --batch <filename>

With a static file (we are in the privacyidea.postinst!), that looks like this:

    Key-Type: RSA
    Key-Length: 2048
    Subkey-Type: RSA
    Subkey-Length: 2048
    Name-Real: privacyIDEA Server
    Name-Comment: Import GPG Key
    Name-Email: --maybe we can fill this with the machine name--
    Expire-Date: 0
    %commit


Resolving patch:
diff --git a/privacyidea/api/system.py b/privacyidea/api/system.py
--- a/privacyidea/api/system.py
+++ b/privacyidea/api/system.py
@@ -3,6 +3,8 @@
 # http://www.privacyidea.org
 # (c) cornelius kölbel, privacyidea.org
 #
+# 2017-07-11 Cornelius Kölbel <cornelius.koelbel@netknights.it>
+#            Allow to return GPG keys
 # 2015-12-18 Cornelius Kölbel <cornelius.koelbel@netknights.it>
 #            Remove the complete before and after logic
 # 2015-10-12 Cornelius Kölbel <cornelius.koelbel@netknights.it>
@@ -70,6 +72,7 @@
 from privacyidea.lib.auth import get_db_admins
 from privacyidea.lib.error import HSMException
 from privacyidea.lib.crypto import geturandom
+from privacyidea.lib.importotp import GPGImport
 import base64
 import binascii
 
@@ -109,6 +112,18 @@ def get_config_documentation():
     return re.sub("\n{3,}", "\n\n", render_template("documentation.rst",
                                                context=context))
 
+@system_blueprint.route('/gpgkeys', methods=['GET'])
+def get_gpg_keys():
+    """
+    Returns the GPG keys in the config directory specified by PI_GNUPG_HOME.
+    
+    :return: A json list of the public GPG keys 
+    """
+    GPG = GPGImport(current_app.config)
+    keys = GPG.get_publickeys()
+    g.audit_object.log({"success": True})
+    return send_result(keys)
+
 
 @system_blueprint.route('/<key>', methods=['GET'])
 @system_blueprint.route('/', methods=['GET'])
diff --git a/privacyidea/config.py b/privacyidea/config.py
--- a/privacyidea/config.py
+++ b/privacyidea/config.py
@@ -18,6 +18,7 @@ class Config(object):
     PI_LOGLEVEL = 9
     CACHE_TYPE = "simple"
     PI_EXTERNAL_LINKS = True
+    # PI_GNUPG_HOME = "gpg"
     # PI_LOGO = "otherlogo.png"
     # PI_AUDIT_SQL_URI = sqlite://
 


Test patch:
diff --git a/tests/test_api_system.py b/tests/test_api_system.py
--- a/tests/test_api_system.py
+++ b/tests/test_api_system.py
@@ -839,3 +839,16 @@ def test_18_test_random(self):
             # This is base64. We can decode
             import base64
             base64.b64decode(value)
+
+    def test_19_get_gpg_keys(self):
+        with self.app.test_request_context('/system/gpgkeys',
+                                           method="GET",
+                                           headers={'Authorization': self.at}):
+            res = self.app.full_dispatch_request()
+            self.assertTrue(res.status_code == 200, res)
+            result = json.loads(res.data).get("result")
+            value = result.get("value")
+            # We probably have no keys in here
+            # But value returns a dictionary with the KeyID and "armor" and
+            # "fingerprint"
+            pass