Make this code WARNS=4

Add an option to the netpgp command to produce a detached signature.
This commit is contained in:
agc 2009-05-02 02:38:54 +00:00
parent 71e559c1d8
commit de70477951
10 changed files with 260 additions and 163 deletions

View File

@ -41,3 +41,4 @@ real naming scheme
get rid of malloc() instances -> calloc()
change include directory
Install man pages
WARNS=4 (again)

View File

@ -57,7 +57,7 @@ int netpgp_generate_key(netpgp_t *, char *, int);
/* file management */
int netpgp_encrypt_file(netpgp_t *, char *, char *, char *, int);
int netpgp_decrypt_file(netpgp_t *, char *, char *, int);
int netpgp_sign_file(netpgp_t *, char *, char *, char *, int, int);
int netpgp_sign_file(netpgp_t *, char *, char *, char *, int, int, int);
int netpgp_verify_file(netpgp_t *, char *, int);
#endif /* !NETPGP_H_ */

View File

@ -1,4 +1,4 @@
.\" $NetBSD: netpgp.1,v 1.3 2009/04/28 09:19:15 wiz Exp $
.\" $NetBSD: netpgp.1,v 1.4 2009/05/02 02:38:54 agc Exp $
.\"
.\" Copyright (c) 2009 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -27,7 +27,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd February 1, 2009
.Dd May 1, 2009
.Dt NETPGP 1
.Os
.Sh NAME
@ -38,6 +38,7 @@
.Op Fl Fl armour
.Op Fl Fl clearsign
.Op Fl Fl decrypt
.Op Fl Fl detached
.Op Fl Fl encrypt
.Op Fl Fl export-key
.Op Fl Fl find-key
@ -94,6 +95,9 @@ Decrypt the file using the user's private key.
The pass phrase will be optained by prompting the user
to type it in, using
.Xr getpass 3 .
.It Fl Fl detached
when signing a file, place the resulting signature in a separate
file from the one being signed.
.It Fl Fl encrypt
Use the user's public key to encrypt the files named on the command line.
.It Fl Fl export-key

View File

@ -67,6 +67,7 @@ enum optdefs {
ARMOUR,
HOMEDIR,
NUMBITS,
DETACHED,
/* debug */
OPS_DEBUG
@ -101,6 +102,7 @@ static struct option long_options[] = {
{"armor", no_argument, NULL, ARMOUR},
{"armour", no_argument, NULL, ARMOUR},
{"numbits", required_argument, NULL, NUMBITS},
{"detached", no_argument, NULL, DETACHED},
/* debug */
{"debug", required_argument, NULL, OPS_DEBUG},
@ -118,6 +120,7 @@ typedef struct prog_t {
int overwrite; /* overwrite files? */
int numbits; /* # of bits */
int armour; /* ASCII armor */
int detached; /* use separate file */
int cmd; /* netpgp command */
int ex; /* exit code */
} prog_t;
@ -160,10 +163,12 @@ netpgp_cmd(netpgp_t *netpgp, prog_t *p, char *f)
netpgp_decrypt_file(netpgp, f, NULL, p->armour);
break;
case SIGN:
netpgp_sign_file(netpgp, p->userid, f, NULL, p->armour, 0);
netpgp_sign_file(netpgp, p->userid, f, NULL, p->armour, 0,
p->detached);
break;
case CLEARSIGN:
netpgp_sign_file(netpgp, p->userid, f, NULL, p->armour, 1);
netpgp_sign_file(netpgp, p->userid, f, NULL, p->armour, 1,
p->detached);
break;
case VERIFY:
netpgp_verify_file(netpgp, f, p->armour);
@ -253,6 +258,10 @@ main(int argc, char **argv)
p.armour = 1;
break;
case DETACHED:
p.detached = 1;
break;
case HOMEDIR:
if (optarg == NULL) {
(void) fprintf(stderr, "No home directory argument provided\n");

View File

@ -38,7 +38,6 @@
#include <string.h>
#include "packet-parse.h"
#include "crypto.h"
#include "errors.h"
#include "netpgpdefs.h"
#include "parse_local.h"
@ -80,8 +79,8 @@ typedef struct {
static int
zlib_compressed_data_reader(void *dest, size_t length,
__ops_error_t ** errors,
__ops_reader_info_t * rinfo,
__ops_parse_cb_info_t * cbinfo)
__ops_reader_info_t *rinfo,
__ops_parse_cb_info_t *cbinfo)
{
z_decompress_t *z = __ops_reader_get_arg(rinfo);
size_t len;

View File

@ -1081,7 +1081,6 @@ __ops_write_literal_data_from_file(const char *filename,
unsigned char *mmapped;
__ops_memory_t *mem = NULL;
struct stat st;
size_t initial_size = 1024;
size_t len = 0;
int fd = 0;
bool rtn;
@ -1099,17 +1098,18 @@ __ops_write_literal_data_from_file(const char *filename,
#ifdef USE_MMAP_FOR_FILES
if (fstat(fd, &st) == 0) {
mem->length = st.st_size;
mmapped = mem->buf = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
mmapped = mem->buf = mmap(NULL, (size_t)st.st_size, PROT_READ,
MAP_FILE | MAP_PRIVATE, fd, 0);
}
#endif
if (mmapped == MAP_FAILED) {
__ops_memory_init(mem, initial_size);
__ops_memory_init(mem, (size_t)st.st_size);
for (;;) {
ssize_t n = 0;
n = read(fd, buf, sizeof(buf));
if (!n)
if ((n = read(fd, buf, sizeof(buf))) == 0) {
break;
}
__ops_memory_add(mem, buf, (unsigned)n);
}
}
@ -1125,7 +1125,7 @@ __ops_write_literal_data_from_file(const char *filename,
__ops_write(__ops_memory_get_data(mem), len, info);
#ifdef USE_MMAP_FOR_FILES
if (mmapped != NULL) {
if (mmapped != MAP_FAILED) {
munmap(mmapped, mem->length);
mmapped = buf;
}
@ -1145,21 +1145,19 @@ __ops_write_literal_data_from_file(const char *filename,
\param errnum Pointer to error
\return new __ops_memory_t pointer containing the contents of the file
\note If there was an error opening the file or reading from it, errnum is set to the cause
\note If there was an error opening the file or reading from it,
errnum is set to the cause
\note It is the caller's responsibility to call __ops_memory_free(mem)
*/
__ops_memory_t *
__ops_write_mem_from_file(const char *filename, int *errnum)
{
size_t initial_size = 1024;
int fd = 0;
unsigned char buf[1024];
__ops_memory_t *mem = NULL;
unsigned char buf[1024];
struct stat st;
int fd = 0;
*errnum = 0;
#ifdef O_BINARY
fd = open(filename, O_RDONLY | O_BINARY);
#else
@ -1170,19 +1168,22 @@ __ops_write_mem_from_file(const char *filename, int *errnum)
return false;
}
mem = __ops_memory_new();
__ops_memory_init(mem, initial_size);
(void) fstat(fd, &st);
__ops_memory_init(mem, (unsigned)st.st_size);
for (;;) {
ssize_t n = 0;
n = read(fd, buf, 1024);
n = read(fd, buf, sizeof(buf));
if (n < 0) {
*errnum = errno;
break;
}
if (!n)
if (!n) {
break;
__ops_memory_add(mem, &buf[0], (unsigned)n);
}
__ops_memory_add(mem, buf, (unsigned)n);
}
close(fd);
(void) close(fd);
return mem;
}
@ -1199,17 +1200,19 @@ __ops_write_mem_from_file(const char *filename, int *errnum)
*/
int
__ops_write_file_from_buf(const char *filename, const char *buf, const size_t len, const bool overwrite)
__ops_write_file_from_buf(const char *filename, const char *buf,
const size_t len, const bool overwrite)
{
int fd = 0;
size_t n = 0;
int flags = 0;
size_t n = 0;
int flags = 0;
int fd = 0;
flags = O_WRONLY | O_CREAT;
if (overwrite == true)
if (overwrite == true) {
flags |= O_TRUNC;
else
} else {
flags |= O_EXCL;
}
#ifdef O_BINARY
flags |= O_BINARY;
#endif

View File

@ -54,10 +54,15 @@
#include <assert.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include <regex.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@ -151,6 +156,83 @@ psuccess(char *f, __ops_validation_t *results, __ops_keyring_t *pubring)
}
}
/* sign a file, and put the signature in a separate file */
static int
sign_detached(__ops_secret_key_t *seckey, const char *hashstr, char *f,
char *sigfile)
{
__ops_create_signature_t *sig;
__ops_hash_algorithm_t alg;
__ops_create_info_t *info;
unsigned char keyid[OPS_KEY_ID_SIZE];
time_t t;
char fname[MAXPATHLEN];
int fd;
/* find out which hash algorithm to use */
alg = __ops_hash_algorithm_from_text(hashstr);
if (alg == OPS_HASH_UNKNOWN) {
(void) fprintf(stderr,"Unknown hash algorithm: %s\n", hashstr);
return 0;
}
/* create a new signature */
sig = __ops_create_signature_new();
__ops_signature_start_cleartext_signature(sig, seckey, alg,
OPS_SIG_BINARY);
/* read the contents of 'f' */
fd = open(f, O_RDONLY);
if (fd < 0) {
(void) fprintf(stderr, "can't open file \"%s\" to sign\n",
f);
return 0;
}
for (;;) {
unsigned char buf[8192];
int n;
if ((n = read(fd, buf, sizeof(buf))) == 0) {
break;
}
if (n < 0) {
(void) fprintf(stderr, "short read \"%s\"\n", f);
(void) close(fd);
return 0;
}
__ops_signature_add_data(sig, buf, (unsigned)n);
}
(void) close(fd);
/* calculate the signature */
t = time(NULL);
__ops_signature_add_creation_time(sig, t);
__ops_keyid(keyid, OPS_KEY_ID_SIZE, OPS_KEY_ID_SIZE,
&seckey->public_key);
__ops_signature_add_issuer_key_id(sig, keyid);
__ops_signature_hashed_subpackets_end(sig);
/* write the signature to the detached file */
if (sigfile == NULL) {
(void) snprintf(fname, sizeof(fname), "%s.sig", f);
sigfile = fname;
}
fd = open(sigfile, O_CREAT|O_TRUNC|O_WRONLY, 0666);
if (fd < 0) {
(void) fprintf(stderr, "can't write signature to \"%s\"\n",
sigfile);
return 0;
}
info = __ops_create_info_new();
__ops_writer_set_fd(info, fd);
__ops_write_signature(sig, &seckey->public_key, seckey, info);
__ops_secret_key_free(seckey);
(void) close(fd);
return 1;
}
/***************************************************************************/
/* exported functions start here */
/***************************************************************************/
@ -348,7 +430,8 @@ netpgp_decrypt_file(netpgp_t *netpgp, char *f, char *out, int armored)
/* sign a file */
int
netpgp_sign_file(netpgp_t *netpgp, char *userid, char *f, char *out, int armored, int cleartext)
netpgp_sign_file(netpgp_t *netpgp, char *userid, char *f, char *out,
int armored, int cleartext, int detached)
{
const __ops_keydata_t *keypair;
__ops_secret_key_t *seckey;
@ -358,8 +441,10 @@ netpgp_sign_file(netpgp_t *netpgp, char *userid, char *f, char *out, int armored
userid = netpgp->userid;
}
/* get key with which to sign */
if ((keypair = __ops_keyring_find_key_by_userid(netpgp->secring, userid)) == NULL) {
(void) fprintf(stderr, "Userid '%s' not found in keyring\n", userid);
keypair = __ops_keyring_find_key_by_userid(netpgp->secring, userid);
if (keypair == NULL) {
(void) fprintf(stderr, "Userid '%s' not found in keyring\n",
userid);
return 0;
}
do {
@ -368,13 +453,17 @@ netpgp_sign_file(netpgp_t *netpgp, char *userid, char *f, char *out, int armored
/* get the passphrase */
get_pass_phrase(passphrase, sizeof(passphrase));
/* now decrypt key */
if ((seckey = __ops_decrypt_secret_key_from_data(keypair, passphrase)) == NULL) {
seckey = __ops_decrypt_secret_key_from_data(keypair,
passphrase);
if (seckey == NULL) {
(void) fprintf(stderr, "Bad passphrase\n");
}
} while (seckey == NULL);
/* sign file */
if (cleartext) {
__ops_sign_file_as_cleartext(f, out, seckey, true);
} else if (detached) {
sign_detached(seckey, "SHA1", f, out);
} else {
__ops_sign_file(f, out, seckey, armored, true);
}

View File

@ -1023,8 +1023,8 @@ __ops_sign_file_as_cleartext(const char *input_filename, const char *output_file
if (__ops_writer_push_clearsigned(cinfo, sig) != true) {
return false;
}
/* Do the signing */
/* Do the signing */
for (;;) {
int n = 0;

View File

@ -40,21 +40,19 @@
#include <string.h>
/* Does the signed hash match the given hash? */
static bool
check_binary_signature(const unsigned len,
const unsigned char *data,
const __ops_signature_t * sig,
const __ops_public_key_t * signer __attribute__((unused)))
{
/* Does the signed hash match the given hash? */
__ops_hash_t hash;
unsigned char hashout[OPS_MAX_HASH_SIZE];
unsigned char trailer[6];
unsigned int hashedlen;
__ops_hash_t hash;
unsigned n = 0;
/* common_init_signature(&hash,sig); */
__ops_hash_any(&hash, sig->info.hash_algorithm);
hash.init(&hash);
hash.add(&hash, data, len);
@ -69,8 +67,8 @@ check_binary_signature(const unsigned len,
break;
case OPS_V4:
hash.add(&hash, sig->info.v4_hashed_data, sig->info.v4_hashed_data_length);
hash.add(&hash, sig->info.v4_hashed_data,
sig->info.v4_hashed_data_length);
trailer[0] = 0x04; /* version */
trailer[1] = 0xFF;
hashedlen = sig->info.v4_hashed_data_length;
@ -79,20 +77,19 @@ check_binary_signature(const unsigned len,
trailer[4] = hashedlen >> 8;
trailer[5] = hashedlen;
hash.add(&hash, &trailer[0], 6);
break;
default:
fprintf(stderr, "Invalid signature version %d\n", sig->info.version);
fprintf(stderr, "Invalid signature version %d\n",
sig->info.version);
return false;
}
n = hash.finish(&hash, hashout);
if (__ops_get_debug_level(__FILE__)) {
printf("check_binary_signature: hash length %" PRIsize "u\n", hash.size);
printf("check_binary_signature: hash length %" PRIsize "u\n",
hash.size);
}
/* return false; */
return __ops_check_signature(hashout, n, sig, signer);
}
@ -116,9 +113,12 @@ keydata_reader(void *dest, size_t length, __ops_error_t ** errors,
* we should never be asked to cross a packet boundary in a single
* read
*/
assert(reader->key->packets[reader->packet].length >= reader->offset + length);
assert(reader->key->packets[reader->packet].length >=
reader->offset + length);
(void) memcpy(dest, &reader->key->packets[reader->packet].raw[reader->offset], length);
(void) memcpy(dest,
&reader->key->packets[reader->packet].raw[reader->offset],
length);
reader->offset += length;
return length;
@ -132,21 +132,25 @@ free_signature_info(__ops_signature_info_t * sig)
}
static void
copy_signature_info(__ops_signature_info_t * dst, const __ops_signature_info_t * src)
copy_signature_info(__ops_signature_info_t * dst,
const __ops_signature_info_t * src)
{
(void) memcpy(dst, src, sizeof(*src));
dst->v4_hashed_data = calloc(1, src->v4_hashed_data_length);
(void) memcpy(dst->v4_hashed_data, src->v4_hashed_data, src->v4_hashed_data_length);
(void) memcpy(dst->v4_hashed_data, src->v4_hashed_data,
src->v4_hashed_data_length);
}
static void
add_sig_to_list(const __ops_signature_info_t *sig, __ops_signature_info_t **sigs,
unsigned *count)
add_sig_to_list(const __ops_signature_info_t *sig,
__ops_signature_info_t **sigs,
unsigned *count)
{
if (*count == 0) {
*sigs = calloc(*count + 1, sizeof(__ops_signature_info_t));
} else {
*sigs = realloc(*sigs, (*count + 1) * sizeof(__ops_signature_info_t));
*sigs = realloc(*sigs,
(*count + 1) * sizeof(__ops_signature_info_t));
}
copy_signature_info(&(*sigs)[*count], sig);
*count += 1;
@ -154,16 +158,18 @@ add_sig_to_list(const __ops_signature_info_t *sig, __ops_signature_info_t **sigs
__ops_parse_cb_return_t
__ops_validate_key_cb(const __ops_parser_content_t * contents, __ops_parse_cb_info_t * cbinfo)
__ops_validate_key_cb(const __ops_parser_content_t * contents,
__ops_parse_cb_info_t * cbinfo)
{
const __ops_parser_content_union_t *content = &contents->u;
validate_key_cb_t *key = __ops_parse_cb_get_arg(cbinfo);
__ops_error_t **errors = __ops_parse_cb_get_errors(cbinfo);
const __ops_keydata_t *signer;
bool valid = false;
const __ops_keydata_t *signer;
validate_key_cb_t *key = __ops_parse_cb_get_arg(cbinfo);
__ops_error_t **errors = __ops_parse_cb_get_errors(cbinfo);
bool valid = false;
if (__ops_get_debug_level(__FILE__))
if (__ops_get_debug_level(__FILE__)) {
printf("%s\n", __ops_show_packet_tag(contents->tag));
}
switch (contents->tag) {
case OPS_PTAG_CT_PUBLIC_KEY:
@ -191,7 +197,8 @@ __ops_validate_key_cb(const __ops_parser_content_t * contents, __ops_parse_cb_in
case OPS_PTAG_CT_USER_ATTRIBUTE:
assert(content->user_attribute.data.len);
printf("user attribute, length=%d\n", (int) content->user_attribute.data.len);
printf("user attribute, length=%d\n",
(int) content->user_attribute.data.len);
if (key->user_attribute.data.len)
__ops_user_attribute_free(&key->user_attribute);
key->user_attribute = content->user_attribute;
@ -259,7 +266,8 @@ __ops_validate_key_cb(const __ops_parser_content_t * contents, __ops_parse_cb_in
default:
OPS_ERROR_1(errors, OPS_E_UNIMPLEMENTED,
"Unexpected signature type 0x%02x\n", content->signature.info.type);
"Unexpected signature type 0x%02x\n",
content->signature.info.type);
}
if (valid) {
@ -267,7 +275,7 @@ __ops_validate_key_cb(const __ops_parser_content_t * contents, __ops_parse_cb_in
&key->result->valid_sigs,
&key->result->validc);
} else {
OPS_ERROR(errors, OPS_E_V_BAD_SIGNATURE, "Bad Signature");
OPS_ERROR(errors, OPS_E_V_BAD_SIGNATURE, "Bad Sig");
add_sig_to_list(&content->signature.info,
&key->result->invalid_sigs,
&key->result->invalidc);
@ -295,16 +303,18 @@ __ops_validate_key_cb(const __ops_parser_content_t * contents, __ops_parse_cb_in
}
__ops_parse_cb_return_t
validate_data_cb(const __ops_parser_content_t * contents, __ops_parse_cb_info_t * cbinfo)
validate_data_cb(const __ops_parser_content_t * contents,
__ops_parse_cb_info_t * cbinfo)
{
const __ops_parser_content_union_t *content = &contents->u;
validate_data_cb_t *data = __ops_parse_cb_get_arg(cbinfo);
__ops_error_t **errors = __ops_parse_cb_get_errors(cbinfo);
const __ops_keydata_t *signer;
bool valid = false;
const __ops_keydata_t *signer;
validate_data_cb_t *data = __ops_parse_cb_get_arg(cbinfo);
__ops_error_t **errors = __ops_parse_cb_get_errors(cbinfo);
bool valid = false;
if (__ops_get_debug_level(__FILE__)) {
printf("validate_data_cb: %s\n", __ops_show_packet_tag(contents->tag));
printf("validate_data_cb: %s\n",
__ops_show_packet_tag(contents->tag));
}
switch (contents->tag) {
case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER:
@ -338,14 +348,19 @@ validate_data_cb(const __ops_parser_content_t * contents, __ops_parse_cb_info_t
case OPS_PTAG_CT_SIGNATURE: /* V3 sigs */
case OPS_PTAG_CT_SIGNATURE_FOOTER: /* V4 sigs */
if (__ops_get_debug_level(__FILE__)) {
unsigned int zzz = 0;
unsigned i = 0;
printf("\n*** hashed data:\n");
for (zzz = 0; zzz < content->signature.info.v4_hashed_data_length; zzz++)
printf("0x%02x ", content->signature.info.v4_hashed_data[zzz]);
for (i = 0;
i < content->signature.info.v4_hashed_data_length;
i++) {
printf("0x%02x ",
content->signature.info.v4_hashed_data[i]);
}
printf("\n");
printf(" type=%02x signer_id=", content->signature.info.type);
printf(" type=%02x signer_id=",
content->signature.info.type);
hexdump(content->signature.info.signer_id,
sizeof(content->signature.info.signer_id), "");
printf("\n");
@ -353,7 +368,8 @@ validate_data_cb(const __ops_parser_content_t * contents, __ops_parse_cb_info_t
signer = __ops_keyring_find_key_by_id(data->keyring,
content->signature.info.signer_id);
if (!signer) {
OPS_ERROR(errors, OPS_E_V_UNKNOWN_SIGNER, "Unknown Signer");
OPS_ERROR(errors, OPS_E_V_UNKNOWN_SIGNER,
"Unknown Signer");
add_sig_to_list(&content->signature.info,
&data->result->unknown_sigs,
&data->result->unknownc);
@ -362,16 +378,17 @@ validate_data_cb(const __ops_parser_content_t * contents, __ops_parse_cb_info_t
switch (content->signature.info.type) {
case OPS_SIG_BINARY:
case OPS_SIG_TEXT:
valid = check_binary_signature(__ops_memory_get_length(data->mem),
__ops_memory_get_data(data->mem),
&content->signature,
__ops_get_public_key_from_data(signer));
valid = check_binary_signature(
__ops_memory_get_length(data->mem),
__ops_memory_get_data(data->mem),
&content->signature,
__ops_get_public_key_from_data(signer));
break;
default:
OPS_ERROR_1(errors, OPS_E_UNIMPLEMENTED,
"Verification of signature type 0x%02x not yet implemented\n", content->signature.info.type);
"No Sig Verification type 0x%02x yet\n",
content->signature.info.type);
break;
}
@ -383,7 +400,8 @@ validate_data_cb(const __ops_parser_content_t * contents, __ops_parse_cb_info_t
&data->result->valid_sigs,
&data->result->validc);
} else {
OPS_ERROR(errors, OPS_E_V_BAD_SIGNATURE, "Bad Signature");
OPS_ERROR(errors, OPS_E_V_BAD_SIGNATURE,
"Bad Signature");
add_sig_to_list(&content->signature.info,
&data->result->invalid_sigs,
&data->result->invalidc);
@ -413,7 +431,8 @@ keydata_destroyer(__ops_reader_info_t * rinfo)
}
void
__ops_keydata_reader_set(__ops_parse_info_t * pinfo, const __ops_keydata_t * key)
__ops_keydata_reader_set(__ops_parse_info_t *pinfo,
const __ops_keydata_t *key)
{
validate_reader_t *data = calloc(1, sizeof(*data));
@ -428,7 +447,8 @@ __ops_keydata_reader_set(__ops_parse_info_t * pinfo, const __ops_keydata_t * key
* \ingroup HighLevel_Verify
* \brief Indicicates whether any errors were found
* \param result Validation result to check
* \return false if any invalid signatures or unknown signers or no valid signatures; else true
* \return false if any invalid signatures or unknown signers
or no valid signatures; else true
*/
static bool
validate_result_status(__ops_validation_t *val)
@ -446,27 +466,10 @@ validate_result_status(__ops_validation_t *val)
* \return true if all signatures OK; else false
* \note It is the caller's responsiblity to free result after use.
* \sa __ops_validate_result_free()
Example Code:
\code
void example(const __ops_keydata_t* key, const __ops_keyring_t *keyring)
{
__ops_validation_t *result=NULL;
if (__ops_validate_key_signatures(result, key, keyring, callback_cmd_get_passphrase_from_cmdline)==true)
printf("OK");
else
printf("ERR");
printf("valid=%d, invalid=%d, unknown=%d\n",
result->validc,
result->invalidc,
result->unknownc);
__ops_validate_result_free(result);
}
\endcode
*/
bool
__ops_validate_key_signatures(__ops_validation_t * result, const __ops_keydata_t * key,
__ops_validate_key_signatures(__ops_validation_t * result,
const __ops_keydata_t * key,
const __ops_keyring_t * keyring,
__ops_parse_cb_return_t cb_get_passphrase(const __ops_parser_content_t *, __ops_parse_cb_info_t *)
)
@ -524,8 +527,10 @@ __ops_validate_all_signatures(__ops_validation_t * result,
int n;
(void) memset(result, 0x0, sizeof(*result));
for (n = 0; n < ring->nkeys; ++n)
__ops_validate_key_signatures(result, &ring->keys[n], ring, cb_get_passphrase);
for (n = 0; n < ring->nkeys; ++n) {
__ops_validate_key_signatures(result, &ring->keys[n], ring,
cb_get_passphrase);
}
return validate_result_status(result);
}
@ -536,20 +541,21 @@ __ops_validate_all_signatures(__ops_validation_t * result,
\note Must be called after validation functions
*/
void
__ops_validate_result_free(__ops_validation_t * result)
__ops_validate_result_free(__ops_validation_t *result)
{
if (!result)
return;
if (result->valid_sigs)
free_signature_info(result->valid_sigs);
if (result->invalid_sigs)
free_signature_info(result->invalid_sigs);
if (result->unknown_sigs)
free_signature_info(result->unknown_sigs);
free(result);
result = NULL;
if (result != NULL) {
if (result->valid_sigs) {
free_signature_info(result->valid_sigs);
}
if (result->invalid_sigs) {
free_signature_info(result->invalid_sigs);
}
if (result->unknown_sigs) {
free_signature_info(result->unknown_sigs);
}
(void) free(result);
result = NULL;
}
}
/**
@ -559,47 +565,30 @@ __ops_validate_result_free(__ops_validation_t * result)
\param filename Name of file to be validated
\param armoured Treat file as armoured, if set
\param keyring Keyring to use
\return true if signatures validate successfully; false if signatures fail or there are no signatures
\return true if signatures validate successfully;
false if signatures fail or there are no signatures
\note After verification, result holds the details of all keys which
have passed, failed and not been recognised.
\note It is the caller's responsiblity to call __ops_validate_result_free(result) after use.
Example code:
\code
void example(const char* filename, const int armoured, const __ops_keyring_t* keyring)
{
__ops_validation_t* result=calloc(1, sizeof(*result));
if (__ops_validate_file(result, filename, armoured, keyring)==true)
{
printf("OK");
// look at result for details of keys with good signatures
}
else
{
printf("ERR");
// look at result for details of failed signatures or unknown signers
}
__ops_validate_result_free(result);
}
\endcode
\note It is the caller's responsiblity to call
__ops_validate_result_free(result) after use.
*/
bool
__ops_validate_file(__ops_validation_t * result, const char *filename, const int armoured, const __ops_keyring_t * keyring)
__ops_validate_file(__ops_validation_t *result,
const char *filename,
const int armoured,
const __ops_keyring_t *keyring)
{
__ops_parse_info_t *pinfo = NULL;
validate_data_cb_t validation;
int fd = 0;
/* */
fd = __ops_setup_file_read(&pinfo, filename, &validation, validate_data_cb, true);
if (fd < 0)
fd = __ops_setup_file_read(&pinfo, filename, &validation,
validate_data_cb, true);
if (fd < 0) {
return false;
}
/* Set verification reader and handling options */
(void) memset(&validation, 0x0, sizeof(validation));
validation.result = result;
validation.keyring = keyring;
@ -609,22 +598,23 @@ __ops_validate_file(__ops_validation_t * result, const char *filename, const int
/* is never used. */
validation.rarg = pinfo->rinfo.arg;
if (armoured)
if (armoured) {
__ops_reader_push_dearmour(pinfo);
}
/* Do the verification */
__ops_parse(pinfo);
if (__ops_get_debug_level(__FILE__)) {
printf("valid=%d, invalid=%d, unknown=%d\n",
result->validc,
result->invalidc,
result->unknownc);
}
/* Tidy up */
if (armoured)
if (armoured) {
__ops_reader_pop_dearmour(pinfo);
}
__ops_teardown_file_read(pinfo, fd);
return validate_result_status(result);
@ -640,20 +630,21 @@ __ops_validate_file(__ops_validation_t * result, const char *filename, const int
\return true if signature validates successfully; false if not
\note After verification, result holds the details of all keys which
have passed, failed and not been recognised.
\note It is the caller's responsiblity to call __ops_validate_result_free(result) after use.
\note It is the caller's responsiblity to call
__ops_validate_result_free(result) after use.
*/
bool
__ops_validate_mem(__ops_validation_t *result, __ops_memory_t * mem, const int armoured, const __ops_keyring_t * keyring)
__ops_validate_mem(__ops_validation_t *result, __ops_memory_t *mem,
const int armoured, const __ops_keyring_t *keyring)
{
__ops_parse_info_t *pinfo = NULL;
validate_data_cb_t validation;
/* */
__ops_setup_memory_read(&pinfo, mem, &validation, validate_data_cb, true);
__ops_setup_memory_read(&pinfo, mem, &validation, validate_data_cb,
true);
/* Set verification reader and handling options */
(void) memset(&validation, 0x0, sizeof(validation));
validation.result = result;
validation.keyring = keyring;
@ -663,22 +654,23 @@ __ops_validate_mem(__ops_validation_t *result, __ops_memory_t * mem, const int a
/* is never used. */
validation.rarg = pinfo->rinfo.arg;
if (armoured)
if (armoured) {
__ops_reader_push_dearmour(pinfo);
}
/* Do the verification */
__ops_parse(pinfo);
if (__ops_get_debug_level(__FILE__)) {
printf("valid=%d, invalid=%d, unknown=%d\n",
result->validc,
result->invalidc,
result->unknownc);
}
/* Tidy up */
if (armoured)
if (armoured) {
__ops_reader_pop_dearmour(pinfo);
}
__ops_teardown_memory_read(pinfo, mem);
return validate_result_status(result);

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.3 2009/04/30 04:59:14 agc Exp $
# $NetBSD: Makefile,v 1.4 2009/05/02 02:38:55 agc Exp $
.include <bsd.own.mk>
@ -11,7 +11,7 @@ SRCS+= packet-print.c packet-show.c reader.c signature.c
SRCS+= symmetric.c validate.c writer.c
CPPFLAGS+= -I${EXTDIST}/include
MAN= libnetpgp.3
WARNS=3
WARNS=4
EXTDIST=${NETBSDSRCDIR}/crypto/external/bsd/netpgp/dist