updated api docs.

This commit is contained in:
git@daemon.de
2014-02-20 15:36:49 +01:00
parent f13f60bfc2
commit 08bc0bc8bf
11 changed files with 654 additions and 91 deletions

View File

@@ -170,7 +170,6 @@ unsigned char *pcp_box_encrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
\return Returns an allocated unsigned char array of the size csize which contains the encrypted result.
In case of an error, it returns NULL sets csize to 0. Use fatals_ifany() to check for errors.
*/
unsigne
unsigned char *pcp_box_decrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
unsigned char *cipher, size_t ciphersize,
size_t *dsize);

View File

@@ -29,11 +29,12 @@
\section intro_sec Introduction
This is the API documentation of libpcp, the library behind
Pretty Curved Privacy (pcp). The library can be used independently
<a href="/PrettyCurvedPrivacy">Pretty Curved Privacy (pcp)</a>.
The library can be used independently
of pcp to manage keys and to encrypt or sign files or buffers.
For most actual crypto related things, libpcp uses libsodium,
the portable NaCL library.
For most actual crypto related things, libpcp uses
<a href="https://github.com/jedisct1/libsodium">libsodium, the portable NaCL library</a>.
\section sample_sec Sample usage
@@ -56,7 +57,7 @@ typedef unsigned char byte; /* Single unsigned byte = 8 bits */
typedef unsigned short dbyte; /* Double byte = 16 bits */
typedef unsigned int qbyte; /* Quad byte = 32 bits */
/* key stuff */
/* key stuff, deprecated. */
#define PCP_KEY_HEADER "----- BEGIN PCP SECRET KEY -----"
#define PCP_KEY_FOOTER "------ END PCP SECRET KEY ------"
@@ -79,11 +80,25 @@ typedef unsigned int qbyte; /* Quad byte = 32 bits */
#define PCP_KEY_VERSION 6
#define PCP_KEY_PRIMITIVE "CURVE25519-ED25519-SALSA20-POLY1305"
#define PCP_KEY_TYPE_MAINSECRET 1
#define PCP_KEY_TYPE_SECRET 2
#define PCP_KEY_TYPE_PUBLIC 3
#define PCP_KEYSIG_NATIVE 4
#define PCP_KEYSIG_PBP 5
/**
\addtogroup KEYS
@{
*/
/** \enum _PCP_KEY_TYPES
Internal key types.
*/
typedef enum _PCP_KEY_TYPES {
PCP_KEY_TYPE_MAINSECRET = 1, /**< 1 - Primary secret */
PCP_KEY_TYPE_SECRET = 2, /**< 2 - Other secret */
PCP_KEY_TYPE_PUBLIC = 3, /**< 3 - Public */
PCP_KEYSIG_NATIVE = 4, /**< 4 - PCP native key signature */
PCP_KEYSIG_PBP = 5 /**< 5 - PBP key signature */
} PCP_KEY_TYPES;
/** @}
*/
/* save typing, dammit */
#define PCP_ENCRYPT_MAC crypto_secretbox_ZEROBYTES + crypto_secretbox_NONCEBYTES

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013 T.Linden.
Copyright (C) 2013-2014 T.v.Dein.
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
@@ -16,16 +16,19 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
You can contact me by mail: <tlinden AT cpan DOT org>.
*/
/*
ED25519 signatures. Currently unbuffered
You can contact me by mail: <tom AT vondein DOT org>.
*/
#ifndef _HAVE_PCP_ED_H
#define _HAVE_PCP_ED_H
/** \defgroup ED SIGNING
@{
ED25519 signature functions.
*/
#include <sodium.h>
#include <string.h>
#include <stdio.h>
@@ -39,30 +42,150 @@
#include "util.h"
#include "pcpstream.h"
/* sign a message of messagesize using s->edsecret, if it works
return message+signature (size: messagesize + crypto_sign_BYTES),
returns NULL otherwise */
/** Sign a raw message.
Sign a message of messagesize using s->edsecret.
This is just a convenience wrapper around crypto_sign().
\param[in] message The message to sign.
\param[in] messagesize Size of the message.
\param[in] s Pointer to secret key structure.
\return Returns message+signature with size of messagesize + crypto_sign_BYTES,
or NULL in case of an error.
*/
unsigned char *pcp_ed_sign(unsigned char *message, size_t messagesize, pcp_key_t *s);
/* the same, but use the mastersecret instead, usually for keysigning */
unsigned char *pcp_ed_sign_key(unsigned char *message, size_t messagesize, pcp_key_t *s);
/** Sign a raw message using s->mastersecret.
/* verify a signature of siglen size using p->edpub, if the signature verifies
return the raw message with the signature removed (size: siglen - crypto_sign_BYTES),
returns NULL otherwise */
The same as pcp_ed_sign() but uses the mastersecret for signing.
Usually used for key signing only.
\param[in] message The message to sign.
\param[in] messagesize Size of the message.
\param[in] s Pointer to secret key structure.
\return Returns message+signature with size of messagesize + crypto_sign_BYTES,
or NULL in case of an error.
*/unsigned char *pcp_ed_sign_key(unsigned char *message, size_t messagesize, pcp_key_t *s);
/** Verify a signature.
Verify a signature of size siglen using p->edpub.
The signature must contain the message+nacl signature (with size crypto_sign_BYTES).
\param[in] signature Message+signature.
\param[in] siglen Size of message+signature.
\param[in] p Pointer to public key structure.
\return If the signature verifies return the raw message with the signature removed (size: siglen - crypto_sign_BYTES),
returns NULL in case of errors. Check fatals_if_any().
*/
unsigned char *pcp_ed_verify(unsigned char *signature, size_t siglen, pcp_pubkey_t *p);
/* the same, but use the mastersecret instead, usually for keysigning */
/** Verify a signature using the mastersecret.
Verify a signature of size siglen using p->masterpub.
The signature must contain the message+nacl signature (with size crypto_sign_BYTES).
\param[in] signature Message+signature.
\param[in] siglen Size of message+signature.
\param[in] p Pointer to public key structure.
\return If the signature verifies return the raw message with the signature removed (size: siglen - crypto_sign_BYTES),
returns NULL in case of errors. Check fatals_if_any().
*/
unsigned char *pcp_ed_verify_key(unsigned char *signature, size_t siglen, pcp_pubkey_t *p);
/* same as pcp_ed_sign() but work on i/o directly, we're making a hash
of the input 32k-wise, copy in=>out, sign the hash and append the
sig only to the output */
/** Sign a stream in 32k block mode.
This function reads blockwise from the stream \a in and generates a hash
of the contents of the stream. It outputs the stream to \a out, also blockwise
and appends the signature afterwards, which consists of the hash+nacl-signature.
\param[in] in Stream to read from.
\param[out] out Stream to write to.
\param[in] s Pointer to secret key.
\param[in] z85 Flag which indicates if to create an armored signature or not. 1=armored, 0=raw.
\return Returns the number of bytes written to the output stream.
*/
size_t pcp_ed_sign_buffered(Pcpstream *in, Pcpstream *out, pcp_key_t *s, int z85);
/** Verify a signature from a stream in 32k block mode.
This function reads blockwise from the stream \a in and generates a hash
of the contents of the stream. While reading from the stream it extracts
the appended signature (hash+sig). It then verifies the signature using
p->edpub and compares the signature hash with the hash it calculated
from the signed content.
The parameter \a p can be NULL. In this case the function loops through
the global public key hash pcppubkey_hash to find a public key which is able to verify
the signature.
\param[in] in Stream to read from.
\param[in] p Pointer to public key structure.
\return Returns a pointer to a public key which were used to verify the signature or NULL if
an error occurred. Check fatals_if_any().
*/
pcp_pubkey_t *pcp_ed_verify_buffered(Pcpstream *in, pcp_pubkey_t *p);
/** Generate a detached signature from a stream in 32k block mode.
This function reads blockwise from the stream \a in and generates a hash
of the contents of the stream. It then signs that hash and writes the
hash and the signature to the output stream \a out.
\param[in] in Stream to read from.
\param[out] out Stream to write to.
\param[in] s Pointer to secret key.
\return Returns the size of the detached signature written or 0 in case of errors. Check fatals_if_any().
*/
size_t pcp_ed_detachsign_buffered(Pcpstream *in, Pcpstream *out, pcp_key_t *s);
/** Verify a detached signature from a stream in 32k block mode.
This function reads blockwise from the stream \a in and generates a hash
of the contents of the stream. It then reads the signature from the stream
\a sigfd and verifies the signature from it using p->edpub and compares
the signature hash with the hash it calculated
from the signed content.
\param[in] in Stream to read from.
\param[in] sigfd Stream containing the detached signature.
\param[in] p Pointer to public key structure.
\return Returns a pointer to a public key which were used to verify the signature or NULL if
an error occurred. Check fatals_if_any().
*/
pcp_pubkey_t *pcp_ed_detachverify_buffered(Pcpstream *in, Pcpstream *sigfd, pcp_pubkey_t *p);
#endif /* _HAVE_PCP_ED_H */
/**@}*/

View File

@@ -428,7 +428,16 @@ int pcp_sanitycheck_pub(pcp_pubkey_t *key);
*/
int pcp_sanitycheck_key(pcp_key_t *key);
/** Dump a secret key structure to stderr.
\param[in] k Secret key to dump.
*/
void pcp_dumpkey(pcp_key_t *k);
/** Dump a public key structure to stderr.
\param[in] k Public key to dump.
*/
void pcp_dumppubkey(pcp_pubkey_t *k);

View File

@@ -22,37 +22,125 @@
#ifndef _HAVE_KEYHASH_H
#define _HAVE_KEYHASH_H
/** \defgroup KEYHASH KEYHASH
@{
Uthashes of secret and public key structures.
Libpcp uses the <a href="http://troydhanson.github.io/uthash/">uthash</a>
system to maintain lists of keys. There's one hash per key type. The
hash has the same type as the key structure itself, but is global.
*/
#include "uthash.h"
#include "key.h"
/* storage of keys in a global hash */
/** Global hash for secret keys. */
extern pcp_key_t *pcpkey_hash;
/** Global hash for public keys. */
extern pcp_pubkey_t *pcppubkey_hash;
extern pcp_key_t *__k;
extern pcp_pubkey_t *__p;
/* wrapper for HASH_ITER */
/** Iterate over the list of secret keys.
Sample use:
@code
pcp_key_t k = NULL;
pcphash_iterate(k) {
pcp_dumpkey(k);
}
@endcode
Also, don't free() the keyhash or the temporary key pointer
yourself. Use pcphash_clean() instead when done.
*/
#define pcphash_iterate(key) \
__k = NULL; \
HASH_ITER(hh, pcpkey_hash, key, __k)
/** Iterate over the list of public keys.
Sample use:
@code
pcp_pubkey_t k = NULL;
pcphash_iteratepub(k) {
pcp_dumppubkey(k);
}
@endcode
Also, don't free() the keyhash or the temporary key pointer
yourself. Use pcphash_clean() instead when done.
*/
#define pcphash_iteratepub(key) \
__p = NULL; \
HASH_ITER(hh, pcppubkey_hash, key, __p)
/** Initialize the global hashes. */
void pcphash_init();
/** Delete an entry from a hash.
\param[in] key A pointer to the key structure to delete.
\param[in] type An integer specifying the key type to delete. \see _PCP_KEY_TYPES.
*/
void pcphash_del(void *key, int type);
/** Frees the memory allocated by the hashes.
Clears and frees memory of all keys in the hash lists
and the hashes themselfes.
*/
void pcphash_clean();
/** Check if a secret key with a given key-id exists in the hash.
\param[in] id A string with the key-id (max 17 chars incl 0).
\return Returns a pointer to the matching key or NULL if the id doesn't match.
*/
pcp_key_t *pcphash_keyexists(char *id);
/** Check if a publickey with a given key-id exists in the hash.
\param[in] id A string with the key-id (max 17 chars incl 0).
\return Returns a pointer to the matching key or NULL if the id doesn't match.
*/
pcp_pubkey_t *pcphash_pubkeyexists(char *id);
/** Add a key structure to the hash list.
\param[in] key A pointer to the key structure to delete.
\param[in] type An integer specifying the key type to delete. \see _PCP_KEY_TYPES.
*/
void pcphash_add(void *key, int type);
/** Returns the number of secret keys in the hash.
\return Number of keys.
*/
int pcphash_count();
/** Returns the number of public keys in the hash.
\return Number of keys.
*/
int pcphash_countpub();
/* the same, for keysigs */
/** Global hash for key signatures. */
extern pcp_keysig_t *pcpkeysig_hash;
extern pcp_keysig_t *__s;
@@ -63,3 +151,5 @@ extern pcp_keysig_t *__s;
pcp_keysig_t *pcphash_keysigexists(char *id);
#endif /* _HAVE_KEYHASH_H */
/**@}*/

View File

@@ -23,6 +23,10 @@
#ifndef _HAVE_PCP_MAC
#define _HAVE_PCP_MAC
/**
* \addtogroup CRYPTO
* @{
*/
#include <strings.h>
#include <stdlib.h>
#include <errno.h>
@@ -34,35 +38,47 @@
/* how many times do we hash the passphrase */
#define HCYCLES 128000
/* encrypt some arbitrary cleartext using */
/* a curve25519 secret key and a given nonce. */
/* */
/* expects a pointer to the target binary */
/* stream containing the encrypted data, */
/* the cleartext string, its size, the nonce */
/* (24 bytes) and the secret key (32 bytes). */
/* */
/* allocates memory for the returned cipher */
/* and it is up to the user to free it after use. */
/* */
/* returns the size of the returned cipherstream. */
/* in case of an error, the cipher will be set */
/* to NULL. */
/** Symmetrically encrypt a message.
This function encrypts a message symmetrically
using crypto_secretbox() using the given Curve25519 raw
secret key and the nonce.
It allocates apropriate memory for the result,
which will be stored in \a cipher.
\param[out] cipher Encrypted result.
\param[in] cleartext Clear message.
\param[in] clearsize Size of message.
\param[in] nonce A random nonce (24 Bytes).
\param[in] key A Curve25519 key (32 Bytes).
\return Returns the size of \a cipher.
*/
size_t pcp_sodium_mac(unsigned char **cipher,
unsigned char *cleartext,
size_t clearsize,
unsigned char *nonce,
unsigned char *key);
/* does the opposite of pcp_sodium_mac and decrypts */
/* a given encrypted binary stream using a nonce and */
/* a secret key (sizes: see above). */
/* */
/* allocates memory for the returned cleartext and */
/* it is up to the user to free it after use. */
/* */
/* returns 0 if decryption and verification were */
/* successful, otherwise -1. */
/** Decrypt a symmetrically encrypted message.
This function decrypts a symmetrically encrypted message
using crypto_secretbox_open() using the given Curve25519 raw
secret key and the nonce.
It allocates apropriate memory for the result,
which will be stored in \a cleartext.
\param[out] cleartext The decrypted result.
\param[in] message The encrypted message.
\param[in] messagesize Size of message.
\param[in] nonce A random nonce (24 Bytes).
\param[in] key A Curve25519 key (32 Bytes).
\return Returns 0 in case of success of -1 in case of an error. Check fatals_if_any().
*/
int pcp_sodium_verify_mac(unsigned char **cleartext,
unsigned char* message,
size_t messagesize,
@@ -73,3 +89,5 @@ int pcp_sodium_verify_mac(unsigned char **cleartext,
#endif /* _HAVE_PCP_MAC */
/**@}*/

View File

@@ -25,15 +25,80 @@
#ifndef _HAVE_PCP_UTIL_H
#define _HAVE_PCP_UTIL_H
/** \defgroup UTILs UTILS
@{
Various useful helper functions.
*/
#include <ctype.h>
#include <wctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/** Convert a char array to lowercase.
The supplied char array will be directly modified. Use
a copy if you want to retain the original.
\param[in,out] in The char array to convert.
\return Returns the pointer to the char array.
*/
char *_lc(char *in);
/** Find the offset of some offset marker in some arbitrary data.
Sample input:
@code
ABABABABnacl-98a7sd98a7das98d7
@endcode
If you look for the offset of "nacl" within that data, the
function will return 9, which is the position within the data
where the marker starts.
\param[in] bin Aribrary data where to look for the marker.
\param[in] binlen The size of the data.
\param[in] sigstart The offset marker.
\param[in] hlen Size of the offset marker.
\return Returns the offset or -1 of the offset were not found.
*/
size_t _findoffset(unsigned char *bin, size_t binlen, char *sigstart, size_t hlen);
/** XOR an input buffer with another buffer.
Both buffers have to have the same size. The input
buffer will bei modified directly.
\param[in] iv The buffer to XOR with.
\param[in,out] buf The buffer which will be XORed with 'iv'.
\param[in] xlen The size of the buffers (they must have the same size).
*/
void _xorbuf(unsigned char *iv, unsigned char *buf, size_t xlen);
/** Dump binary data as hex to stderr.
\param[in] n Description, string.
\param[in] d Data to print.
\param[in] s Size of d.
*/
void _dump(char *n, unsigned char *d, size_t s);
#endif /* _HAVE_PCP_UTIL_H */
/**@}*/

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013 T.Linden.
Copyright (C) 2013-2014 T.v.Dein.
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
@@ -16,13 +16,66 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
You can contact me by mail: <tlinden AT cpan DOT org>.
You can contact me by mail: <tom AT vondein DOT org>.
*/
#ifndef _HAVE_PCP_VAULT
#define _HAVE_PCP_VAULT
/** \defgroup VAULT VAULT
@{
The vault file is used to store keys and key-signatures on disk.
It works like a keyring.
\section vformat Vault File Format
The vault file contains all public and secret keys. It's a portable
binary file.
The file starts with a header:
@code
+-------------------------------------------+
| Field Size Description |
+-------------------------------------------+
| File ID | 1 | Vault Identifier 0xC4 |
+-------------------------------------------+
| Version | 4 | Big endian, version |
+-------------------------------------------+
| Checksum | 32 | SHA256 Checksum |
+-------------------------------------------+
@endcode
The checksum is a checksum of all keys.
The header is followed by the keys. Each key is preceded by an
item header which looks like this:
@code
+--------------------------------------------+
| Field Size Description |
+--------------------------------------------+
| Type | 1 | Key type (S,P,M) |
+--------------------------------------------+
| Size | 4 | Big endian, keysize |
+--------------------------------------------+
| Version | 4 | Big endian, keyversion |
+--------------------------------------------+
| Checksum | 32 | SHA256 Key Checksum |
+--------------------------------------------+
@endcode
Type can be one of:
- PCP_KEY_TYPE_MAINSECRET 0x01
- PCP_KEY_TYPE_SECRET 0x02
- PCP_KEY_TYPE_PUBLIC 0x03
The item header is followed by the actual key contents.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
@@ -37,51 +90,167 @@
#include "buffer.h"
#include "keysig.h"
/** \struct _vault_t
This structure represents a vault. */
struct _vault_t {
char *filename;
FILE *fd;
uint8_t unsafed;
uint8_t isnew;
uint32_t size;
time_t modified;
mode_t mode;
uint32_t version;
byte checksum[32];
};
struct _vault_header_t {
uint8_t fileid;
uint32_t version;
byte checksum[32];
};
struct _vault_item_header_t {
uint8_t type;
uint32_t size;
uint32_t version;
byte checksum[32];
char *filename; /**< The filename of the vault (full path) */
FILE *fd; /**< Filehandle if opened */
uint8_t unsafed; /**< Flag to tell if the file needs to be written */
uint8_t isnew; /**< Flag to tell if the vault has been newly created */
uint32_t size; /**< Filesize */
time_t modified; /**< mtime */
mode_t mode; /**< File mode */
uint32_t version; /**< Vault version */
byte checksum[32]; /**< SHA256 checksum over the whole vault */
};
/** Name of the struct */
typedef struct _vault_t vault_t;
/** \struct _vault_header_t
Defines the vault header. */
struct _vault_header_t {
uint8_t fileid; /**< File id, proprietary. Marks the vault as a vault */
uint32_t version; /**< File version */
byte checksum[32]; /**< SHA256 checksum over the whole vault */
};
/** Name of the struct */
typedef struct _vault_header_t vault_header_t;
/** \struct _vault_item_header_t
An item header. */
struct _vault_item_header_t {
uint8_t type; /**< Item type (secret key, public, key, keysig, \see _PCP_KEY_TYPES */
uint32_t size; /**< Size of the item */
uint32_t version; /**< Version of the item */
byte checksum[32]; /**< SHA256 checksum of the item */
};
/** Name of the struct */
typedef struct _vault_item_header_t vault_item_header_t;
/** Open a vault file.
If the file doesn't exist, it will be created.
\param[in] filename The filename of the vault file.
\return Returns a vault object.
*/
vault_t *pcpvault_init(char *filename);
/* Creates a new vault file. Called internally only.
If is_tmp If set to 1, create a temporary vault file.
*/
vault_t *pcpvault_new(char *filename, int is_tmp);
/* Writes the initial vault header to the vault.
Called internally only. */
int pcpvault_create(vault_t *vault);
/** Add an item to the vault.
Adds \a item with the size \a itemsize and type \a type
to the vault. Generates the item header and the checksum
of the item.
This function writes directly into the vault file. Use
with care. To be safe, use pcpvault_addkey() instead.
\param[out] vault The vault object.
\param[in] item The item to write.
\param[in] itemsize Size of the item.
\param[in] type Type of the item. \see _PCP_KEY_TYPES.
\return Returns the number of bytes written or 0 in case of
an error. Check fatals_if_any().
*/
int pcpvault_additem(vault_t *vault, void *item, size_t itemsize, uint8_t type);
/** Add a key to the vault.
This function determines the size of the item to write
based on the given type. It converts the internal structure
to a binary blob and converty multibyte values to big
endian.
It copies the given vault file to a temporary vault file,
adds the item and if this went ok, copies the temporary file
back to the original location. It then re-calculates the
vault checksum and puts it into the vault header.
\param[out] vault The vault object.
\param[in] item The item to write (a key or keysig)
\param[in] type Type of the item. \see _PCP_KEY_TYPES.
\return Returns 0 on success or 1 in case of errors. Check fatals_if_any().
*/
int pcpvault_addkey(vault_t *vault, void *item, uint8_t type);
/** Close a vault file.
If the vault is in unsafed state, write everything to disk
and close the vault. Before overwriting the current vault file
a backup will be made. If anything fails during writing the
backup file will be retained and the error message will
contain the filename of the backup file, so that the user
doesn't loose data.
\param[out] vault The vault object.
\return Returns 0. Check fatals_if_any() anyway.
*/
int pcpvault_close(vault_t *vault);
/** Reads in the vault contents.
This function reads the open vault contents and puts
them into the apropriate hashes. \see KEYHASH.
Currently only known types can be read. If your're saving
unknown types to the vault, an error will occur. \see _PCP_KEY_TYPES.
Each item will be converted put into the aproprieate
structure, multibyte values will be converted to
host endianess. It also calculates the checksum of the vault
contents and compares it with the one stored in the vault
header. If it doesn't match an error will be thrown.
\param[out] vault The vault object.
\return Returns 0 on success or -1 in case of errors. Check fatals_if_any().
*/
int pcpvault_fetchall(vault_t *vault);
/* Write everything back to disk. */
int pcpvault_writeall(vault_t *vault);
/* copy a vault to another file */
int pcpvault_copy(vault_t *tmp, vault_t *vault);
/* delete a vault file */
void pcpvault_unlink(vault_t *tmp);
/* calculate the vault checksum */
unsigned char *pcpvault_create_checksum(vault_t *vault);
/* write the new checksum to the header of the current vault */
void pcpvault_update_checksum(vault_t *vault);
/* bigendian converters */
vault_header_t * vh2be(vault_header_t *h);
vault_header_t * vh2native(vault_header_t *h);
vault_item_header_t * ih2be(vault_item_header_t *h);
vault_item_header_t * ih2native(vault_item_header_t *h);
#endif /* _HAVE_PCP_VAULT */
/**@}*/

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013 T.Linden.
Copyright (C) 2013-2014 T.v.Dein.
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
@@ -16,36 +16,114 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
You can contact me by mail: <tlinden AT cpan DOT org>.
You can contact me by mail: <tom AT vondein DOT org>.
*/
/* from https://github.com/tlinden/curve-keygen/ */
#ifndef _HAVE_PCP_Z85_H
#include <ctype.h>
/**
* \defgroup Z85 Z85
* @{
Z85 Encoding functions.
The Z85 encoding format is described here: <a href="http://rfc.zeromq.org/spec:32">ZeroMQ Spec.32</a>.
It's part of <a href="http://zeromq.org">ZeroMQ</a>. Z85 is based on ASCII85 with
a couple of modifications (portability, readability etc).
To fulfil the requirements of the ZeroMQ Z85 functions, PCP
does some additional preparations of raw input before actually doing the
encoding, since the input for zmq_z85_encode() must be divisible by 4. Therefore
we pad the input with zeroes and remove them after decoding.
*/
#include <ctype.h>
#include "defines.h"
#include "zmq_z85.h"
#include "mem.h"
#include "buffer.h"
/* convert a binary stream to one which gets accepted by zmq_z85_encode */
/* we pad it with zeroes and put the number of zerores in front of it */
/** Zero-pad some input data.
This function allocates new memory for the returned data. It puts
the original pointer into it and adds a number of zeros so that the
result has a size divisable by 4.
\param[in] src Unpadded data.
\param[in] srclen Size of unpadded data.
\param[in] dstlen Returned size of padded data (pointer to int).
\return Returns a pointer to the padded data.
*/
unsigned char *pcp_padfour(unsigned char *src, size_t srclen, size_t *dstlen);
/* the reverse of the above */
/** Unpad padded input data.
It just calculates the size of the unpadded result (size - all trailing zeroes).
Doesn't allocate any memory or modify anything.
\param[in] src Padded data.
\param[in] srclen Size of padded data.
\return Returns the unpadded size of the data.
*/
size_t pcp_unpadfour(unsigned char *src, size_t srclen);
/* wrapper around zmq Z85 encoding function */
/** Decode data from Z85 encoding.
The input \a z85block may contain newlines which will be removed.
\param[in] z85block The Z85 encoded string.
\param[in] dstlen Returned size of decoded data (pointer to int).
\return Returns a newly allocated pointer to the decoded data. If decoding failed,
returns NULL. Check fatals_if_any().
*/
unsigned char *pcp_z85_decode(char *z85block, size_t *dstlen);
/* the reverse of the above */
/** Encode data to Z85 encoding.
Beside Z85 encoding it also adds a newline everiy 72 characters.
\param[in] raw Pointer to raw data.
\param[in] srclen Size of the data.
\param[in] dstlen Returned size of encoded data (pointer to int).
\return Returns a string (char array) containing the Z85 encoded data.
*/
char *pcp_z85_encode(unsigned char *raw, size_t srclen, size_t *dstlen);
/** Read a Z85 encoded file.
Reads a file and returns the raw Z85 encoded string.
It ignores newlines, comments and Headerstrings.
\param[in] infile FILE stream to read from.
\return Raw Z85 encoded string with comments, headers and newlines removed.
*/
char *pcp_readz85file(FILE *infile);
/** Read a Z85 encoded string.
Parses the given input string and returns the raw Z85 encoded string.
It ignores newlines, comments and Headerstrings.
\param[in] input Z85 encoded string.
\param[in] bufsize Size of the string.
\return Raw Z85 encoded string with comments, headers and newlines removed.
*/
char *pcp_readz85string(unsigned char *input, size_t bufsize);
size_t _buffer_is_binary(unsigned char *buf, size_t len);
#endif /* _HAVE_PCP_Z85_H */
/**@}*/

View File

@@ -31,9 +31,6 @@
#include "keyhash.h"
#include "base85.h"
void pcp_dumpkey(pcp_key_t *k);
void pcp_dumppubkey(pcp_pubkey_t *k);
void pcpkey_print(pcp_key_t *key, FILE *out);
void pcppubkey_print(pcp_pubkey_t *key, FILE *out);

View File

@@ -25,7 +25,7 @@ int main() {
/* prepare the pubkey recipient list (only 1 recipient: Bob) */
pubhash = NULL;
strncpy(bobpub->id, pcp_getkeyid(bobpub), 17);
strncpy(bobpub->id, pcp_getpubkeyid(bobpub), 17);
HASH_ADD_STR( pubhash, id, bobpub);
/* actually encrypt the message, don't sign it
@@ -33,7 +33,7 @@ int main() {
pcp_encrypt_stream(clear_in, crypt_out, alice, pubhash, 0);
/* now, print the encrypted result */
fprintf(stderr, "Alice encrypted %d bytes for Bob:\n", strlen(message));
fprintf(stderr, "Alice encrypted %ld bytes for Bob:\n", strlen(message));
buffer_dump(ps_buffer(crypt_out));
/* ---- encryption don, now decrypt ---- */
@@ -52,7 +52,7 @@ int main() {
fatals_ifany();
else {
/* and finally print out the decrypted message */
fprintf(stderr, "Bob decrypted %d bytes from Alice:\n", buffer_size(ps_buffer(crypt_out)));
fprintf(stderr, "Bob decrypted %ld bytes from Alice:\n", buffer_size(ps_buffer(crypt_out)));
printf("Decrypted message: %s\n", buffer_get_str(ps_buffer(clear_out)));
}