Skip to content

Commit

Permalink
Introduce buffer_write_file()
Browse files Browse the repository at this point in the history
Rewrite buf_write_string_file to buffer_write_file, which is simpler to
use and can deal with not-null-terminated strings.  Mostly implemented so
this can be easily reused for tls-crypt-v2 (client) key files.

Signed-off-by: Steffan Karger <steffan.karger@fox-it.com>
Acked-by: Antonio Quartulli <antonio@openvpn.net>
Tested-by: Antonio Quartulli <antonio@openvpn.net>
Message-Id: <1533542553-7383-1-git-send-email-steffan.karger@fox-it.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg17371.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
  • Loading branch information
syzzer authored and cron2 committed Aug 8, 2018
1 parent 7a81090 commit a8fa167
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 38 deletions.
31 changes: 24 additions & 7 deletions src/openvpn/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -343,16 +343,33 @@ convert_to_one_line(struct buffer *buf)
}
}

/* NOTE: requires that string be null terminated */
void
buf_write_string_file(const struct buffer *buf, const char *filename, int fd)
bool
buffer_write_file(const char *filename, const struct buffer *buf)
{
const int len = strlen((char *) BPTR(buf));
const int size = write(fd, BPTR(buf), len);
if (size != len)
bool ret = false;
int fd = platform_open(filename, O_CREAT | O_TRUNC | O_WRONLY,
S_IRUSR | S_IWUSR);
if (fd == -1)
{
msg(M_ERRNO, "Cannot open file '%s' for write", filename);
return false;
}

const int size = write(fd, BPTR(buf), BLEN(buf));
if (size != BLEN(buf))
{
msg(M_ERR, "Write error on file '%s'", filename);
msg(M_ERRNO, "Write error on file '%s'", filename);
goto cleanup;
}

ret = true;
cleanup:
if (close(fd) < 0)
{
msg(M_ERRNO, "Close error on file %s", filename);
ret = false;
}
return ret;
}

/*
Expand Down
12 changes: 8 additions & 4 deletions src/openvpn/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -469,11 +469,15 @@ const char *skip_leading_whitespace(const char *str);

void string_null_terminate(char *str, int len, int capacity);

/*
* Write string in buf to file descriptor fd.
* NOTE: requires that string be null terminated.
/**
* Write buffer contents to file.
*
* @param filename The filename to write the buffer to.
* @param buf The buffer to write to the file.
*
* @return true on success, false otherwise.
*/
void buf_write_string_file(const struct buffer *buf, const char *filename, int fd);
bool buffer_write_file(const char *filename, const struct buffer *buf);

/*
* write a string to the end of a buffer that was
Expand Down
33 changes: 6 additions & 27 deletions src/openvpn/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -1418,36 +1418,24 @@ read_key_file(struct key2 *key2, const char *file, const unsigned int flags)
gc_free(&gc);
}

/*
* Write key to file, return number of random bits
* written.
*/
int
write_key_file(const int nkeys, const char *filename)
{
struct gc_arena gc = gc_new();

int fd, i;
int nbits = 0;
int nbits = nkeys * sizeof(struct key) * 8;

/* must be large enough to hold full key file */
struct buffer out = alloc_buf_gc(2048, &gc);
struct buffer nbits_head_text = alloc_buf_gc(128, &gc);

/* how to format the ascii file representation of key */
const int bytes_per_line = 16;

/* open key file */
fd = platform_open(filename, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR);

if (fd == -1)
{
msg(M_ERR, "Cannot open shared secret file '%s' for write", filename);
}

/* write header */
buf_printf(&out, "#\n# %d bit OpenVPN static key\n#\n", nbits);
buf_printf(&out, "%s\n", static_key_head);

for (i = 0; i < nkeys; ++i)
for (int i = 0; i < nkeys; ++i)
{
struct key key;
char *fmt;
Expand All @@ -1463,9 +1451,6 @@ write_key_file(const int nkeys, const char *filename)
"\n",
&gc);

/* increment random bits counter */
nbits += sizeof(key) * 8;

/* write to holding buffer */
buf_printf(&out, "%s\n", fmt);

Expand All @@ -1476,16 +1461,10 @@ write_key_file(const int nkeys, const char *filename)

buf_printf(&out, "%s\n", static_key_foot);

/* write number of bits */
buf_printf(&nbits_head_text, "#\n# %d bit OpenVPN static key\n#\n", nbits);
buf_write_string_file(&nbits_head_text, filename, fd);

/* write key file, now formatted in out, to file */
buf_write_string_file(&out, filename, fd);

if (close(fd))
if(!buffer_write_file(filename, &out))
{
msg(M_ERR, "Close error on shared secret file %s", filename);
nbits = -1;
}

/* zero memory which held file content (memory will be freed by GC) */
Expand Down
5 changes: 5 additions & 0 deletions src/openvpn/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,11 @@ struct crypto_options
#define RKF_INLINE (1<<1)
void read_key_file(struct key2 *key2, const char *file, const unsigned int flags);

/**
* Write nkeys 1024-bits keys to file.
*
* @returns number of random bits written, or -1 on failure.
*/
int write_key_file(const int nkeys, const char *filename);

int read_passphrase_hash(const char *passphrase_file,
Expand Down
4 changes: 4 additions & 0 deletions src/openvpn/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -1041,6 +1041,10 @@ do_genkey(const struct options *options)
}

nbits_written = write_key_file(2, options->shared_secret_file);
if (nbits_written < 0)
{
msg(M_FATAL, "Failed to write key file");
}

msg(D_GENKEY | M_NOPREFIX,
"Randomly generated %d bit key written to %s", nbits_written,
Expand Down

0 comments on commit a8fa167

Please sign in to comment.