Browse Source

Simplify error handling in the secret module

Abort on memory allocation errors and use assert() to check
pointers passed to any function.
master
Damien Goutte-Gattat 5 years ago
parent
commit
0a3743c872
  1. 153
      src/secret.c
  2. 2
      src/secret.h

153
src/secret.c

@ -25,10 +25,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <gcrypt.h>
#include <libgfshare.h>
#include <xmem.h>
#include "util.h"
/** @file secret.c
@ -108,24 +111,23 @@ gfsec_fill_rand(unsigned char *buffer, unsigned int len)
/**
* Initializes a new share object.
*
* @return The share object, or NULL if memory could not be allocated.
* @return The share object.
*/
gfsec_share_t *
gfsec_share_new(void)
{
gfsec_share_t *s = NULL;
gfsec_share_t *s;
if ( (s = malloc(sizeof(gfsec_share_t))) ) {
s->number = GFSEC_SHARE_NUMBER_AUTOASSIGN;
s = xmalloc(sizeof(gfsec_share_t));
s->number = GFSEC_SHARE_NUMBER_AUTOASSIGN;
s->scheme = GFSEC_SCHEME_FILE;
s->authority = NULL;
s->path = NULL;
s->scheme = GFSEC_SCHEME_FILE;
s->authority = NULL;
s->path = NULL;
s->len = 0;
s->data = NULL;
s->hash = NULL;
}
s->len = 0;
s->data = NULL;
s->hash = NULL;
return s;
}
@ -147,10 +149,8 @@ gfsec_share_new(void)
* @param path The path part of the URI (may be NULL);
* @param hash A buffer containing a SHA-256 hash of the
* share's data (may be NULL).
*
* @return 0 if successful, or one of the GFSEC_ERR_* error codes.
*/
int
void
gfsec_share_set_info(gfsec_share_t *share,
unsigned char number,
gfsec_scheme_t scheme,
@ -158,21 +158,18 @@ gfsec_share_set_info(gfsec_share_t *share,
const char *path,
const unsigned char *hash)
{
if ( ! share )
return GFSEC_ERR_INVALID_CALL;
assert(share != NULL);
share->number = number;
share->scheme = scheme;
if ( authority && ! (share->authority = strdup(authority)) )
return GFSEC_ERR_SYSTEM_ERROR;
if ( path && ! (share->path = strdup(path)) )
return GFSEC_ERR_SYSTEM_ERROR;
if ( authority )
share->authority = xstrdup(authority);
if ( path )
share->path = xstrdup(path);
if ( hash )
memcpy(share->hash, hash, 32);
return 0;
}
/**
@ -187,7 +184,8 @@ gfsec_share_set_info(gfsec_share_t *share,
* freed when the gfsec_share_free function is called;
* @param len The size of the data buffer.
*
* @return 0 if successfull, or one of the GFSEC_ERR_* error codes.
* @return 0 if successfull, or GFSEC_ERR_INVALID_SHARE is the
* data does not match the share's expected hash.
*/
int
gfsec_share_set_data(gfsec_share_t *share,
@ -196,8 +194,8 @@ gfsec_share_set_data(gfsec_share_t *share,
{
int ret;
if ( ! share || ! data )
return GFSEC_ERR_INVALID_CALL;
assert(share != NULL);
assert(data != NULL);
share->data = data;
share->len = len;
@ -224,8 +222,7 @@ gfsec_share_set_data(gfsec_share_t *share,
* @param buffer The buffer to write the URI into.
* @param len The size of the buffer.
*
* @return The number of characters written into the buffer,
* or GFSEC_ERR_INVALID_CALL if an invalid poitner was passed.
* @return The number of characters written into the buffer.
*/
int
gfsec_share_get_uri(gfsec_share_t *share,
@ -235,8 +232,8 @@ gfsec_share_get_uri(gfsec_share_t *share,
static char *schemes[] = { "file://", "uuid://", "label://", "mtp://" };
int ret;
if ( ! share || ! buffer )
return GFSEC_ERR_INVALID_CALL;
assert(share != NULL);
assert(buffer != NULL);
ret = snprintf(buffer, len, "%s%s%s",
schemes[share->scheme],
@ -254,8 +251,7 @@ gfsec_share_get_uri(gfsec_share_t *share,
void
gfsec_share_free(gfsec_share_t *share)
{
if ( ! share )
return;
assert(share != NULL);
if ( share->authority )
free(share->authority);
@ -273,28 +269,27 @@ gfsec_share_free(gfsec_share_t *share)
/**
* Initializes a new secret object.
*
* @return The secret object, or NULL if memory could not be allocated.
* @return The secret object.
*/
gfsec_secret_t *
gfsec_secret_new(void)
{
gfsec_secret_t *s = NULL;
gfsec_secret_t *s;
if ( (s = malloc(sizeof(*s))) ) {
s->filename = NULL;
s = xmalloc(sizeof(*s));
s->filename = NULL;
s->data = NULL;
s->len = 0;
s->data = NULL;
s->len = 0;
s->n_shares = 0;
s->max_shares = 0;
s->threshold = 0;
s->n_shares = 0;
s->max_shares = 0;
s->threshold = 0;
s->shares = NULL;
s->full_share = NULL;
s->shares = NULL;
s->full_share = NULL;
s->can_combine = 0;
}
s->can_combine = 0;
return s;
}
@ -305,17 +300,17 @@ gfsec_secret_new(void)
* @param secret The secret object.
* @param filename The location of the file to read the secret from.
*
* @return 0 if successful, or one of the GFSEC_ERR_* error codes.
* @return 0 if successful, or one of the GFSEC_ERR_SYSTEM_ERROR if
* an I/O error occured.
*/
int
gfsec_secret_set_secret_file(gfsec_secret_t *secret,
const char *filename)
{
if ( ! secret || ! filename )
return GFSEC_ERR_INVALID_CALL;
assert(secret != NULL);
assert(filename != NULL);
if ( ! (secret->filename = strdup(filename)) )
return GFSEC_ERR_SYSTEM_ERROR;
secret->filename = xstrdup(filename);
if ( ! (secret->data = read_file(filename, &(secret->len),
GFSEC_SECRET_MAX_SIZE)) )
@ -330,22 +325,17 @@ gfsec_secret_set_secret_file(gfsec_secret_t *secret,
* @param secret The secret object.
* @param share The share to add.
*
* @return
* - 0 if successful;
* - GFSEC_ERR_INVALID_CALL if improperly called;
* - GFSEC_ERR_TOO_MANY_SHARES if the secret object already has the
* maximal number of shares allowed;
* - GFSEC_ERR_SYSTEM_ERROR if a memory allocation error occurs.
* @return 0 if successful, or GFSEC_ERR_TOO_MANY_SHARES if the
* secret object already has the maximal number of shares allowed.
*/
int
gfsec_secret_add_share(gfsec_secret_t *secret, gfsec_share_t *share)
{
if ( ! secret || ! share )
return GFSEC_ERR_INVALID_CALL;
assert(secret != NULL);
assert(share != NULL);
if ( secret->n_shares >= secret->max_shares ) {
size_t new_max;
void *tmp;
new_max = secret->max_shares + 10;
if ( new_max > 255 ) {
@ -354,11 +344,7 @@ gfsec_secret_add_share(gfsec_secret_t *secret, gfsec_share_t *share)
return GFSEC_ERR_TOO_MANY_SHARES;
}
tmp = realloc(secret->shares, new_max * sizeof(gfsec_share_t *));
if ( ! tmp )
return GFSEC_ERR_SYSTEM_ERROR;
secret->shares = tmp;
secret->shares = xrealloc(secret->shares, new_max * sizeof(gfsec_share_t *));
secret->max_shares = new_max;
}
@ -378,9 +364,7 @@ gfsec_secret_add_share(gfsec_secret_t *secret, gfsec_share_t *share)
share->number = nr;
if ( asprintf(&tmp, "%s.%03d", share->path, nr) == -1 )
return GFSEC_ERR_SYSTEM_ERROR;
xasprintf(&tmp, "%s.%03d", share->path, nr);
free(share->path);
share->path = tmp;
}
@ -399,7 +383,6 @@ gfsec_secret_add_share(gfsec_secret_t *secret, gfsec_share_t *share)
*
* @return
* - 0 if the secret can be reconstituted;
* - GFSEC_ERR_INVALID_CALL if improperly called (secret is NULL);
* - GFSEC_ERR_INVALID_LENGTH if not all shares have the same length;
* - GFSEC_ERR_NOT_ENOUGH_SHARES if not enough shares are available.
*/
@ -409,8 +392,7 @@ gfsec_secret_can_combine(gfsec_secret_t *secret)
unsigned u, avail_shares;
gfsec_share_t *share;
if ( ! secret )
return GFSEC_ERR_INVALID_CALL;
assert(secret != NULL);
for ( u = 0, avail_shares = 0; u < secret->n_shares; u++ ) {
share = secret->shares[u];
@ -445,11 +427,11 @@ gfsec_secret_can_combine(gfsec_secret_t *secret)
*
* @return
* - 0 if successful;
* - GFSEC_ERR_INVALID_CALL if called improperly (secret is NULL,
* or gfsec_secret_can_recombine has not been called previously,
* - GFSEC_ERR_INVALID_CALL if called improperly (either
* gfsec_secret_can_recombine has not been called previously,
* or it has been called but has found the secret could not be
* reconstituted);
* - GFSEC_ERR_SYSTEM_ERROR if a memory allocation error occurs.
* - GFSEC_ERR_SYSTEM_ERROR if an error occured in Libgfshare.
*/
int
gfsec_secret_combine(gfsec_secret_t *secret)
@ -457,14 +439,12 @@ gfsec_secret_combine(gfsec_secret_t *secret)
gfsec_share_t *share;
unsigned u;
if ( ! secret )
return GFSEC_ERR_INVALID_CALL;
assert(secret != NULL);
if ( ! secret->can_combine )
return GFSEC_ERR_INVALID_CALL;
if ( ! (secret->data = malloc(secret->len)) )
return GFSEC_ERR_SYSTEM_ERROR;
secret->data = xmalloc(secret->len);
if ( gfshare_fill_rand == NULL )
gfshare_fill_rand = gfsec_fill_rand;
@ -522,10 +502,10 @@ gfsec_secret_get_partial_share_count(gfsec_secret_t *secret)
*
* @return
* - 0 if successful;
* - GFSEC_ERR_INVALID_CALL if called improperly;
* - GFSEC_ERR_NOT_ENOUGH_SHARES if the secret object does not define
* enough shares to satisfy the desired threshold;
* - GFSEC_ERR_SYSTEM_ERROR if a memory allocation error occurs.
* - GFSEC_ERR_SYSTEM_ERROR if an error occured in Libgfshare or
* Libgcrypt.
*/
int
gfsec_secret_split(gfsec_secret_t *secret, unsigned char threshold)
@ -537,8 +517,7 @@ gfsec_secret_split(gfsec_secret_t *secret, unsigned char threshold)
unsigned u, v, n;
int rc;
if ( ! secret )
return GFSEC_ERR_INVALID_CALL;
assert(secret != NULL);
n = gfsec_secret_get_partial_share_count(secret);
if ( threshold >= n )
@ -549,22 +528,19 @@ gfsec_secret_split(gfsec_secret_t *secret, unsigned char threshold)
if ( gfshare_fill_rand == NULL )
gfshare_fill_rand = gfsec_fill_rand;
for ( u = v = rc = 0; u < secret->n_shares && rc == 0; u++ ) {
for ( u = v = rc = 0; u < secret->n_shares; u++ ) {
share = secret->shares[u];
if ( ! gfsec_share_is_full(share) )
sharenrs[v++] = share->number;
if ( ! (share->data = malloc(secret->len)) )
rc = GFSEC_ERR_SYSTEM_ERROR;
if ( ! (share->hash = malloc(32)) )
rc = GFSEC_ERR_SYSTEM_ERROR;
share->data = xmalloc(secret->len);
share->hash = xmalloc(32);
share->len = secret->len;
}
if ( rc == 0 && ! (ctx = gfshare_ctx_init_enc(sharenrs, n, threshold,
secret->len)) )
if ( ! (ctx = gfshare_ctx_init_enc(sharenrs, n, threshold, secret->len)) )
rc = GFSEC_ERR_SYSTEM_ERROR;
if ( rc == 0 && gcry_md_open(&md, GCRY_MD_SHA256, 0) != 0 )
@ -619,8 +595,7 @@ gfsec_secret_free(gfsec_secret_t *secret)
{
unsigned u;
if ( ! secret )
return;
assert(secret != NULL);
if ( secret->filename )
free(secret->filename);

2
src/secret.h

@ -96,7 +96,7 @@ extern "C" {
gfsec_share_t *
gfsec_share_new(void);
int
void
gfsec_share_set_info(gfsec_share_t *,
unsigned char,
gfsec_scheme_t,

Loading…
Cancel
Save