[libvirt] [PATCH 1/9] Add volume encryption information handling.

Miloslav Trmac mitr at redhat.com
Fri Jul 24 04:08:32 UTC 2009


----- "Daniel P. Berrange" <berrange at redhat.com> wrote:
> On Tue, Jul 21, 2009 at 01:11:57PM +0200, Miloslav Trma?? wrote:
> > +#include <stdbool.h>
> > +#include <libxml/tree.h>
> > +
> > +enum virStorageEncryptionFormat {
> > +    VIR_STORAGE_ENCRYPTION_FORMAT_UNENCRYPTED = 0,
> > +    VIR_STORAGE_ENCRYPTION_FORMAT_QCOW, /* Both qcow and qcow2 */
> > +
> > +    VIR_STORAGE_ENCRYPTION_FORMAT_LAST,
> > +};
> > +VIR_ENUM_DECL(virStorageEncryptionFormat)
> > +
> > +typedef struct _virStorageEncryption virStorageEncryption;
> > +typedef virStorageEncryption *virStorageEncryptionPtr;
> > +struct _virStorageEncryption {
> > +    int format;            /* enum virStorageEncryptionFormat */
> > +
> > +    union {                /* Format-specific data */
> > +        struct {
> > +            char *passphrase;
> > +        } qcow;
> > +    } v;
> > +};
> 
> As with the XML format, I'd like to avoid encoding qcow as a 
> structural element here. Instead go for a generic storage of
> secrets.
> 
>   enum virStorageEncryptionSecret {
>     VIR_STORAGE_ENCRYPTION_SECRET_PASSPHRASE,
>   };
>  
>   struct virStorageSecret{
>      int type;    /* enum virStorageSecret */
> 
>      union {
>         char *passphrase;
>      } data;
>   };
> 
>   struct _virStorageEncryption {
>     unsigned encrypted : 1;
> 
>     int nsecrets;
>     virStorageSecret *secrets;
>   }
> 
> This allows for > 1 secret should we need that (eg, for
> LUKS/cryptsetup volume)
As argued in the 0/9 e-mail, the "encryption format" is an independent piece of information that needs to be stored, and the set of other information that needs to be stored can differ among formats.  Should we ever need support for more than one secret in LUKS, that a separate struct { ... } luks should be added to the union: it seems to me that support for storing more than one passphrase is not necessary for libvirt's use of LUKS (although LUKS supports it) - on the other hand, if such support would be necessary, it would most likely be necessary to store the slot used by each passphrase as well.

We know that the type and amount of information that will need to be stored will vary depending on the "encryption format"; on the other hand, expecting that the information consists of independent "secrets", each with a simple and format-independent definition, is probably too optimistic.  (As mentioned above, we might need a key slot ID associated with a LUKS passphrase; we might also need a password hash algorithm associated with a dm-crypt passphrase.  The encryption formats used in practice are often complex enough that a "simple passphrase" can not be used.)  Once we have to assume that each secret can have an "encryption format"-dependent format, I think it is much clearer to use something like
   enum { FORMAT_1, FORMAT_2, FORMAT_3 } format;
   union {
     struct { char *secret_1; } format_1;
     struct { struct { char *secret, id; } secrets[N]; } format_2;
     struct { int param_1, param_2, param_3; char *secret_1, *secret_2 }; format_2;
   }
which explicitly defines what information is requested for each format, and how it is related, (and which allows showing the data related to a single format in a debugger by simply choosing a single member of the union) than something like
  struct {
    enum { SECRET_FMT_1, SECRET_FMT_2, PARAM_FMT_1, PARAM_FMT_2 } type;
    union {
      char *secret_fmt_1;
      struct { char *secret, id} secret_fmt_2;
      int param_fmt_1;
      char *param_fmt_2;
   }
  } [...]
with implicit assumptions about the secret and parameter formats used by various "encryption formats".

Even if the XML uses one or more generic-looking <secret> elements, the information will have to be categorized depending on its meaning and relations before being used; it seems to me cleaner to do it once, when parsing the XML, than to parse the XML without assigning much semantic value to it, and then re-parse the internal representation to categorize the information.

Categorizing the information already when parsing the XML will also make it easy to detect invalid or missing data already when parsing the XML, before any "real" operations that might be costly or difficult to undo are started, or before the information is used or stored by other components of libvirt.
    Mirek




More information about the libvir-list mailing list