mirror of
https://codeberg.org/scip/pcp.git
synced 2025-12-18 12:20:58 +01:00
started documenting the api.
This commit is contained in:
@@ -19,18 +19,6 @@
|
||||
You can contact me by mail: <tom AT vondein DOT org>.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Flexible buffer management, idea from openssh/buffer.c.
|
||||
This allows us to dissect buffers into parts at will
|
||||
whithout the hassle of boundary checking in each and every
|
||||
line. Therefore it is more secure, since this system wraps
|
||||
all this stuff from us, so in case we're attemt to overflow
|
||||
a buffer or the like, the buffer functions will catch this,
|
||||
warn us and die.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef HAVE_PCP_BUFFER_H
|
||||
#define HAVE_PCP_BUFFER_H
|
||||
|
||||
@@ -40,116 +28,551 @@
|
||||
#include "util.h"
|
||||
#include "defines.h"
|
||||
|
||||
/**
|
||||
* \defgroup Buffer Buffer, a flexible buffer management class.
|
||||
* @{
|
||||
|
||||
Flexible buffer management, idea from openssh/buffer.c.
|
||||
|
||||
This class allows us to dissect buffers into parts at will
|
||||
whithout the hassle of boundary checking in each and every
|
||||
line. Therefore it is more secure, since this system wraps
|
||||
all this stuff from us, so in case we're attemt to overflow
|
||||
a buffer or the like, the buffer functions will catch this,
|
||||
warn us and die.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/** \struct _pcp_buffer
|
||||
A flexible buffer object wich automatically resizes, if neccessary.
|
||||
*/
|
||||
struct _pcp_buffer {
|
||||
char *name; /* just for convenience in error messages and the
|
||||
like, so we know which buffer cause trouble */
|
||||
uint8_t allocated;
|
||||
size_t blocksize;
|
||||
size_t size;
|
||||
size_t offset; /* read position */
|
||||
size_t end; /* write position, data end */
|
||||
uint8_t isstring; /* treat as char array */
|
||||
void *buf;
|
||||
char *name; /**< just for convenience in error messages and the like, so we know which buffer cause trouble */
|
||||
uint8_t allocated; /**< marks the buffer as allocated */
|
||||
size_t blocksize; /**< the blocksize to use when resizing, also used for initial malloc() */
|
||||
size_t size; /**< stores the current allocated size of the object */
|
||||
size_t offset; /**< current read position */
|
||||
size_t end; /**< current write position, data end. maybe less than size. */
|
||||
uint8_t isstring; /**< treat as char array/string */
|
||||
void *buf; /**< the actual storage buffer */
|
||||
};
|
||||
|
||||
/** The name used everywhere */
|
||||
typedef struct _pcp_buffer Buffer;
|
||||
|
||||
/* create a new buffer, initially alloc'd to blocksize and zero-filled */
|
||||
/** Create a new buffer.
|
||||
|
||||
Create a new buffer, initially alloc'd to blocksize and zero-filled.
|
||||
|
||||
\param[in] blocksize Initial blocksize. The smaller the more often
|
||||
the buffer will be resized. Choose with care.
|
||||
|
||||
\param[in] name A name for the Buffer. Just used for debugging purposes or in error messages.
|
||||
|
||||
\return Returns a new Buffer object.
|
||||
*/
|
||||
Buffer *buffer_new(size_t blocksize, char *name);
|
||||
|
||||
/* same, but enable isstring */
|
||||
/** Create a new buffer.
|
||||
|
||||
Create a new buffer, initially alloc'd to a blocksize of 32 bytes and zero-filled.
|
||||
The buffer will be a string buffer. See buffer_get_str().
|
||||
|
||||
\param[in] name A name for the Buffer. Just used for debugging purposes or in error messages.
|
||||
|
||||
\return Returns a new Buffer object.
|
||||
*/
|
||||
Buffer *buffer_new_str(char *name);
|
||||
|
||||
/* initialize buffer vars */
|
||||
void buffer_init(Buffer *b, size_t blocksize, char *name);
|
||||
|
||||
/* zero the buffer and free it, if allocated */
|
||||
/** Clears and frees the Buffer.
|
||||
|
||||
This clears the buffer by filling it with zeroes and frees any
|
||||
allocated memory, including the Buffer object itself. Use this
|
||||
function instead of directly calling free(Buffer).
|
||||
|
||||
\param[in] b The Buffer object.
|
||||
*/
|
||||
void buffer_free(Buffer *b);
|
||||
|
||||
/* zero the buffer, reset counters, always called from buffer_free() */
|
||||
/** Clears the Buffer.
|
||||
|
||||
This clears the buffer by filling it with zeroes and resetting
|
||||
all counters. Memory will not be free'd. Called from buffer_free()
|
||||
before free'ing memory.
|
||||
|
||||
\param[in] b The Buffer object.
|
||||
*/
|
||||
void buffer_clear(Buffer *b);
|
||||
|
||||
/* put read offset to start */
|
||||
/** Put read offset back to start.
|
||||
|
||||
This function sets the read offset counter back to 0 (start
|
||||
of the buffer).
|
||||
|
||||
\param[in] b The Buffer object.
|
||||
*/
|
||||
void buffer_rewind(Buffer *b);
|
||||
|
||||
/* add data to the buffer, memorize end position */
|
||||
/** Add data to the buffer.
|
||||
|
||||
Adds data of the size len to the buffer and resizes the
|
||||
buffer, if neccessary. The write position ('end' field)
|
||||
will be updated accordingly.
|
||||
|
||||
Data will be copied, you can free() the given pointer after copying..
|
||||
|
||||
\param[in] b The Buffer object.
|
||||
|
||||
\param[out] data Arbitrary data to add to the Buffer.
|
||||
|
||||
\param[in] len The size of the data to add in Bytes.
|
||||
*/
|
||||
void buffer_add(Buffer *b, const void *data, size_t len);
|
||||
|
||||
/* the same but use another buffer as source */
|
||||
/** Add data to the buffer.
|
||||
|
||||
Adds data from the given Buffer src to the buffer and resizes the
|
||||
buffer, if neccessary. The write position ('end' field)
|
||||
will be updated accordingly.
|
||||
|
||||
Data will be copied, you can buffer_free() the given src Buffer after the copying.
|
||||
|
||||
\param[out] dst The destination Buffer object to copy data into.
|
||||
|
||||
\param[in] src The source Buffer object to copy data from.
|
||||
*/
|
||||
void buffer_add_buf(Buffer *dst, Buffer *src);
|
||||
|
||||
/* add a string, support printf style */
|
||||
/** Add a formated string to the buffer.
|
||||
|
||||
Use printf() like syntax to add a formatted string
|
||||
to the buffer. Refer to the documentation of printf() for
|
||||
details.
|
||||
|
||||
Data will be copied, you can free() the given format string and params after copying.
|
||||
|
||||
Example:
|
||||
@code
|
||||
Buffer *x = buffer_new_str("test");
|
||||
buffer_add_str(x, "There are %d elements left in %s\n", 4, "list");
|
||||
@endcode
|
||||
|
||||
\param[in] b The Buffer object.
|
||||
|
||||
\param[in] fmt The printf() compatible format description.
|
||||
|
||||
\param[in] ... A variable number of arguments for the format string.
|
||||
*/
|
||||
void buffer_add_str(Buffer *b, const char * fmt, ...);
|
||||
|
||||
/* add some binary data to the buffer, but as hex string */
|
||||
/** Add data as hex string to the buffer.
|
||||
|
||||
Adds data of the size len to the buffer and resizes the
|
||||
buffer, if neccessary. The write position ('end' field)
|
||||
will be updated accordingly. Each byte will be put in its
|
||||
HEX form into the buffer (%02x).
|
||||
|
||||
Data will be copied, you can free() the given pointer after copying..
|
||||
|
||||
\param[in] b The Buffer object.
|
||||
|
||||
\param[in] data Arbitrary data to add as hex into the Buffer.
|
||||
|
||||
\param[in] len The size of the data to add in Bytes.
|
||||
*/
|
||||
void buffer_add_hex(Buffer *b, void *data, size_t len);
|
||||
|
||||
/* resize the buffer if necessary */
|
||||
/* resize the buffer if necessary, used internally only */
|
||||
void buffer_resize(Buffer *b, size_t len);
|
||||
|
||||
/* return true if there are no more bytes to read */
|
||||
/** Tell if there are no more bytes to read.
|
||||
|
||||
This functions tells if the EOF of the buffer is reached
|
||||
during read operations (no more data to read left).
|
||||
|
||||
\param[in] b The Buffer object.
|
||||
|
||||
\return Returns 1 of EOF has been reached or 0 if there are more data left to read.
|
||||
*/
|
||||
int buffer_done(Buffer *b);
|
||||
|
||||
/* get some chunk of data from the buffer, starting from offset til len */
|
||||
/** Read some chunk of data from the Buffer.
|
||||
|
||||
Read some chunk of data from the Buffer, starting from current read
|
||||
offset til len.
|
||||
|
||||
Example: suppose you've got a buffer with the following content:
|
||||
|
||||
@code
|
||||
AAAABBBBCCCC
|
||||
@endcode
|
||||
|
||||
Then the following code would:
|
||||
|
||||
@code
|
||||
unsigned char g[4];
|
||||
buffer_get_chunk(b, g, 4); // => g now contains 'AAAA'
|
||||
buffer_get_chunk(b, g, 4); // => g now contains 'BBBB'
|
||||
buffer_get_chunk(b, g, 4); // => g now contains 'CCCC'
|
||||
@endcode
|
||||
|
||||
In order to catch buffer overflow, check the return value, which will
|
||||
be 0 in case of errors. See also: fatals_ifany(), buffer_done() and buffer_left().
|
||||
|
||||
\param[in] b The Buffer object to read from.
|
||||
|
||||
\param[out] buf The destination pointer where the data will be copied to. This pointer
|
||||
must be allocated by the caller properly and it must have at least a size of len.
|
||||
|
||||
\param[in] len The number of bytes to read from the Buffer.
|
||||
|
||||
*/
|
||||
size_t buffer_get_chunk(Buffer *b, void *buf, size_t len);
|
||||
|
||||
/* return the whole buffer contents */
|
||||
/** Read the whole Buffer content.
|
||||
|
||||
This function returns the whole buffer contents as a pointer
|
||||
to the internal data member (Buffer->buf). The returned pointer
|
||||
is allocated and filled with data up to buffer_size(Buffer),
|
||||
however, the allocated memory might be more than size, in fact
|
||||
it will be a multitude of Buffer-blocksize.
|
||||
|
||||
Don't free() the pointer directly, use buffer_free() always.
|
||||
|
||||
\param[in] b The Buffer object to read from.
|
||||
|
||||
\return Pointer to the buffer data storage.
|
||||
*/
|
||||
unsigned char *buffer_get(Buffer *b);
|
||||
|
||||
/* access the buffer content as string (char *) the returned pointer
|
||||
points to b->buf and should not be free'd directly*/
|
||||
/** Read the whole Buffer content as string.
|
||||
|
||||
Access the Buffer content as string (char *).
|
||||
|
||||
The returned pointer
|
||||
is allocated and filled with data up to buffer_size(Buffer),
|
||||
however, the allocated memory might be more than size, in fact
|
||||
it will be a multitude of Buffer-blocksize.
|
||||
|
||||
The byte after buffer_size(Buffer) will be a \0.
|
||||
|
||||
Don't free() the pointer directly, use buffer_free() always.
|
||||
|
||||
Sample usage:
|
||||
|
||||
@code
|
||||
[..]
|
||||
fprintf(stdout, "Our buffer content: %s\n", buffer_get_str(b));
|
||||
@endcode
|
||||
|
||||
\param[in] b The Buffer object to read from.
|
||||
|
||||
\return Pointer to the buffer data storage.
|
||||
*/
|
||||
char *buffer_get_str(Buffer *b);
|
||||
|
||||
/* fetch whatever is left in the buffer */
|
||||
/** Read the remaining data after current read offset.
|
||||
|
||||
Fetch whatever is left in the buffer. This works like
|
||||
buffer_get() but instead doesn't return everything,
|
||||
but only the part of the buffer, which follows after
|
||||
the current read offset.
|
||||
|
||||
The returned pointer will be allocated by buffer_get_remainder()
|
||||
with a size of buffer_left(). It's up to the caller to free()
|
||||
the returned pointer later on.
|
||||
|
||||
Example: suppose you've got a buffer with the following content:
|
||||
|
||||
@code
|
||||
AAAABBBBCCCC
|
||||
@endcode
|
||||
|
||||
Then:
|
||||
|
||||
@code
|
||||
[..]
|
||||
unsigned char g[4];
|
||||
unsigned char *r = NULL;
|
||||
buffer_get_chunk(b, g, 4); // => g now contains 'AAAA'
|
||||
size_t rs = buffer_left(b); // => rs = 8
|
||||
r = buffer_get_remainder(b); // => r now contains 'BBBBCCCC' and has a size of 8
|
||||
memset(r, 0, rs); // zerofill r
|
||||
free(r); // done with it
|
||||
@endcode
|
||||
|
||||
\param[in] b The Buffer object to read from.
|
||||
|
||||
\return Pointer to the remaining chunk of data (copy).
|
||||
*/
|
||||
unsigned char *buffer_get_remainder(Buffer *b);
|
||||
|
||||
/* same as buffer_get() but fetch some data chunk from somewhere
|
||||
in the middle of the buffer */
|
||||
/** Read some data inside the Buffer.
|
||||
|
||||
Same as buffer_get() but fetch some data chunk from somewhere
|
||||
in the middle of the buffer.
|
||||
|
||||
The returned pointer has to be allocated by the caller to
|
||||
at least a size of len bytes.
|
||||
|
||||
The read offset will be left untouched by this function.
|
||||
|
||||
Example: suppose you've got a buffer with the following content:
|
||||
|
||||
@code
|
||||
AAAABBBBCCCC
|
||||
@endcode
|
||||
|
||||
Then:
|
||||
@code
|
||||
[..]
|
||||
unsigned char g[4];
|
||||
buffer_extract(b, g, 4, 4); // => g now contains 'BBBB'
|
||||
@endcode
|
||||
|
||||
\param[in] b The Buffer object to read from.
|
||||
|
||||
\param[out] buf The buffer to copy data to.
|
||||
|
||||
\param[in] offset Where to start copying.
|
||||
|
||||
\param[in] len How mush data to copy.
|
||||
|
||||
\return Returns the size of bytes read. Returns 0 in case of
|
||||
an overflow, which can be catched with fatals_ifany().
|
||||
|
||||
*/
|
||||
size_t buffer_extract(Buffer *b, void *buf, size_t offset, size_t len);
|
||||
|
||||
/* dump the buffer contents to stderr */
|
||||
/** Dump the Buffer contents to stderr in hex form.
|
||||
|
||||
\param[in] b The Buffer object to dump.
|
||||
*/
|
||||
void buffer_dump(const Buffer *b);
|
||||
|
||||
/* print buffer counters to stderr */
|
||||
/** Print Buffer counters to stderr.
|
||||
|
||||
\param[in] b The Buffer object to print infos about.
|
||||
*/
|
||||
void buffer_info(const Buffer *b);
|
||||
|
||||
/* tell how much data there is in the buffer */
|
||||
/** Tell how much data there is in the buffer available.
|
||||
|
||||
This function returns the number of bytes stored in the
|
||||
buffer so far. Please note, that the actual allocation might
|
||||
be bigger, because we always allocate memory blockwise.
|
||||
|
||||
\param[in] b The Buffer object to get the size from.
|
||||
|
||||
\return The number of bytes stored in the Buffer.
|
||||
*/
|
||||
size_t buffer_size(const Buffer *b);
|
||||
|
||||
/* tell how much data is left to read */
|
||||
/** Tell how much data is left to read in the Buffer.
|
||||
|
||||
Use this function to check if it's ok to read more
|
||||
bytes from to buffer to avoid buffer overflows.
|
||||
|
||||
Example: suppose you've got a buffer with the following content:
|
||||
|
||||
@code
|
||||
AAAABBBBCCCC
|
||||
@endcode
|
||||
|
||||
Then:
|
||||
@code
|
||||
[..]
|
||||
unsigned char g[4];
|
||||
unsigned char x[16];
|
||||
buffer_get_chunk(b, g, 4); // => g now contains 'BBBB'
|
||||
if(buffer_left(b) >= 16) // => will return 8 and therefore fail
|
||||
buffer_get_chunk(b, x, 16);
|
||||
else
|
||||
printf("not enough data"); // => will be printed
|
||||
@endcode
|
||||
|
||||
\param[in] b The Buffer object to get the size from.
|
||||
|
||||
\return The number of bytes left to read from the Buffer.
|
||||
|
||||
*/
|
||||
size_t buffer_left(const Buffer *b);
|
||||
|
||||
/* same as get_chunk, but return numbers directly */
|
||||
/** Read 1 byte (8 bit) number from a Buffer.
|
||||
|
||||
\param[in] b The Buffer object to read from.
|
||||
|
||||
\return a uint8_t.
|
||||
*/
|
||||
uint8_t buffer_get8(Buffer *b);
|
||||
|
||||
/** Read 2 bytes (16 bit) number from a Buffer.
|
||||
|
||||
\param[in] b The Buffer object to read from.
|
||||
|
||||
\return a uint16_t.
|
||||
*/
|
||||
uint16_t buffer_get16(Buffer *b);
|
||||
|
||||
/** Read 4 byte (32 bit) number from a Buffer.
|
||||
|
||||
\param[in] b The Buffer object to read from.
|
||||
|
||||
\return a uint32_t.
|
||||
*/
|
||||
uint32_t buffer_get32(Buffer *b);
|
||||
|
||||
/** Read 8 byte (64 bit) from a Buffer.
|
||||
|
||||
\param[in] b The Buffer object to read from.
|
||||
|
||||
\return a uint64_t.
|
||||
*/
|
||||
uint64_t buffer_get64(Buffer *b);
|
||||
|
||||
/* same, but convert to native endian before return */
|
||||
/** Read 2 bytes (16 bit) number from a Buffer, converted to host endian.
|
||||
|
||||
\param[in] b The Buffer object to read from.
|
||||
|
||||
\return a uint16_t.
|
||||
*/
|
||||
uint16_t buffer_get16na(Buffer *b);
|
||||
|
||||
/** Read 4 byte (32 bit) number from a Buffer, converted to host endian.
|
||||
|
||||
\param[in] b The Buffer object to read from.
|
||||
|
||||
\return a uint32_t.
|
||||
*/
|
||||
uint32_t buffer_get32na(Buffer *b);
|
||||
|
||||
/** Read 8 byte (64 bit) from a Buffer, converted to host endian.
|
||||
|
||||
\param[in] b The Buffer object to read from.
|
||||
|
||||
\return a uint64_t.
|
||||
*/
|
||||
uint64_t buffer_get64na(Buffer *b);
|
||||
|
||||
/* access the last byte(s) as numbers directly, save typing,
|
||||
in contrast to buffer_get() it doesn't increment offset */
|
||||
/** Read the last 1 byte (8 bit) number from a Buffer.
|
||||
|
||||
Doesn't increment offset.
|
||||
|
||||
\param[in] b The Buffer object to read from.
|
||||
|
||||
\return a uint8_t.
|
||||
*/
|
||||
uint8_t buffer_last8(Buffer *b);
|
||||
|
||||
/** Read the last 2 byte (16 bit) number from a Buffer.
|
||||
|
||||
Doesn't increment offset.
|
||||
|
||||
\param[in] b The Buffer object to read from.
|
||||
|
||||
\return a uint16_t.
|
||||
*/
|
||||
uint16_t buffer_last16(Buffer *b);
|
||||
|
||||
/** Read the last 4 byte (32 bit) number from a Buffer.
|
||||
|
||||
Doesn't increment offset.
|
||||
|
||||
\param[in] b The Buffer object to read from.
|
||||
|
||||
\return a uint32_t.
|
||||
*/
|
||||
uint32_t buffer_last32(Buffer *b);
|
||||
|
||||
/** Read the last 8 byte (64 bit) number from a Buffer.
|
||||
|
||||
Doesn't increment offset.
|
||||
|
||||
\param[in] b The Buffer object to read from.
|
||||
|
||||
\return a uint64_t.
|
||||
*/
|
||||
uint64_t buffer_last64(Buffer *b);
|
||||
|
||||
/* read from a file directly into a buffer object */
|
||||
/** Read data from a file directly into a Buffer.
|
||||
|
||||
This function reads in len bytes from the FILE stream
|
||||
'in' into the Buffer. The file must already be opened
|
||||
by the caller.
|
||||
|
||||
\param[in,out] b The Buffer object to read from.
|
||||
|
||||
\param[in] in The FILE stream to read from.
|
||||
|
||||
\param[in] len The number of bytes to read.
|
||||
|
||||
\return Returns the number of bytes read or 0 in case of an error or EOF.
|
||||
Use feof() and ferror() to check this afterwards, call fatals_ifany()
|
||||
in case of errors.
|
||||
*/
|
||||
size_t buffer_fd_read(Buffer *b, FILE *in, size_t len);
|
||||
|
||||
/* write numbers as binary into the buffer */
|
||||
/** Write a 1 byte (8 bit) number in binary form into the buffer.
|
||||
|
||||
\param[out] b The Buffer object to write to.
|
||||
|
||||
\param[in] v The uint8_t to write to the buffer.
|
||||
*/
|
||||
void buffer_add8(Buffer *b, uint8_t v);
|
||||
|
||||
/** Write a 2 byte (16 bit) number in binary form into the buffer.
|
||||
|
||||
\param[out] b The Buffer object to write to.
|
||||
|
||||
\param[in] v The uint16_t to write to the buffer.
|
||||
*/
|
||||
void buffer_add16(Buffer *b, uint16_t v);
|
||||
|
||||
/** Write a 4 byte (32 bit) number in binary form into the buffer.
|
||||
|
||||
\param[out] b The Buffer object to write to.
|
||||
|
||||
\param[in] v The uint32_t to write to the buffer.
|
||||
*/
|
||||
void buffer_add32(Buffer *b, uint32_t v);
|
||||
|
||||
/** Write a 8 byte (64 bit) number in binary form into the buffer.
|
||||
|
||||
\param[out] b The Buffer object to write to.
|
||||
|
||||
\param[in] v The uint64_t to write to the buffer.
|
||||
*/
|
||||
void buffer_add64(Buffer *b, uint64_t v);
|
||||
|
||||
/* the same, but convert to big-endian before doing so */
|
||||
/** Write a 2 byte (16 bit) number in binary form into the buffer, converted to big endian.
|
||||
|
||||
\param[out] b The Buffer object to write to.
|
||||
|
||||
\param[in] v The uint16_t to write to the buffer.
|
||||
*/
|
||||
void buffer_add16be(Buffer *b, uint16_t v);
|
||||
|
||||
/** Write a 4 byte (32 bit) number in binary form into the buffer, converted to big endian.
|
||||
|
||||
\param[out] b The Buffer object to write to.
|
||||
|
||||
\param[in] v The uint32_t to write to the buffer.
|
||||
*/
|
||||
void buffer_add32be(Buffer *b, uint32_t v);
|
||||
|
||||
/** Write a 8 byte (64 bit) number in binary form into the buffer, converted to big endian.
|
||||
|
||||
\param[out] b The Buffer object to write to.
|
||||
|
||||
\param[in] v The uint64_t to write to the buffer.
|
||||
*/
|
||||
void buffer_add64be(Buffer *b, uint64_t v);
|
||||
|
||||
|
||||
#endif // HAVE_PCP_BUFFER_H
|
||||
|
||||
/**@}*/
|
||||
|
||||
@@ -92,21 +92,62 @@ typedef unsigned int qbyte; /* Quad byte = 32 bits */
|
||||
|
||||
#define PCP_RFC_CIPHER 0x21 /* curve25519+ed25519+poly1305+salsa20+blake2 */
|
||||
|
||||
/**
|
||||
* \defgroup FATALS global variables and functions for error handling.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* error handling */
|
||||
|
||||
/** \var PCP_ERR
|
||||
|
||||
Global variable holding the last error message.
|
||||
Can be retrieved with fatals_ifany().
|
||||
*/
|
||||
extern char *PCP_ERR;
|
||||
|
||||
/** \var PCP_ERRSET
|
||||
|
||||
Global variable indicating if an error occurred.
|
||||
*/
|
||||
extern byte PCP_ERRSET;
|
||||
|
||||
/** \var PCP_EXIT
|
||||
|
||||
Exitcode for the pcp commandline utility.
|
||||
*/
|
||||
extern int PCP_EXIT;
|
||||
|
||||
/* set error */
|
||||
/** Set an error message.
|
||||
|
||||
This function gets a printf() like error message,
|
||||
which it stores in the global PCP_ERR variable
|
||||
and sets PCP_ERRSET to 1.
|
||||
|
||||
\param[in] fmt printf() like format description.
|
||||
|
||||
\param[in] ... format parameters, if any.
|
||||
*/
|
||||
void fatal(const char * fmt, ...);
|
||||
|
||||
/* fetch error */
|
||||
/** Prints error messages to STDERR, if there are some.
|
||||
|
||||
FIXME: add something like this which returns the
|
||||
message.
|
||||
*/
|
||||
void fatals_ifany();
|
||||
|
||||
/* reset */
|
||||
/** Reset the error variables.
|
||||
|
||||
This can be used to ignore previous errors.
|
||||
Use with care.
|
||||
*/
|
||||
void fatals_reset();
|
||||
|
||||
/* free mem */
|
||||
/** Cleans up memory allocation of global error variables.
|
||||
*/
|
||||
void fatals_done();
|
||||
|
||||
#endif /* _DEFINES_H */
|
||||
|
||||
/**@}*/
|
||||
|
||||
@@ -40,11 +40,21 @@
|
||||
#include "scrypt.h"
|
||||
#include "keysig.h"
|
||||
|
||||
/*
|
||||
PCP private key structure. Most fields are self explanatory.
|
||||
|
||||
/**
|
||||
* \defgroup PCPKEY PCP public and secret key functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** \struct _pcp_key_t
|
||||
|
||||
PCP private key structure. Most fields are self explanatory.
|
||||
|
||||
Some notes:
|
||||
|
||||
'encrypted' contains the encrypted ed25519 secret key. If it's set,
|
||||
'encrypted' contains the encrypted secret keys (contatenated mastersecret,
|
||||
secret and edsecret). If it's set,
|
||||
the field 'secret' which contains the clear secret key will
|
||||
be zeroed with random values, the first byte will be 0. Same
|
||||
for the field 'edsecret'.
|
||||
@@ -76,41 +86,55 @@
|
||||
|
||||
*/
|
||||
struct _pcp_key_t {
|
||||
byte masterpub[32];
|
||||
byte mastersecret[64];
|
||||
byte pub[32];
|
||||
byte secret[32];
|
||||
byte edpub[32];
|
||||
byte edsecret[64];
|
||||
byte nonce[24];
|
||||
byte encrypted[176]; /* both sign+ed+curve encrypted */
|
||||
char owner[255];
|
||||
char mail[255];
|
||||
char id[17];
|
||||
uint8_t type;
|
||||
uint64_t ctime; /* 8 */
|
||||
uint32_t version; /* 4 */
|
||||
uint32_t serial; /* 4 */
|
||||
byte masterpub[32]; /**< ED25519 master public key signing key */
|
||||
byte mastersecret[64]; /**< ED25519 master secret key signing key */
|
||||
byte pub[32]; /**< Curve25519 encryption public key */
|
||||
byte secret[32]; /**< Curve25519 encryption secret key */
|
||||
byte edpub[32]; /**< ED25519 public signing key */
|
||||
byte edsecret[64]; /**< ED25519 secret signing key */
|
||||
byte nonce[24]; /**< random nonce used to encrypt secret keys */
|
||||
byte encrypted[176]; /**< concatenated and encrypted secret keys */
|
||||
char owner[255]; /**< the key owner, string */
|
||||
char mail[255]; /**< mail address of the owner, string */
|
||||
char id[17]; /**< key-id, used internally only, jenhash of public keys */
|
||||
uint8_t type; /**< key type: MASTER_SECRET or SECRET */
|
||||
uint64_t ctime; /**< creation time, epoch */
|
||||
uint32_t version; /**< key version */
|
||||
uint32_t serial; /**< serial number of the key, randomly generated */
|
||||
UT_hash_handle hh;
|
||||
};
|
||||
|
||||
/** Typedef for secret keys */
|
||||
typedef struct _pcp_key_t pcp_key_t;
|
||||
|
||||
/** \struct _pcp_pubkey_t
|
||||
|
||||
PCP public key structure.
|
||||
|
||||
This structure contains a subset of the pcp_key_t structure
|
||||
without the secret and nonce fields.
|
||||
*/
|
||||
struct _pcp_pubkey_t {
|
||||
byte masterpub[32];
|
||||
byte sigpub[32];
|
||||
byte pub[32];
|
||||
byte edpub[32];
|
||||
char owner[255];
|
||||
char mail[255];
|
||||
char id[17];
|
||||
uint8_t type;
|
||||
uint64_t ctime;
|
||||
uint32_t version;
|
||||
uint32_t serial;
|
||||
uint8_t valid;
|
||||
byte signature[crypto_generichash_BYTES_MAX + crypto_sign_BYTES];
|
||||
byte masterpub[32]; /**< ED25519 master public key signing key */
|
||||
byte sigpub[32]; /**< ED25519 public signing key */
|
||||
byte pub[32]; /**< Curve25519 encryption public key */
|
||||
byte edpub[32]; /**< ED25519 public signing key (FIXME: huh? 2 of them???) */
|
||||
char owner[255]; /**< the key owner, string */
|
||||
char mail[255]; /**< mail address of the owner, string */
|
||||
char id[17]; /**< key-id, used internally only, jenhash of public keys */
|
||||
uint8_t type; /**< key type: MASTER_SECRET or SECRET */
|
||||
uint64_t ctime; /**< creation time, epoch */
|
||||
uint32_t version; /**< key version */
|
||||
uint32_t serial; /**< serial number of the key, randomly generated */
|
||||
uint8_t valid; /**< 1 if import signature verified, 0 if not */
|
||||
byte signature[crypto_generichash_BYTES_MAX + crypto_sign_BYTES]; /**< raw binary blob of pubkey export signature */
|
||||
UT_hash_handle hh;
|
||||
};
|
||||
|
||||
/** Typedef for public keys */
|
||||
typedef struct _pcp_pubkey_t pcp_pubkey_t;
|
||||
|
||||
|
||||
/* the PBP public key format */
|
||||
/* keys.mp+keys.cp+keys.sp+keys.name */
|
||||
struct _pbp_pubkey_t {
|
||||
@@ -122,9 +146,6 @@ struct _pbp_pubkey_t {
|
||||
char name[1024];
|
||||
};
|
||||
|
||||
|
||||
typedef struct _pcp_key_t pcp_key_t;
|
||||
typedef struct _pcp_pubkey_t pcp_pubkey_t;
|
||||
typedef struct _pbp_pubkey_t pbp_pubkey_t;
|
||||
|
||||
/*
|
||||
@@ -145,25 +166,212 @@ typedef struct _pcp_rec_t pcp_rec_t;
|
||||
#define PCP_RAW_PUBKEYSIZE sizeof(pcp_pubkey_t) - sizeof(UT_hash_handle)
|
||||
|
||||
|
||||
/** Generate a new key structure.
|
||||
|
||||
void pcp_cleanhashes();
|
||||
Owner and mail field must be filled by the caller.
|
||||
Memory for the returned pointer will be allocated
|
||||
by the function.
|
||||
|
||||
\return Returns pointer to new pcp_key_t structure.
|
||||
*/
|
||||
pcp_key_t *pcpkey_new ();
|
||||
|
||||
void pcp_keypairs(byte *msk, byte *mpk, byte *csk, byte *cpk, byte *esk, byte *epk);
|
||||
|
||||
/** Generate an ASCII art image of the public key.
|
||||
|
||||
This functions originally appeared in OpenSSH rev 1.70,
|
||||
comitted by Alexander von Gernler, published under the
|
||||
BSD license.
|
||||
|
||||
Human beings are bad at memorizing numbers, especially
|
||||
large numbers, but we are very good at recognizing images.
|
||||
This function calculates an ascii art image of a public
|
||||
key, which the user shall always see, when used. If the
|
||||
image changes, the user would immediately recognize the
|
||||
change, even unconsciously.
|
||||
|
||||
Sample random art image from the following public key:
|
||||
|
||||
@code
|
||||
c308455ed4cf0c140bf48bfb0d87c4999c66e823bbe74ff16e2a9adc8e770747
|
||||
|
||||
+----------------+
|
||||
| .o.ooo. |
|
||||
| o . o |
|
||||
| . . = |
|
||||
| . o + |
|
||||
| . + |
|
||||
| . |
|
||||
| |
|
||||
| |
|
||||
+----------------+
|
||||
@endcode
|
||||
|
||||
\param[in] k The public key structure.
|
||||
|
||||
\return Returns an allocated char pointer containing the ASCII art image.
|
||||
The caller is responsible to free() it.
|
||||
*/
|
||||
char *pcppubkey_get_art(pcp_pubkey_t *k);
|
||||
|
||||
/** Generate an ASCII art image of the public key part of a secret key.
|
||||
|
||||
see pcppubkey_get_art() for details.
|
||||
|
||||
\param[in] k The secret key structure.
|
||||
|
||||
\return Returns an allocated char pointer containing the ASCII art image.
|
||||
The caller is responsible to free() it.
|
||||
*/
|
||||
char *pcpkey_get_art(pcp_key_t *k);
|
||||
|
||||
pcp_key_t *pcpkey_encrypt(pcp_key_t *key, char *passphrase);
|
||||
pcp_key_t *pcpkey_decrypt(pcp_key_t *key, char *passphrase);
|
||||
pcp_pubkey_t *pcpkey_pub_from_secret(pcp_key_t *key);
|
||||
char *pcp_getkeyid(pcp_key_t *k);
|
||||
char *pcp_getpubkeyid(pcp_pubkey_t *k);
|
||||
unsigned char *pcppubkey_getchecksum(pcp_pubkey_t *k);
|
||||
unsigned char *pcpkey_getchecksum(pcp_key_t *k);
|
||||
void pcp_inithashes();
|
||||
/** Encrypt a secret key structure.
|
||||
|
||||
The given passphrase will be used to calculate an encryption
|
||||
key using the scrypt() function.
|
||||
|
||||
The secret keys will be concatenated and encrypted, the result
|
||||
will be put into the 'encrypted' field. The first byte of each
|
||||
secret key field will be set to 0 to indicate the key is encrypted.
|
||||
|
||||
The data structure will be modified directly, no new memory
|
||||
will be allocated.
|
||||
|
||||
The caller is responsible to clear the passphrase right after
|
||||
use and free() it as soon as possible.
|
||||
|
||||
\param[in,out] key The secret key structure.
|
||||
|
||||
\param[in] passphrase The passphrase used to encrypt the key.
|
||||
|
||||
\return Returns a pointer to the encrypted key structure or NULL
|
||||
in case of an error. Use fatals_ifany() to catch them.
|
||||
*/
|
||||
pcp_key_t *pcpkey_encrypt(pcp_key_t *key, char *passphrase);
|
||||
|
||||
/** Decrypt a secret key structure.
|
||||
|
||||
The given passphrase will be used to calculate an encryption
|
||||
key using the scrypt() function.
|
||||
|
||||
The encryption key will be used to decrypt the 'encrypted'
|
||||
field of the structure. If it works, the result will be dissected
|
||||
and put into the correspondig secret key fields.
|
||||
|
||||
The data structure will be modified directly, no new memory
|
||||
will be allocated.
|
||||
|
||||
The caller is responsible to clear the passphrase right after
|
||||
use and free() it as soon as possible.
|
||||
|
||||
\param[in,out] key The secret key structure.
|
||||
|
||||
\param[in] passphrase The passphrase used to decrypt the key.
|
||||
|
||||
\return Returns a pointer to the decrypted key structure or NULL
|
||||
in case of an error. Use fatals_ifany() to catch them.
|
||||
|
||||
*/
|
||||
pcp_key_t *pcpkey_decrypt(pcp_key_t *key, char *passphrase);
|
||||
|
||||
/** Generate a public key structure from a given secret key structure.
|
||||
|
||||
This function extracts all required fields and fills a newly
|
||||
allocated pcp_pubkey_t structure.
|
||||
|
||||
The caller is responsible to clear and free() it after use.
|
||||
|
||||
\param[in] key The secret key structure.
|
||||
|
||||
\return Returns a new pcp_pubkey_t structure.
|
||||
*/
|
||||
pcp_pubkey_t *pcpkey_pub_from_secret(pcp_key_t *key);
|
||||
|
||||
|
||||
/** Calculate a key-id from public key fields.
|
||||
|
||||
This function calculates 2 JEN Hashes: one from the 'pub'
|
||||
field and one from the 'edpub' field. It the puts them
|
||||
together into a newly allocated char pointer of 17 bytes
|
||||
length as hex, terminated with a 0.
|
||||
|
||||
The key-id is supposed to be collision save, but there's
|
||||
no guarantee. However, it's used locally only, it wont be
|
||||
transmitted over the network and it's not part of any exported
|
||||
packet.
|
||||
|
||||
\param[in] k The secret key structure.
|
||||
|
||||
\return Returns a char pointer containing the key-id string.
|
||||
*/
|
||||
char *pcp_getkeyid(pcp_key_t *k);
|
||||
|
||||
|
||||
/** Calculate a key-id from public key fields.
|
||||
|
||||
This does the same as pcp_getkeyid() but uses a pcp_pubkey_t
|
||||
as input.
|
||||
|
||||
|
||||
\param[in] k The public key structure.
|
||||
|
||||
\return Returns a char pointer containing the key-id string.
|
||||
*/
|
||||
char *pcp_getpubkeyid(pcp_pubkey_t *k);
|
||||
|
||||
/** Calculate a checksum of a public key.
|
||||
|
||||
This function calculates a 32 byte checksum of the
|
||||
encryption public key part of the given pcp_pubkey_t
|
||||
structure using crypto_hash_sha256.
|
||||
|
||||
The returned pointer will be allocated and it is the
|
||||
responsibility of the caller to free() ist after use.
|
||||
|
||||
\param[in] k The public key structure.
|
||||
|
||||
\return Returns a pointer to an 32 byte unsigned char.
|
||||
*/
|
||||
unsigned char *pcppubkey_getchecksum(pcp_pubkey_t *k);
|
||||
|
||||
/** Calculate a checksum of a public key part of the given secret key.
|
||||
|
||||
See pcppubkey_getchecksum().
|
||||
|
||||
\param[in] k The secret key structure.
|
||||
|
||||
\return Returns a pointer to an 32 byte unsigned char.
|
||||
*/
|
||||
unsigned char *pcpkey_getchecksum(pcp_key_t *k);
|
||||
|
||||
|
||||
/** Checks if a secret key structure is registered in the secret key hash.
|
||||
|
||||
Returns a pointer to a pcp_key_t structure if there
|
||||
exists a secret key structure with the given id in the
|
||||
secret key hash.
|
||||
|
||||
FIXME: needs to be moved to keyhash.h.
|
||||
|
||||
\param[in] id A null-terminated char pointer of 17 bytes containing a key-id.
|
||||
|
||||
\return Returns a pointer to a pcp_key_t struture or NULL if no key exists.
|
||||
*/
|
||||
pcp_key_t *pcpkey_exists(char *id);
|
||||
|
||||
/** Checks if a public key structure is registered in the public key hash.
|
||||
|
||||
Returns a pointer to a pcp_pubkey_t structure if there
|
||||
exists a public key structure with the given id in the
|
||||
public key hash.
|
||||
|
||||
FIXME: needs to be moved to keyhash.h.
|
||||
|
||||
\param[in] id A null-terminated char pointer of 17 bytes containing a key-id.
|
||||
|
||||
\return Returns a pointer to a pcp_pubkey_t struture or NULL if no key exists.
|
||||
*/
|
||||
pcp_pubkey_t *pcppubkey_exists(char *id);
|
||||
|
||||
pcp_key_t * key2be(pcp_key_t *k);
|
||||
@@ -171,22 +379,45 @@ pcp_key_t *key2native(pcp_key_t *k);
|
||||
pcp_pubkey_t * pubkey2be(pcp_pubkey_t *k);
|
||||
pcp_pubkey_t *pubkey2native(pcp_pubkey_t *k);
|
||||
|
||||
/** Generate a nonce.
|
||||
|
||||
This function generates a 24 byte nonce used for cryptographic
|
||||
functions. It allocates the memory and the caller is responsible
|
||||
to clear and free() it after use.
|
||||
|
||||
\return Returns a pointer to a 24 byte unsigned char array.
|
||||
*/
|
||||
unsigned char * pcp_gennonce();
|
||||
|
||||
void pcpedit_key(char *keyid);
|
||||
|
||||
/* use scrypt() to create a key from a passphrase and a nonce */
|
||||
/* use scrypt() to create a key from a passphrase and a nonce
|
||||
FIXME: use pure scrypt() instead.
|
||||
*/
|
||||
unsigned char *pcp_derivekey(char *passphrase, unsigned char *nonce);
|
||||
|
||||
pcp_key_t *pcp_derive_pcpkey (pcp_key_t *ours, char *theirs);
|
||||
|
||||
/* FIXME: abandon and use Buffer instead */
|
||||
void pcp_seckeyblob(void *blob, pcp_key_t *k);
|
||||
void pcp_pubkeyblob(void *blob, pcp_pubkey_t *k);
|
||||
void *pcp_keyblob(void *k, int type); /* allocates blob */
|
||||
|
||||
/** Make a sanity check of the given public key structure.
|
||||
|
||||
\param[in] key The public key structure.
|
||||
|
||||
\return Returns 1 if the sanity check succeeds, 0 otherwise.
|
||||
Use fatals_ifany() to check why.
|
||||
*/
|
||||
int pcp_sanitycheck_pub(pcp_pubkey_t *key);
|
||||
|
||||
/** Make a sanity check of the given secret key structure.
|
||||
|
||||
\param[in] key The secret key structure.
|
||||
|
||||
\return Returns 1 if the sanity check succeeds, 0 otherwise.
|
||||
Use fatals_ifany() to check why.
|
||||
*/
|
||||
int pcp_sanitycheck_key(pcp_key_t *key);
|
||||
|
||||
|
||||
#endif /* _HAVE_PCP_KEYPAIR_H */
|
||||
|
||||
/**@}*/
|
||||
|
||||
@@ -43,88 +43,12 @@
|
||||
/* key management api, export, import, yaml and stuff */
|
||||
|
||||
|
||||
/**
|
||||
* \defgroup PubKeyExport Key export functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* RFC4880 alike public key export with some modifications:
|
||||
|
||||
- Key material is native to us and not specified in the
|
||||
rfc for curve25519/ed25519. Therefore we're doing it like
|
||||
so: mp|sp|cp
|
||||
where mp = master keysigning public key (ed25519), 32 bytes
|
||||
sp = signing public key (ed25519), 32 bytes
|
||||
cp = encryption public key (curve25519), 32 bytes
|
||||
|
||||
- The various cipher (algorithm) id's are unspecified for
|
||||
our native ciphers. Therefore I created them, starting at
|
||||
33 (afaik 22 is the last officially assigned one). Once
|
||||
those cipher numbers become official, I'll use them instead
|
||||
of my own.
|
||||
|
||||
- The exported public key packet contains a signature. We're
|
||||
filling out all required fields. A signature has a variable
|
||||
number of sig sub packets. We use only these types:
|
||||
|
||||
2 = Signature Creation Time (4 byte)
|
||||
3 = Signature Expiration Time (4 byte)
|
||||
9 = Key Expiration Time (4 bytes)
|
||||
20 = Notation Data (4 byte flags, N bytes name+value)
|
||||
27 = Key Flags (1 byte, use 0x02, 0x08 and 0x80
|
||||
|
||||
- We use 3 notation fields:
|
||||
* "owner", which contains the owner name, if set
|
||||
* "mail", which contains the emailaddress, if set
|
||||
* "serial", which contains the 32bit serial number
|
||||
|
||||
- The actual signature field consists of the blake2 hash of
|
||||
(mp|sp|cp|keysig) followed by the nacl signature. However, we do
|
||||
not put an extra 16byte value of the hash, since the nacl
|
||||
signature already contains the full hash. So, an implementation
|
||||
could simply pull the fist 16 bytes of said hash to get
|
||||
the same result.
|
||||
|
||||
- The mp keypair will be used for signing. The recipient can
|
||||
verify the signature, since mp is included.
|
||||
|
||||
- While we put expiration dates for the key and the signature
|
||||
into the export as the rfc demands, we ignore them. Key expiring
|
||||
is not implemented in PCP yet.
|
||||
|
||||
So, a full pubkey export looks like this
|
||||
|
||||
version
|
||||
ctime
|
||||
cipher
|
||||
3 x raw keys \
|
||||
sigheader > calc hash from this
|
||||
sigsubs (header+data) /
|
||||
hash
|
||||
signature
|
||||
|
||||
We use big-endian always.
|
||||
|
||||
Unlike RC4880 public key exports, we're using Z85 encoding if
|
||||
armoring have been requested by the user. Armored output has
|
||||
a header and a footer line, however they are ignored by the
|
||||
parser and are therefore optional. Newlines, if present, are
|
||||
optional as well.
|
||||
|
||||
http://tools.ietf.org/html/rfc4880#section-5.2.3
|
||||
|
||||
The key sig blob will be saved in the Vault if we import a public key
|
||||
unaltered, so we can verify the signature at will anytime. When exporting
|
||||
a foreign public key, we will just put out that key sig blob to the
|
||||
export untouched.
|
||||
|
||||
Currently PCP only support self-signed public key exports.
|
||||
|
||||
We only support one key signature per key. However, it would be easily
|
||||
possible to support foreign keysigs as well in the future.
|
||||
|
||||
-----------
|
||||
|
||||
Secret key are exported in proprietary format. We just encrypt the
|
||||
whole structure symmetrically and prepend it with a nonce.
|
||||
|
||||
*/
|
||||
|
||||
/* various helper structs, used internally only */
|
||||
struct _pcp_rfc_pubkey_header_t {
|
||||
@@ -197,29 +121,181 @@ typedef struct _pcp_ks_bundle_t pcp_ks_bundle_t;
|
||||
#define EXP_FORMAT_PY 5
|
||||
#define EXP_FORMAT_PERL 6
|
||||
|
||||
/** RFC4880 alike public key export with some modifications.
|
||||
|
||||
/* export self signed public key from master secret */
|
||||
RFC4880 alike public key export with the following modifications:
|
||||
|
||||
- Key material is native to us and not specified in the
|
||||
rfc for curve25519/ed25519. Therefore we're doing it like
|
||||
so: mp|sp|cp
|
||||
where mp = master keysigning public key (ed25519), 32 bytes
|
||||
sp = signing public key (ed25519), 32 bytes
|
||||
cp = encryption public key (curve25519), 32 bytes
|
||||
|
||||
- The various cipher (algorithm) id's are unspecified for
|
||||
our native ciphers. Therefore I created them, starting at
|
||||
33 (afaik 22 is the last officially assigned one). Once
|
||||
those cipher numbers become official, I'll use them instead
|
||||
of my own.
|
||||
|
||||
- The exported public key packet contains a signature. We're
|
||||
filling out all required fields. A signature has a variable
|
||||
number of sig sub packets. We use only these types:
|
||||
|
||||
2 = Signature Creation Time (4 byte)
|
||||
3 = Signature Expiration Time (4 byte)
|
||||
9 = Key Expiration Time (4 bytes)
|
||||
20 = Notation Data (4 byte flags, N bytes name+value)
|
||||
27 = Key Flags (1 byte, use 0x02, 0x08 and 0x80
|
||||
|
||||
- We use 3 notation fields:
|
||||
* "owner", which contains the owner name, if set
|
||||
* "mail", which contains the emailaddress, if set
|
||||
* "serial", which contains the 32bit serial number
|
||||
|
||||
- The actual signature field consists of the blake2 hash of
|
||||
(mp|sp|cp|keysig) followed by the nacl signature. However, we do
|
||||
not put an extra 16byte value of the hash, since the nacl
|
||||
signature already contains the full hash. So, an implementation
|
||||
could simply pull the fist 16 bytes of said hash to get
|
||||
the same result.
|
||||
|
||||
- The mp keypair will be used for signing. The recipient can
|
||||
verify the signature, since mp is included.
|
||||
|
||||
- While we put expiration dates for the key and the signature
|
||||
into the export as the rfc demands, we ignore them. Key expiring
|
||||
is not implemented in PCP yet.
|
||||
|
||||
So, a full pubkey export looks like this
|
||||
|
||||
version
|
||||
ctime
|
||||
cipher
|
||||
3 x raw keys \
|
||||
sigheader > calc hash from this
|
||||
sigsubs (header+data) /
|
||||
hash
|
||||
signature
|
||||
|
||||
We use big-endian always.
|
||||
|
||||
Unlike RC4880 public key exports, we're using Z85 encoding if
|
||||
armoring have been requested by the user. Armored output has
|
||||
a header and a footer line, however they are ignored by the
|
||||
parser and are therefore optional. Newlines, if present, are
|
||||
optional as well.
|
||||
|
||||
http://tools.ietf.org/html/rfc4880#section-5.2.3
|
||||
|
||||
The key sig blob will be saved in the Vault if we import a public key
|
||||
unaltered, so we can verify the signature at will anytime. When exporting
|
||||
a foreign public key, we will just put out that key sig blob to the
|
||||
export untouched.
|
||||
|
||||
Currently PCP only support self-signed public key exports.
|
||||
|
||||
We only support one key signature per key. However, it would be easily
|
||||
possible to support foreign keysigs as well in the future.
|
||||
|
||||
|
||||
\param sk a secret key structure of type pcp_key_t. The secret keys
|
||||
in there have to be already decrypted.
|
||||
|
||||
\return the function returns a Buffer object containing the binary
|
||||
blob in the format described above.
|
||||
|
||||
*/
|
||||
Buffer *pcp_export_rfc_pub (pcp_key_t *sk);
|
||||
|
||||
/* export foreign public key
|
||||
Buffer *pcp_export_rfc_pub_foreign (pcp_pubkey_t *pub); */
|
||||
|
||||
/* export public key in pbp format */
|
||||
/** Export a public key in PBP format.
|
||||
Export a public key in the format described at
|
||||
https://github.com/stef/pbp/blob/master/doc/fileformats.txt
|
||||
|
||||
\param sk a secret key structure of type pcp_key_t. The secret keys
|
||||
in there have to be already decrypted.
|
||||
|
||||
\return the function returns a Buffer object containing the binary
|
||||
blob in the format described above.
|
||||
*/
|
||||
Buffer *pcp_export_pbp_pub(pcp_key_t *sk);
|
||||
|
||||
/* export public key in yaml format */
|
||||
/** Export a public key in yaml format.
|
||||
Export a public key in yaml format.
|
||||
|
||||
\param sk a secret key structure of type pcp_key_t. The secret keys
|
||||
in there have to be already decrypted.
|
||||
|
||||
\return the function returns a Buffer object containing the binary
|
||||
blob containing a YAML string.
|
||||
*/
|
||||
Buffer *pcp_export_yaml_pub(pcp_key_t *sk);
|
||||
|
||||
/* export public key in perl format */
|
||||
/** Export a public key in perl code format.
|
||||
Export a public key in perl code format.
|
||||
|
||||
\param sk a secret key structure of type pcp_key_t. The secret keys
|
||||
in there have to be already decrypted.
|
||||
|
||||
\return the function returns a Buffer object containing the binary
|
||||
blob containing a perl code string (a hash definition).
|
||||
*/
|
||||
Buffer *pcp_export_perl_pub(pcp_key_t *sk);
|
||||
|
||||
/* export public key in C format */
|
||||
/** Export a public key in C code format.
|
||||
Export a public key in C code format.
|
||||
|
||||
\param sk a secret key structure of type pcp_key_t. The secret keys
|
||||
in there have to be already decrypted.
|
||||
|
||||
\return the function returns a Buffer object containing the binary
|
||||
blob containing a C code string.
|
||||
*/
|
||||
Buffer *pcp_export_c_pub(pcp_key_t *sk);
|
||||
|
||||
/* export secret key */
|
||||
/** Export secret key.
|
||||
|
||||
Export a secret key.
|
||||
|
||||
Secret key are exported in proprietary format.
|
||||
|
||||
The exported binary blob is symmetrically encrypted using the NACL
|
||||
function crypto_secret(). The passphrase will be used to derive an
|
||||
encryption key using the STAR function scrypt().
|
||||
|
||||
The binary data before encryption consists of:
|
||||
|
||||
- ED25519 master signing secret
|
||||
- Curve25519 encryption secret
|
||||
- ED25519 signing secret
|
||||
- ED25519 master signing public
|
||||
- Curve25519 encryption public
|
||||
- ED25519 signing public
|
||||
- Optional notations, currently supported are the 'owner' and 'mail' attributes.
|
||||
If an attribute is empty, the len field contains zero.
|
||||
-# len(VAL) (2 byte uint)
|
||||
-# VAL (string without trailing zero)
|
||||
- 8 byte creation time (epoch)
|
||||
- 4 byte key version
|
||||
- 4 byte serial number
|
||||
|
||||
The encrypted cipher will be prepended with the random nonce used
|
||||
to encrypt the data and looks after encryption as such:
|
||||
|
||||
Nonce | Cipher
|
||||
|
||||
\param sk a secret key structure of type pcp_key_t. The secret keys
|
||||
in there have to be already decrypted.
|
||||
|
||||
\param passphrase the passphrase to be used to encrypt the export,
|
||||
a null terminated char array.
|
||||
|
||||
\return the function returns a Buffer object containing the binary
|
||||
blob in the format described above.
|
||||
*/
|
||||
Buffer *pcp_export_secret(pcp_key_t *sk, char *passphrase);
|
||||
|
||||
/* import public keys */
|
||||
pcp_ks_bundle_t *pcp_import_pub(unsigned char *raw, size_t rawsize);
|
||||
pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob);
|
||||
pcp_ks_bundle_t *pcp_import_pub_pbp(Buffer *blob);
|
||||
@@ -229,3 +305,5 @@ pcp_key_t *pcp_import_secret(unsigned char *raw, size_t rawsize, char *passphras
|
||||
pcp_key_t *pcp_import_secret_native(Buffer *cipher, char *passphrase);
|
||||
|
||||
#endif // _HAVE_PCP_MGMT_H
|
||||
|
||||
/**@}*/
|
||||
|
||||
Reference in New Issue
Block a user