Browse files

Updated docs for fedmsg.crypto.

  • Loading branch information...
ralphbean committed Sep 6, 2012
1 parent 11460bb commit b39e6cfe1857487ddf975413db4d64fb8d0be70c
Showing with 169 additions and 24 deletions.
  1. +1 −0 .gitignore
  2. +87 −0 doc/config.rst
  3. +6 −8 doc/crypto.rst
  4. +4 −2 doc/index.rst
  5. +71 −14 fedmsg/
@@ -7,3 +7,4 @@ dist
@@ -0,0 +1,87 @@
+.. automodule:: fedmsg.config
+ :members:
+ :undoc-members:
+ :show-inheritance:
+Glossary of Configuration Values
+.. glossary::
+ sign_messages
+ ``bool`` - If set to true, then :mod:`fedmsg.core` will try to sign
+ every message sent using the machinery from :mod:`fedmsg.crypto`.
+ It is often useful to set this to `False` when developing. You may not
+ have X509 certs or the tools to generate them just laying around. If
+ disabled, you will likely want to also disable
+ :term:`validate_signatures`.
+ validate_signatures
+ ``bool`` - If set to true, then the base class
+ :class:`fedmsg.consumers.FedmsgConsumer` will try to use
+ :func:`fedmsg.crypto.validate` to validate messages before handing
+ them off to the particular consumer for which the message is bound.
+ This is also used by :mod:`fedmsg.text` to denote trustworthiness
+ in the natural language representations produced by that module.
+ ssldir
+ ``str`` - This should be directory on the filesystem
+ where the certificates used by :mod:`fedmsg.crypto` can be found.
+ Typically ``/etc/pki/fedmsg/``.
+ crl_location
+ ``str`` - This should be a URL where the certificate revocation list can
+ be found. This is checked by :function:`fedmsg.crypto.validate` and
+ cached on disk.
+ crl_cache
+ ``str`` - This should be the path to a filename on the filesystem where
+ the CRL downloaded from :term:`crl_location` can be saved. The python
+ process should have write access there.
+ crl_cache_expiry
+ ``int`` - Number of seconds to keep the CRL cached before checking
+ :term:`crl_location` for a new one.
+ certnames
+ ``dict`` - This should be a mapping of certnames to cert prefixes.
+ The keys should be of the form ``<service>.<host>``. For example:
+ ``bodhi.app01``.
+ The values should be the prefixes of cert/key pairs to be found in
+ :term:`ssldir`. For example, if
+ ```` and
+ ```` are to be found in
+ :term:`ssldir`, then the value
+ ```` should appear in the
+ :term:`certnames` dict.
+ Putting it all together, this value could be specified as follows::
+ certnames={
+ "bodhi.app01": "",
+ # ... other certname mappings may follow here.
+ }
+ .. note::
+ This is one of the most cumbersome parts of fedmsg. The reason we
+ have to enumerate all these redundant mappings between
+ "service.hostname" and "service-fqdn" has to do with the limitations
+ of reverse dns lookup. Case in point, try running the following on
+ app01.stg inside Fedora Infrastructure's environment.
+ >>> import socket
+ >>> print socket.getfqdn()
+ You might expect it to print "", but
+ it doesn't. It prints "". Since
+ we can't rely on programatically extracting the fully qualified
+ domain names of the host machine during runtime, we need to
+ explicitly list all of the certs in the config.
@@ -1,9 +1,7 @@
-Use of X509 Certs
+Cryptography and Message Signing
-TODO - this has yet to be written.
-For now, check out the doc strings at
-They're actually pretty good. :)
+.. automodule:: fedmsg.crypto
+ :members:
+ :undoc-members:
+ :show-inheritance:
@@ -7,9 +7,11 @@ Fedora Infrastructure to send and receive messages to and from applications.
You can find the source at
- :doc:`overview`
- - :doc:`status`
- - :doc:`services`
- :doc:`topology`
+ - :doc:`status`
+ - :doc:`commands`
+ - :doc:`config`
+ - :doc:`encoding`
- :doc:`sending`
- :doc:`receiving`
- :doc:`crypto`
@@ -17,17 +17,21 @@
# Authors: Ralph Bean <>
-""" Cryptographic component of fedmsg.
+""" ``fedmsg.crypto`` - Cryptographic component of fedmsg.
In general, we assume that 'everything on the bus is public'. Even though all
the zmq endpoints are firewalled off from the outside world with iptables, we
-intend to someday have a forwarding service setup that will indiscriminantly
-forward all messages to anyone who wants them. So, the issue is not encrypting
-messages so they can't be read. It is up to sensitive services like FAS to
-*not send* sensitive information in the first place (like passwords, for
-Since at some point, some services will respond to and act on messages that
+do have a forwarding service setup that indiscriminantly
+forwards all messages to anyone who wants them.
+(See :mod:`fedmsg.commands.gateway` for that service.)
+So, the issue is not encrypting messages so they can't be read. It is up to
+sensitive services like FAS to *not send* sensitive information in the first
+place (like passwords, for instance).
+However, since at some point, services will respond to and act on messages that
come across the bus, we need facilities for guaranteeing a message comes from
where it *ought* to come from. (Tangentially, message consumers need a simple
way to declare where they expect their messages to come from and have
@@ -40,13 +44,60 @@
difficult to sign messages. A consumer of those messages should be allowed
to ignore validation for those and only those expected unsigned messages
-This module encapsulates standalone functions for:
+To accomplish message signing, fedmsg must be able to read certificates and a
+private key on disk. For message validation, it only need be able to read the
+certificate. Exactly *which* certificates are used are determined by looking up
+the ``certname`` in the ``certnames`` config dict.
+We use a large number of certs for the deployment of fedmsg. We have one cert
+per `service-host`. For example, if we have 3 fedmsg-enabled services and each
+service runs on 10 hosts, then we have 30 unique certificate/key pairs in all.
+The intent is to create difficulty for attackers. If a low-security service on
+a particular box is compromised, we don't want the attacker automatically have
+access to the same certificate used for signing high-security service messages.
+Furthermore, attempts are made at the sysadmin-level to ensure that
+fedmsg-enabled services run as users that have exclusive read access to their
+own keys. See the `Fedora Infrastructure SOP
+<>`_ for more
+information (including how to generate new certs/bring up new services).
+By convention, configuration values for :mod:`fedmsg.crypto` are kept in
+``/etc/fedmsg.d/``, although technically they can be kept in any
+config ``dict`` in ``/etc/fedmsg.d`` (or in any of the config locations checked
+by :mod:`fedmsg.config`).
+The cryptography routines expect the following values to be defined:
+ - :term:`sign_messages`
+ - :term:`validate_signatures`
+ - :term:`ssldir`
+ - :term:`crl_location`
+ - :term:`crl_cache`
+ - :term:`crl_cache_expiry`
+ - :term:`certnames`
+For general information on configuration, see :mod:`fedmsg.config`.
+Module Contents
+:mod:`fedmsg.crypto` encapsulates standalone functions for:
- Message signing.
- Signature validation.
+ - Stripping crypto information for view.
+It also contains some hidden/private machinery to handle refreshing a cached
-To accomplish this, we'll use puppet's already in place PKI involving X509
-certificates and RSA signatures.
@@ -72,8 +123,10 @@
def sign(message, ssldir, certname, **config):
""" Insert two new fields into the message dict and return it.
- 'signature' - the computed RSA message digest of the JSON repr.
- 'certificate' - the base64 X509 certificate of the sending host.
+ Those fields are:
+ - 'signature' - the computed RSA message digest of the JSON repr.
+ - 'certificate' - the base64 X509 certificate of the sending host.
certificate = M2Crypto.X509.load_cert(
@@ -172,7 +225,11 @@ def fail(reason):
def strip_credentials(message):
- """ Strip credentials from a message dict. """
+ """ Strip credentials from a message dict.
+ A new dict is returned without either `signature` or `certificate` keys.
+ This method can be called safely; the original dict is not modified.
+ """
message = copy.deepcopy(message)
for field in ['signature', 'certificate']:
if field in message:

0 comments on commit b39e6cf

Please sign in to comment.