Merge branch 'develop'

master v0.3.2
Damien Goutte-Gattat 7 years ago
commit 7b38034f3f
  1. 2
      Makefile.am
  2. 6
      NEWS
  3. 39
      README.md
  4. 2
      configure.ac
  5. 11
      man/scdrand.1.in
  6. 2
      src/otpauth.c
  7. 45
      src/scdrand.c

@ -2,4 +2,4 @@ SUBDIRS = lib src man
ACLOCAL_AMFLAGS = -I m4 --install
dist_doc_DATA = AUTHORS COPYING README
dist_doc_DATA = AUTHORS COPYING README.md

@ -1,3 +1,9 @@
Changes in scdtools 0.3.2
* Add the -e, --entropy-bits option to scdrand.
* Fix improper handling of HOTP URIs.
Changes in scdtools 0.3.1
* Add the -w, --window option to scdtotp.

@ -10,48 +10,47 @@ Scdrand - Extract random numbers from a smartcard
Scdrand obtains up to 256 bytes of random data from a ISO7816-compliant
smartcard and adds them to the kernel entropy pool.
It uses Scdaemon to send a GET CHALLENGE to the smartcard. As per
It uses Scdaemon to send a `GET CHALLENGE` to the smartcard. As per
ISO 7816-4, the smartcard replies with random bytes, which Scdrand then
sends to the Linux kernel entropy pool through the RNDADDENTROPY ioctl
call on /dev/random.
call on `/dev/random`.
Since that call requires root privileges, scdrand is installed with the
setuid bit set. To mitigate risks associated with running as root, the
program forks itself at startup and only the child retains the root
privileges needed to write to /dev/random. The parent process, in charge
of communicating with the smartcard, then runs with the privileges on
the calling user.
privileges needed to write to `/dev/random`. The parent process, in
charge of communicating with the smartcard, then runs with the
privileges on the calling user.
Scdtotp - Generate time-based OTP from an OpenPGP smartcard
-----------------------------------------------------------
Scdtotp uses an OpenPGP smartcard as a poor man’s one-time password
generator token. It generates time-based one-time password (TOTP)
as per RFC 6238, based on a key it expects to find in the private
data object of the inserted OpenPGP smartcard.
generator token. It generates time-based one-time password (TOTP) as per
[RFC 6238](http://tools.ietf.org/html/rfc6238), based on a key it
expects to find in the private data object of the inserted OpenPGP
smartcard.
Note that contrary to a true password generator token, the key cannot
remain only on the smartcard, it has to be sent to the computer so
that scdtotp can derive the password from it. Thus it cannot provide
the same level of security.
The key must be stored as an otpauth:// URI as specified in
<https://code.google.com/p/google-authenticator/wiki/KeyUriFormat>,
The key must be stored as an `otpauth://` URI as specified in [Google
Authenticator’s wiki](https://code.google.com/p/google-authenticator/wiki/KeyUriFormat),
e.g.:
otpauth://totp/alice@example.org?secret=KIMEFUAW4SRW
otpauth://totp/alice@example.org?secret=KIMEFUAW4SRW
where the “secret” parameter is the Base32-encoded key. This format
where the _secret_ parameter is the Base32-encoded key. This format
allows to specify also the non-secret parameters of the TOTP
algorithm:
– the HMAC algorithm to use: "&algorithm=mac", where “mac” can be
“sha1” (default), “sha256”, or “sha512”;
– the time period: "&period=N", where N is expressed in seconds
(30 seconds by default);
– the number of digits to output: "&digits=N" (defaults to 6).
- the HMAC algorithm to use: `&algorithm=mac`, where _mac_ can be `sha1`
(default), `sha256`, or `sha512`;
- the time period: `&period=N`, where _N_ is expressed in seconds (30
seconds by default);
- the number of digits to output: `&digits=N` (defaults to 6).
All of these parameters may be overridden by command line options.
@ -60,7 +59,7 @@ Copying
-------
Scdtools is distributed under the terms of the GNU General Public
License, version 3 or higher. The full license is included in the
COPYING file of the source distribution.
[COPYING file](COPYING) of the source distribution.
Homepage and contact

@ -1,6 +1,6 @@
dnl Configure template for the scdrand package
AC_INIT([scdtools], [0.3.1],
AC_INIT([scdtools], [0.3.2],
[dgouttegattat@incenp.org])
AC_CONFIG_SRCDIR([configure.ac])
AC_CONFIG_MACRO_DIR([m4])

@ -14,6 +14,8 @@ scdrand \- Extract random numbers from a smartcard
.IR N ]
.RB [ \-t | --threshold
.IR N ]
.RB [ \-e | --entropy-bits
.IR N ]
.RB [ nbytes ]
.YS
@ -51,8 +53,13 @@ seconds between iterations.
.TP
.BR -t ", " --threshold " " \fiN\fR
Feed the kernel entropy pool only if it contains less than
.N N
.I N
bits of entropy.
.TP
.BR -e ", " --entropy-bits " " \fiN\fR
Define the entropic value of a single random byte.
.I N
must be comprised between 1 and 8, inclusive.
.SH EXAMPLES
.PP
@ -77,7 +84,7 @@ Damien Goutte-Gattat
.SH COPYRIGHT
.ad l
.PP
Copyright \(co 2014 Damien Goutte-Gattat
Copyright \(co 2014, 2015 Damien Goutte-Gattat
.PP
This program is released under the GNU General Public License.
See the COPYING file in the source distribution or

@ -293,7 +293,7 @@ otp_parse_uri(const char *uri)
otp->type = OTP_TYPE_TOTP;
otp->period = 30;
}
else if ( strncmp(p, "hotp", 5) == 0 && (p += 5) ) {
else if ( strncmp(p, "hotp/", 5) == 0 && (p += 5) ) {
otp->type = OTP_TYPE_HOTP;
otp->counter = 0;
}

@ -1,6 +1,6 @@
/*
* scdtools - Tools for Scdaemon and OpenPGP smartcards
* Copyright (C) 2014 Damien Goutte-Gattat
* Copyright (C) 2014,2015 Damien Goutte-Gattat
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -44,6 +44,7 @@
#define DEFAULT_RANDOM_BYTES 8
#define DEFAULT_LOOP_ITERATIONS 1
#define DEFAULT_LOOP_INTERVAL 10
#define DEFAULT_ENTROPY_FACTOR 8
static void
usage(int status)
@ -71,6 +72,11 @@ specified, the default is %d bytes.\n\n", DEFAULT_RANDOM_BYTES);
Set to 0 (default) to always add entropy.\n\
");
printf("\
-e, --entropy-bits N Set the entropic value of a random byte.\n\
Must be between 1 and 8. Default is %d.\n\
\n", DEFAULT_ENTROPY_FACTOR);
printf("Report bugs to <%s>.\n", PACKAGE_BUGREPORT);
exit(status);
@ -81,7 +87,7 @@ info(void)
{
printf("\
scdrand (scdtools %s)\n\
Copyright (C) 2014 Damien Goutte-Gattat\n\
Copyright (C) 2014,2015 Damien Goutte-Gattat\n\
\n\
This program is released under the GNU General Public License.\n\
See the COPYING file or <http://www.gnu.org/licenses/gpl.html>.\n\
@ -184,12 +190,14 @@ wait_for_threshold(unsigned threshold, unsigned interval)
* The function only returns in the parent process; the child process
* remains in a loop until it terminates.
*
* @param factor The number of entropy bits in a single byte.
*
* @return
* A file descriptor for the pipe connecting the parent process to
* its child.
*/
static int
start_privileged_process(void)
start_privileged_process(unsigned factor)
{
int fd[2];
pid_t pid;
@ -218,7 +226,7 @@ start_privileged_process(void)
if ( n == 0 ) /* EOF, parent process must have closed its end. */
exit(EXIT_SUCCESS);
rpi->entropy_count = n * 8;
rpi->entropy_count = n * factor;
rpi->buf_size = n;
memcpy(&(rpi->buf[0]), buffer, n);
@ -259,28 +267,31 @@ int
main(int argc, char **argv)
{
int c, fd, n, loop;
unsigned nbytes, interval, threshold;
unsigned nbytes, interval, threshold, factor;
assuan_context_t ctx;
gpg_error_t e;
unsigned char random_buffer[MAX_RANDOM_BYTES];
struct option options[] = {
{ "help", 0, NULL, 'h' },
{ "version", 0, NULL, 'v' },
{ "loop", 0, NULL, 'l' },
{ "max-loop", 1, NULL, 'L' },
{ "interval", 1, NULL, 'i' },
{ "threshold", 1, NULL, 't' },
{ NULL, 0, NULL, 0 }
{ "help", 0, NULL, 'h' },
{ "version", 0, NULL, 'v' },
{ "loop", 0, NULL, 'l' },
{ "max-loop", 1, NULL, 'L' },
{ "interval", 1, NULL, 'i' },
{ "threshold", 1, NULL, 't' },
{ "entropy-bits", 1, NULL, 'e' },
{ NULL, 0, NULL, 0 }
};
setprogname(argv[0]);
nbytes = DEFAULT_RANDOM_BYTES;
loop = DEFAULT_LOOP_ITERATIONS;
interval = DEFAULT_LOOP_INTERVAL;
factor = DEFAULT_ENTROPY_FACTOR;
threshold = 0;
while ( (c = getopt_long(argc, argv, "hvlL:i:t:", options, NULL)) != -1 ) {
while ( (c = getopt_long(argc, argv, "hvlL:i:t:e:",
options, NULL)) != -1 ) {
switch ( c ) {
case 'h':
usage(EXIT_SUCCESS);
@ -309,10 +320,16 @@ main(int argc, char **argv)
case 't':
threshold = get_uinteger_or_die(optarg);
break;
case 'e':
factor = get_uinteger_or_die(optarg);
if ( factor == 0 || factor > 8 )
errx(EXIT_FAILURE, "Expected an entropy factor between 1 and 8");
break;
}
}
fd = start_privileged_process();
fd = start_privileged_process(factor);
if ( optind < argc ) {
nbytes = get_uinteger_or_die(argv[optind++]);

Loading…
Cancel
Save