add entropy check for entered passphrases

This commit is contained in:
TLINDEN
2015-08-16 21:35:06 +02:00
parent 32030afd62
commit 0d7282ad35
4 changed files with 55 additions and 3 deletions

View File

@@ -360,6 +360,8 @@ AS_IF([test "x$enable_optimize" != "xno"], [
CXXFLAGS="$CFLAGS"
# FIXME: check for libm
LIBS="$LIBS -lm"
# conditionals for bindings and stuff

View File

@@ -28,6 +28,10 @@
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <stdlib.h>
#include <stdbool.h>
#include "defines.h"
#include "platform.h"
#include "mem.h"
@@ -309,6 +313,8 @@ void pcp_dumppubkey(pcp_pubkey_t *k);
*/
void pcpkey_setowner(pcp_key_t *key, char *owner, char *mail);
double pcp_getentropy(char *source);
#endif /* _HAVE_PCP_KEYPAIR_H */
/**@}*/

View File

@@ -543,3 +543,38 @@ void pcp_dumppubkey(pcp_pubkey_t *k) {
printf(" type: 0x%02X\n", k->type);
}
/*
via
http://rosettacode.org/wiki/Entropy#C
*/
double pcp_getentropy(char *source) {
int len;
int *hist;
double H;
int wherechar[256];
int i,histlen;
histlen = 0;
H = 0;
len = (int)strlen(source);
hist = (int*)calloc(len, sizeof(int));
for(i=0; i<256; i++)
wherechar[i] =- 1;
for(i=0; i<len; i++){
if(wherechar[(int)source[i]] == -1) {
wherechar[(int)source[i]] = histlen;
histlen++;
}
hist[wherechar[(int)source[i]]]++;
}
for(i=0; i<histlen; i++) {
H -= (double)hist[i] / len * log2((double)hist[i] / len);
}
return H;
}

View File

@@ -82,12 +82,16 @@ void pcp_keygen(char *passwd) {
"Enter the passphrase again", 1, NULL);
}
else {
passphrase = ucmalloc(strlen(passwd)+1);
memcpy(passphrase, passwd, strlen(passwd)+1);
passphrase = passwd;
}
if(strnlen(passphrase, 1024) > 0)
if(strnlen(passphrase, 1024) > 0) {
double ent = pcp_getentropy(passphrase);
if(ent < 3) {
fprintf(stderr, "WARNING: you are using a weak passphrase (entropy: %lf)\n", ent);
}
key = pcpkey_encrypt(ptx, k, passphrase);
}
else {
char *yes = pcp_getstdin("WARNING: secret key will be stored unencrypted. Are you sure [yes|NO]?");
if(strncmp(yes, "yes", 1024) == 0)
@@ -108,6 +112,11 @@ void pcp_keygen(char *passwd) {
}
}
if(passwd == NULL) {
/* if passwd is set, it'll be free'd in main() */
sfree(passphrase);
}
errkg1:
free(mail);
free(owner);