|
|
4418f4 |
/*
|
|
|
4418f4 |
keyrand implementation using /dev/random
|
|
|
4418f4 |
Copyright (C) 2006 Red Hat, Inc.
|
|
|
4418f4 |
|
|
|
4418f4 |
This program is free software; you can redistribute it and/or modify
|
|
|
4418f4 |
it under the terms of the GNU General Public License as published by
|
|
|
4418f4 |
the Free Software Foundation; either version 2 of the License, or
|
|
|
4418f4 |
(at your option) any later version.
|
|
|
4418f4 |
|
|
|
4418f4 |
This program is distributed in the hope that it will be useful,
|
|
|
4418f4 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
4418f4 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
4418f4 |
GNU General Public License for more details.
|
|
|
4418f4 |
|
|
|
4418f4 |
You should have received a copy of the GNU General Public License
|
|
|
4418f4 |
along with this program; if not, write to the Free Software
|
|
|
4418f4 |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
4418f4 |
|
|
|
4418f4 |
*/
|
|
|
4418f4 |
|
|
|
4418f4 |
#include <sys/types.h>
|
|
|
4418f4 |
|
|
|
4418f4 |
#include <unistd.h>
|
|
|
4418f4 |
#include <string.h>
|
|
|
4418f4 |
#include <stdio.h>
|
|
|
4418f4 |
#include <fcntl.h>
|
|
|
4418f4 |
#include <errno.h>
|
|
|
4418f4 |
#include <stdlib.h>
|
|
|
4418f4 |
|
|
|
4418f4 |
#include <slang/slang.h>
|
|
|
4418f4 |
#include <newt.h>
|
|
|
4418f4 |
|
|
|
4418f4 |
static void collect_bytes(int fd, char *buffer, int total)
|
|
|
4418f4 |
{
|
|
|
4418f4 |
int count;
|
|
|
4418f4 |
newtComponent title, form, scale;
|
|
|
4418f4 |
char message[1024];
|
|
|
4418f4 |
newtGrid box;
|
|
|
4418f4 |
|
|
|
4418f4 |
box = newtCreateGrid(1, 3);
|
|
|
4418f4 |
|
|
|
4418f4 |
snprintf(message, sizeof message,
|
|
|
4418f4 |
"To generate %u random bits from the "
|
|
|
4418f4 |
"kernel random number generator, some "
|
|
|
4418f4 |
"keyboard or mouse input may be necessary at the "
|
|
|
4418f4 |
"console for this host. Please try entering "
|
|
|
4418f4 |
"some random text or moving the mouse, if "
|
|
|
4418f4 |
"running this program locally.", total * 8);
|
|
|
4418f4 |
|
|
|
4418f4 |
title = newtTextboxReflowed(1, 1, message, 60, 10, 0, 0);
|
|
|
4418f4 |
|
|
|
4418f4 |
newtGridSetField(box, 0, 0, NEWT_GRID_COMPONENT, title,
|
|
|
4418f4 |
0, 0, 0, 0, 0, 0);
|
|
|
4418f4 |
|
|
|
4418f4 |
/* The progress bar */
|
|
|
4418f4 |
scale = newtScale(0, 0, 30, total);
|
|
|
4418f4 |
newtScaleSet(scale, 0);
|
|
|
4418f4 |
|
|
|
4418f4 |
newtGridSetField(box, 0, 1, NEWT_GRID_COMPONENT, scale,
|
|
|
4418f4 |
0, 1, 0, 0, 0, 0);
|
|
|
4418f4 |
|
|
|
4418f4 |
form = newtForm(NULL, NULL, 0);
|
|
|
4418f4 |
newtGridAddComponentsToForm(box, form, 1);
|
|
|
4418f4 |
|
|
|
4418f4 |
newtGridWrappedWindow(box, "Collecting random data");
|
|
|
4418f4 |
|
|
|
4418f4 |
newtDrawForm(form);
|
|
|
4418f4 |
|
|
|
4418f4 |
count = 0;
|
|
|
4418f4 |
|
|
|
4418f4 |
do {
|
|
|
4418f4 |
ssize_t rv;
|
|
|
4418f4 |
|
|
|
4418f4 |
newtScaleSet(scale, count);
|
|
|
4418f4 |
newtRefresh();
|
|
|
4418f4 |
|
|
|
4418f4 |
rv = read(fd, buffer + count, total - count);
|
|
|
4418f4 |
if (rv == -1 && errno == EINTR) continue;
|
|
|
4418f4 |
else if (rv < 0) {
|
|
|
4418f4 |
newtWinMessage("Error", "Exit",
|
|
|
4418f4 |
"Error reading from /dev/random");
|
|
|
4418f4 |
newtFinished();
|
|
|
4418f4 |
exit(1);
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
SLang_flush_input();
|
|
|
4418f4 |
count += rv;
|
|
|
4418f4 |
} while (count < total);
|
|
|
4418f4 |
|
|
|
4418f4 |
newtFormDestroy(form);
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
|
|
|
4418f4 |
int main(int argc, char **argv)
|
|
|
4418f4 |
{
|
|
|
4418f4 |
const char *output;
|
|
|
4418f4 |
int bits, bytes, fd, rfd;
|
|
|
4418f4 |
char *buffer;
|
|
|
4418f4 |
|
|
|
4418f4 |
if (argc < 3) {
|
|
|
4418f4 |
fprintf(stderr, "Usage: keyrand <number-of-bits> <output-file>\n");
|
|
|
4418f4 |
exit(1);
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
bits = atoi(argv[1]);
|
|
|
4418f4 |
output = argv[2];
|
|
|
4418f4 |
fd = open(output, O_APPEND|O_WRONLY);
|
|
|
4418f4 |
rfd = open("/dev/random", O_RDONLY);
|
|
|
4418f4 |
|
|
|
4418f4 |
newtInit();
|
|
|
4418f4 |
newtCls();
|
|
|
4418f4 |
|
|
|
4418f4 |
newtDrawRootText(0, 0,
|
|
|
4418f4 |
"Red Hat Keypair Generation (c) 2006 Red Hat, Inc.");
|
|
|
4418f4 |
|
|
|
4418f4 |
if (fd < 0) {
|
|
|
4418f4 |
newtWinMessage("Error", "Exit", "Could not open output file");
|
|
|
4418f4 |
newtFinished();
|
|
|
4418f4 |
exit(1);
|
|
|
4418f4 |
}
|
|
|
4418f4 |
else if (rfd < 0) {
|
|
|
4418f4 |
newtWinMessage("Error", "Exit", "Could not open /dev/random");
|
|
|
4418f4 |
newtFinished();
|
|
|
4418f4 |
exit(1);
|
|
|
4418f4 |
}
|
|
|
4418f4 |
else if (bits < 8 || bits > 800 * 1024) {
|
|
|
4418f4 |
newtWinMessage("Error", "Exit", "More than 8 bits must be requested");
|
|
|
4418f4 |
newtFinished();
|
|
|
4418f4 |
exit(1);
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
bytes = bits / 8;
|
|
|
4418f4 |
buffer = malloc(bytes);
|
|
|
4418f4 |
sleep(1);
|
|
|
4418f4 |
|
|
|
4418f4 |
collect_bytes(rfd, buffer, bytes);
|
|
|
4418f4 |
|
|
|
4418f4 |
if (write(fd, buffer, bytes) != bytes || close(fd)) {
|
|
|
4418f4 |
newtWinMessage("Error", "Exit", "Error writing to random file");
|
|
|
4418f4 |
newtFinished();
|
|
|
4418f4 |
exit(1);
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|
|
|
4418f4 |
newtFinished();
|
|
|
4418f4 |
|
|
|
4418f4 |
newtRefresh();
|
|
|
4418f4 |
|
|
|
4418f4 |
sleep(1);
|
|
|
4418f4 |
newtPopWindow();
|
|
|
4418f4 |
SLang_flush_input();
|
|
|
4418f4 |
newtClearKeyBuffer();
|
|
|
4418f4 |
|
|
|
4418f4 |
return 0;
|
|
|
4418f4 |
}
|
|
|
4418f4 |
|