Browse Source

Refactor around the secret module

Move all code to split and combine into a dedicated 'secret'
module.
master
Damien Goutte-Gattat 5 years ago
parent
commit
82ca0497b3
  1. 2
      src/Makefile.am
  2. 143
      src/gfsec-use.c
  3. 387
      src/secret.c
  4. 118
      src/secret.h
  5. 71
      src/secretcfg.c
  6. 14
      src/secretcfg.h
  7. 60
      src/share.c
  8. 57
      src/share.h

2
src/Makefile.am

@ -1,6 +1,6 @@
bin_PROGRAMS = gfsec-use
gfsec_use_SOURCES = gfsec-use.c util.c util.h share.c share.h \
gfsec_use_SOURCES = gfsec-use.c util.c util.h secret.c secret.h \
secretcfg.c secretcfg.h \
mtp-support.c mtp-support.h \
uuid-support.c uuid-support.h

143
src/gfsec-use.c

@ -32,11 +32,10 @@
#include <getopt.h>
#include <err.h>
#include <libgfshare.h>
#include <gcrypt.h>
#include "util.h"
#include "share.h"
#include "secret.h"
#include "secretcfg.h"
#include "mtp-support.h"
#include "uuid-support.h"
@ -139,49 +138,41 @@ get_share_display_name(gfsec_share_t *share)
}
static int
get_share_data(gfsec_share_t *share, gcry_md_hd_t md)
get_share_data(gfsec_share_t *share)
{
int rc = -1;
unsigned char *data;
size_t len;
switch ( share->scheme ) {
case SCHEME_FILE:
if ( (share->data = read_file(share->path, &(share->length))) )
case GFSEC_SCHEME_FILE:
if ( (data = read_file(share->path, &len)) )
rc = 0;
break;
case SCHEME_UUID:
if ( (share->data = gfsec_get_file_from_uuid(share->authority,
share->path, &(share->length))) )
case GFSEC_SCHEME_UUID:
if ( (data = gfsec_get_file_from_uuid(share->authority,
share->path, &len)) )
rc = 0;
break;
case SCHEME_LABEL:
if ( (share->data = gfsec_get_file_from_label(share->authority,
share->path, &(share->length))) )
case GFSEC_SCHEME_LABEL:
if ( (data = gfsec_get_file_from_label(share->authority,
share->path, &len)) )
rc = 0;
break;
case SCHEME_MTP:
if ( (share->data = gfsec_get_file_from_mtp(share->authority,
share->path, &(share->length))) )
case GFSEC_SCHEME_MTP:
if ( (data = gfsec_get_file_from_mtp(share->authority,
share->path, &len)) )
rc = 0;
break;
}
if ( rc == 0 && share->sha256 ) {
unsigned char *md_val;
gcry_md_write(md, share->data, share->length);
md_val = gcry_md_read(md, 0);
if ( memcmp(share->sha256, md_val, 32) != 0 ) {
warnx("Incorrect hash value for share %s\n", get_share_display_name(share));
free(share->data);
share->data = NULL;
rc = -1;
}
gcry_md_reset(md);
if ( rc == 0 && gfsec_share_set_data(share, data, len) != 0 ) {
warnx("Incorrect hash value for share %s\n", get_share_display_name(share));
free(data);
rc = -1;
}
return rc;
@ -193,11 +184,10 @@ main(int argc, char **argv)
int c;
const char *cfg_file, *output_file;
char cfg_path[255];
gfsec_secret_config_t *cfg;
gfsec_secret_t *cfg;
gfsec_share_t *share;
unsigned have_shares, have_full;
pid_t pid;
gcry_md_hd_t md;
unsigned u;
struct option options[] = {
{ "help", 0, NULL, 'h' },
@ -209,7 +199,6 @@ main(int argc, char **argv)
setprogname(argv[0]);
cfg_file = output_file = NULL;
have_shares = have_full = 0;
while ( (c = getopt_long(argc, argv, "hvc:o:", options, NULL)) != -1 ) {
switch ( c ) {
@ -249,95 +238,31 @@ main(int argc, char **argv)
if ( ! (cfg = gfsec_read_config(cfg_path)) )
err(EXIT_FAILURE, "Cannot parse configuration file");
if ( ! output_file && ! (output_file = cfg->output_file) )
if ( ! output_file && ! (output_file = cfg->filename) )
errx(EXIT_FAILURE, "No output file specified");
if ( gcry_md_open(&md, GCRY_MD_SHA256, 0) )
errx(EXIT_FAILURE, "Cannot create hashing context");
share = cfg->shares;
while ( share ) {
if ( get_share_data(share, md) == 0 ) {
if ( (share->flags & GFSEC_SHARE_FLAGS_FULL) > 0 )
have_full = 1;
else
have_shares += 1;
for ( u = 0; u < cfg->n_shares; u++ ) {
share = cfg->shares[u];
if ( get_share_data(share) == 0 )
printf("Found share data in %s\n", get_share_display_name(share));
}
share = share->next;
}
gcry_md_close(md);
if ( gfsec_secret_can_combine(cfg) != 0 )
errx(EXIT_FAILURE, "Cannot reconstitute secret");
if ( have_full ) {
share = cfg->shares;
while ( share ) {
if ( share->data && (share->flags & GFSEC_SHARE_FLAGS_FULL) > 0 )
break;
share = share->next;
}
if ( gfsec_secret_combine(cfg) != 0 )
errx(EXIT_FAILURE, "Error while reconsituting secret");
printf("Using full data in %s\n", get_share_display_name(share));
if ( write_file(output_file, share->data, share->length) == -1 )
err(EXIT_FAILURE, "Cannot write secret");
}
else if ( have_shares >= cfg->threshold ) {
gfshare_ctx *ctx;
unsigned char sharenrs[255], *secret;
unsigned n, size;
n = size = 0;
share = cfg->shares;
while ( share ) {
if ( share->data && share->share_nr > 0 ) {
sharenrs[n++] = share->share_nr;
if ( size == 0 )
size = share->length;
else if ( size != share->length )
errx(EXIT_FAILURE, "Shares have different sizes");
}
share = share->next;
}
if ( ! (secret = malloc(size)) || mlock(secret, size) == -1 )
err(EXIT_FAILURE, "Cannot allocated mlocked memory");
if ( ! (ctx = gfshare_ctx_init_dec(sharenrs, n, size)) )
errx(EXIT_FAILURE, "Cannot initialize libgfshare context");
n = 0;
share = cfg->shares;
while ( share ) {
if ( share->data && share->share_nr > 0 ) {
printf("using share data in %s\n", get_share_display_name(share));
gfshare_ctx_dec_giveshare(ctx, n++, share->data);
}
share = share->next;
}
gfshare_ctx_dec_extract(ctx, secret);
if ( write_file(output_file, secret, size) == -1 )
err(EXIT_FAILURE, "Cannot write secret");
memset(secret, 0, size);
munlock(secret, size);
free(secret);
}
else
errx(EXIT_FAILURE, "Not enough data to reconstitute secret");
if ( write_file(output_file, cfg->data, cfg->len) == -1 )
err(EXIT_FAILURE, "Cannot write secret");
if ( (pid = fork()) == -1 ) {
unlink(cfg->output_file);
unlink(cfg->filename);
err(EXIT_FAILURE, "Cannot fork");
}
else if ( pid == 0 ) {
gfsec_destroy_config(cfg);
gfsec_secret_free(cfg);
if ( optind < argc ) {
execvp(argv[optind], &(argv[optind]));
@ -370,7 +295,7 @@ main(int argc, char **argv)
unlink(output_file);
}
gfsec_destroy_config(cfg);
gfsec_secret_free(cfg);
return EXIT_SUCCESS;
}

387
src/secret.c

@ -0,0 +1,387 @@
/*
* gfsecret - Secret sharing tools
* Copyright (C) 2016 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "secret.h"
#include <stdlib.h>
#include <string.h>
#include <gcrypt.h>
#include <libgfshare.h>
#include "util.h"
gfsec_share_t *
gfsec_share_new(void)
{
gfsec_share_t *s = NULL;
if ( (s = malloc(sizeof(gfsec_share_t))) ) {
s->number = GFSEC_SHARE_NUMBER_AUTOASSIGN;
s->scheme = GFSEC_SCHEME_FILE;
s->authority = NULL;
s->path = NULL;
s->len = 0;
s->data = NULL;
s->hash = NULL;
}
return s;
}
int
gfsec_share_set_info(gfsec_share_t *share,
unsigned char number,
gfsec_scheme_t scheme,
const char *authority,
const char *path,
const unsigned char *hash)
{
if ( ! share )
return GFSEC_ERR_INVALID_CALL;
share->number = number;
share->scheme = scheme;
if ( ! (share->authority = strdup(authority)) )
return GFSEC_ERR_SYSTEM_ERROR;
if ( ! (share->path = strdup(path)) )
return GFSEC_ERR_SYSTEM_ERROR;
if ( hash )
memcpy(share->hash, hash, 32);
return 0;
}
int
gfsec_share_set_data(gfsec_share_t *share,
unsigned char *data,
size_t len)
{
int ret;
if ( ! share || ! data )
return GFSEC_ERR_INVALID_CALL;
share->data = data;
share->len = len;
ret = 0;
if ( share->hash ) {
gcry_md_hd_t md;
unsigned char *hash;
gcry_md_open(&md, GCRY_MD_SHA256, 0);
gcry_md_write(md, data, len);
hash = gcry_md_read(md, 0);
if ( memcmp(share->hash, hash, 32) != 0 ) {
ret = GFSEC_ERR_INVALID_SHARE;
share->data = NULL;
share->len = 0;
}
gcry_md_close(md);
}
return ret;
}
void
gfsec_share_free(gfsec_share_t *share)
{
if ( ! share )
return;
if ( share->authority )
free(share->authority);
if ( share->path )
free(share->path);
if ( share->data )
free(share->data);
if ( share->hash )
free(share->hash);
free(share);
}
gfsec_secret_t *
gfsec_secret_new(void)
{
gfsec_secret_t *s = NULL;
if ( (s = malloc(sizeof(*s))) ) {
s->filename = NULL;
s->data = NULL;
s->len = 0;
s->n_shares = 0;
s->max_shares = 0;
s->threshold = 0;
s->shares = NULL;
s->full_share = NULL;
s->can_combine = 0;
}
return s;
}
int
gfsec_secret_set_secret_file(gfsec_secret_t *secret,
const char *filename)
{
if ( ! secret || ! filename )
return GFSEC_ERR_INVALID_CALL;
if ( (secret->filename = strdup(filename)) )
return GFSEC_ERR_SYSTEM_ERROR;
if ( ! (secret->data = read_file(filename, &(secret->len))) )
return GFSEC_ERR_SYSTEM_ERROR;
}
int
gfsec_secret_add_share(gfsec_secret_t *secret, gfsec_share_t *share)
{
if ( ! secret || ! share )
return GFSEC_ERR_INVALID_CALL;
if ( secret->n_shares >= secret->max_shares ) {
size_t new_max;
void *tmp;
new_max = secret->max_shares + 10;
if ( new_max > 255 ) {
new_max = 255;
if ( secret->n_shares >= new_max )
return GFSEC_ERR_TOO_MANY_SHARES;
}
tmp = realloc(secret->shares, new_max);
if ( ! tmp )
return GFSEC_ERR_SYSTEM_ERROR;
secret->shares = tmp;
secret->max_shares = new_max;
}
if ( share->number == GFSEC_SHARE_NUMBER_AUTOASSIGN ) {
unsigned nr, u;
do {
nr = (random() & 0xFF00) >> 8;
if ( nr == 0 )
nr = 1;
for ( u = 0; u < secret->n_shares; u++ )
if ( secret->shares[u]->number == nr )
nr = 0;
} while ( nr == 0 );
share->number = nr;
}
secret->shares[secret->n_shares++] = share;
return 0;
}
int
gfsec_secret_can_combine(gfsec_secret_t *secret)
{
int ret;
unsigned u, avail_shares;
gfsec_share_t *share;
if ( ! secret )
return GFSEC_ERR_INVALID_CALL;
for ( u = 0, avail_shares = 0; u < secret->n_shares; u++ ) {
share = secret->shares[u];
if ( share->data ) {
if ( secret->len == 0 )
secret->len = share->len;
else if ( secret->len != share->len )
return GFSEC_ERR_INVALID_LENGTH;
if ( gfsec_share_is_full(share) )
secret->full_share = share;
else
avail_shares += 1;
}
}
if ( ! secret->full_share && avail_shares < secret->threshold )
return GFSEC_ERR_NOT_ENOUGH_SHARES;
secret->can_combine = 1;
return 0;
}
int
gfsec_secret_combine(gfsec_secret_t *secret)
{
gfsec_share_t *share;
unsigned u;
if ( ! secret )
return GFSEC_ERR_INVALID_CALL;
if ( ! secret->can_combine )
return GFSEC_ERR_INVALID_CALL;
if ( ! (secret->data = malloc(secret->len)) )
return GFSEC_ERR_SYSTEM_ERROR;
if ( secret->full_share )
memcpy(secret->data, secret->full_share->data, secret->len);
else {
gfshare_ctx *ctx;
unsigned char sharenrs[255];
unsigned v;
for ( u = v = 0; u < secret->n_shares; u++ ) {
share = secret->shares[u];
if ( ! gfsec_share_is_full(share) )
sharenrs[v++] = share->number;
}
if ( ! (ctx= gfshare_ctx_init_dec(sharenrs, v, secret->len)) )
return GFSEC_ERR_SYSTEM_ERROR;
for ( u = v = 0; u < secret->n_shares; u++ ) {
share = secret->shares[u];
if ( share->data && ! gfsec_share_is_full(share) )
gfshare_ctx_dec_giveshare(ctx, v++, share->data);
}
gfshare_ctx_dec_extract(ctx, secret->data);
}
return 0;
}
static int
gfsec_secret_get_partial_share_count(gfsec_secret_t *secret)
{
unsigned u, n;
for ( u = n = 0; u < secret->n_shares; u++ )
if ( gfsec_share_is_full(secret->shares[u]) )
n += 1;
return n;
}
static void
gfsec_secret_hash_shares(gfsec_secret_t *secret)
{
gcry_md_hd_t md;
gfsec_share_t *share;
unsigned u;
gcry_md_open(&md, GCRY_MD_SHA256, 0);
for ( u = 0; u < secret->n_shares; u++ ) {
share = secret->shares[u];
gcry_md_write(md, share->data, share->len);
memcpy(share->hash, gcry_md_read(md, 0), 32);
gcry_md_reset(md);
}
gcry_md_close(md);
}
int
gfsec_secret_split(gfsec_secret_t *secret, unsigned char threshold)
{
gfshare_ctx *ctx;
gfsec_share_t *share;
unsigned char sharenrs[255];
unsigned u, v, n;
if ( ! secret )
return GFSEC_ERR_INVALID_CALL;
n = gfsec_secret_get_partial_share_count(secret);
if ( threshold >= n )
return GFSEC_ERR_NOT_ENOUGH_SHARES;
for ( u = v = 0; u < secret->n_shares; u++ ) {
share = secret->shares[u];
if ( share->number != 0 )
sharenrs[v++] = share->number;
if ( ! (share->data = malloc(secret->len)) )
return GFSEC_ERR_SYSTEM_ERROR;
if ( ! (share->hash = malloc(32)) )
return GFSEC_ERR_SYSTEM_ERROR;
}
if ( ! (ctx = gfshare_ctx_init_enc(sharenrs, n, threshold, secret->len)) )
return GFSEC_ERR_SYSTEM_ERROR;
gfshare_ctx_enc_setsecret(ctx, secret->data);
for ( u = v = 0; u < secret->n_shares; u++ ) {
share = secret->shares[u];
if ( share->number != 0 )
gfshare_ctx_enc_getshare(ctx, v++, share->data);
else
memcpy(share->data, secret->data, secret->len);
}
gfshare_ctx_free(ctx);
return 0;
}
void
gfsec_secret_free(gfsec_secret_t *secret)
{
unsigned u;
if ( ! secret )
return;
if ( secret->filename )
free(secret->filename);
if ( secret->data )
free(secret->data);
for ( u = 0; u < secret->n_shares; u++ )
gfsec_share_free(secret->shares[u]);
if ( secret->shares )
free(secret->shares);
free(secret);
}

118
src/secret.h

@ -0,0 +1,118 @@
/*
* gfsecret - Secret sharing tools
* Copyright (C) 2016 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ICP20160807_SECRET_H
#define ICP20160807_SECRET_H
#define GFSEC_ERR_SYSTEM_ERROR 1
#define GFSEC_ERR_INVALID_CALL 2
#define GFSEC_ERR_NOT_ENOUGH_SHARES 3
#define GFSEC_ERR_TOO_MANY_SHARES 4
#define GFSEC_ERR_SHARE_NOT_AVAILABLE 5
#define GFSEC_ERR_INVALID_LENGTH 6
#define GFSEC_ERR_INVALID_SHARE 7
#define GFSEC_SHARE_NUMBER_FULL 0
#define GFSEC_SHARE_NUMBER_AUTOASSIGN 256
typedef enum gfsec_scheme {
GFSEC_SCHEME_FILE,
GFSEC_SCHEME_UUID,
GFSEC_SCHEME_LABEL,
GFSEC_SCHEME_MTP
} gfsec_scheme_t;
typedef struct gfsec_share {
unsigned short number;
gfsec_scheme_t scheme;
char *authority;
char *path;
size_t len;
unsigned char *data;
unsigned char *hash;
} gfsec_share_t;
#define gfsec_share_is_full(share) (share->number == 0)
typedef struct gfsec_secret {
char *filename;
unsigned char *data;
size_t len;
unsigned char n_shares;
unsigned char max_shares;
unsigned char threshold;
gfsec_share_t **shares;
gfsec_share_t *full_share;
unsigned can_combine;
} gfsec_secret_t;
#ifdef __cpluscplus
extern "C" {
#endif
gfsec_share_t *
gfsec_share_new(void);
int
gfsec_share_set_info(gfsec_share_t *,
unsigned char,
gfsec_scheme_t,
const char *,
const char *,
const unsigned char *);
int
gfsec_share_set_data(gfsec_share_t *,
unsigned char *,
size_t);
void
gfsec_share_free(gfsec_share_t *);
gfsec_secret_t *
gfsec_secret_new(void);
int
gfsec_secret_set_secret_file(gfsec_secret_t *, const char *);
int
gfsec_secret_add_share(gfsec_secret_t *, gfsec_share_t *);
int
gfsec_secret_can_combine(gfsec_secret_t *);
int
gfsec_secret_combine(gfsec_secret_t *);
int
gfsec_secret_split(gfsec_secret_t *, unsigned char);
void
gfsec_secret_free(gfsec_secret_t *);
#ifdef __cplusplus
}
#endif
#endif /* !ICP20160807_SECRET_H */

71
src/secretcfg.c

@ -205,12 +205,12 @@ parse_parameter(const char **uri, gfsec_share_t *share)
if ( strncmp(*uri, "share", eq - *uri) == 0 ) {
amp = strchrnul(++eq, '&');
if ( strncmp(eq, "no", amp - eq) == 0 )
share->flags |= GFSEC_SHARE_FLAGS_FULL;
share->number = 0;
*uri = amp;
}
else if ( strncmp(*uri, "sha256", eq - *uri) == 0 ) {
amp = strchrnul(++eq, '&');
if ( ! (share->sha256 = parse_sha256(eq, amp - eq)) )
if ( ! (share->hash = parse_sha256(eq, amp - eq)) )
rc = -1;
*uri = amp;
}
@ -260,36 +260,27 @@ get_share_number_from_path(const char *path)
* is set to EBADMSG).
*/
static int
parse_uri(const char *uri, gfsec_secret_config_t *cfg)
parse_uri(const char *uri, gfsec_secret_t *secret)
{
gfsec_share_t *share;
const char *p = uri;
if ( ! uri || ! cfg ) {
if ( ! uri || ! secret ) {
errno = EINVAL;
return -1;
}
if ( ! (share = malloc(sizeof(*share))) )
if ( ! (share = gfsec_share_new()) )
return -1;
share->next = NULL;
share->authority = NULL;
share->path = NULL;
share->share_nr = 0;
share->flags = GFSEC_SHARE_FLAGS_NONE;
share->length = 0;
share->data = NULL;
share->sha256 = NULL;
if ( strncmp(p, "file://", 7) == 0 && (p += 7) )
share->scheme = SCHEME_FILE;
share->scheme = GFSEC_SCHEME_FILE;
else if ( strncmp(p, "uuid://", 7) == 0 && (p += 7) )
share->scheme = SCHEME_UUID;
share->scheme = GFSEC_SCHEME_UUID;
else if ( strncmp(p, "label://", 8) == 0 && (p += 8) )
share->scheme = SCHEME_LABEL;
share->scheme = GFSEC_SCHEME_LABEL;
else if ( strncmp(p, "mtp://", 6) == 0 && (p += 6) )
share->scheme = SCHEME_MTP;
share->scheme = GFSEC_SCHEME_MTP;
else {
errno = EBADMSG;
goto bad_uri;
@ -306,28 +297,19 @@ parse_uri(const char *uri, gfsec_secret_config_t *cfg)
goto bad_uri;
}
if ( (share->flags & GFSEC_SHARE_FLAGS_FULL) == 0 ) {
if ( (share->share_nr = get_share_number_from_path(share->path)) == 0 ) {
if ( ! gfsec_share_is_full(share) ) {
if ( (share->number = get_share_number_from_path(share->path)) == 0 ) {
errno = EBADMSG;
goto bad_uri;
}
}
if ( cfg->shares ) {
gfsec_share_t *cursor = cfg->shares;
while ( cursor->next )
cursor = cursor->next;
cursor->next = share;
}
else
cfg->shares = share;
cfg->n_shares += 1;
gfsec_secret_add_share(secret, share);
return 0;
bad_uri:
gfsec_destroy_share(share, 0);
gfsec_share_free(share);
return -1;
}
@ -339,12 +321,12 @@ bad_uri:
* an error occured. If the configuration file contains an
* error, errno is set to EBADMSG.
*/
gfsec_secret_config_t *
gfsec_secret_t *
gfsec_read_config(const char *filename)
{
FILE *f;
char buffer[MAX_LINE_LENGTH];
gfsec_secret_config_t *cfg;
gfsec_secret_t *cfg;
int rc;
if ( ! filename ) {
@ -354,13 +336,11 @@ gfsec_read_config(const char *filename)
if ( ! (f = fopen(filename, "r")) )
return NULL;
if ( ! (cfg = malloc(sizeof(*cfg))) ) {
if ( ! (cfg = gfsec_secret_new()) ) {
fclose(f);
return NULL;
}
cfg->output_file = NULL;
cfg->shares = NULL;
cfg->threshold = 2;
rc = 0;
@ -375,7 +355,7 @@ gfsec_read_config(const char *filename)
else if ( n == 0 || buffer[0] == '#' )
; /* Comment or empty line */
else if ( strncmp("OUTFILE=", buffer, 8) == 0 ) {
if ( ! (cfg->output_file = strdup(buffer + 8)) )
if ( ! (cfg->filename = strdup(buffer + 8)) )
rc = -1;
}
else if ( strncmp("MINSHARES=", buffer, 10) == 0 ) {
@ -397,24 +377,9 @@ gfsec_read_config(const char *filename)
fclose(f);
if ( rc == -1 ) {
gfsec_destroy_config(cfg);
gfsec_secret_free(cfg);
cfg = NULL;
}
return cfg;
}
/**
* Frees the specified configuration object.
*/
void
gfsec_destroy_config(gfsec_secret_config_t *cfg)
{
if ( cfg ) {
if ( cfg->output_file )
free(cfg->output_file);
gfsec_destroy_share(cfg->shares, 1);
free(cfg);
}
}

14
src/secretcfg.h

@ -19,25 +19,15 @@
#ifndef ICP20160206_SECRETCFG_H
#define ICP20160206_SECRETCFG_H
#include "share.h"
typedef struct gfsec_secret_config {
char *output_file;
gfsec_share_t *shares;
unsigned char n_shares;
unsigned char threshold;
} gfsec_secret_config_t;
#include "secret.h"
#ifdef __cpluscplus
extern "C" {
#endif
gfsec_secret_config_t *
gfsec_secret_t *
gfsec_read_config(const char *);
void
gfsec_destroy_config(gfsec_secret_config_t *);
#ifdef __cplusplus
}
#endif

60
src/share.c

@ -1,60 +0,0 @@
/*
* gfsec - Secret sharing tools
* Copyright (C) 2016 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "share.h"
#include <string.h>
/**
* Frees the specified share object.
*
* @param share The share object to destroy.
* @param linked If non-zero, also free all linked share objects.
*/
void
gfsec_destroy_share(gfsec_share_t *share, int linked)
{
while ( share ) {
if ( share->authority )
free(share->authority);
if ( share->path )
free(share->path);
if ( share->data ) {
memset(share->data, 0, share->length);
free(share->data);
}
if ( share->sha256 )
free(share->sha256);
if ( linked ) {
gfsec_share_t *tmp = share->next;
free(share);
share = tmp;
}
else {
free(share);
share = NULL;
}
}
}

57
src/share.h

@ -1,57 +0,0 @@
/*
* gfsec - Secret sharing tools
* Copyright (C) 2016 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ICP20160206_SHARE_H
#define ICP20160206_SHARE_H
#include <stdlib.h>
#define GFSEC_SHARE_FLAGS_NONE 0x00
#define GFSEC_SHARE_FLAGS_FULL 0x01
typedef enum gfsec_scheme {
SCHEME_FILE = 0,
SCHEME_UUID,
SCHEME_LABEL,
SCHEME_MTP
} gfsec_scheme_t;
typedef struct gfsec_share {
struct gfsec_share *next;
gfsec_scheme_t scheme;
char *authority;
char *path;
unsigned char share_nr;
unsigned flags;
size_t length;
unsigned char *data;
unsigned char *sha256;
} gfsec_share_t;
#ifdef __cpluscplus
extern "C" {
#endif
void
gfsec_destroy_share(gfsec_share_t *, int);
#ifdef __cplusplus
}
#endif
#endif /* !ICP20160206_SHARE_H */
Loading…
Cancel
Save