Tools to make secret sharing easier.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

505 lines
18 KiB

\input texinfo
@setfilename gfsecret.info
@settitle The Gfsecret Manual
@include version.texi
@copying
This is the manual for Gfsecret (version @value{VERSION}, last updated
@value{UPDATED}).
Copyright @copyright{} 2017 Damien Goutte-Gattat
@quotation
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
Texts. A copy of the license is included in the section entitled ``GNU
Free Documentation License''.
@end quotation
@end copying
@titlepage
@title Gfsecret
@subtitle for version @value{VERSION}, @value{UPDATED}
@author Damien Goutte-Gattat (@email{devel@@incenp.org})
@page
@vskip 0pt plus 1filll
@insertcopying
@end titlepage
@contents
@ifnottex
@node Top
@top Gfsecret
This manual is for Gfsecret (version @value{VERSION}, @value{UPDATED}).
@end ifnottex
@menu
* Introduction::
* The Share URI Syntax::
* Splitting a Secret::
* Using a Splitted Secret::
* Examples::
* GNU Free Documentation License::
* Index::
@end menu
@node Introduction
@chapter Introduction
You may have some important files that you both don't want to lose and
don't want to fall into any other hands than yours. It may be files
containing your OpenPGP private keys, the file containing all your
online passwords, the file describing your plan for total world
domination, whatever.
Such files pose an interesting problem. Obviously, you have to backup
them to avoid losing them, but any supplementary copy gives your
adversary one more opportunity to grab your secret.
@menu
* Adi Shamir's Secret Sharing::
* Overview of Gfsecret::
@end menu
@node Adi Shamir's Secret Sharing
@section Adi Shamir's Secret Sharing
A secret sharing scheme is precisely what you need to fulfill both of
the contradictory goals.
The Adi Shamir's secret sharing scheme, devised by the famous
cryptographer Adi Shamir (the ``A'' in the RSA public cryptography
algorithm) in 1979, relies on the fact that @math{n + 1} points are
required to uniquely define a curve corresponding to a polynom of order
@math{n}.
To illustrate the scheme, let's say you want to share a secret value
@math{b} in two or more shares, so that at least two shares are needed
to reconstitute the secret. You will define a curve of the form
@math{f(x) = ax + b}, where @math{a} is a randomly chosen coefficient
and @math{b} (the secret value) is the y coordinate where the curve
intersects the Y axis.
A share is then a point on that curve, that is, a couple @math{x, f(x)}.
If you have only one point, there's no way for you to know what the
curve is, and where it intersects the Y axis, because there's an
infinity of curves passing through this point.
As soon as you have (at least) two points, however, you have all the
information that you need: there's only one straight curve passing
through two distinct points, and you can trace it, and trivially find
where it intersects the Y axis (and thus retrieve the secret value).
@node Overview of Gfsecret
@section Overview of Gfsecret
Gfsecret implements the Adi Shamir's secret sharing scheme to allow its
user to split a secret file into a given number of @emph{shares}, to
dispatch the shares onto several external storage devoces such as USB
sticks, and to temporarily reconstruct the original file when needed.
Gfsecret comprises two programs: @command{gfsec-split} splits a secret
file into shares and dispatches them, leaving behind a configuration
file describing the location of the shares; @command{fgsec-use} reads
the configuration file left by @command{gfsec-split}, attempts to fetch
the shares, and reconstructs the secret file if enough shares are
available. If the reconstruction is successful, @command{gfsec-use}
will then execute a single command (or start a new interactive shell if
the user didn't specify any command), and remove the reconstructed
secret once that command terminates.
@node The Share URI Syntax
@chapter The Share URI Syntax
Both @command{gfsec-split} and @command{gfsec-use} use the concept of a
@emph{share URI} to describe and represent shares. A share URI is an
URI-like string of the form @samp{scheme://authority/path?parameters}.
The @var{scheme} part indicates the method to use to access the share.
It can be: @samp{file} for a share on the local filesystem; @samp{label}
for a share on an external volume identified by its label; @samp{uuid}
for a share on an external volume identified by its UUID; or @samp{mtp}
for a share on a MTP-compliant device identified by its serial number.
The @var{authority} part identifies the storage device. It should be
empty when using the @samp{file://} scheme (although for consistency
with other uses of that scheme by other programs, it is permitted to
specify @samp{localhost}). It represents the volume's label when using
the @samp{label://} scheme, the volume's UUID when using the
@samp{uuid://} scheme, and the device's serial number when using the
@samp{mtp://} scheme.
The @var{path} part is the pathname to the share file on the device.
The filename itself should end with a numeric extension representing the
share number (needed by @command{gfsec-use} to appropriately reconstruct
the secret). That share number is automatically determined and appended
to the original filename by @command{gfsec-split}.
Finally, the optional @var{parameters} part may contains options
expressed as @samp{key=value} pairs. Currently, valid options are
@samp{sha256}, which specifies a SHA2-256 hash that the share should
match (@command{gfsec-use} will refuse to use the share otherwise), and
@samp{share=no}, which indicates that the corresponding share actually
contains the whole secret.
@node Splitting a Secret
@chapter Splitting a Secret
The @command{gfsec-split} tool is used to split a secret file into
shares.
The program must be given the pathname of the file to split as its first
positional argument. The location of the shares to create can either be
specified as @emph{share URIs} (@ref{The Share URI Syntax}) as
subsequent positional arguments on the command line (@ref{Specifying
Share URIs on the Command Line}), or be given through an interactive
menu (@ref{Interactive Selection of Shares}).
The threshold, that is, the minimal number of shares needed to
reconstruct the original file, is specified with the option @option{-n}
(@option{--threshold}). The default threshold is 2. The total number of
shares must of course be greater than or equal to that threshold, and
@command{gfsec-split} will fail otherwise (obviously you cannot split a
secret in two shares and require three shares to reconstruct it).
By default, if the split is successful, @command{gfsec-split} will
delete the original secret file once the shares have been dispatched to
their final location. Use the option @option{-k} (@option{--keep}) to
leave the original file intact.
A configuration file, needed by @command{gfsec-use} to reconstruct the
splitted file, will be automatically generated in the directory
@file{$XDG_CONFIG_HOME/gfsecret/@var{basename}.conf}, where
@var{basename} is the basename of the original file (without any
directory part and file extension). For example, when called to split a
file @file{/home/alice/Documents/mysecret.dat}, @command{gfsec-split} will
generate a configuration file in
@file{/home/alice/.config/gfsecret/mysecret.conf} (assuming the default
value for the @var{XDG_CONFIG_HOME} environment variable).
Use the option @option{-c} (@option{--config}) @var{name} to specify
yourself the name of the configuration file. If @var{name} is a filename
without extension and without a directory part, the configuration file
will be written to @file{$XDG_CONFIG_HOME/gfsecret/@var{name}.conf}.
Otherwise it will be written exactly at the specified location.
@menu
* Specifying Share URIs on the Command Line::
* Interactive Selection of Shares::
@end menu
@node Specifying Share URIs on the Command Line
@section Specifying Share URIs on the Command Line
The first method to tell @command{gfsec-split} where to put the shares
is to give it @emph{share URIs} (@ref{The Share URI Syntax}) on the
command line, as follows:
@example
$ gfsec-split @var{secretfile} @var{uri1} @var{uri2} @var{uri3}
@end example
Before actually splitting the secret, you may invoke
@command{gfsec-split} with the option @option{-l}
(@option{--list-supports}) to get a list of available storage devices so
that you can construct the needed share URIs:
@example
$ gfsec-split -l
file:/// Local filesystem
label://USBSTICK/ External volume with label 'USBSTICK'
mtp://RF2GB6X704P/ Samsung Galaxy A3
@end example
With those informations, you may then proceed to the actual split. Here,
assuming you want to put a share on each one of the available devices:
@example
$ gfsec-split @var{secretfile} \
file:///home/alice/.shares/mysecret \
label://USBSTICK/mysecret \
mtp://RF2GB6X704P/Documents/mysecret
@end example
(Note that shares do not need to have the same filename.)
With this example, @command{gfsec-split} with split @var{secretfile} in
three shares and store the first one in Alice's home directory, the
second one in the USB mass storage device called @emph{USBSTICK}, and
the third one on the Samsung Galaxy A3 smartphone with serial number
@emph{RF2GB6X704P}. External volumes will be automatically mounted if
needed (in that case they will also be unmounted at the end).
Note that @command{gfsec-split} will not create parent directories,
which must exist beforehand.
@node Interactive Selection of Shares
@section Interactive Selection of Shares
To avoid manually specifying the share URIs, use the @option{-i}
(@option{--interactive}). You will then be presented with an interactive
menu with the available devices:
@example
$ gfsec-split -i @var{secretfile}
Select a support for share #1:
(1) Local filesystem
(2) External volume with label 'USBSTICK'
(3) Samsung Galaxy A3
(x) Done
Your choice?
@end example
Select the device on which you want to put the first share, then enter
the pathname to use on that device when prompted (again, be aware that
no parent directories will be created).
Repeat for all the shares you want to create, then select @kbd{x} when
you are done. @command{gfsec-split} will then show you a summary of what
you have selected, and ask for your confirmation:
@example
The following shares will be created:
file:///home/alice/.shares/mysecret.XXX
label://USBSTICK/mysecret.XXX
mtp://RF2GB6X704P/Documents/mysecret.XXX
Proceed (y/N)?
@end example
Note that you can use both the command line and the interactive menu in
the same invocation of @command{gfsec-split}. The shares that you
describe on the command line will be added to the one you select in the
menu.
@node Using a Splitted Secret
@chapter Using a Splitted Secret
The @command{gfsec-use} program allows its user to temporarily
reconstruct a previously splitted file.
It reads a configuration file (automatically generated by the
@command{gfsec-split} program, although a configuration file can also be
crafted by hand) which gives, in particular, the location of the shares
(@ref{The Gfsecret Configuration File}).
Configuration files are normally stored in
@file{$XDG_CONFIG_HOME/gfsecret}, and @command{gfsec-use} reads by
default the file @file{XDG_CONFIG_HOME/gfsecret/default.conf}. The
option @option{-c} (@option{--config}) allows to specify another file:
@example
$ gfsec-use -c @var{myconfig}
@end example
If the file @var{myconfig} exists, it is used as the configuration file;
otherwise, @command{gfsec-use} looks for a file named
@file{@var{myconfig}.conf} in the directory
@file{XDG_CONFIG_HOME/gfsecret}.
Once the splitted file has been reconstructed (if enough shares are
available), @command{gfsec-use} will either spawn a new shell, or
execute any program specified at the end of the command line. When the
shell, or the user-specified program, terminates, the reconstructed file
is deleted again.
The @option{-k} (@option{--keep}) prevents @command{gfsec-use} from
deleting the reconstructed file. As a special case, if this option is
used and there is no user-specified command to execute,
@command{gfsec-use} will not spawn a new shell, but exits as soon as the
file is reconstructed.
The reconstructed file is normally written at the location of the
original file (or any other location specified by the @option{OUTFILE}
key in the configuration file). It may be written elsewhere by using the
@option{-o} (@option{--output}).
@menu
* The Gfsecret Configuration File::
@end menu
@node The Gfsecret Configuration File
@section The Gfsecret Configuration File
A configuration file contains all the informations needed by
@command{gfsec-use} to reconstruct a splitted file.
Those informations are stored as @code{key=value} pairs, with one such a
pair per line. Blank lines are ignored, as well as lines starting with a
@code{#} character.
The following table lists the allowed keys and their signification:
@table @code
@item OUTFILE
This is the pathname to the file where the reconstructed secret is to be
written. When the configuration file is generated by
@command{gfsec-split}, this defaults to the location of the original
file.
@item MINSHARES
This is the threshold, indicating the lowest number of shares required
to reconstruct the secret.
@item URI
This is an URI representing one of the shares, as described previously in
@ref{The Share URI Syntax}.
@end table
@node Examples
@chapter Examples
This chapter describes some precise use cases for Gfsecret.
@menu
* Keeping a GnuPG Master Key Offline::
@end menu
@node Keeping a GnuPG Master Key Offline
@section Keeping a GnuPG Master Key Offline
In this example, Alice has a GnuPG keyring containing a @emph{master
key} and two subkeys: one for signing and one for encryption. Alice only
needs her master key on rare occasions (mainly to certify other people's
keys), and thus wants to keep it offline most of the time.
Note that the following is only possible when using GnuPG 2.1 (or
greater).
The first thing Alice has to do is to obtain the @emph{keygrip} of her
master key:
@example
$ gpg2 --list-secret-keys --with-keygrip
/home/alice/.gnupg/pubring.kbx
------------------------------
sec rsa4096 2016-12-25 [SC] [expires: 2019-12-25]
DFF9C8A3FE6663F9DD157E16F5C95C96DD4C784D
Keygrip = @emph{47921AA1A41065B89D2790C3EAD88922063E8AA8}
uid [ultimate] Alice Smith <alice@@example.org>
ssb rsa2048 2016-12-25 [E] [expires: 2017-12-25]
Keygrip = 543E2A5037F6C5B8C655255CA76DCF5FB0D9C9C0
ssb rsa2048 2016-12-25 [S] [expires: 2017-12-25]
Keygrip = 6BA62F5EFDB16B8F1D7407E12466166FE90424B8
@end example
The master key has the keygrip @code{47921A[...]3E8AA8}. This means
(with GnuPG 2.1) that it is stored in the file
@file{~/.gnupg/private-keys-v1.d/47921A[...]3E8AA8.key}.
Alice plugs in her removable storage devices and calls
@command{gfsec-split} with the @option{-l} option:
@example
$ gfsec-split -l
file:/// Local filesystem
label://USBKEY/ External volume with label 'USBKEY'
mtp://RF2GB6X704P/ Samsung Galaxy A3
@end example
Alice wants now to split her master key in three shares, one for each of
the available devices. She thus calls @command{gfsec-split} again as
follows:
@example
$ gfsec-split -c master \
/home/alice/.gnupg/private-keys-v1.d/47921A[...]3EA88A.key \
file:///home/alice/.local/share/gfsecret/master-key \
label://USBKEY/master-key \
mtp://RF2GB6X704P/Documents/master-key
@end example
Here, Alice explicitly sets the name of the configuration file to
generate (with the @option{-c} option). The default behavior of
@command{gfsec-split} would have created a configuration file named with
the 40 characters of the keygrip, which would have been especially
impractical.
If the command succeeded, Alice can check with GnuPG that her master key
is indeed no longer available:
@example
$ gpg2 --list-secret-keys
/home/alice/.gnupg/pubring.kbx
------------------------------
sec# rsa4096 2016-12-25 [SC] [expires: 2019-12-25]
DFF9C8A3FE6663F9DD157E16F5C95C96DD4C784D
uid [ultimate] Alice Smith <alice@@example.org>
ssb rsa2048 2016-12-25 [E] [expires: 2017-12-25]
ssb rsa2048 2016-12-25 [S] [expires: 2017-12-25]
@end example
Note the @code{#} symbol following the @code{sec} keyword: it indicates
that the corresponding private key is not available.
Later on, Alice obtains Bob's public key and wants to certify it. For
that, she needs her master private key. In order to reconstruct it, she
calls @command{gfsec-use} with the name of the configuration file she
specified above:
@example
$ gfsec-use -c master
Found share data in file:///home/alice/.local/share/gfsecret/master-key.070
gfsec-use: Cannot reconstitute the secret: Not enough shares available
@end example
The reconstruction attempt failed because @command{gfsec-use} found only
the share stored on the local filesystem. Alice then plugs in one of her
two removable devices and run the same command again:
@example
$ gfsec-use -c master
Found share data in file:///home/alice/.local/share/gfsecret/master-key.070
Found share data in label://USBKEY/master-key.134
gfsec>
@end example
This time, the reconstruction was successful, and Alice is dropped into
a new shell in which she can do everything she needs to do with her
private key. Once she is done, she can quit that shell, and her
reconstructed key will be deleted again:
@example
gfsec> ^D
Removing secret.
@end example
Instead of spawning a shell, Alice could also have directly invoked the
key editor of GnuPG from @command{gfsec-use}'s command line:
@example
$ gfsec-use -c master -- gpg2 --edit-key bob@@example.com
@end example
(Note the @code{--}: it is needed to make sure @command{gfsec-use} will
not try to parse options that belongs to @command{gpg2}, such as
@option{--edit-key} in this example.)
@node GNU Free Documentation License
@appendix GNU Free Documentation License
@include fdl.texi
@node Index
@unnumbered Index
@printindex cp
@bye