1
0
Fork 0
mirror of https://github.com/deltachat/deltachat-core.git synced 2025-10-04 10:19:16 +02:00

Update netpgp.

This commit is contained in:
B. Petersen 2017-05-19 03:33:33 +02:00
parent 15a4434013
commit 11157137ad
46 changed files with 4887 additions and 7217 deletions

View file

@ -54,7 +54,7 @@
<Add directory="libs/libetpan/include" />
<Add directory="libs/libetpan/include/libetpan" />
<Add directory="libs/sqlite" />
<Add directory="libs/netpgp" />
<Add directory="libs/netpgp/include" />
</Compiler>
<Unit filename="README.md" />
<Unit filename="libs/libetpan/src/data-types/base64.c">
@ -372,58 +372,46 @@
<Unit filename="libs/libetpan/src/main/libetpan_version.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="libs/netpgp/bufgap.c">
<Unit filename="libs/netpgp/src/compress.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="libs/netpgp/compress.c">
<Unit filename="libs/netpgp/src/create.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="libs/netpgp/create.c">
<Unit filename="libs/netpgp/src/crypto.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="libs/netpgp/crypto.c">
<Unit filename="libs/netpgp/src/keyring.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="libs/netpgp/keyring.c">
<Unit filename="libs/netpgp/src/misc.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="libs/netpgp/misc.c">
<Unit filename="libs/netpgp/src/netpgp.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="libs/netpgp/mj.c">
<Unit filename="libs/netpgp/src/openssl_crypto.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="libs/netpgp/netpgp.c">
<Unit filename="libs/netpgp/src/packet-parse.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="libs/netpgp/openssl_crypto.c">
<Unit filename="libs/netpgp/src/packet-show.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="libs/netpgp/packet-parse.c">
<Unit filename="libs/netpgp/src/reader.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="libs/netpgp/packet-print.c">
<Unit filename="libs/netpgp/src/signature.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="libs/netpgp/packet-show.c">
<Unit filename="libs/netpgp/src/symmetric.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="libs/netpgp/reader.c">
<Unit filename="libs/netpgp/src/validate.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="libs/netpgp/signature.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="libs/netpgp/ssh2pgp.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="libs/netpgp/symmetric.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="libs/netpgp/validate.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="libs/netpgp/writer.c">
<Unit filename="libs/netpgp/src/writer.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="libs/sqlite/sqlite3.c">

View file

@ -1,12 +1,13 @@
#ifndef __NETPGP_EXTRA_H__
#define __NETPGP_EXTRA_H__
#include "netpgp/config-netpgp.h"
#include <netpgp.h>
#include "packet-parse.h"
#include "errors-netpgp.h"
#include "netpgpdefs.h"
#include "crypto-netpgp.h"
#include "create-netpgp.h"
#include "netpgp/packet-parse.h"
#include "netpgp/errors.h"
#include "netpgp/defs.h"
#include "netpgp/crypto.h"
#include "netpgp/create.h"
unsigned rsa_generate_keypair(pgp_key_t *keydata, const int numbits, const unsigned long e, const char *hashalg, const char *cipher);
#endif // __NETPGP_EXTRA_H__

View file

@ -57,9 +57,6 @@ typedef struct netpgp_t {
int netpgp_init(netpgp_t *);
int netpgp_end(netpgp_t *);
/* debugging, reflection and information */
int netpgp_set_debug(const char *);
int netpgp_get_debug(const char *);
const char *netpgp_get_info(const char *);
int netpgp_list_packets(netpgp_t *, char *, int, char *);
@ -78,6 +75,8 @@ int netpgp_list_keys_json(netpgp_t *, char **, const int);
int netpgp_find_key(netpgp_t *, char *);
char *netpgp_get_key(netpgp_t *, const char *, const char *);
char *netpgp_export_key(netpgp_t *, char *);
int netpgp_save_secring(netpgp_t *);
int netpgp_save_pubring(netpgp_t *);
int netpgp_import_key(netpgp_t *, char *);
int netpgp_generate_key(netpgp_t *, char *, int);

View file

@ -0,0 +1,160 @@
//
// config.h
// netpgp
#ifndef netpgp_config_h
#define netpgp_config_h
/* Define to 1 if you have the <bzlib.h> header file. */
#define HAVE_BZLIB_H 1
/* Define to 1 if you have the <CommonCrypto/CommonDigest.h> header file. */
#define HAVE_COMMONCRYPTO_COMMONDIGEST_H 1
/* Define to 1 if you have the <direct.h> header file. */
/* #undef HAVE_DIRECT_H */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the <dmalloc.h> header file. */
/* #undef HAVE_DMALLOC_H */
/* Define to 1 if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define to 1 if the system has the type 'long long int'. */
#define HAVE_LONG_LONG_INT 1
/* Define to 1 if you have the <malloc.h> header file. */
/* #undef HAVE_MALLOC_H */
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the <openssl/aes.h> header file. */
#define HAVE_OPENSSL_AES_H 1
/* Define to 1 if you have the <openssl/bn.h> header file. */
#define HAVE_OPENSSL_BN_H 1
/* Define to 1 if you have the <openssl/camellia.h> header file. */
/* #undef HAVE_OPENSSL_CAMELLIA_H */
/* Define to 1 if you have the <openssl/cast.h> header file. */
#define HAVE_OPENSSL_CAST_H 1
/* Define to 1 if you have the <openssl/des.h> header file. */
#define HAVE_OPENSSL_DES_H 1
/* Define to 1 if you have the <openssl/dsa.h> header file. */
#define HAVE_OPENSSL_DSA_H 1
/* Define to 1 if you have the <openssl/err.h> header file. */
#define HAVE_OPENSSL_ERR_H 1
/* Define to 1 if you have the <openssl/idea.h> header file. */
/* #undef HAVE_OPENSSL_IDEA_H */
/* Define to 1 if you have the <openssl/md5.h> header file. */
#define HAVE_OPENSSL_MD5_H 1
/* Define to 1 if you have the <openssl/rand.h> header file. */
#define HAVE_OPENSSL_RAND_H 1
/* Define to 1 if you have the <openssl/rsa.h> header file. */
#define HAVE_OPENSSL_RSA_H 1
/* Define to 1 if you have the <openssl/sha.h> header file. */
#define HAVE_OPENSSL_SHA_H 1
/* Define to 1 if the system has the type `SHA256_CTX'. */
#define HAVE_SHA256_CTX 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/cdefs.h> header file. */
#define HAVE_SYS_CDEFS_H 1
/* Define to 1 if you have the <sys/file.h> header file. */
#define HAVE_SYS_FILE_H 1
/* Define to 1 if you have the <sys/mman.h> header file. */
#define HAVE_SYS_MMAN_H 1
/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1
/* Define to 1 if you have the <sys/resource.h> header file. */
#define HAVE_SYS_RESOURCE_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/uio.h> header file. */
#define HAVE_SYS_UIO_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if the system has the type 'unsigned long long int'. */
#define HAVE_UNSIGNED_LONG_LONG_INT 1
/* Define to 1 if you have the <zlib.h> header file. */
#define HAVE_ZLIB_H 1
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "netpgp"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT " pEp NetPGP Team <netpgp@pep-project.org> "
/* Define to the full name of this package. */
#define PACKAGE_NAME "netpgp"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "netpgp beta0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "netpgp"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "beta0"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "beta0"
#define OPENSSL_NO_IDEA 1
#endif

View file

@ -52,13 +52,13 @@
#ifndef CREATE_H_
#define CREATE_H_
#include "types-netpgp.h"
#include "packet-netpgp.h"
#include "crypto-netpgp.h"
#include "errors-netpgp.h"
#include "keyring-netpgp.h"
#include "writer-netpgp.h"
#include "memory-netpgp.h"
#include "types.h"
#include "packet.h"
#include "crypto.h"
#include "errors.h"
#include "keyring.h"
#include "writer.h"
#include "memory.h"
/**
* \ingroup Create
@ -78,11 +78,17 @@ void pgp_build_pubkey(pgp_memory_t *, const pgp_pubkey_t *, unsigned);
unsigned pgp_calc_sesskey_checksum(pgp_pk_sesskey_t *, uint8_t *);
unsigned pgp_write_struct_userid(pgp_output_t *, const uint8_t *);
unsigned pgp_write_ss_header(pgp_output_t *, unsigned, pgp_content_enum);
unsigned pgp_write_ss_header(pgp_output_t *, size_t, pgp_content_enum);
unsigned pgp_write_struct_seckey_ptag(const pgp_seckey_t *key,
const uint8_t *passphrase,
const size_t pplen,
pgp_output_t *output,
pgp_content_enum ptag);
unsigned pgp_write_struct_seckey(const pgp_seckey_t *,
const uint8_t *,
const size_t,
pgp_output_t *);
unsigned pgp_write_struct_pubkey(pgp_output_t *, const pgp_pubkey_t *);
unsigned pgp_write_one_pass_sig(pgp_output_t *,
const pgp_seckey_t *,
const pgp_hash_alg_t,
@ -91,15 +97,11 @@ unsigned pgp_write_litdata(pgp_output_t *,
const uint8_t *,
const int,
const pgp_litdata_enum);
pgp_pk_sesskey_t *pgp_create_pk_sesskey(const pgp_key_t *, const char *);
pgp_pk_sesskey_t *pgp_create_pk_sesskey(pgp_key_t *, const char *, pgp_pk_sesskey_t *);
unsigned pgp_write_pk_sesskey(pgp_output_t *, pgp_pk_sesskey_t *);
unsigned pgp_write_xfer_pubkey(pgp_output_t *,
const pgp_key_t *, const unsigned);
unsigned pgp_write_xfer_seckey(pgp_output_t *,
const pgp_key_t *,
const uint8_t *,
const size_t,
const unsigned);
unsigned pgp_write_xfer_key(pgp_output_t *output,
const pgp_key_t *key,
const unsigned armoured);
void pgp_fast_create_userid(uint8_t **, uint8_t *);
unsigned pgp_write_userid(const uint8_t *, pgp_output_t *);

View file

@ -53,9 +53,9 @@
#ifndef CRYPTO_H_
#define CRYPTO_H_
#include "keyring-netpgp.h"
#include "packet-netpgp.h"
#include "memory-netpgp.h"
#include "keyring.h"
#include "packet.h"
#include "memory.h"
#include "packet-parse.h"
#include <openssl/dsa.h>
@ -100,6 +100,17 @@ struct pgp_crypt_t {
void *decrypt_key;
};
typedef struct pgp_validation_t {
unsigned validc;
pgp_sig_info_t *valid_sigs;
unsigned invalidc;
pgp_sig_info_t *invalid_sigs;
unsigned unknownc;
pgp_sig_info_t *unknown_sigs;
time_t birthtime;
time_t duration;
} pgp_validation_t;
void pgp_crypto_finish(void);
void pgp_hash_md5(pgp_hash_t *);
void pgp_hash_sha1(pgp_hash_t *);
@ -107,7 +118,7 @@ void pgp_hash_sha256(pgp_hash_t *);
void pgp_hash_sha512(pgp_hash_t *);
void pgp_hash_sha384(pgp_hash_t *);
void pgp_hash_sha224(pgp_hash_t *);
void pgp_hash_any(pgp_hash_t *, pgp_hash_alg_t);
unsigned pgp_hash_any(pgp_hash_t *, pgp_hash_alg_t);
pgp_hash_alg_t pgp_str_to_hash_alg(const char *);
const char *pgp_text_from_hash(pgp_hash_t *);
unsigned pgp_hash_size(pgp_hash_alg_t);
@ -190,8 +201,8 @@ unsigned pgp_decrypt_file(pgp_io_t *,
pgp_memory_t *
pgp_encrypt_buf(pgp_io_t *, const void *, const size_t,
const pgp_key_t *,
const unsigned, const char *);
const pgp_keyring_t *,
const unsigned, const char *, unsigned);
pgp_memory_t *
pgp_decrypt_buf(pgp_io_t *,
const void *,
@ -204,18 +215,35 @@ pgp_decrypt_buf(pgp_io_t *,
int,
pgp_cbfunc_t *);
pgp_memory_t *
pgp_decrypt_and_validate_buf(pgp_io_t *io,
pgp_validation_t *result,
const void *input,
const size_t insize,
pgp_keyring_t *secring,
pgp_keyring_t *pubring,
const unsigned use_armour,
key_id_t **recipients_key_ids,
unsigned *recipients_count);
/* Keys */
pgp_key_t *pgp_rsa_new_selfsign_key(const int,
const unsigned long, const uint8_t *, const char *,
const char *);
unsigned pgp_rsa_generate_keypair(pgp_key_t *,
const int,
const unsigned long,
const char *,
const char *,
const uint8_t *,
const size_t);
int pgp_dsa_size(const pgp_dsa_pubkey_t *);
DSA_SIG *pgp_dsa_sign(uint8_t *, unsigned,
pgp_dsa_sig_t *pgp_dsa_sign(uint8_t *, unsigned,
const pgp_dsa_seckey_t *,
const pgp_dsa_pubkey_t *);
int openssl_read_pem_seckey(const char *, pgp_key_t *, const char *, int);
/** pgp_reader_t */
struct pgp_reader_t {
pgp_reader_func_t *reader; /* reader func to get parse data */
@ -228,6 +256,13 @@ struct pgp_reader_t {
unsigned position; /* reader-specific offset */
pgp_reader_t *next;
pgp_stream_t *parent;/* parent parse_info structure */
unsigned partial_read:1;
unsigned coalescing:1;
/* used for partial length coalescing */
unsigned virtualc;
unsigned virtualoff;
uint8_t *virtualpkt;
};
@ -237,9 +272,10 @@ struct pgp_reader_t {
struct pgp_cryptinfo_t {
char *passphrase;
pgp_keyring_t *secring;
const pgp_key_t *keydata;
pgp_key_t *keydata;
pgp_cbfunc_t *getpassphrase;
pgp_keyring_t *pubring;
DYNARRAY(key_id_t, recipients_key_ids);
};
/** pgp_cbdata_t */
@ -301,15 +337,10 @@ struct pgp_stream_t {
pgp_cryptinfo_t cryptinfo;
size_t hashc;
pgp_hashtype_t *hashes;
unsigned reading_v3_secret:1;
unsigned reading_mpi_len:1;
unsigned exact_read:1;
unsigned partial_read:1;
unsigned coalescing:1;
/* used for partial length coalescing */
unsigned virtualc;
unsigned virtualoff;
uint8_t *virtualpkt;
//unsigned reading_v3_secret:1;
//unsigned reading_mpi_len:1;
//unsigned exact_read:1;
};
#endif /* CRYPTO_H_ */

View file

@ -1,4 +1,4 @@
/* $NetBSD: defs.h,v 1.2 2009/12/06 17:43:05 agc Exp $ */
/* $NetBSD$ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.

View file

@ -0,0 +1,206 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
* All rights reserved.
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
* their moral rights under the UK Copyright Design and Patents Act 1988 to
* be recorded as the authors of this copyright work.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** \file
*/
#ifndef KEYRING_H_
#define KEYRING_H_
#include "packet.h"
#include "packet-parse.h"
#include "memory.h"
enum {
MAX_ID_LENGTH = 128,
MAX_PASSPHRASE_LENGTH = 256
};
typedef struct pgp_key_t pgp_key_t;
/** \struct pgp_keyring_t
* A keyring
*/
typedef struct pgp_keyring_t {
DYNARRAY(pgp_key_t, key);
pgp_hash_alg_t hashtype;
} pgp_keyring_t;
pgp_key_t *pgp_getkeybyid(pgp_io_t *,
const pgp_keyring_t *,
const uint8_t *,
unsigned *,
pgp_pubkey_t **,
pgp_seckey_t **,
unsigned checkrevoke,
unsigned checkexpiry);
unsigned pgp_deletekeybyid(pgp_io_t *,
pgp_keyring_t *,
const uint8_t *);
pgp_key_t *pgp_getkeybyfpr(pgp_io_t *,
const pgp_keyring_t *,
const uint8_t *fpr,
size_t length,
unsigned *from,
pgp_pubkey_t **,
unsigned checkrevoke,
unsigned checkexpiry);
unsigned pgp_deletekeybyfpr(pgp_io_t *,
pgp_keyring_t *,
const uint8_t *fpr,
size_t length);
const pgp_key_t *pgp_getkeybyname(pgp_io_t *,
const pgp_keyring_t *,
const char *);
const pgp_key_t *pgp_getnextkeybyname(pgp_io_t *,
const pgp_keyring_t *,
const char *,
unsigned *);
void pgp_key_free(pgp_key_t *);
void pgp_keydata_free(pgp_key_t *);
void pgp_keyring_free(pgp_keyring_t *);
void pgp_keyring_purge(pgp_keyring_t *);
void pgp_dump_keyring(const pgp_keyring_t *);
pgp_pubkey_t *pgp_key_get_pubkey(pgp_key_t *);
unsigned pgp_is_key_secret(pgp_key_t *);
pgp_seckey_t *pgp_get_seckey(pgp_key_t *);
pgp_seckey_t *pgp_get_writable_seckey(pgp_key_t *);
// pgp_seckey_t *pgp_decrypt_seckey(const pgp_key_t *, void *);
unsigned
pgp_keyring_fileread(pgp_io_t *io,
pgp_keyring_t *pubring,
pgp_keyring_t *secring,
const unsigned armour,
const char *filename);
unsigned
pgp_keyring_read_from_mem(pgp_io_t *io,
pgp_keyring_t *pubring,
pgp_keyring_t *secring,
const unsigned armour,
pgp_memory_t *mem);
int pgp_keyring_list(pgp_io_t *, const pgp_keyring_t *, const int);
void pgp_forget(void *, unsigned);
// uint8_t *pgp_add_userid(pgp_key_t *, const uint8_t *);
unsigned pgp_update_userid(
pgp_key_t *key,
const uint8_t *userid,
const pgp_subpacket_t *sigpkt,
pgp_sig_info_t *siginfo);
// pgp_subpacket_t *pgp_add_subpacket(pgp_key_t *,
// const pgp_subpacket_t *);
// pgp_subpacket_t *pgp_replace_subpacket(pgp_key_t *,
// const pgp_subpacket_t *,
// unsigned );
unsigned pgp_add_selfsigned_userid(pgp_key_t *skey, pgp_key_t *pkey, const uint8_t *userid, time_t duration);
pgp_key_t *pgp_keydata_new(void);
void pgp_keydata_init(pgp_key_t *, const pgp_content_enum);
char *pgp_export_key(pgp_io_t *, const pgp_key_t *, uint8_t *);
int pgp_keyring_add(pgp_keyring_t *, const pgp_key_t *);
// int pgp_add_to_pubring(pgp_keyring_t *, const pgp_pubkey_t *, pgp_content_enum tag);
pgp_key_t *pgp_ensure_pubkey(
pgp_keyring_t *,
pgp_pubkey_t *,
uint8_t *);
pgp_key_t *pgp_ensure_seckey(
pgp_keyring_t *keyring,
pgp_seckey_t *seckey,
uint8_t *pubkeyid);
unsigned pgp_add_directsig(
pgp_key_t *key,
const pgp_subpacket_t *sigpkt,
pgp_sig_info_t *siginfo);
unsigned pgp_update_subkey(
pgp_key_t *key,
pgp_content_enum subkeytype,
pgp_keydata_key_t *subkey,
const pgp_subpacket_t *sigpkt,
pgp_sig_info_t *siginfo);
// int pgp_add_to_secring(pgp_keyring_t *, const pgp_seckey_t *);
int pgp_append_keyring(pgp_keyring_t *, pgp_keyring_t *);
pgp_subpacket_t * pgp_copy_packet(pgp_subpacket_t *, const pgp_subpacket_t *);
uint8_t * pgp_copy_userid(uint8_t **dst, const uint8_t *src);
const int32_t pgp_key_get_uid0(pgp_key_t *keydata);
const uint8_t *pgp_key_get_primary_userid(pgp_key_t *key);
pgp_pubkey_t * pgp_key_get_sigkey(pgp_key_t *key);
pgp_seckey_t * pgp_key_get_certkey(pgp_key_t *key);
pgp_pubkey_t * pgp_key_get_enckey(pgp_key_t *key, const uint8_t **id);
pgp_seckey_t * pgp_key_get_deckey(pgp_key_t *key, const uint8_t **id);
const int32_t
pgp_key_find_uid_cond(
const pgp_key_t *key,
unsigned(*uidcond) ( uint8_t *, void *),
void *uidcondarg,
unsigned(*sigcond) ( const pgp_sig_info_t *, void *),
void *sigcondarg,
time_t *youngest,
unsigned checkrevoke,
unsigned checkexpiry);
const pgp_key_rating_t pgp_key_get_rating(pgp_key_t *key);
unsigned
pgp_key_revoke(pgp_key_t *skey, pgp_key_t *pkey, uint8_t code, const char *reason);
#endif /* KEYRING_H_ */

View file

@ -54,7 +54,7 @@
#include <sys/types.h>
#include "packet-netpgp.h"
#include "packet.h"
/** pgp_memory_t
*/

View file

@ -65,8 +65,4 @@ void *pgp_new(size_t);
} \
} while(/* CONSTCOND */0)
#ifndef MIN
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#endif
#endif /* !NETPGPDEFS_H_ */

View file

@ -50,6 +50,7 @@
/* SHA1 Hash Size */
#define PGP_SHA1_HASH_SIZE SHA_DIGEST_LENGTH
#define PGP_SHA256_HASH_SIZE SHA256_DIGEST_LENGTH
#define PGP_SHA512_HASH_SIZE SHA512_DIGEST_LENGTH
#define PGP_CHECKHASH_SIZE PGP_SHA1_HASH_SIZE
#endif /* NETPGPDIGEST_H_ */

View file

@ -29,34 +29,17 @@
#ifndef NETPGPSDK_H_
#define NETPGPSDK_H_
#include "keyring-netpgp.h"
#include "crypto-netpgp.h"
#include "signature-netpgp.h"
#include "keyring.h"
#include "crypto.h"
#include "signature.h"
#include "packet-show.h"
#ifndef __printflike
#define __printflike(n, m) __attribute__((format(printf,n,m)))
#endif
typedef struct pgp_validation_t {
unsigned validc;
pgp_sig_info_t *valid_sigs;
unsigned invalidc;
pgp_sig_info_t *invalid_sigs;
unsigned unknownc;
pgp_sig_info_t *unknown_sigs;
time_t birthtime;
time_t duration;
} pgp_validation_t;
void pgp_validate_result_free(pgp_validation_t *);
unsigned
pgp_validate_key_sigs(pgp_validation_t *,
const pgp_key_t *,
const pgp_keyring_t *,
pgp_cb_ret_t cb(const pgp_packet_t *, pgp_cbdata_t *));
unsigned
pgp_validate_all_sigs(pgp_validation_t *,
const pgp_keyring_t *,
@ -74,5 +57,4 @@ void netpgp_log(const char *, ...) __printflike(1, 2);
int netpgp_strcasecmp(const char *, const char *);
char *netpgp_strdup(const char *);
#endif

View file

@ -0,0 +1,133 @@
int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
{
/* If the fields n and e in r are NULL, the corresponding input
* parameters MUST be non-NULL for n and e. d may be
* left NULL (in case only the public key is used).
*/
if ((r->n == NULL && n == NULL)
|| (r->e == NULL && e == NULL))
return 0;
if (n != NULL) {
BN_free(r->n);
r->n = n;
}
if (e != NULL) {
BN_free(r->e);
r->e = e;
}
if (d != NULL) {
BN_free(r->d);
r->d = d;
}
return 1;
}
int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
{
/* If the fields p and q in r are NULL, the corresponding input
* parameters MUST be non-NULL.
*/
if ((r->p == NULL && p == NULL)
|| (r->q == NULL && q == NULL))
return 0;
if (p != NULL) {
BN_free(r->p);
r->p = p;
}
if (q != NULL) {
BN_free(r->q);
r->q = q;
}
return 1;
}
void RSA_get0_key(const RSA *r,
const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
{
if (n != NULL)
*n = r->n;
if (e != NULL)
*e = r->e;
if (d != NULL)
*d = r->d;
}
void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
{
if (p != NULL)
*p = r->p;
if (q != NULL)
*q = r->q;
}
int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s)
{
if (r == NULL || s == NULL)
return 0;
BN_clear_free(sig->r);
BN_clear_free(sig->s);
sig->r = r;
sig->s = s;
return 1;
}
void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
{
if (pr != NULL)
*pr = sig->r;
if (ps != NULL)
*ps = sig->s;
}
int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
{
/* If the fields p, q and g in d are NULL, the corresponding input
* parameters MUST be non-NULL.
*/
if ((d->p == NULL && p == NULL)
|| (d->q == NULL && q == NULL)
|| (d->g == NULL && g == NULL))
return 0;
if (p != NULL) {
BN_free(d->p);
d->p = p;
}
if (q != NULL) {
BN_free(d->q);
d->q = q;
}
if (g != NULL) {
BN_free(d->g);
d->g = g;
}
return 1;
}
int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
{
/* If the field pub_key in d is NULL, the corresponding input
* parameters MUST be non-NULL. The priv_key field may
* be left NULL.
*/
if (d->pub_key == NULL && pub_key == NULL)
return 0;
if (pub_key != NULL) {
BN_free(d->pub_key);
d->pub_key = pub_key;
}
if (priv_key != NULL) {
BN_free(d->priv_key);
d->priv_key = priv_key;
}
return 1;
}

View file

@ -54,8 +54,8 @@
#ifndef PACKET_PARSE_H_
#define PACKET_PARSE_H_
#include "types-netpgp.h"
#include "packet-netpgp.h"
#include "types.h"
#include "packet.h"
/** pgp_region_t */
typedef struct pgp_region_t {
@ -166,4 +166,7 @@ int pgp_decompress(pgp_region_t *, pgp_stream_t *,
unsigned pgp_writez(pgp_output_t *, const uint8_t *,
const unsigned);
void
copy_sig_info(pgp_sig_info_t *dst, const pgp_sig_info_t *src);
#endif /* PACKET_PARSE_H_ */

View file

@ -53,7 +53,7 @@
#ifndef PACKET_SHOW_H_
#define PACKET_SHOW_H_
#include "packet-netpgp.h"
#include "packet.h"
/** pgp_list_t
*/
@ -86,10 +86,8 @@ const char *pgp_show_ss_type(pgp_content_enum);
const char *pgp_show_sig_type(pgp_sig_type_t);
const char *pgp_show_pka(pgp_pubkey_alg_t);
pgp_text_t *pgp_showall_ss_zpref(const pgp_data_t *);
const char *pgp_show_ss_zpref(uint8_t);
pgp_text_t *pgp_showall_ss_hashpref(const pgp_data_t *);
const char *pgp_show_hash_alg(uint8_t);
const char *pgp_show_symm_alg(uint8_t);
@ -100,10 +98,8 @@ const char *pgp_show_ss_rr_code(pgp_ss_rr_code_t);
pgp_text_t *pgp_showall_ss_features(pgp_data_t);
pgp_text_t *pgp_showall_ss_key_flags(const pgp_data_t *);
const char *pgp_show_ss_key_flag(uint8_t, pgp_bit_map_t *);
pgp_text_t *pgp_show_keyserv_prefs(const pgp_data_t *);
const char *pgp_show_keyserv_pref(uint8_t, pgp_bit_map_t *);
pgp_text_t *pgp_showall_notation(pgp_ss_notation_t);

View file

@ -54,16 +54,16 @@
#ifndef PACKET_H_
#define PACKET_H_
#include "config-netpgp.h"
#include <time.h>
#ifdef HAVE_OPENSSL_BN_H
#include <openssl/bn.h>
#endif
#include "types-netpgp.h"
#include "errors-netpgp.h"
#include <openssl/ossl_typ.h>
#include "types.h"
#include "errors.h"
/* structure to keep track of printing state variables */
typedef struct pgp_printstate_t {
@ -620,6 +620,8 @@ typedef struct pgp_sig_info_t {
pgp_sig_type_t type; /* signature type value */
time_t birthtime; /* creation time of the signature */
time_t duration; /* number of seconds it's valid for */
time_t key_expiry; /* number of seconds key is valid for */
uint8_t key_flags;
uint8_t signer_id[PGP_KEY_ID_SIZE]; /* Eight-octet key ID
* of signer */
pgp_pubkey_alg_t key_alg; /* public key algorithm number */
@ -635,8 +637,21 @@ typedef struct pgp_sig_info_t {
unsigned birthtime_set:1;
unsigned signer_id_set:1;
unsigned duration_set:1;
unsigned key_expiry_set:1;
unsigned key_flags_set:1;
unsigned primary_userid:1;
} pgp_sig_info_t;
typedef enum {
PGP_KEYFLAG_CERT_KEYS = 0x01,
PGP_KEYFLAG_SIGN_DATA = 0x02,
PGP_KEYFLAG_ENC_COMM = 0x04,
PGP_KEYFLAG_ENC_STORAGE = 0x08,
PGP_KEYFLAG_SPLIT = 0x10,
PGP_KEYFLAG_AUTH = 0x20,
PGP_KEYFLAG_GROUP = 0x80
} pgp_key_flags_t;
/** Struct used when parsing a signature */
typedef struct pgp_sig_t {
pgp_sig_info_t info; /* The signature information */
@ -789,9 +804,10 @@ typedef union {
} pgp_pk_sesskey_params_t;
/** pgp_pk_sesskey_t */
typedef uint8_t key_id_t[PGP_KEY_ID_SIZE];
typedef struct {
unsigned version;
uint8_t key_id[PGP_KEY_ID_SIZE];
key_id_t key_id;
pgp_pubkey_alg_t alg;
pgp_pk_sesskey_params_t params;
pgp_symm_alg_t symm_alg;
@ -886,6 +902,7 @@ int pgp_fingerprint(pgp_fingerprint_t *, const pgp_pubkey_t *, pgp_hash_alg_t);
void pgp_finish(void);
void pgp_pubkey_free(pgp_pubkey_t *);
int pgp_pubkey_dup(pgp_pubkey_t *,pgp_pubkey_t *);
void pgp_userid_free(uint8_t **);
void pgp_data_free(pgp_data_t *);
void pgp_sig_free(pgp_sig_t *);
@ -896,10 +913,9 @@ void pgp_ss_sig_target_free(pgp_ss_sig_target_t *);
void pgp_subpacket_free(pgp_subpacket_t *);
void pgp_parser_content_free(pgp_packet_t *);
void pgp_seckey_free(pgp_seckey_t *);
int pgp_seckey_dup(pgp_seckey_t *,pgp_seckey_t *);
void pgp_pk_sesskey_free(pgp_pk_sesskey_t *);
int pgp_print_packet(pgp_printstate_t *, const pgp_packet_t *);
#define DYNARRAY(type, arr) \
unsigned arr##c; unsigned arr##vsize; type *arr##s
@ -921,6 +937,21 @@ int pgp_print_packet(pgp_printstate_t *, const pgp_packet_t *);
} \
} while(/*CONSTCOND*/0)
#define FREE_ARRAY(str, arr) do { \
if (str->arr##s) { \
free(str->arr##s); \
str->arr##s = NULL; \
str->arr##vsize = 0; \
str->arr##c = 0; \
} \
} while(/*CONSTCOND*/0)
#define INIT_ARRAY(str, arr) do { \
str->arr##s = NULL; \
str->arr##vsize = 0; \
str->arr##c = 0; \
} while(/*CONSTCOND*/0)
/** pgp_keydata_key_t
*/
typedef union {
@ -928,47 +959,59 @@ typedef union {
pgp_seckey_t seckey;
} pgp_keydata_key_t;
/* sigpacket_t */
typedef struct {
uint8_t **userid;
pgp_subpacket_t *packet;
} sigpacket_t;
/* user revocation info */
typedef struct pgp_revoke_t {
uint32_t uid; /* index in uid array */
uint8_t code; /* revocation code */
char *reason; /* c'mon, spill the beans */
} pgp_revoke_t;
/** signature subpackets */
typedef struct pgp_subsig_t {
/** userid signature subpackets */
typedef struct pgp_uidsig_t {
uint32_t uid; /* index in userid array in key */
pgp_sig_t sig; /* trust signature */
pgp_sig_info_t siginfo;
uint8_t trustlevel; /* level of trust */
uint8_t trustamount; /* amount of trust */
} pgp_subsig_t;
pgp_subpacket_t packet;
} pgp_uidsig_t;
/** subkey signature subpackets */
typedef struct pgp_subkeysig_t {
uint32_t subkey; /* index of subkey in array */
pgp_sig_info_t siginfo;
pgp_subpacket_t packet;
} pgp_subkeysig_t;
typedef struct pgp_subkey_t {
pgp_keydata_key_t key; /* pubkey/seckey data */
uint8_t id[PGP_KEY_ID_SIZE];
} pgp_subkey_t;
typedef struct pgp_directsig_t {
pgp_sig_info_t siginfo;
pgp_subpacket_t packet;
} pgp_directsig_t;
/* describes a user's key */
struct pgp_key_t {
DYNARRAY(uint8_t *, uid); /* array of user ids */
DYNARRAY(pgp_subpacket_t, packet); /* array of raw subpackets */
DYNARRAY(pgp_subsig_t, subsig); /* array of signature subkeys */
DYNARRAY(pgp_revoke_t, revoke); /* array of signature revocations */
pgp_content_enum type; /* type of key */
pgp_keydata_key_t key; /* pubkey/seckey data */
pgp_pubkey_t sigkey; /* signature key */
uint8_t sigid[PGP_KEY_ID_SIZE];
pgp_fingerprint_t sigfingerprint; /* pgp signature fingerprint */
pgp_pubkey_t enckey; /* encryption key */
uint8_t encid[PGP_KEY_ID_SIZE];
pgp_fingerprint_t encfingerprint; /* pgp encryption id fingerprint */
uint32_t uid0; /* primary uid index in uids array */
uint8_t revoked; /* key has been revoked */
pgp_revoke_t revocation; /* revocation reason */
DYNARRAY(pgp_directsig_t, directsig); /* direct signatures */
DYNARRAY(uint8_t *, uid); /* array of user ids */
DYNARRAY(pgp_uidsig_t, uidsig); /* array of signature for user ids */
/* TODO user attributes */
DYNARRAY(pgp_subkey_t, subkey); /* array of subkeys */
DYNARRAY(pgp_subkeysig_t, subkeysig); /* array of sigs for subkeys */
uint8_t pubkeyid[PGP_KEY_ID_SIZE];
pgp_fingerprint_t pubkeyfpr; /* pgp signature fingerprint */
};
#define MDC_PKT_TAG 0xd3
typedef enum {
PGP_VALID,
PGP_WEAK,
PGP_TOOSHORT,
PGP_INVALID,
PGP_EXPIRED,
PGP_REVOKED
} pgp_key_rating_t;
#define MDC_PKT_TAG 0xd3
#endif /* PACKET_H_ */

View file

@ -50,9 +50,9 @@
#ifndef READERWRITER_H_
#define READERWRITER_H_
#include "create-netpgp.h"
#include "create.h"
#include "memory-netpgp.h"
#include "memory.h"
/* if this is defined, we'll use mmap in preference to file ops */
#define USE_MMAP_FOR_FILES 1
@ -75,7 +75,7 @@ unsigned pgp_write_se_ip_pktset(pgp_output_t *, const uint8_t *,
const unsigned,
pgp_crypt_t *);
void pgp_push_enc_crypt(pgp_output_t *, pgp_crypt_t *);
int pgp_push_enc_se_ip(pgp_output_t *, const pgp_key_t *, const char *);
int pgp_push_enc_se_ip(pgp_output_t *, const pgp_keyring_t *, const char *, unsigned);
/* Secret Key checksum */
void pgp_push_checksum_writer(pgp_output_t *, pgp_seckey_t *);

View file

@ -57,9 +57,9 @@
#include <inttypes.h>
#include "packet-netpgp.h"
#include "create-netpgp.h"
#include "memory-netpgp.h"
#include "packet.h"
#include "create.h"
#include "memory.h"
typedef struct pgp_create_sig_t pgp_create_sig_t;
@ -69,22 +69,18 @@ void pgp_create_sig_delete(pgp_create_sig_t *);
unsigned pgp_check_useridcert_sig(const pgp_pubkey_t *,
const uint8_t *,
const pgp_sig_t *,
const pgp_pubkey_t *,
const uint8_t *);
const pgp_pubkey_t *);
unsigned pgp_check_userattrcert_sig(const pgp_pubkey_t *,
const pgp_data_t *,
const pgp_sig_t *,
const pgp_pubkey_t *,
const uint8_t *);
const pgp_pubkey_t *);
unsigned pgp_check_subkey_sig(const pgp_pubkey_t *,
const pgp_pubkey_t *,
const pgp_sig_t *,
const pgp_pubkey_t *,
const uint8_t *);
const pgp_pubkey_t *);
unsigned pgp_check_direct_sig(const pgp_pubkey_t *,
const pgp_sig_t *,
const pgp_pubkey_t *,
const uint8_t *);
const pgp_pubkey_t *);
unsigned pgp_check_hash_sig(pgp_hash_t *,
const pgp_sig_t *,
const pgp_pubkey_t *);
@ -102,19 +98,31 @@ pgp_hash_t *pgp_sig_get_hash(pgp_create_sig_t *);
unsigned pgp_end_hashed_subpkts(pgp_create_sig_t *);
unsigned pgp_write_sig(pgp_output_t *, pgp_create_sig_t *,
const pgp_pubkey_t *, const pgp_seckey_t *);
unsigned pgp_add_time(pgp_create_sig_t *, int64_t, const char *);
unsigned pgp_add_issuer_keyid(pgp_create_sig_t *,
const uint8_t *);
void pgp_add_primary_userid(pgp_create_sig_t *, unsigned);
unsigned
pgp_add_creation_time(pgp_create_sig_t *sig, time_t when);
unsigned
pgp_add_sig_expiration_time(pgp_create_sig_t *sig, time_t duration);
unsigned
pgp_add_key_expiration_time(pgp_create_sig_t *sig, time_t duration);
unsigned
pgp_add_key_flags(pgp_create_sig_t *sig, uint8_t flags);
unsigned
pgp_add_key_prefs(pgp_create_sig_t *sig);
unsigned
pgp_add_key_features(pgp_create_sig_t *sig);
/* Standard Interface */
unsigned pgp_sign_file(pgp_io_t *,
const char *,
const char *,
const pgp_seckey_t *,
const char *,
const int64_t,
const uint64_t,
const time_t,
const time_t,
const unsigned,
const unsigned,
const unsigned);
@ -122,10 +130,10 @@ unsigned pgp_sign_file(pgp_io_t *,
int pgp_sign_detached(pgp_io_t *,
const char *,
char *,
pgp_seckey_t *,
const pgp_seckey_t *,
const char *,
const int64_t,
const uint64_t,
const time_t,
const time_t,
const unsigned,
const unsigned);
@ -157,15 +165,33 @@ pgp_memory_t *pgp_sign_buf(pgp_io_t *,
const void *,
const size_t,
const pgp_seckey_t *,
const int64_t,
const uint64_t,
const time_t,
const time_t,
const char *,
const unsigned,
const unsigned);
unsigned pgp_keyring_read_from_mem(pgp_io_t *,
pgp_keyring_t *,
const unsigned,
pgp_memory_t *);
/** \ingroup Core_Create
* needed for signature creation
*/
struct pgp_create_sig_t {
pgp_hash_t hash;
pgp_sig_t sig;
pgp_memory_t *mem;
pgp_output_t *output; /* how to do the writing */
unsigned hashoff; /* hashed count offset */
unsigned hashlen;
unsigned unhashoff;
};
void
pgp_sig_start_key_rev(pgp_create_sig_t *sig,
const pgp_pubkey_t *key,
pgp_sig_type_t type);
unsigned
pgp_add_revocation_reason(
pgp_create_sig_t *sig,
uint8_t code, const char *reason);
#endif /* SIGNATURE_H_ */

View file

@ -49,8 +49,6 @@
#ifndef TYPES_H_
#define TYPES_H_
#include "config-netpgp.h"
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif

View file

@ -49,29 +49,36 @@
#ifndef VALIDATE_H_
#define VALIDATE_H_ 1
typedef struct {
const pgp_key_t *key;
unsigned packet;
unsigned offset;
} validate_reader_t;
/** Struct used with the validate_key_cb callback */
typedef struct {
pgp_pubkey_t pubkey;
pgp_pubkey_t subkey;
pgp_seckey_t seckey;
typedef struct validate_key_cb_t{
pgp_content_enum type; /* type of key */
pgp_keydata_key_t key; /* pubkey/seckey data */
pgp_keydata_key_t subkey;
uint8_t pubkeyid[PGP_KEY_ID_SIZE];
enum {
ATTRIBUTE = 1,
ID
LS_UNKNOWN = 0,
LS_ATTRIBUTE,
LS_ID,
LS_SUBKEY,
LS_PRIMARY,
} last_seen;
uint8_t *userid;
pgp_data_t userattr;
uint8_t hash[PGP_MAX_HASH_SIZE];
const pgp_keyring_t *keyring;
validate_reader_t *reader;
pgp_validation_t *result;
pgp_cb_ret_t(*getpassphrase) (const pgp_packet_t *,
pgp_cbdata_t *);
unsigned not_commited; /* tells on_valid it is first commit of that key */
pgp_sig_info_t valid_sig_info; /* store last valid sig info */
unsigned sig_is_valid; /* condition to call on_valid at packet end */
pgp_cb_ret_t(*on_valid) ( /* callback for action on valid sig */
struct validate_key_cb_t *, /* this struct */
const pgp_subpacket_t *); /* sig packet */
void *on_valid_args; /* pointer to argument for on_valid callback */
} validate_key_cb_t;
/** Struct use with the validate_data_cb callback */
@ -87,13 +94,10 @@ typedef struct {
uint8_t hash[PGP_MAX_HASH_SIZE];
pgp_memory_t *mem;
const pgp_keyring_t *keyring;
validate_reader_t *reader;/* reader-specific arg */
pgp_validation_t *result;
char *detachname;
} validate_data_cb_t;
void pgp_keydata_reader_set(pgp_stream_t *, const pgp_key_t *);
pgp_cb_ret_t pgp_validate_key_cb(const pgp_packet_t *, pgp_cbdata_t *);
unsigned check_binary_sig(const uint8_t *,
@ -115,6 +119,30 @@ unsigned pgp_validate_mem(pgp_io_t *,
const int,
const pgp_keyring_t *);
pgp_cb_ret_t validate_data_cb(const pgp_packet_t *, pgp_cbdata_t *);
unsigned pgp_validate_mem_detached(pgp_io_t *,
pgp_validation_t *,
pgp_memory_t *,
pgp_memory_t **,
const int,
const pgp_keyring_t *,
pgp_memory_t *);
pgp_cb_ret_t validate_data_cb(const pgp_packet_t *, pgp_cbdata_t *);
void pgp_free_sig_info(pgp_sig_info_t *);
unsigned
pgp_filter_keys_fileread(pgp_io_t *io,
pgp_keyring_t *destpubring,
pgp_keyring_t *destsecring,
pgp_keyring_t *certring,
const unsigned armour,
const char *filename);
unsigned
pgp_filter_keys_from_mem(pgp_io_t *io,
pgp_keyring_t *destpubring,
pgp_keyring_t *destsecring,
pgp_keyring_t *certring,
const unsigned armour,
pgp_memory_t *mem);
#endif /* !VALIDATE_H_ */

View file

@ -58,9 +58,9 @@
#endif
/* development versions have .99 suffix */
#define NETPGP_BASE_VERSION "3.99.17"
#define NETPGP_BASE_VERSION "3.99.99"
#define NETPGP_VERSION_CAT(a, b) "NetPGP portable " a "/[" b "]"
#define NETPGP_VERSION_CAT(a, b) "NetPGP for pEp " a "/[" b "]"
#define NETPGP_VERSION_STRING \
NETPGP_VERSION_CAT(NETPGP_BASE_VERSION, NETPGP_AUTOCONF_VERSION)

View file

@ -53,11 +53,11 @@
#ifndef WRITER_H_
#define WRITER_H_
#include "types-netpgp.h"
#include "packet-netpgp.h"
#include "crypto-netpgp.h"
#include "errors-netpgp.h"
#include "keyring-netpgp.h"
#include "types.h"
#include "packet.h"
#include "crypto.h"
#include "errors.h"
#include "keyring.h"
/**
* \ingroup Writer
@ -114,6 +114,10 @@ unsigned pgp_write_mpi(pgp_output_t *, const BIGNUM *);
void pgp_writer_info_delete(pgp_writer_t *);
unsigned pgp_writer_info_finalise(pgp_error_t **, pgp_writer_t *);
void pgp_push_stream_enc_se_ip(pgp_output_t *, const pgp_key_t *, const char *);
void pgp_push_stream_enc_se_ip(pgp_output_t *, pgp_key_t *, const char *);
void pgp_push_sum16_writer(pgp_output_t *output);
uint16_t pgp_pop_sum16_writer(pgp_output_t *output);
#endif /* WRITER_H_ */

View file

@ -1,152 +0,0 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
* All rights reserved.
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
* their moral rights under the UK Copyright Design and Patents Act 1988 to
* be recorded as the authors of this copyright work.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** \file
*/
#ifndef KEYRING_H_
#define KEYRING_H_
#include "packet-netpgp.h"
#include "packet-parse.h"
#include "mj.h"
enum {
MAX_ID_LENGTH = 128,
MAX_PASSPHRASE_LENGTH = 256
};
typedef struct pgp_key_t pgp_key_t;
/** \struct pgp_keyring_t
* A keyring
*/
typedef struct pgp_keyring_t {
DYNARRAY(pgp_key_t, key);
pgp_hash_alg_t hashtype;
} pgp_keyring_t;
const pgp_key_t *pgp_getkeybyid(pgp_io_t *,
const pgp_keyring_t *,
const uint8_t *,
unsigned *,
pgp_pubkey_t **);
const pgp_key_t *pgp_getkeybyname(pgp_io_t *,
const pgp_keyring_t *,
const char *);
const pgp_key_t *pgp_getnextkeybyname(pgp_io_t *,
const pgp_keyring_t *,
const char *,
unsigned *);
void pgp_keydata_free(pgp_key_t *);
void pgp_keyring_free(pgp_keyring_t *);
void pgp_dump_keyring(const pgp_keyring_t *);
const pgp_pubkey_t *pgp_get_pubkey(const pgp_key_t *);
unsigned pgp_is_key_secret(const pgp_key_t *);
const pgp_seckey_t *pgp_get_seckey(const pgp_key_t *);
pgp_seckey_t *pgp_get_writable_seckey(pgp_key_t *);
pgp_seckey_t *pgp_decrypt_seckey(const pgp_key_t *, void *);
unsigned pgp_keyring_fileread(pgp_keyring_t *, const unsigned,
const char *);
int pgp_keyring_list(pgp_io_t *, const pgp_keyring_t *, const int);
int pgp_keyring_json(pgp_io_t *, const pgp_keyring_t *, mj_t *, const int);
void pgp_set_seckey(pgp_contents_t *, const pgp_key_t *);
void pgp_forget(void *, unsigned);
const uint8_t *pgp_get_key_id(const pgp_key_t *);
unsigned pgp_get_userid_count(const pgp_key_t *);
const uint8_t *pgp_get_userid(const pgp_key_t *, unsigned);
unsigned pgp_is_key_supported(const pgp_key_t *);
uint8_t *pgp_add_userid(pgp_key_t *, const uint8_t *);
pgp_subpacket_t *pgp_add_subpacket(pgp_key_t *,
const pgp_subpacket_t *);
unsigned pgp_add_selfsigned_userid(pgp_key_t *, const uint8_t *);
pgp_key_t *pgp_keydata_new(void);
void pgp_keydata_init(pgp_key_t *, const pgp_content_enum);
int pgp_parse_and_accumulate(pgp_keyring_t *, pgp_stream_t *);
int pgp_sprint_keydata(pgp_io_t *, const pgp_keyring_t *,
const pgp_key_t *, char **, const char *,
const pgp_pubkey_t *, const int);
int pgp_sprint_mj(pgp_io_t *, const pgp_keyring_t *,
const pgp_key_t *, mj_t *, const char *,
const pgp_pubkey_t *, const int);
int pgp_hkp_sprint_keydata(pgp_io_t *, const pgp_keyring_t *,
const pgp_key_t *, char **,
const pgp_pubkey_t *, const int);
void pgp_print_keydata(pgp_io_t *, const pgp_keyring_t *, const pgp_key_t *,
const char *, const pgp_pubkey_t *, const int);
void pgp_print_sig(pgp_io_t *, const pgp_key_t *, const char *,
const pgp_pubkey_t *);
void pgp_print_pubkey(const pgp_pubkey_t *);
int pgp_sprint_pubkey(const pgp_key_t *, char *, size_t);
int pgp_list_packets(pgp_io_t *,
char *,
unsigned,
pgp_keyring_t *,
pgp_keyring_t *,
void *,
pgp_cbfunc_t *);
char *pgp_export_key(pgp_io_t *, const pgp_key_t *, uint8_t *);
int pgp_add_to_pubring(pgp_keyring_t *, const pgp_pubkey_t *, pgp_content_enum tag);
int pgp_add_to_secring(pgp_keyring_t *, const pgp_seckey_t *);
int pgp_append_keyring(pgp_keyring_t *, pgp_keyring_t *);
#endif /* KEYRING_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,653 +0,0 @@
/*-
* Copyright (c) 2010 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <inttypes.h>
#include <regex.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "mj.h"
#include "defs-netpgp.h"
/* save 'n' chars of 's' in malloc'd memory */
static char *
strnsave(const char *s, int n, unsigned encoded)
{
char *newc;
char *cp;
int i;
if (n < 0) {
n = (int)strlen(s);
}
NEWARRAY(char, cp, n + n + 1, "strnsave", return NULL);
if (encoded) {
newc = cp;
for (i = 0 ; i < n ; i++) {
if ((uint8_t)*s == 0xac) {
*newc++ = (char)0xac;
*newc++ = '1';
s += 1;
} else if (*s == '"') {
*newc++ = (char)0xac;
*newc++ = '2';
s += 1;
} else if (*s == 0x0) {
*newc++ = (char)0xac;
*newc++ = '0';
s += 1;
} else {
*newc++ = *s++;
}
}
*newc = 0x0;
} else {
(void) memcpy(cp, s, (unsigned)n);
cp[n] = 0x0;
}
return cp;
}
/* look in an object for the item */
static int
findentry(mj_t *atom, const char *name, const unsigned from, const unsigned incr)
{
unsigned i;
for (i = from ; i < atom->c ; i += incr) {
if (strcmp(name, atom->value.v[i].value.s) == 0) {
return i;
}
}
return -1;
}
/* create a real number */
static void
create_number(mj_t *atom, double d)
{
char number[128];
atom->type = MJ_NUMBER;
atom->c = snprintf(number, sizeof(number), "%g", d);
atom->value.s = strnsave(number, (int)atom->c, MJ_HUMAN);
}
/* create an integer */
static void
create_integer(mj_t *atom, int64_t i)
{
char number[128];
atom->type = MJ_NUMBER;
atom->c = snprintf(number, sizeof(number), "%" PRIi64, i);
atom->value.s = strnsave(number, (int)atom->c, MJ_HUMAN);
}
/* create a string */
static void
create_string(mj_t *atom, const char *s, ssize_t len)
{
atom->type = MJ_STRING;
atom->value.s = strnsave(s, (int)len, MJ_JSON_ENCODE);
atom->c = (unsigned)strlen(atom->value.s);
}
#define MJ_OPEN_BRACKET (MJ_OBJECT + 1) /* 8 */
#define MJ_CLOSE_BRACKET (MJ_OPEN_BRACKET + 1) /* 9 */
#define MJ_OPEN_BRACE (MJ_CLOSE_BRACKET + 1) /* 10 */
#define MJ_CLOSE_BRACE (MJ_OPEN_BRACE + 1) /* 11 */
#define MJ_COLON (MJ_CLOSE_BRACE + 1) /* 12 */
#define MJ_COMMA (MJ_COLON + 1) /* 13 */
/* return the token type, and start and finish locations in string */
static int
gettok(const char *s, int *from, int *to, int *tok)
{
static regex_t tokregex;
regmatch_t matches[15];
static int compiled;
if (!compiled) {
compiled = 1;
(void) regcomp(&tokregex,
"[ \t\r\n]*(([+-]?[0-9]{1,21}(\\.[0-9]*)?([eE][-+][0-9]+)?)|"
"(\"([^\"]|\\\\.)*\")|(null)|(false)|(true)|([][{}:,]))",
REG_EXTENDED);
}
if (regexec(&tokregex, &s[*from = *to], 15, matches, 0) != 0) {
return *tok = -1;
}
*to = *from + (int)(matches[1].rm_eo);
*tok = (matches[2].rm_so >= 0) ? MJ_NUMBER :
(matches[5].rm_so >= 0) ? MJ_STRING :
(matches[7].rm_so >= 0) ? MJ_NULL :
(matches[8].rm_so >= 0) ? MJ_FALSE :
(matches[9].rm_so >= 0) ? MJ_TRUE :
(matches[10].rm_so < 0) ? -1 :
(s[*from + (int)(matches[10].rm_so)] == '[') ? MJ_OPEN_BRACKET :
(s[*from + (int)(matches[10].rm_so)] == ']') ? MJ_CLOSE_BRACKET :
(s[*from + (int)(matches[10].rm_so)] == '{') ? MJ_OPEN_BRACE :
(s[*from + (int)(matches[10].rm_so)] == '}') ? MJ_CLOSE_BRACE :
(s[*from + (int)(matches[10].rm_so)] == ':') ? MJ_COLON :
MJ_COMMA;
*from += (int)(matches[1].rm_so);
return *tok;
}
/* minor function used to indent a JSON field */
static void
indent(FILE *fp, unsigned depth, const char *trailer)
{
unsigned i;
for (i = 0 ; i < depth ; i++) {
(void) fprintf(fp, " ");
}
if (trailer) {
(void) fprintf(fp, "%s", trailer);
}
}
/***************************************************************************/
/* return the number of entries in the array */
int
mj_arraycount(mj_t *atom)
{
return atom->c;
}
/* create a new JSON node */
int
mj_create(mj_t *atom, const char *type, ...)
{
va_list args;
ssize_t len;
char *s;
if (strcmp(type, "false") == 0) {
atom->type = MJ_FALSE;
atom->c = 0;
} else if (strcmp(type, "true") == 0) {
atom->type = MJ_TRUE;
atom->c = 1;
} else if (strcmp(type, "null") == 0) {
atom->type = MJ_NULL;
} else if (strcmp(type, "number") == 0) {
va_start(args, type);
create_number(atom, (double)va_arg(args, double));
va_end(args);
} else if (strcmp(type, "integer") == 0) {
va_start(args, type);
create_integer(atom, (int64_t)va_arg(args, int64_t));
va_end(args);
} else if (strcmp(type, "string") == 0) {
va_start(args, type);
s = (char *)va_arg(args, char *);
len = (size_t)va_arg(args, size_t);
va_end(args);
create_string(atom, s, len);
} else if (strcmp(type, "array") == 0) {
atom->type = MJ_ARRAY;
} else if (strcmp(type, "object") == 0) {
atom->type = MJ_OBJECT;
} else {
(void) fprintf(stderr, "weird type '%s'\n", type);
return 0;
}
return 1;
}
/* put a JSON tree into a text string */
int
mj_snprint(char *buf, size_t size, mj_t *atom, int encoded)
{
unsigned i;
char *s;
char *bp;
int cc;
switch(atom->type) {
case MJ_NULL:
return snprintf(buf, size, "null");
case MJ_FALSE:
return snprintf(buf, size, "false");
case MJ_TRUE:
return snprintf(buf, size, "true");
case MJ_NUMBER:
return snprintf(buf, size, "%s", atom->value.s);
case MJ_STRING:
if (encoded) {
return snprintf(buf, size, "\"%s\"", atom->value.s);
}
for (bp = buf, *bp++ = '"', s = atom->value.s ;
(size_t)(bp - buf) < size && (unsigned)(s - atom->value.s) < atom->c ; ) {
if ((uint8_t)*s == 0xac) {
switch(s[1]) {
case '0':
*bp++ = 0x0;
s += 2;
break;
case '1':
*bp++ = (char)0xac;
s += 2;
break;
case '2':
*bp++ = '"';
s += 2;
break;
default:
(void) fprintf(stderr, "unrecognised character '%02x'\n", (uint8_t)s[1]);
s += 1;
break;
}
} else {
*bp++ = *s++;
}
}
*bp++ = '"';
*bp = 0x0;
return (int)(bp - buf) - 1;
case MJ_ARRAY:
cc = snprintf(buf, size, "[ ");
for (i = 0 ; i < atom->c ; i++) {
cc += mj_snprint(&buf[cc], size - cc, &atom->value.v[i], encoded);
if (i < atom->c - 1) {
cc += snprintf(&buf[cc], size - cc, ", ");
}
}
return cc + snprintf(&buf[cc], size - cc, "]\n");
case MJ_OBJECT:
cc = snprintf(buf, size, "{ ");
for (i = 0 ; i < atom->c ; i += 2) {
cc += mj_snprint(&buf[cc], size - cc, &atom->value.v[i], encoded);
cc += snprintf(&buf[cc], size - cc, ":");
cc += mj_snprint(&buf[cc], size - cc, &atom->value.v[i + 1], encoded);
if (i + 1 < atom->c - 1) {
cc += snprintf(&buf[cc], size - cc, ", ");
}
}
return cc + snprintf(&buf[cc], size - cc, "}\n");
default:
(void) fprintf(stderr, "mj_snprint: weird type %d\n", atom->type);
return 0;
}
}
/* allocate and print the atom */
int
mj_asprint(char **buf, mj_t *atom, int encoded)
{
int size;
size = mj_string_size(atom);
if ((*buf = calloc(1, (unsigned)(size + 1))) == NULL) {
return -1;
}
return mj_snprint(*buf, (unsigned)(size + 1), atom, encoded) + 1;
}
/* read into a JSON tree from a string */
int
mj_parse(mj_t *atom, const char *s, int *from, int *to, int *tok)
{
int i;
switch(atom->type = *tok = gettok(s, from, to, tok)) {
case MJ_NUMBER:
atom->value.s = strnsave(&s[*from], *to - *from, MJ_JSON_ENCODE);
atom->c = atom->size = (unsigned)strlen(atom->value.s);
return gettok(s, from, to, tok);
case MJ_STRING:
atom->value.s = strnsave(&s[*from + 1], *to - *from - 2, MJ_HUMAN);
atom->c = atom->size = (unsigned)strlen(atom->value.s);
return gettok(s, from, to, tok);
case MJ_NULL:
case MJ_FALSE:
case MJ_TRUE:
atom->c = (unsigned)*to;
return gettok(s, from, to, tok);
case MJ_OPEN_BRACKET:
mj_create(atom, "array");
ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_parse()", return 0);
while (mj_parse(&atom->value.v[atom->c++], s, from, to, tok) >= 0 && *tok != MJ_CLOSE_BRACKET) {
if (*tok != MJ_COMMA) {
(void) fprintf(stderr, "1. expected comma (got %d) at '%s'\n", *tok, &s[*from]);
break;
}
ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_parse()", return 0);
}
return gettok(s, from, to, tok);
case MJ_OPEN_BRACE:
mj_create(atom, "object");
ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_parse()", return 0);
for (i = 0 ; mj_parse(&atom->value.v[atom->c++], s, from, to, tok) >= 0 && *tok != MJ_CLOSE_BRACE ; i++) {
if (((i % 2) == 0 && *tok != MJ_COLON) || ((i % 2) == 1 && *tok != MJ_COMMA)) {
(void) fprintf(stderr, "2. expected comma (got %d) at '%s'\n", *tok, &s[*from]);
break;
}
ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_parse()", return 0);
}
return gettok(s, from, to, tok);
default:
return *tok;
}
}
/* return the index of the item which corresponds to the name in the array */
int
mj_object_find(mj_t *atom, const char *name, const unsigned from, const unsigned incr)
{
return findentry(atom, name, from, incr);
}
/* find an atom in a composite mj JSON node */
mj_t *
mj_get_atom(mj_t *atom, ...)
{
unsigned i;
va_list args;
char *name;
int n;
switch(atom->type) {
case MJ_ARRAY:
va_start(args, atom);
i = va_arg(args, int);
va_end(args);
return (i < atom->c) ? &atom->value.v[i] : NULL;
case MJ_OBJECT:
va_start(args, atom);
name = va_arg(args, char *);
va_end(args);
return ((n = findentry(atom, name, 0, 2)) >= 0) ? &atom->value.v[n + 1] : NULL;
default:
return NULL;
}
}
/* perform a deep copy on an mj JSON atom */
int
mj_deepcopy(mj_t *dst, mj_t *src)
{
unsigned i;
switch(src->type) {
case MJ_FALSE:
case MJ_TRUE:
case MJ_NULL:
(void) memcpy(dst, src, sizeof(*dst));
return 1;
case MJ_STRING:
case MJ_NUMBER:
(void) memcpy(dst, src, sizeof(*dst));
dst->value.s = strnsave(src->value.s, -1, MJ_HUMAN);
dst->c = dst->size = (unsigned)strlen(dst->value.s);
return 1;
case MJ_ARRAY:
case MJ_OBJECT:
(void) memcpy(dst, src, sizeof(*dst));
NEWARRAY(mj_t, dst->value.v, dst->size, "mj_deepcopy()", return 0);
for (i = 0 ; i < src->c ; i++) {
if (!mj_deepcopy(&dst->value.v[i], &src->value.v[i])) {
return 0;
}
}
return 1;
default:
(void) fprintf(stderr, "weird type '%d'\n", src->type);
return 0;
}
}
/* do a deep delete on the object */
void
mj_delete(mj_t *atom)
{
unsigned i;
switch(atom->type) {
case MJ_STRING:
case MJ_NUMBER:
free(atom->value.s);
break;
case MJ_ARRAY:
case MJ_OBJECT:
for (i = 0 ; i < atom->c ; i++) {
mj_delete(&atom->value.v[i]);
}
/* XXX - agc - causing problems? free(atom->value.v); */
break;
default:
break;
}
}
/* return the string size needed for the textual output of the JSON node */
int
mj_string_size(mj_t *atom)
{
unsigned i;
int cc;
switch(atom->type) {
case MJ_NULL:
case MJ_TRUE:
return 4;
case MJ_FALSE:
return 5;
case MJ_NUMBER:
return atom->c;
case MJ_STRING:
return atom->c + 2;
case MJ_ARRAY:
for (cc = 2, i = 0 ; i < atom->c ; i++) {
cc += mj_string_size(&atom->value.v[i]);
if (i < atom->c - 1) {
cc += 2;
}
}
return cc + 1 + 1;
case MJ_OBJECT:
for (cc = 2, i = 0 ; i < atom->c ; i += 2) {
cc += mj_string_size(&atom->value.v[i]) + 1 + mj_string_size(&atom->value.v[i + 1]);
if (i + 1 < atom->c - 1) {
cc += 2;
}
}
return cc + 1 + 1;
default:
(void) fprintf(stderr, "mj_string_size: weird type %d\n", atom->type);
return 0;
}
}
/* create a new atom, and append it to the array or object */
int
mj_append(mj_t *atom, const char *type, ...)
{
va_list args;
ssize_t len;
char *s;
if (atom->type != MJ_ARRAY && atom->type != MJ_OBJECT) {
return 0;
}
ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_append()", return 0);
va_start(args, type);
if (strcmp(type, "string") == 0) {
s = (char *)va_arg(args, char *);
len = (ssize_t)va_arg(args, ssize_t);
create_string(&atom->value.v[atom->c++], s, len);
} else if (strcmp(type, "integer") == 0) {
create_integer(&atom->value.v[atom->c++], (int64_t)va_arg(args, int64_t));
} else if (strcmp(type, "object") == 0 || strcmp(type, "array") == 0) {
mj_deepcopy(&atom->value.v[atom->c++], (mj_t *)va_arg(args, mj_t *));
} else {
(void) fprintf(stderr, "mj_append: weird type '%s'\n", type);
}
va_end(args);
return 1;
}
/* append a field to an object */
int
mj_append_field(mj_t *atom, const char *name, const char *type, ...)
{
va_list args;
ssize_t len;
char *s;
if (atom->type != MJ_OBJECT) {
return 0;
}
mj_append(atom, "string", name, -1);
ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_append_field()", return 0);
va_start(args, type);
if (strcmp(type, "string") == 0) {
s = (char *)va_arg(args, char *);
len = (ssize_t)va_arg(args, ssize_t);
create_string(&atom->value.v[atom->c++], s, len);
} else if (strcmp(type, "integer") == 0) {
create_integer(&atom->value.v[atom->c++], (int64_t)va_arg(args, int64_t));
} else if (strcmp(type, "object") == 0 || strcmp(type, "array") == 0) {
mj_deepcopy(&atom->value.v[atom->c++], (mj_t *)va_arg(args, mj_t *));
} else {
(void) fprintf(stderr, "mj_append_field: weird type '%s'\n", type);
}
va_end(args);
return 1;
}
/* make sure a JSON object is politically correct */
int
mj_lint(mj_t *obj)
{
unsigned i;
int ret;
switch(obj->type) {
case MJ_NULL:
case MJ_FALSE:
case MJ_TRUE:
if (obj->value.s != NULL) {
(void) fprintf(stderr, "null/false/true: non zero string\n");
return 0;
}
return 1;
case MJ_NUMBER:
case MJ_STRING:
if (obj->c > obj->size) {
(void) fprintf(stderr, "string/number lint c (%u) > size (%u)\n", obj->c, obj->size);
return 0;
}
return 1;
case MJ_ARRAY:
case MJ_OBJECT:
if (obj->c > obj->size) {
(void) fprintf(stderr, "array/object lint c (%u) > size (%u)\n", obj->c, obj->size);
return 0;
}
for (ret = 1, i = 0 ; i < obj->c ; i++) {
if (!mj_lint(&obj->value.v[i])) {
(void) fprintf(stderr, "array/object lint found at %d of %p\n", i, obj);
ret = 0;
}
}
return ret;
default:
(void) fprintf(stderr, "problem type %d in %p\n", obj->type, obj);
return 0;
}
}
/* pretty-print a JSON struct - can be called recursively */
int
mj_pretty(mj_t *mj, void *vp, unsigned depth, const char *trailer)
{
unsigned i;
FILE *fp;
char *s;
fp = (FILE *)vp;
switch(mj->type) {
case MJ_NUMBER:
case MJ_TRUE:
case MJ_FALSE:
case MJ_NULL:
indent(fp, depth, mj->value.s);
break;
case MJ_STRING:
indent(fp, depth, NULL);
mj_asprint(&s, mj, MJ_HUMAN);
(void) fprintf(fp, "\"%s\"", s);
free(s);
break;
case MJ_ARRAY:
indent(fp, depth, "[\n");
for (i = 0 ; i < mj->c ; i++) {
mj_pretty(&mj->value.v[i], fp, depth + 1, (i < mj->c - 1) ? ",\n" : "\n");
}
indent(fp, depth, "]");
break;
case MJ_OBJECT:
indent(fp, depth, "{\n");
for (i = 0 ; i < mj->c ; i += 2) {
mj_pretty(&mj->value.v[i], fp, depth + 1, " : ");
mj_pretty(&mj->value.v[i + 1], fp, 0, (i < mj->c - 2) ? ",\n" : "\n");
}
indent(fp, depth, "}");
break;
}
indent(fp, 0, trailer);
return 1;
}
/* show the contents of the simple atom as a string representation */
const char *
mj_string_rep(mj_t *atom)
{
if (atom == NULL) {
return 0;
}
switch(atom->type) {
case MJ_STRING:
case MJ_NUMBER:
return atom->value.s;
case MJ_NULL:
return "null";
case MJ_FALSE:
return "false";
case MJ_TRUE:
return "true";
default:
return NULL;
}
}

View file

@ -1,79 +0,0 @@
/*-
* Copyright (c) 2010,2011 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef MJ_H_
#define MJ_H_ 20110607
enum {
MJ_NULL = 1,
MJ_FALSE = 2,
MJ_TRUE = 3,
MJ_NUMBER = 4,
MJ_STRING = 5,
MJ_ARRAY = 6,
MJ_OBJECT = 7,
MJ_LAST = MJ_OBJECT,
MJ_HUMAN = 0, /* human readable, not encoded */
MJ_JSON_ENCODE = 1 /* encoded JSON */
};
/* a minimalist JSON node */
typedef struct mj_t {
unsigned type; /* type of JSON node */
unsigned c; /* # of chars */
unsigned size; /* size of array */
union {
struct mj_t *v; /* sub-objects */
char *s; /* string value */
} value;
} mj_t;
/* creation and deletion */
int mj_create(mj_t */*atom*/, const char */*type*/, .../*value*/);
int mj_parse(mj_t */*atom*/, const char */*s*/, int */*from*/,
int */*to*/, int */*token*/);
int mj_append(mj_t */*atom*/, const char */*type*/, .../*value*/);
int mj_append_field(mj_t */*atom*/, const char */*name*/, const char */*type*/,
.../*value*/);
int mj_deepcopy(mj_t */*dst*/, mj_t */*src*/);
void mj_delete(mj_t */*atom*/);
/* JSON object access */
int mj_arraycount(mj_t */*atom*/);
int mj_object_find(mj_t */*atom*/, const char */*name*/,
const unsigned /*from*/, const unsigned /*incr*/);
mj_t *mj_get_atom(mj_t */*atom*/, ...);
int mj_lint(mj_t */*atom*/);
/* textual output */
int mj_snprint(char */*buf*/, size_t /*size*/, mj_t */*atom*/, int /*encoded*/);
int mj_asprint(char **/*bufp*/, mj_t */*atom*/, int /*encoded*/);
int mj_string_size(mj_t */*atom*/);
int mj_pretty(mj_t */*atom*/, void */*fp*/, unsigned /*depth*/,
const char */*trailer*/);
const char *mj_string_rep(mj_t */*atom*/);
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -49,7 +49,7 @@
/** \file
*/
#include "config-netpgp.h"
#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
@ -57,7 +57,7 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
__RCSID("$NetBSD: compress.c,v 1.23 2012/03/05 02:20:18 christos Exp $");
__RCSID("$NetBSD$");
#endif
#ifdef HAVE_ZLIB_H
@ -70,12 +70,12 @@ __RCSID("$NetBSD: compress.c,v 1.23 2012/03/05 02:20:18 christos Exp $");
#include <string.h>
#include "packet-parse.h"
#include "errors-netpgp.h"
#include "netpgpdefs.h"
#include "crypto-netpgp.h"
#include "memory-netpgp.h"
#include "writer-netpgp.h"
#include "netpgp/packet-parse.h"
#include "netpgp/errors.h"
#include "netpgp/netpgpdefs.h"
#include "netpgp/crypto.h"
#include "netpgp/memory.h"
#include "netpgp/writer.h"
#define DECOMPRESS_BUFFER 1024
@ -108,7 +108,7 @@ typedef struct {
} compress_t;
/*
* \todo remove code duplication between this and
* \todo re move code duplication between this and
* bzip2_compressed_data_reader
*/
static int
@ -188,8 +188,9 @@ zlib_compressed_data_reader(pgp_stream_t *stream, void *dest, size_t length,
return 0;
}
len = (size_t)(z->zstream.next_out - &z->out[z->offset]);
if (len > length) {
len = length;
size_t left_in_cdest = length - cc;
if (len > left_in_cdest) {
len = left_in_cdest;
}
(void) memcpy(&cdest[cc], &z->out[z->offset], len);
z->offset += len;

View file

@ -49,7 +49,7 @@
/** \file
*/
#include "config-netpgp.h"
#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
@ -57,7 +57,7 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
__RCSID("$NetBSD: create.c,v 1.38 2010/11/15 08:03:39 agc Exp $");
__RCSID("$NetBSD$");
#endif
#include <sys/types.h>
@ -78,15 +78,15 @@ __RCSID("$NetBSD: create.c,v 1.38 2010/11/15 08:03:39 agc Exp $");
#include <openssl/cast.h>
#endif
#include "create-netpgp.h"
#include "keyring-netpgp.h"
#include "packet-netpgp.h"
#include "signature-netpgp.h"
#include "writer-netpgp.h"
#include "readerwriter-netpgp.h"
#include "memory-netpgp.h"
#include "netpgpdefs.h"
#include "netpgpdigest.h"
#include "netpgp/create.h"
#include "netpgp/keyring.h"
#include "netpgp/packet.h"
#include "netpgp/signature.h"
#include "netpgp/writer.h"
#include "netpgp/readerwriter.h"
#include "netpgp/memory.h"
#include "netpgp/netpgpdefs.h"
#include "netpgp/netpgpdigest.h"
/**
* \ingroup Core_Create
@ -98,10 +98,10 @@ __RCSID("$NetBSD: create.c,v 1.38 2010/11/15 08:03:39 agc Exp $");
unsigned
pgp_write_ss_header(pgp_output_t *output,
unsigned length,
size_t length,
pgp_content_enum type)
{
return pgp_write_length(output, length) &&
return pgp_write_length(output, (unsigned int)length) &&
pgp_write_scalar(output, (unsigned)(type -
(unsigned)PGP_PTAG_SIG_SUBPKT_BASE), 1);
}
@ -176,6 +176,11 @@ pubkey_length(const pgp_pubkey_t *key)
case PGP_PKA_RSA:
return mpi_length(key->key.rsa.n) + mpi_length(key->key.rsa.e);
case PGP_PKA_ELGAMAL:
return mpi_length(key->key.elgamal.p) +
mpi_length(key->key.elgamal.g) +
mpi_length(key->key.elgamal.y);
default:
(void) fprintf(stderr,
"pubkey_length: unknown key algorithm\n");
@ -188,7 +193,6 @@ seckey_length(const pgp_seckey_t *key)
{
int len;
len = 0;
switch (key->pubkey.alg) {
case PGP_PKA_DSA:
return (unsigned)(mpi_length(key->key.dsa.x) + pubkey_length(&key->pubkey));
@ -197,6 +201,11 @@ seckey_length(const pgp_seckey_t *key)
mpi_length(key->key.rsa.q) + mpi_length(key->key.rsa.u);
return (unsigned)(len + pubkey_length(&key->pubkey));
case PGP_PKA_ELGAMAL:
return (unsigned)(
mpi_length(key->key.dsa.x) + pubkey_length(&key->pubkey));
default:
(void) fprintf(stderr,
"seckey_length: unknown key algorithm\n");
@ -273,7 +282,7 @@ write_pubkey_body(const pgp_pubkey_t *key, pgp_output_t *output)
* Note that we support v3 keys here because they're needed for
* verification.
*/
unsigned
static unsigned
write_seckey_body(const pgp_seckey_t *key,
const uint8_t *passphrase,
const size_t pplen,
@ -285,17 +294,17 @@ write_seckey_body(const pgp_seckey_t *key,
pgp_hash_t hash;
unsigned done = 0;
unsigned i = 0;
uint8_t *hashed;
uint8_t sesskey[CAST_KEY_LENGTH];
if (!write_pubkey_body(&key->pubkey, output)) {
return 0;
}
if (key->s2k_usage != PGP_S2KU_ENCRYPTED_AND_HASHED) {
(void) fprintf(stderr, "write_seckey_body: s2k usage\n");
if (!pgp_write_scalar(output, (unsigned)key->s2k_usage, 1)) {
return 0;
}
if (!pgp_write_scalar(output, (unsigned)key->s2k_usage, 1)) {
if (key->s2k_usage != PGP_S2KU_NONE) {
if (key->s2k_usage != PGP_S2KU_ENCRYPTED_AND_HASHED) {
(void) fprintf(stderr, "write_seckey_body: s2k usage\n");
return 0;
}
@ -365,6 +374,7 @@ write_seckey_body(const pgp_seckey_t *key,
unsigned needed;
unsigned size;
uint8_t zero = 0;
uint8_t *hashed;
/* Hard-coded SHA1 for session key */
pgp_hash_any(&hash, PGP_HASH_SHA1);
@ -377,6 +387,7 @@ write_seckey_body(const pgp_seckey_t *key,
}
if (!hash.init(&hash)) {
(void) fprintf(stderr, "write_seckey_body: bad alloc\n");
free(hashed);
return 0;
}
@ -405,6 +416,7 @@ write_seckey_body(const pgp_seckey_t *key,
(void) memcpy(&sesskey[i * hashsize],
hashed, (unsigned)size);
done += (unsigned)size;
free(hashed);
if (done > CAST_KEY_LENGTH) {
(void) fprintf(stderr,
"write_seckey_body: short add\n");
@ -439,6 +451,9 @@ write_seckey_body(const pgp_seckey_t *key,
(void) fprintf(stderr, "\nturning encryption on...\n");
}
pgp_push_enc_crypt(output, &crypted);
}else{
pgp_push_sum16_writer(output);
}
switch (key->pubkey.alg) {
case PGP_PKA_RSA:
@ -463,11 +478,19 @@ write_seckey_body(const pgp_seckey_t *key,
return 0;
}
if (key->s2k_usage != PGP_S2KU_NONE) {
if (!pgp_write(output, key->checkhash, PGP_CHECKHASH_SIZE)) {
return 0;
}
pgp_writer_pop(output);
}else{
uint16_t checksum = pgp_pop_sum16_writer(output);
if (!pgp_write_scalar(output, checksum, 2)) {
return 0;
}
}
return 1;
}
@ -480,13 +503,20 @@ write_seckey_body(const pgp_seckey_t *key,
* \return 1 if OK, otherwise 0
*/
unsigned
write_struct_pubkey(pgp_output_t *output, const pgp_pubkey_t *key)
pgp_write_struct_pubkey_ptag(
pgp_output_t *output,
const pgp_pubkey_t *key,
pgp_content_enum ptag)
{
return pgp_write_ptag(output, PGP_PTAG_CT_PUBLIC_KEY) &&
return pgp_write_ptag(output, ptag) &&
pgp_write_length(output, 1 + 4 + 1 + pubkey_length(key)) &&
write_pubkey_body(key, output);
}
unsigned
pgp_write_struct_pubkey(pgp_output_t *output, const pgp_pubkey_t *key)
{
return pgp_write_struct_pubkey_ptag(output, key, PGP_PTAG_CT_PUBLIC_KEY);
}
/**
\ingroup HighLevel_KeyWrite
@ -500,40 +530,104 @@ write_struct_pubkey(pgp_output_t *output, const pgp_pubkey_t *key)
*/
unsigned
pgp_write_xfer_pubkey(pgp_output_t *output,
pgp_write_xfer_key(pgp_output_t *output,
const pgp_key_t *key,
const unsigned armoured)
{
unsigned i, j;
unsigned directsigidx = 0;
pgp_directsig_t *directsigp;
unsigned uididx = 0;
unsigned uidsigidx = 0;
uint8_t **uidp;
pgp_uidsig_t *uidsigp;
pgp_subkey_t *subkeyp;
unsigned subkeyidx = 0;
unsigned subkeysigidx = 0;
pgp_subkeysig_t *subkeysigp;
if (armoured) {
pgp_writer_push_armoured(output, PGP_PGP_PUBLIC_KEY_BLOCK);
}
/* public key */
if (!write_struct_pubkey(output, &key->key.pubkey)) {
/* primary key */
if (key->type == PGP_PTAG_CT_PUBLIC_KEY) {
if (!pgp_write_struct_pubkey(output, &key->key.pubkey)) {
return 0;
}
/* TODO: revocation signatures go here */
/* user ids and corresponding signatures */
for (i = 0; i < key->uidc; i++) {
if (!pgp_write_struct_userid(output, key->uids[i])) {
}else{
if (!pgp_write_struct_seckey(&key->key.seckey, (const uint8_t *)"", 0, output)) {
return 0;
}
for (j = 0; j < key->packetc; j++) {
if (!pgp_write(output, key->packets[j].raw, (unsigned)key->packets[j].length)) {
}
directsigp = key->directsigs;
for (directsigidx = 0 ; directsigidx < key->directsigc;
directsigidx++, directsigp++)
{
if (!pgp_write(output, directsigp->packet.raw,
(unsigned)directsigp->packet.length)) {
return 0;
}
}
/* Loop over key's user ids*/
uidp = key->uids;
for (uididx = 0 ; uididx < key->uidc; uididx++, uidp++)
{
if (!pgp_write_struct_userid(output, *uidp)) {
return 0;
}
/* Loop over key's user ids sigs */
uidsigp = key->uidsigs;
for (uidsigidx = 0 ; uidsigidx < key->uidsigc; uidsigidx++, uidsigp++)
{
/* matching selected user id */
if(uidsigp->uid == uididx)
{
if (!pgp_write(output, uidsigp->packet.raw,
(unsigned)uidsigp->packet.length)) {
return 0;
}
}
}
}
/* TODO: user attributes and corresponding signatures */
/* TODO attibutes */
/*
* subkey packets and corresponding signatures and optional
* revocation
*/
/* Loop over key's subkeys */
subkeyp = key->subkeys;
for (subkeyidx = 0 ; subkeyidx < key->subkeyc; subkeyidx++, subkeyp++)
{
if (key->type == PGP_PTAG_CT_PUBLIC_KEY) {
if (!pgp_write_struct_pubkey_ptag(
output, &subkeyp->key.pubkey,
PGP_PTAG_CT_PUBLIC_SUBKEY)) {
return 0;
}
}else{
if (!pgp_write_struct_seckey_ptag(
/* TODO support passphrase again */
&subkeyp->key.seckey, (const uint8_t *)"", 0, output,
PGP_PTAG_CT_SECRET_SUBKEY)) {
return 0;
}
}
/* Loop over key's subkeys sigs */
subkeysigp = key->subkeysigs;
for (subkeysigidx = 0 ; subkeysigidx < key->subkeysigc;
subkeysigidx++, subkeysigp++)
{
/* matching selected subkey */
if(subkeysigp->subkey == subkeyidx)
{
if (!pgp_write(output, subkeysigp->packet.raw,
(unsigned)subkeysigp->packet.length)) {
return 0;
}
}
}
}
if (armoured) {
pgp_writer_info_finalise(&output->errors, &output->writer);
@ -554,52 +648,14 @@ pgp_write_xfer_pubkey(pgp_output_t *output,
\param output Output stream
*/
/* TODO have encrypted key export again
unsigned
pgp_write_xfer_seckey(pgp_output_t *output,
const pgp_key_t *key,
const uint8_t *passphrase,
const size_t pplen,
unsigned armoured)
{
unsigned i, j;
if (armoured) {
pgp_writer_push_armoured(output, PGP_PGP_PRIVATE_KEY_BLOCK);
}
/* public key */
if (!pgp_write_struct_seckey(&key->key.seckey, passphrase,
pplen, output)) {
return 0;
}
/* TODO: revocation signatures go here */
/* user ids and corresponding signatures */
for (i = 0; i < key->uidc; i++) {
if (!pgp_write_struct_userid(output, key->uids[i])) {
return 0;
}
for (j = 0; j < key->packetc; j++) {
if (!pgp_write(output, key->packets[j].raw, (unsigned)key->packets[j].length)) {
return 0;
}
}
}
/* TODO: user attributes and corresponding signatures */
/*
* subkey packets and corresponding signatures and optional
* revocation
*/
if (armoured) {
pgp_writer_info_finalise(&output->errors, &output->writer);
pgp_writer_pop(output);
}
return 1;
}
*/
/**
* \ingroup Core_WritePackets
@ -620,7 +676,7 @@ pgp_write_rsa_pubkey(time_t t, const BIGNUM *n,
pgp_pubkey_t key;
pgp_fast_create_rsa_pubkey(&key, t, __UNCONST(n), __UNCONST(e));
return write_struct_pubkey(output, &key);
return pgp_write_struct_pubkey(output, &key);
}
/**
@ -693,10 +749,11 @@ pgp_fast_create_rsa_seckey(pgp_seckey_t *key, time_t t,
* \return 1 if OK; else 0
*/
unsigned
pgp_write_struct_seckey(const pgp_seckey_t *key,
pgp_write_struct_seckey_ptag(const pgp_seckey_t *key,
const uint8_t *passphrase,
const size_t pplen,
pgp_output_t *output)
pgp_output_t *output,
pgp_content_enum ptag)
{
int length = 0;
@ -709,7 +766,7 @@ pgp_write_struct_seckey(const pgp_seckey_t *key,
/* Ref: RFC4880 Section 5.5.3 */
/* pubkey, excluding MPIs */
length += 1 + 4 + 1 + 1;
length += 1 + 4 + 1;
/* s2k usage */
length += 1;
@ -776,12 +833,21 @@ pgp_write_struct_seckey(const pgp_seckey_t *key,
/* secret key and public key MPIs */
length += (unsigned)seckey_length(key);
return pgp_write_ptag(output, PGP_PTAG_CT_SECRET_KEY) &&
return pgp_write_ptag(output, ptag) &&
/* pgp_write_length(output,1+4+1+1+seckey_length(key)+2) && */
pgp_write_length(output, (unsigned)length) &&
write_seckey_body(key, passphrase, pplen, output);
}
unsigned
pgp_write_struct_seckey(const pgp_seckey_t *key,
const uint8_t *passphrase,
const size_t pplen,
pgp_output_t *output)
{
return pgp_write_struct_seckey_ptag(
key, passphrase, pplen, output, PGP_PTAG_CT_SECRET_KEY);
}
/**
* \ingroup Core_Create
*
@ -932,7 +998,7 @@ encode_m_buf(const uint8_t *M, size_t mLen, const pgp_pubkey_t * pubkey,
\note Currently hard-coded to use RSA
*/
pgp_pk_sesskey_t *
pgp_create_pk_sesskey(const pgp_key_t *key, const char *ciphername)
pgp_create_pk_sesskey(pgp_key_t *key, const char *ciphername, pgp_pk_sesskey_t *initial_sesskey)
{
/*
* Creates a random session key and encrypts it for the given key
@ -941,7 +1007,7 @@ pgp_create_pk_sesskey(const pgp_key_t *key, const char *ciphername)
* can be any, we're hardcoding RSA for now
*/
const pgp_pubkey_t *pubkey;
pgp_pubkey_t *pubkey;
pgp_pk_sesskey_t *sesskey;
pgp_symm_alg_t cipher;
const uint8_t *id;
@ -950,13 +1016,8 @@ pgp_create_pk_sesskey(const pgp_key_t *key, const char *ciphername)
uint8_t *encoded_m_buf;
size_t sz_encoded_m_buf;
if (memcmp(key->encid, "\0\0\0\0\0\0\0\0", 8) == 0) {
pubkey = pgp_get_pubkey(key);
id = key->sigid;
} else {
pubkey = &key->enckey;
id = key->encid;
}
pubkey = pgp_key_get_enckey(key, &id);
/* allocate unencoded_m_buf here */
(void) memset(&cipherinfo, 0x0, sizeof(cipherinfo));
pgp_crypt_any(&cipherinfo,
@ -1022,7 +1083,14 @@ pgp_create_pk_sesskey(const pgp_key_t *key, const char *ciphername)
sesskey->alg = pubkey->alg;
sesskey->symm_alg = cipher;
if(initial_sesskey){
if(initial_sesskey->symm_alg != cipher){
return NULL;
}
memcpy(sesskey->key, initial_sesskey->key, cipherinfo.keysize);
}else{
pgp_random(sesskey->key, cipherinfo.keysize);
}
if (pgp_get_debug_level(__FILE__)) {
hexdump(stderr, "sesskey created", sesskey->key,

View file

@ -46,7 +46,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "config-netpgp.h"
#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
@ -54,7 +54,7 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
__RCSID("$NetBSD: crypto.c,v 1.36 2014/02/17 07:39:19 agc Exp $");
__RCSID("$NetBSD$");
#endif
#include <sys/types.h>
@ -66,12 +66,14 @@ __RCSID("$NetBSD: crypto.c,v 1.36 2014/02/17 07:39:19 agc Exp $");
#include <string.h>
#include "types-netpgp.h"
#include "crypto-netpgp.h"
#include "readerwriter-netpgp.h"
#include "memory-netpgp.h"
#include "netpgpdefs.h"
#include "signature-netpgp.h"
#include "netpgp/types.h"
#include "netpgp/crypto.h"
#include "netpgp/readerwriter.h"
#include "netpgp/memory.h"
#include "netpgp/netpgpdefs.h"
#include "netpgp/signature.h"
#include "netpgp/netpgpsdk.h"
#include "netpgp/validate.h"
/**
\ingroup Core_MPI
@ -273,7 +275,7 @@ write_parsed_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
if (pgp_get_debug_level(__FILE__)) {
printf("write_parsed_cb: ");
pgp_print_packet(&cbinfo->printstate, pkt);
//pgp_print_packet(&cbinfo->printstate, pkt);
}
if (pkt->tag != PGP_PTAG_CT_UNARMOURED_TEXT && cbinfo->printstate.skipping) {
puts("...end of skip");
@ -304,7 +306,10 @@ write_parsed_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
return pgp_get_seckey_cb(pkt, cbinfo);
case PGP_GET_PASSPHRASE:
if (cbinfo->cryptinfo.getpassphrase) {
return cbinfo->cryptinfo.getpassphrase(pkt, cbinfo);
}
break;
case PGP_PTAG_CT_LITDATA_BODY:
return pgp_litdata_cb(pkt, cbinfo);
@ -356,6 +361,7 @@ pgp_encrypt_file(pgp_io_t *io,
{
pgp_output_t *output;
pgp_memory_t *inmem;
pgp_keyring_t *rcpts;
int fd_out;
__PGP_USED(io);
@ -374,11 +380,23 @@ pgp_encrypt_file(pgp_io_t *io,
pgp_writer_push_armor_msg(output);
}
if ((rcpts = calloc(1, sizeof(*rcpts))) == NULL) {
(void) fprintf(io->errs,
"netpgp_encrypt_buf: out of memory to create recipients list\n");
return 0;
}
pgp_keyring_add(rcpts, key);
if(rcpts->keys == NULL){
(void) fprintf(io->errs,
"netpgp_encrypt_buf: out of memory to add recipient\n");
return 0;
}
/* Push the encrypted writer */
if (!pgp_push_enc_se_ip(output, key, cipher)) {
if (!pgp_push_enc_se_ip(output, rcpts, cipher, 0)) {
pgp_memory_free(inmem);
return 0;
}
pgp_keyring_free(rcpts);
/* This does the writing */
pgp_write(output, pgp_mem_data(inmem), (unsigned)pgp_mem_len(inmem));
@ -395,9 +413,10 @@ pgp_memory_t *
pgp_encrypt_buf(pgp_io_t *io,
const void *input,
const size_t insize,
const pgp_key_t *pubkey,
const pgp_keyring_t *pubkeys,
const unsigned use_armour,
const char *cipher)
const char *cipher,
unsigned raw)
{
pgp_output_t *output;
pgp_memory_t *outmem;
@ -417,7 +436,7 @@ pgp_encrypt_buf(pgp_io_t *io,
}
/* Push the encrypted writer */
pgp_push_enc_se_ip(output, pubkey, cipher);
pgp_push_enc_se_ip(output, pubkeys, cipher, raw);
/* This does the writing */
pgp_write(output, input, (unsigned)insize);
@ -610,3 +629,132 @@ pgp_decrypt_buf(pgp_io_t *io,
/* if we didn't get the passphrase, return NULL */
return (parse->cbinfo.gotpass) ? outmem : NULL;
}
/* Special callback for decrypt and validate */
static pgp_cb_ret_t
pgp_decrypt_and_validate_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
{
pgp_cb_ret_t ret_write_cb = PGP_RELEASE_MEMORY;
pgp_cb_ret_t ret_validate_cb = PGP_RELEASE_MEMORY;
ret_write_cb = write_parsed_cb(pkt, cbinfo);
/* Filter pkt sent to validate callback */
switch (pkt->tag) {
case PGP_PTAG_CT_LITDATA_BODY:
case PGP_PTAG_CT_SIGNED_CLEARTEXT_BODY:
case PGP_PTAG_CT_SIGNATURE: /* V3 sigs */
case PGP_PTAG_CT_SIGNATURE_FOOTER: /* V4 sigs */
ret_validate_cb = validate_data_cb(pkt, cbinfo);
break;
default:
break;
}
/* Only validate_data_cb takes some arguments.
* Otherwise, stacked callbacks would have been necessary
*/
return (ret_write_cb == PGP_KEEP_MEMORY ||
ret_validate_cb == PGP_KEEP_MEMORY) ?
PGP_KEEP_MEMORY : PGP_RELEASE_MEMORY;
}
/* decrypt and validate an area of memory */
pgp_memory_t *
pgp_decrypt_and_validate_buf(pgp_io_t *io,
pgp_validation_t *result,
const void *input,
const size_t insize,
pgp_keyring_t *secring,
pgp_keyring_t *pubring,
const unsigned use_armour,
key_id_t **recipients_key_ids,
unsigned *recipients_count)
{
// historical code bloat...
const unsigned sshkeys = 0;
void *passfp = NULL;
int numtries = -1;
pgp_cbfunc_t *getpassfunc = NULL;
validate_data_cb_t validation;
pgp_stream_t *stream = NULL;
pgp_memory_t *outmem;
pgp_memory_t *inmem;
const int printerrors = 1;
if (input == NULL) {
(void) fprintf(io->errs,
"pgp_encrypt_buf: null memory\n");
return 0;
}
inmem = pgp_memory_new();
pgp_memory_add(inmem, input, insize);
/* set up to read from memory */
pgp_setup_memory_read(io, &stream, inmem,
&validation,
pgp_decrypt_and_validate_cb,
1);
/* Set verification reader and handling options */
(void) memset(&validation, 0x0, sizeof(validation));
validation.result = result;
validation.keyring = pubring;
validation.mem = pgp_memory_new();
pgp_memory_init(validation.mem, 128);
/* setup for writing decrypted contents */
pgp_setup_memory_write(&stream->cbinfo.output, &outmem, insize);
/* setup keyring and passphrase callback */
stream->cbinfo.cryptinfo.secring = secring;
stream->cbinfo.cryptinfo.pubring = pubring;
stream->cbinfo.passfp = passfp;
stream->cbinfo.cryptinfo.getpassphrase = getpassfunc;
stream->cbinfo.sshseckey = (sshkeys) ? &secring->keys[0].key.seckey : NULL;
stream->cbinfo.numtries = numtries;
/* Set up armour */
if (use_armour) {
pgp_reader_push_dearmour(stream);
}
/* Do it */
pgp_parse(stream, printerrors);
/* Unsetup */
if (use_armour) {
pgp_reader_pop_dearmour(stream);
}
*recipients_count = stream->cbinfo.cryptinfo.recipients_key_idsc;
if (*recipients_count == 0) {
*recipients_key_ids = NULL;
} else {
*recipients_key_ids = calloc(sizeof(key_id_t),*recipients_count);
if( *recipients_key_ids != NULL)
{
memcpy(*recipients_key_ids,
stream->cbinfo.cryptinfo.recipients_key_idss,
sizeof(key_id_t) * *recipients_count);
}
}
if( *recipients_key_ids == NULL)
{
pgp_memory_free(outmem);
*recipients_count = 0;
outmem = NULL;
}
/* tidy up */
pgp_writer_close(stream->cbinfo.output);
pgp_output_delete(stream->cbinfo.output);
pgp_teardown_memory_read(stream, inmem);
pgp_memory_free(validation.mem);
return outmem;
}

1644
libs/netpgp/src/keyring.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -49,7 +49,7 @@
/** \file
*/
#include "config-netpgp.h"
#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
@ -57,7 +57,7 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
__RCSID("$NetBSD: misc.c,v 1.41 2012/03/05 02:20:18 christos Exp $");
__RCSID("$NetBSD$");
#endif
#include <sys/types.h>
@ -78,123 +78,24 @@ __RCSID("$NetBSD: misc.c,v 1.41 2012/03/05 02:20:18 christos Exp $");
#include <openssl/rand.h>
#endif
#include "errors-netpgp.h"
#include "packet-netpgp.h"
#include "crypto-netpgp.h"
#include "create-netpgp.h"
#include "packet-parse.h"
#include "packet-show.h"
#include "signature-netpgp.h"
#include "netpgpsdk.h"
#include "netpgpdefs.h"
#include "memory-netpgp.h"
#include "readerwriter-netpgp.h"
#include "version-netpgp.h"
#include "netpgpdigest.h"
#include "netpgp/errors.h"
#include "netpgp/packet.h"
#include "netpgp/crypto.h"
#include "netpgp/create.h"
#include "netpgp/packet-parse.h"
#include "netpgp/packet-show.h"
#include "netpgp/signature.h"
#include "netpgp/netpgpsdk.h"
#include "netpgp/netpgpdefs.h"
#include "netpgp/memory.h"
#include "netpgp/readerwriter.h"
#include "netpgp/version.h"
#include "netpgp/netpgpdigest.h"
#ifdef WIN32
#define vsnprintf _vsnprintf
#endif
typedef struct {
pgp_keyring_t *keyring;
} accumulate_t;
/**
* \ingroup Core_Callbacks
*/
static pgp_cb_ret_t
accumulate_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
{
const pgp_contents_t *content = &pkt->u;
pgp_keyring_t *keyring;
accumulate_t *accumulate;
if (pgp_get_debug_level(__FILE__)) {
(void) fprintf(stderr, "accumulate callback: packet tag %u\n", pkt->tag);
}
accumulate = pgp_callback_arg(cbinfo);
keyring = accumulate->keyring;
switch (pkt->tag) {
case PGP_PTAG_CT_PUBLIC_KEY:
case PGP_PTAG_CT_PUBLIC_SUBKEY:
pgp_add_to_pubring(keyring, &content->pubkey, pkt->tag);
return PGP_KEEP_MEMORY;
case PGP_PTAG_CT_SECRET_KEY:
case PGP_PTAG_CT_ENCRYPTED_SECRET_KEY:
pgp_add_to_secring(keyring, &content->seckey);
return PGP_KEEP_MEMORY;
case PGP_PTAG_CT_USER_ID:
if (pgp_get_debug_level(__FILE__)) {
(void) fprintf(stderr, "User ID: %s for key %d\n",
content->userid,
keyring->keyc - 1);
}
if (keyring->keyc == 0) {
PGP_ERROR_1(cbinfo->errors, PGP_E_P_NO_USERID, "%s",
"No userid found");
} else {
pgp_add_userid(&keyring->keys[keyring->keyc - 1], content->userid);
}
return PGP_KEEP_MEMORY;
case PGP_PARSER_PACKET_END:
if (keyring->keyc > 0) {
pgp_add_subpacket(&keyring->keys[keyring->keyc - 1],
&content->packet);
return PGP_KEEP_MEMORY;
}
return PGP_RELEASE_MEMORY;
case PGP_PARSER_ERROR:
(void) fprintf(stderr, "Error: %s\n", content->error);
return PGP_FINISHED;
case PGP_PARSER_ERRCODE:
(void) fprintf(stderr, "parse error: %s\n",
pgp_errcode(content->errcode.errcode));
break;
default:
break;
}
/* XXX: we now exclude so many things, we should either drop this or */
/* do something to pass on copies of the stuff we keep */
return pgp_stacked_callback(pkt, cbinfo);
}
/**
* \ingroup Core_Parse
*
* Parse packets from an input stream until EOF or error.
*
* Key data found in the parsed data is added to #keyring.
*
* \param keyring Pointer to an existing keyring
* \param parse Options to use when parsing
*/
int
pgp_parse_and_accumulate(pgp_keyring_t *keyring, pgp_stream_t *parse)
{
accumulate_t accumulate;
const int printerrors = 1;
int ret;
if (parse->readinfo.accumulate) {
(void) fprintf(stderr,
"pgp_parse_and_accumulate: already init\n");
return 0;
}
(void) memset(&accumulate, 0x0, sizeof(accumulate));
accumulate.keyring = keyring;
pgp_callback_push(parse, accumulate_cb, &accumulate);
parse->readinfo.accumulate = 1;
ret = pgp_parse(parse, !printerrors);
return ret;
}
/** \file
* \brief Error Handling
*/
@ -597,7 +498,7 @@ pgp_hash_add_int(pgp_hash_t *hash, unsigned n, unsigned length)
\param hash Hash to set up
\param alg Hash algorithm to use
*/
void
unsigned
pgp_hash_any(pgp_hash_t *hash, pgp_hash_alg_t alg)
{
switch (alg) {
@ -627,7 +528,9 @@ pgp_hash_any(pgp_hash_t *hash, pgp_hash_alg_t alg)
default:
(void) fprintf(stderr, "pgp_hash_any: bad algorithm\n");
return 0;
}
return 1;
}
/**

570
libs/netpgp/src/netpgp.c Normal file
View file

@ -0,0 +1,570 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
__RCSID("$NetBSD$");
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/mman.h>
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include <errno.h>
#include <regex.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <errno.h>
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#include "netpgp.h"
#include "netpgp/packet.h"
#include "netpgp/packet-parse.h"
#include "netpgp/keyring.h"
#include "netpgp/errors.h"
#include "netpgp/packet-show.h"
#include "netpgp/create.h"
#include "netpgp/netpgpsdk.h"
#include "netpgp/memory.h"
#include "netpgp/validate.h"
#include "netpgp/readerwriter.h"
#include "netpgp/netpgpdefs.h"
#include "netpgp/crypto.h"
#include "netpgp/defs.h"
/* read any gpg config file */
static int
conffile(netpgp_t *netpgp, char *homedir, char *userid, size_t length)
{
regmatch_t matchv[10];
regex_t keyre;
char buf[BUFSIZ];
FILE *fp;
__PGP_USED(netpgp);
(void) snprintf(buf, sizeof(buf), "%s/gpg.conf", homedir);
if ((fp = fopen(buf, "r")) == NULL) {
return 0;
}
(void) memset(&keyre, 0x0, sizeof(keyre));
(void) regcomp(&keyre, "^[ \t]*default-key[ \t]+([0-9a-zA-F]+)",
REG_EXTENDED);
while (fgets(buf, (int)sizeof(buf), fp) != NULL) {
if (regexec(&keyre, buf, 10, matchv, 0) == 0) {
(void) memcpy(userid, &buf[(int)matchv[1].rm_so],
MIN((unsigned)(matchv[1].rm_eo -
matchv[1].rm_so), length));
if (netpgp->passfp == NULL) {
(void) fprintf(stderr,
"netpgp: default key set to \"%.*s\"\n",
(int)(matchv[1].rm_eo - matchv[1].rm_so),
&buf[(int)matchv[1].rm_so]);
}
}
}
(void) fclose(fp);
regfree(&keyre);
return 1;
}
/* check there's enough space in the arrays */
static int
size_arrays(netpgp_t *netpgp, unsigned needed)
{
char **temp;
if (netpgp->size == 0) {
/* only get here first time around */
netpgp->size = needed;
if ((netpgp->name = calloc(sizeof(char *), needed)) == NULL) {
(void) fprintf(stderr, "size_arrays: bad alloc\n");
return 0;
}
if ((netpgp->value = calloc(sizeof(char *), needed)) == NULL) {
free(netpgp->name);
(void) fprintf(stderr, "size_arrays: bad alloc\n");
return 0;
}
} else if (netpgp->c == netpgp->size) {
/* only uses 'needed' when filled array */
netpgp->size += needed;
temp = realloc(netpgp->name, sizeof(char *) * needed);
if (temp == NULL) {
(void) fprintf(stderr, "size_arrays: bad alloc\n");
return 0;
}
netpgp->name = temp;
temp = realloc(netpgp->value, sizeof(char *) * needed);
if (temp == NULL) {
(void) fprintf(stderr, "size_arrays: bad alloc\n");
return 0;
}
netpgp->value = temp;
}
return 1;
}
/* find the name in the array */
static int
findvar(netpgp_t *netpgp, const char *name)
{
unsigned i;
for (i = 0 ; i < netpgp->c && strcmp(netpgp->name[i], name) != 0; i++) {
}
return (i == netpgp->c) ? -1 : (int)i;
}
/* read a keyring and return it */
static unsigned
readkeyring(netpgp_t *netpgp,
const char *name,
pgp_keyring_t *pubring,
pgp_keyring_t *secring)
{
const unsigned noarmor = 0;
char *filename;
char f[MAXPATHLEN];
if ((filename = netpgp_getvar(netpgp, name)) == NULL) {
char *homedir;
homedir = netpgp_getvar(netpgp, "homedir");
(void) snprintf(f, sizeof(f), "%s/%s.gpg", homedir, name);
filename = f;
}
if (!pgp_keyring_fileread(netpgp->io, pubring, secring, noarmor, filename)) {
(void) fprintf(stderr, "Can't read %s %s\n", name, filename);
return 0;
}
netpgp_setvar(netpgp, name, filename);
return 1;
}
/* get the uid of the first key in the keyring */
static int
get_first_ring(pgp_keyring_t *ring, char *id, size_t len, int last)
{
uint8_t *src;
int i;
int n;
if (ring == NULL) {
return 0;
}
(void) memset(id, 0x0, len);
src = ring->keys[(last) ? ring->keyc - 1 : 0].pubkeyid;
for (i = 0, n = 0 ; i < PGP_KEY_ID_SIZE ; i += 2) {
n += snprintf(&id[n], len - n, "%02x%02x", src[i], src[i + 1]);
}
id[n] = 0x0;
return 1;
}
/***************************************************************************/
/* exported functions start here */
/***************************************************************************/
/* initialise a netpgp_t structure */
int
netpgp_init(netpgp_t *netpgp)
{
pgp_io_t *io;
time_t t;
char id[MAX_ID_LENGTH];
char *homedir;
char *userid;
char *stream;
char *passfd;
char *results;
int coredumps;
#ifdef HAVE_SYS_RESOURCE_H
struct rlimit limit;
coredumps = netpgp_getvar(netpgp, "coredumps") != NULL;
if (!coredumps) {
(void) memset(&limit, 0x0, sizeof(limit));
if (setrlimit(RLIMIT_CORE, &limit) != 0) {
(void) fprintf(stderr,
"netpgp: warning - can't turn off core dumps\n");
coredumps = 1;
}
}
#else
coredumps = 1;
#endif
if ((io = calloc(1, sizeof(*io))) == NULL) {
(void) fprintf(stderr, "netpgp_init: bad alloc\n");
return 0;
}
io->outs = stdout;
if ((stream = netpgp_getvar(netpgp, "outs")) != NULL &&
strcmp(stream, "<stderr>") == 0) {
io->outs = stderr;
}
io->errs = stderr;
if ((stream = netpgp_getvar(netpgp, "errs")) != NULL &&
strcmp(stream, "<stdout>") == 0) {
io->errs = stdout;
}
if ((results = netpgp_getvar(netpgp, "res")) == NULL) {
io->res = io->errs;
} else if (strcmp(results, "<stdout>") == 0) {
io->res = stdout;
} else if (strcmp(results, "<stderr>") == 0) {
io->res = stderr;
} else {
if ((io->res = fopen(results, "w")) == NULL) {
(void) fprintf(io->errs, "Can't open results %s for writing\n",
results);
free(io);
return 0;
}
}
netpgp->io = io;
/* get passphrase from an fd */
if ((passfd = netpgp_getvar(netpgp, "pass-fd")) != NULL &&
(netpgp->passfp = fdopen(atoi(passfd), "r")) == NULL) {
(void) fprintf(io->errs, "Can't open fd %s for reading\n",
passfd);
return 0;
}
/* warn if core dumps are enabled */
if (coredumps) {
(void) fprintf(io->errs,
"netpgp: warning: core dumps enabled\n");
}
/* get home directory - where keyrings are in a subdir */
if ((homedir = netpgp_getvar(netpgp, "homedir")) == NULL) {
(void) fprintf(io->errs, "netpgp: bad homedir\n");
return 0;
}
if ((netpgp->pubring = calloc(1, sizeof(pgp_keyring_t))) == NULL) {
(void) fprintf(io->errs, "Can't alloc pubring\n");
return 0;
}
if ((netpgp->secring = calloc(1, sizeof(pgp_keyring_t))) == NULL) {
(void) fprintf(io->errs, "Can't alloc secring\n");
return 0;
}
if (!readkeyring(netpgp,
"pubring",
netpgp->pubring,
netpgp->secring)) {
(void) fprintf(io->errs, "Can't read pub keyring\n");
// return 0;
}
/* if a userid has been given, we'll use it */
if ((userid = netpgp_getvar(netpgp, "userid")) == NULL) {
/* also search in config file for default id */
(void) memset(id, 0x0, sizeof(id));
(void) conffile(netpgp, homedir, id, sizeof(id));
if (id[0] != 0x0) {
netpgp_setvar(netpgp, "userid", userid = id);
}
}
/* only read secret keys if we need to */
if (netpgp_getvar(netpgp, "need seckey")) {
/* read the secret ring */
if (!readkeyring(netpgp,
"secring",
netpgp->pubring,
netpgp->secring)) {
(void) fprintf(io->errs, "Can't read sec keyring\n");
// return 0;
}
/* now, if we don't have a valid user, use the first in secring */
if (!userid && netpgp_getvar(netpgp, "need userid") != NULL) {
/* signing - need userid and sec key */
(void) memset(id, 0x0, sizeof(id));
if (get_first_ring(netpgp->secring, id, sizeof(id), 0)) {
netpgp_setvar(netpgp, "userid", userid = id);
}
}
} else if (netpgp_getvar(netpgp, "need userid") != NULL) {
/* encrypting - get first in pubring */
if (!userid && get_first_ring(netpgp->pubring, id, sizeof(id), 0)) {
(void) netpgp_setvar(netpgp, "userid", userid = id);
}
}
if (!userid && netpgp_getvar(netpgp, "need userid")) {
/* if we don't have a user id, and we need one, fail */
(void) fprintf(io->errs, "Cannot find user id\n");
return 0;
}
t = time(NULL);
netpgp_setvar(netpgp, "initialised", ctime(&t));
return 1;
}
/* finish off with the netpgp_t struct */
int
netpgp_end(netpgp_t *netpgp)
{
unsigned i;
for (i = 0 ; i < netpgp->c ; i++) {
if (netpgp->name[i] != NULL) {
free(netpgp->name[i]);
}
if (netpgp->value[i] != NULL) {
free(netpgp->value[i]);
}
}
if (netpgp->name != NULL) {
free(netpgp->name);
}
if (netpgp->value != NULL) {
free(netpgp->value);
}
if (netpgp->pubring != NULL) {
pgp_keyring_free(netpgp->pubring);
}
if (netpgp->secring != NULL) {
pgp_keyring_free(netpgp->secring);
}
free(netpgp->io);
return 1;
}
static int
netpgp_save_ring(netpgp_t *netpgp,
pgp_keyring_t *keyring,
char *name)
{
pgp_io_t *io;
pgp_key_t *key;
unsigned n;
pgp_output_t *output;
int fd;
int err = 0;
char swpfile[MAXPATHLEN];
char backup[MAXPATHLEN];
char *ringfile;
int cur;
time_t curtime;
char f[MAXPATHLEN];
io = netpgp->io;
/* file names */
if ((ringfile = netpgp_getvar(netpgp, name)) == NULL) {
char *homedir;
homedir = netpgp_getvar(netpgp, "homedir");
(void) snprintf(f, sizeof(f), "%s/%s.gpg", homedir, name);
ringfile = f;
}
curtime = time(NULL);
if (snprintf(swpfile, sizeof(swpfile),
"%s.swp", ringfile) >= sizeof(swpfile) ||
(cur = snprintf(backup, sizeof(backup),
"%s.backup_", ringfile)) >= sizeof(backup) ||
strftime(&backup[cur], sizeof(backup)-cur,
"%F.%T", localtime(&curtime)) >= sizeof(backup)-cur){
(void) fprintf(io->errs,
"netpgp_save_%s : file path too long\n", name);
return 0;
}
/* ensure temporary file isn't already existing */
unlink(swpfile);
if ((fd = pgp_setup_file_write(&output, swpfile, 0)) < 0) {
(void) fprintf(io->errs,
"netpgp_save_%s : can't setup write for %s\n", name, swpfile);
return 0;
}
for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) {
pgp_write_xfer_key(output, key, 0);
}
pgp_teardown_file_write(output, fd);
if(err){
unlink(swpfile);
return 0;
}
/* save ring if "backup rings" variable is set */
if (netpgp_getvar(netpgp, "backup rings") != NULL) {
rename(ringfile, backup);
}
/* replace ring file with swap file */
rename(swpfile, ringfile);
netpgp_setvar(netpgp, name, ringfile);
return 1;
}
int
netpgp_save_pubring(netpgp_t *netpgp)
{
return netpgp_save_ring(netpgp, netpgp->pubring, "pubring");
}
int
netpgp_save_secring(netpgp_t *netpgp)
{
return netpgp_save_ring(netpgp, netpgp->secring, "secring");
}
/* set a variable */
int
netpgp_setvar(netpgp_t *netpgp, const char *name, const char *value)
{
char *newval;
int i;
/* protect against the case where 'value' is netpgp->value[i] */
newval = netpgp_strdup(value);
if ((i = findvar(netpgp, name)) < 0) {
/* add the element to the array */
if (size_arrays(netpgp, netpgp->size + 15)) {
netpgp->name[i = netpgp->c++] = netpgp_strdup(name);
}
} else {
/* replace the element in the array */
if (netpgp->value[i]) {
free(netpgp->value[i]);
netpgp->value[i] = NULL;
}
}
/* sanity checks for range of values */
if (strcmp(name, "hash") == 0 || strcmp(name, "algorithm") == 0) {
if (pgp_str_to_hash_alg(newval) == PGP_HASH_UNKNOWN) {
free(newval);
return 0;
}
}
netpgp->value[i] = newval;
return 1;
}
/* unset a variable */
int
netpgp_unsetvar(netpgp_t *netpgp, const char *name)
{
int i;
if ((i = findvar(netpgp, name)) >= 0) {
if (netpgp->value[i]) {
free(netpgp->value[i]);
netpgp->value[i] = NULL;
}
netpgp->value[i] = NULL;
return 1;
}
return 0;
}
/* get a variable's value (NULL if not set) */
char *
netpgp_getvar(netpgp_t *netpgp, const char *name)
{
int i;
return ((i = findvar(netpgp, name)) < 0) ? NULL : netpgp->value[i];
}
/* increment a value */
int
netpgp_incvar(netpgp_t *netpgp, const char *name, const int delta)
{
char *cp;
char num[16];
int val;
val = 0;
if ((cp = netpgp_getvar(netpgp, name)) != NULL) {
val = atoi(cp);
}
(void) snprintf(num, sizeof(num), "%d", val + delta);
netpgp_setvar(netpgp, name, num);
return 1;
}
/* set the home directory value to "home/subdir" */
int
netpgp_set_homedir(netpgp_t *netpgp, char *home, const char *subdir, const int quiet)
{
struct stat st;
char d[MAXPATHLEN];
if (home == NULL) {
if (!quiet) {
(void) fprintf(stderr, "NULL HOME directory\n");
}
return 0;
}
(void) snprintf(d, sizeof(d), "%s%s", home, (subdir) ? subdir : "");
if (stat(d, &st) == 0) {
if ((st.st_mode & S_IFMT) == S_IFDIR) {
netpgp_setvar(netpgp, "homedir", d);
return 1;
}
(void) fprintf(stderr, "netpgp: homedir \"%s\" is not a dir\n",
d);
return 0;
}
if (!quiet) {
(void) fprintf(stderr,
"netpgp: warning homedir \"%s\" not found\n", d);
}
netpgp_setvar(netpgp, "homedir", d);
return 1;
}

View file

@ -49,7 +49,7 @@
/** \file
*/
#include "config-netpgp.h"
#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
@ -57,7 +57,7 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
__RCSID("$NetBSD: openssl_crypto.c,v 1.33 2010/11/07 08:39:59 agc Exp $");
__RCSID("$NetBSD$");
#endif
#ifdef HAVE_OPENSSL_DSA_H
@ -82,12 +82,13 @@ __RCSID("$NetBSD: openssl_crypto.c,v 1.33 2010/11/07 08:39:59 agc Exp $");
#include <unistd.h>
#endif
#include "crypto-netpgp.h"
#include "keyring-netpgp.h"
#include "readerwriter-netpgp.h"
#include "netpgpdefs.h"
#include "netpgpdigest.h"
#include "packet-netpgp.h"
#include "netpgp/crypto.h"
#include "netpgp/keyring.h"
#include "netpgp/readerwriter.h"
#include "netpgp/netpgpdefs.h"
#include "netpgp/netpgpdigest.h"
#include "netpgp/packet.h"
#include "netpgp/openssl11stub.h"
static void
@ -95,12 +96,14 @@ test_seckey(const pgp_seckey_t *seckey)
{
RSA *test = RSA_new();
test->n = BN_dup(seckey->pubkey.key.rsa.n);
test->e = BN_dup(seckey->pubkey.key.rsa.e);
RSA_set0_key(test,
BN_dup(seckey->pubkey.key.rsa.n),
BN_dup(seckey->pubkey.key.rsa.e),
BN_dup(seckey->key.rsa.d));
test->d = BN_dup(seckey->key.rsa.d);
test->p = BN_dup(seckey->key.rsa.p);
test->q = BN_dup(seckey->key.rsa.q);
RSA_set0_factors(test,
BN_dup(seckey->key.rsa.p),
BN_dup(seckey->key.rsa.q));
if (RSA_check_key(test) != 1) {
(void) fprintf(stderr,
@ -440,20 +443,25 @@ pgp_dsa_verify(const uint8_t *hash, size_t hash_length,
int ret;
osig = DSA_SIG_new();
osig->r = sig->r;
osig->s = sig->s;
DSA_SIG_set0(osig,
BN_dup(sig->r),
BN_dup(sig->s));
odsa = DSA_new();
odsa->p = dsa->p;
odsa->q = dsa->q;
odsa->g = dsa->g;
odsa->pub_key = dsa->y;
DSA_set0_pqg(odsa,
BN_dup(dsa->p),
BN_dup(dsa->q),
BN_dup(dsa->g));
DSA_set0_key(odsa,
BN_dup(dsa->y),
NULL);
if (pgp_get_debug_level(__FILE__)) {
hexdump(stderr, "input hash", hash, hash_length);
(void) fprintf(stderr, "Q=%d\n", BN_num_bytes(odsa->q));
(void) fprintf(stderr, "Q=%d\n", BN_num_bytes(dsa->q));
}
if ((qlen = (unsigned)BN_num_bytes(odsa->q)) < hash_length) {
if ((qlen = (unsigned)BN_num_bytes(dsa->q)) < hash_length) {
hash_length = qlen;
}
ret = DSA_do_verify(hash, (int)hash_length, osig, odsa);
@ -465,10 +473,8 @@ pgp_dsa_verify(const uint8_t *hash, size_t hash_length,
return 0;
}
odsa->p = odsa->q = odsa->g = odsa->pub_key = NULL;
DSA_free(odsa);
osig->r = osig->s = NULL;
DSA_SIG_free(osig);
return (unsigned)ret;
@ -493,12 +499,14 @@ pgp_rsa_public_decrypt(uint8_t *out,
int n;
orsa = RSA_new();
orsa->n = pubkey->n;
orsa->e = pubkey->e;
RSA_set0_key(orsa,
BN_dup(pubkey->n),
BN_dup(pubkey->e),
NULL);
n = RSA_public_decrypt((int)length, in, out, orsa, RSA_NO_PADDING);
orsa->n = orsa->e = NULL;
RSA_free(orsa);
return n;
@ -525,20 +533,19 @@ pgp_rsa_private_encrypt(uint8_t *out,
int n;
orsa = RSA_new();
orsa->n = BN_dup(pubkey->n);
orsa->d = seckey->d;
orsa->p = seckey->q; /* p and q are round the other way in openssl */
orsa->q = seckey->p;
RSA_set0_key(orsa,
BN_dup(pubkey->n),
BN_dup(pubkey->e),
BN_dup(seckey->d));
/* p and q are round the other way in openssl */
RSA_set0_factors(orsa,
/* q */ BN_dup(seckey->p),
/* p */ BN_dup(seckey->q));
/* debug */
orsa->e = BN_dup(pubkey->e);
/* If this isn't set, it's very likely that the programmer hasn't */
/* decrypted the secret key. RSA_check_key segfaults in that case. */
/* Use pgp_decrypt_seckey() to do that. */
if (orsa->d == NULL) {
(void) fprintf(stderr, "orsa is not set\n");
return 0;
}
if (RSA_check_key(orsa) != 1) {
(void) fprintf(stderr, "RSA_check_key is not set\n");
return 0;
@ -547,7 +554,6 @@ pgp_rsa_private_encrypt(uint8_t *out,
n = RSA_private_encrypt((int)length, in, out, orsa, RSA_NO_PADDING);
orsa->n = orsa->d = orsa->p = orsa->q = NULL;
RSA_free(orsa);
return n;
@ -575,13 +581,16 @@ pgp_rsa_private_decrypt(uint8_t *out,
char errbuf[1024];
keypair = RSA_new();
keypair->n = pubkey->n; /* XXX: do we need n? */
keypair->d = seckey->d;
keypair->p = seckey->q;
keypair->q = seckey->p;
RSA_set0_key(keypair,
BN_dup(pubkey->n),
BN_dup(pubkey->e),
BN_dup(seckey->d));
RSA_set0_factors(keypair,
BN_dup(seckey->p),
BN_dup(seckey->q));
/* debug */
keypair->e = pubkey->e;
if (RSA_check_key(keypair) != 1) {
(void) fprintf(stderr, "RSA_check_key is not set\n");
return 0;
@ -601,7 +610,6 @@ pgp_rsa_private_decrypt(uint8_t *out,
ERR_error_string(err, &errbuf[0]);
(void) fprintf(stderr, "openssl error : %s\n", errbuf);
}
keypair->n = keypair->d = keypair->p = keypair->q = NULL;
RSA_free(keypair);
return n;
@ -627,8 +635,10 @@ pgp_rsa_public_encrypt(uint8_t *out,
/* printf("pgp_rsa_public_encrypt: length=%ld\n", length); */
orsa = RSA_new();
orsa->n = pubkey->n;
orsa->e = pubkey->e;
RSA_set0_key(orsa,
BN_dup(pubkey->n),
BN_dup(pubkey->e),
NULL);
/* printf("len: %ld\n", length); */
/* pgp_print_bn("n: ", orsa->n); */
@ -641,7 +651,6 @@ pgp_rsa_public_encrypt(uint8_t *out,
fd_out = BIO_new_fd(fileno(stderr), BIO_NOCLOSE);
ERR_print_errors(fd_out);
}
orsa->n = orsa->e = NULL;
RSA_free(orsa);
return n;
@ -656,8 +665,8 @@ pgp_rsa_public_encrypt(uint8_t *out,
void
pgp_crypto_finish(void)
{
CRYPTO_cleanup_all_ex_data();
ERR_remove_state((unsigned long)0);
// No cleanup since OpenSSL 1.1.0
// CRYPTO_cleanup_all_ex_data();
}
/**
@ -682,17 +691,25 @@ pgp_text_from_hash(pgp_hash_t *hash)
\note It is the caller's responsibility to call pgp_keydata_free(keydata)
*/
unsigned
rsa_generate_keypair(pgp_key_t *keydata,
pgp_rsa_generate_keypair(pgp_key_t *keydata,
const int numbits,
const unsigned long e__,
const char *hashalg,
const char *cipher)
const char *cipher,
const uint8_t *passphrase,
const size_t pplen)
{
pgp_seckey_t *seckey;
RSA *rsa = RSA_new();
RSA *rsa;
BN_CTX *ctx;
pgp_output_t *output;
pgp_memory_t *mem;
int res;
const BIGNUM *_n = NULL;
const BIGNUM *_e = NULL;
const BIGNUM *_d = NULL;
const BIGNUM *_p = NULL;
const BIGNUM *_q = NULL;
ctx = BN_CTX_new();
pgp_keydata_init(keydata, PGP_PTAG_CT_SECRET_KEY);
@ -700,14 +717,29 @@ rsa_generate_keypair(pgp_key_t *keydata,
/* generate the key pair */
//rsa = RSA_generate_key(numbits, e, NULL, NULL);
/* generate key */
BIGNUM* e = BN_new();
BN_set_word(e, e__);
if( RSA_generate_key_ex(rsa, numbits, e, 0) != 1 ) {
BIGNUM *exp = BN_new();
BN_set_word(exp, e__);
/*
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
exp = BN_bin2bn((const unsigned char *)&e, sizeof(e), NULL);
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
exp = BN_lebin2bn((const unsigned char *)&e, sizeof(e), NULL);
#else
#error Unsupported endian
#endif
if (!exp)
return 0;
}
BN_free(e);
*/
rsa = RSA_new();
res = RSA_generate_key_ex(rsa, numbits, exp, NULL);
BN_free(exp);
if (!res){
RSA_free(rsa);
return 0;
};
/* populate pgp key from ssl key */
@ -716,11 +748,14 @@ rsa_generate_keypair(pgp_key_t *keydata,
seckey->pubkey.days_valid = 0;
seckey->pubkey.alg = PGP_PKA_RSA;
seckey->pubkey.key.rsa.n = BN_dup(rsa->n);
seckey->pubkey.key.rsa.e = BN_dup(rsa->e);
RSA_get0_key(rsa, &_n, &_e, &_d);
seckey->s2k_usage = PGP_S2KU_ENCRYPTED_AND_HASHED;
seckey->s2k_specifier = PGP_S2KS_SALTED;
seckey->pubkey.key.rsa.n = BN_dup(_n);
seckey->pubkey.key.rsa.e = BN_dup(_e);
/* seckey->s2k_usage = PGP_S2KU_ENCRYPTED_AND_HASHED; */
seckey->s2k_usage = PGP_S2KU_NONE;
/* seckey->s2k_specifier = PGP_S2KS_SALTED;*/
/* seckey->s2k_specifier=PGP_S2KS_SIMPLE; */
if ((seckey->hash_alg = pgp_str_to_hash_alg(hashalg)) == PGP_HASH_UNKNOWN) {
seckey->hash_alg = PGP_HASH_SHA1;
@ -729,20 +764,22 @@ rsa_generate_keypair(pgp_key_t *keydata,
seckey->octetc = 0;
seckey->checksum = 0;
seckey->key.rsa.d = BN_dup(rsa->d);
seckey->key.rsa.p = BN_dup(rsa->p);
seckey->key.rsa.q = BN_dup(rsa->q);
seckey->key.rsa.u = BN_mod_inverse(NULL, rsa->p, rsa->q, ctx);
RSA_get0_factors(rsa, &_p, &_q);
seckey->key.rsa.d = BN_dup(_d);
seckey->key.rsa.p = BN_dup(_p);
seckey->key.rsa.q = BN_dup(_q);
seckey->key.rsa.u = BN_mod_inverse(NULL, _p, _q, ctx);
if (seckey->key.rsa.u == NULL) {
//(void) fprintf(stderr, "seckey->key.rsa.u is NULL\n");
RSA_free(rsa);
(void) fprintf(stderr, "seckey->key.rsa.u is NULL\n");
return 0;
}
BN_CTX_free(ctx);
RSA_free(rsa);
pgp_keyid(keydata->sigid, PGP_KEY_ID_SIZE, &keydata->key.seckey.pubkey, seckey->hash_alg);
pgp_fingerprint(&keydata->sigfingerprint, &keydata->key.seckey.pubkey, seckey->hash_alg);
pgp_keyid(keydata->pubkeyid, PGP_KEY_ID_SIZE, &keydata->key.seckey.pubkey, seckey->hash_alg);
pgp_fingerprint(&keydata->pubkeyfpr, &keydata->key.seckey.pubkey, seckey->hash_alg);
/* Generate checksum */
@ -797,7 +834,7 @@ rsa_generate_keypair(pgp_key_t *keydata,
\return The new keypair or NULL
\note It is the caller's responsibility to call pgp_keydata_free(keydata)
\sa rsa_generate_keypair()
\sa pgp_rsa_generate_keypair()
\sa pgp_keydata_free()
*/
pgp_key_t *
@ -810,15 +847,16 @@ pgp_rsa_new_selfsign_key(const int numbits,
pgp_key_t *keydata;
keydata = pgp_keydata_new();
if (!rsa_generate_keypair(keydata, numbits, e, hashalg, cipher) ||
!pgp_add_selfsigned_userid(keydata, userid)) {
if (!pgp_rsa_generate_keypair(keydata, numbits, e, hashalg, cipher,
(const uint8_t *) "", (const size_t) 0) ||
!pgp_add_selfsigned_userid(keydata, NULL, userid, 0 /*never expire*/)) {
pgp_keydata_free(keydata);
return NULL;
}
return keydata;
}
DSA_SIG *
pgp_dsa_sig_t *
pgp_dsa_sign(uint8_t *hashbuf,
unsigned hashsize,
const pgp_dsa_seckey_t *secdsa,
@ -826,64 +864,37 @@ pgp_dsa_sign(uint8_t *hashbuf,
{
DSA_SIG *dsasig;
DSA *odsa;
pgp_dsa_sig_t *pgpdsasig;
const BIGNUM *pr = NULL;
const BIGNUM *ps = NULL;
odsa = DSA_new();
odsa->p = pubdsa->p;
odsa->q = pubdsa->q;
odsa->g = pubdsa->g;
odsa->pub_key = pubdsa->y;
odsa->priv_key = secdsa->x;
DSA_set0_pqg(odsa,
BN_dup(pubdsa->p),
BN_dup(pubdsa->q),
BN_dup(pubdsa->g));
DSA_set0_key(odsa,
BN_dup(pubdsa->y),
BN_dup(secdsa->x));
dsasig = DSA_do_sign(hashbuf, (int)hashsize, odsa);
odsa->p = odsa->q = odsa->g = odsa->pub_key = odsa->priv_key = NULL;
DSA_free(odsa);
return dsasig;
DSA_SIG_get0(dsasig, &pr, &ps);
pgpdsasig = calloc(1,sizeof(pgp_dsa_sig_t));
if(pgpdsasig != NULL){
pgpdsasig->r = BN_dup(pr);
pgpdsasig->s = BN_dup(ps);
}
DSA_SIG_free(dsasig);
return pgpdsasig;
}
int
openssl_read_pem_seckey(const char *f, pgp_key_t *key, const char *type, int verbose)
{
FILE *fp;
char prompt[BUFSIZ];
char *pass;
DSA *dsa;
RSA *rsa;
int ok;
OpenSSL_add_all_algorithms();
if ((fp = fopen(f, "r")) == NULL) {
if (verbose) {
(void) fprintf(stderr, "can't open '%s'\n", f);
}
return 0;
}
ok = 1;
if (strcmp(type, "ssh-rsa") == 0) {
if ((rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) {
(void) snprintf(prompt, sizeof(prompt), "netpgp PEM %s passphrase: ", f);
do {
pass = getpass(prompt);
rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, pass);
} while (rsa == NULL);
}
key->key.seckey.key.rsa.d = rsa->d;
key->key.seckey.key.rsa.p = rsa->p;
key->key.seckey.key.rsa.q = rsa->q;
key->key.seckey.key.rsa.d = rsa->d;
} else if (strcmp(type, "ssh-dss") == 0) {
if ((dsa = PEM_read_DSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) {
ok = 0;
} else {
key->key.seckey.key.dsa.x = dsa->priv_key;
}
} else {
ok = 0;
}
(void) fclose(fp);
return ok;
}
/*
* Decide the number of bits in the random componont k

View file

@ -50,7 +50,7 @@
/** \file
* \brief Parser for OpenPGP packets
*/
#include "config-netpgp.h"
#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
@ -58,7 +58,7 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
__RCSID("$NetBSD: packet-parse.c,v 1.51 2012/03/05 02:20:18 christos Exp $");
__RCSID("$NetBSD$");
#endif
#include <sys/types.h>
@ -80,16 +80,16 @@ __RCSID("$NetBSD: packet-parse.c,v 1.51 2012/03/05 02:20:18 christos Exp $");
#include <limits.h>
#endif
#include "packet-netpgp.h"
#include "packet-parse.h"
#include "keyring-netpgp.h"
#include "errors-netpgp.h"
#include "packet-show.h"
#include "create-netpgp.h"
#include "readerwriter-netpgp.h"
#include "netpgpdefs.h"
#include "crypto-netpgp.h"
#include "netpgpdigest.h"
#include "netpgp/packet.h"
#include "netpgp/packet-parse.h"
#include "netpgp/keyring.h"
#include "netpgp/errors.h"
#include "netpgp/packet-show.h"
#include "netpgp/create.h"
#include "netpgp/readerwriter.h"
#include "netpgp/netpgpdefs.h"
#include "netpgp/crypto.h"
#include "netpgp/netpgpdigest.h"
#define ERRP(cbinfo, cont, err) do { \
cont.u.error = err; \
@ -189,6 +189,30 @@ pgp_init_subregion(pgp_region_t *subregion, pgp_region_t *region)
* XXX: replace pgp_ptag_t with something more appropriate for limiting reads
*/
/* data from partial blocks is queued up in virtual block in stream */
static int
read_partial_data(pgp_stream_t *stream,
pgp_reader_t *readinfo,
void *dest, size_t length)
{
unsigned n;
if (pgp_get_debug_level(__FILE__)) {
(void) fprintf(stderr, "fd_reader: coalesced data, off %d\n",
readinfo->virtualoff);
}
n = MIN(readinfo->virtualc - readinfo->virtualoff, (unsigned)length);
(void) memcpy(dest, &readinfo->virtualpkt[readinfo->virtualoff], n);
readinfo->virtualoff += n;
if (readinfo->virtualoff == readinfo->virtualc) {
free(readinfo->virtualpkt);
readinfo->virtualpkt = NULL;
readinfo->virtualc = readinfo->virtualoff = 0;
}
return (int)n;
}
/**
* low-level function to read data from reader function
*
@ -231,8 +255,13 @@ sub_base_read(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **err
for (n = 0; n < length;) {
int r;
r = readinfo->reader(stream, (char *) dest + n, length - n, errors,
if (!readinfo->coalescing && readinfo->virtualc && readinfo->virtualoff < readinfo->virtualc) {
r = read_partial_data(stream, readinfo, (char*) dest + n, length - n);
}else{
r = readinfo->reader(stream, (char *) dest + n,
length - n, errors,
readinfo, cbinfo);
}
if (r > (int)(length - n)) {
(void) fprintf(stderr, "sub_base_read: bad read\n");
return 0;
@ -454,6 +483,7 @@ limread(uint8_t *dest, unsigned length,
&info->readinfo, &info->cbinfo);
}
#if 0
static unsigned
exact_limread(uint8_t *dest, unsigned len,
pgp_region_t *region,
@ -466,6 +496,7 @@ exact_limread(uint8_t *dest, unsigned len,
stream->exact_read = 0;
return ret;
}
#endif
/** Skip over length bytes of this packet.
*
@ -655,10 +686,10 @@ limread_mpi(BIGNUM **pbn, pgp_region_t *region, pgp_stream_t *stream)
unsigned nonzero;
unsigned ret;
stream->reading_mpi_len = 1;
//stream->reading_mpi_len = 1;
ret = (unsigned)limread_scalar(&length, 2, region, stream);
stream->reading_mpi_len = 0;
//stream->reading_mpi_len = 0;
if (!ret)
return 0;
@ -704,11 +735,12 @@ static void
streamread(pgp_stream_t *stream, unsigned c)
{
int cc;
pgp_reader_t *readinfo = &stream->readinfo;
stream->virtualpkt = realloc(stream->virtualpkt, stream->virtualc + c);
cc = stream->readinfo.reader(stream, &stream->virtualpkt[stream->virtualc],
c, &stream->errors, &stream->readinfo, &stream->cbinfo);
stream->virtualc += cc;
readinfo->virtualpkt = realloc(readinfo->virtualpkt, readinfo->virtualc + c);
cc = readinfo->reader(stream, &readinfo->virtualpkt[readinfo->virtualc],
c, &stream->errors, readinfo, &stream->cbinfo);
readinfo->virtualc += cc;
}
/* coalesce all the partial blocks together */
@ -716,17 +748,20 @@ static int
coalesce_blocks(pgp_stream_t *stream, unsigned length)
{
unsigned c;
unsigned r;
pgp_reader_t *readinfo = &stream->readinfo;
readinfo->coalescing = 1;
stream->coalescing = 1;
/* already read a partial block length - prime the array */
streamread(stream, length);
while (read_new_length(&c, stream) && stream->partial_read) {
while ((r = read_new_length(&c, stream)) && readinfo->partial_read) {
/* length we read is partial - add to end of array */
streamread(stream, c);
}
/* not partial - add the last extent to the end of the array */
streamread(stream, c);
stream->coalescing = 0;
if(r > 0) streamread(stream, c);
readinfo->coalescing = 0;
return 1;
}
@ -744,8 +779,9 @@ static unsigned
read_new_length(unsigned *length, pgp_stream_t *stream)
{
uint8_t c;
pgp_reader_t *readinfo = &stream->readinfo;
stream->partial_read = 0;
readinfo->partial_read = 0;
if (base_read(&c, 1, stream) != 1) {
return 0;
}
@ -766,13 +802,13 @@ read_new_length(unsigned *length, pgp_stream_t *stream)
}
if (c < 255) {
/* 3. Partial Body Length */
stream->partial_read = 1;
readinfo->partial_read = 1;
*length = 1 << (c & 0x1f);
if (!stream->coalescing) {
if (!readinfo->coalescing) {
/* we have been called from coalesce_blocks -
* just return with the partial length */
coalesce_blocks(stream, *length);
*length = stream->virtualc;
*length = readinfo->virtualc;
}
return 1;
}
@ -802,6 +838,7 @@ limited_read_new_length(unsigned *length, pgp_region_t *region,
pgp_stream_t *stream)
{
uint8_t c = 0x0;
pgp_reader_t *readinfo = &stream->readinfo;
if (!limread(&c, 1, region, stream)) {
return 0;
@ -820,13 +857,13 @@ limited_read_new_length(unsigned *length, pgp_region_t *region,
return 1;
}
if (c < 255) {
stream->partial_read = 1;
readinfo->partial_read = 1;
*length = 1 << (c & 0x1f);
if (!stream->coalescing) {
if (!readinfo->coalescing) {
/* we have been called from coalesce_blocks -
* just return with the partial length */
coalesce_blocks(stream, *length);
*length = stream->virtualc;
*length = readinfo->virtualc;
}
return 1;
}
@ -845,6 +882,14 @@ pgp_data_free(pgp_data_t *data)
data->len = 0;
}
void
pgp_data_dup(pgp_data_t *dst, const pgp_data_t *src)
{
dst->contents = calloc(1, src->len);
memcpy(dst->contents, src->contents, src->len);
dst->len = src->len;
}
/**
\ingroup Core_Create
\brief Free allocated memory
@ -920,28 +965,37 @@ free_BN(BIGNUM **pp)
*pp = NULL;
}
/**
* \ingroup Core_Create
* \brief Free the memory used when parsing a signature
* \param sig
*/
static void
sig_free(pgp_sig_t *sig)
dup_BN(BIGNUM **dst, const BIGNUM *src)
{
switch (sig->info.key_alg) {
*dst = BN_dup(src);
}
void
copy_sig_info(pgp_sig_info_t *dst, const pgp_sig_info_t *src)
{
(void) memcpy(dst, src, sizeof(*src));
if ((dst->v4_hashed = calloc(1, src->v4_hashlen)) == NULL) {
(void) fprintf(stderr, "copy_sig_info: bad alloc\n");
} else {
(void) memcpy(dst->v4_hashed, src->v4_hashed, src->v4_hashlen);
}
switch (src->key_alg) {
case PGP_PKA_RSA:
case PGP_PKA_RSA_SIGN_ONLY:
free_BN(&sig->info.sig.rsa.sig);
dup_BN(&dst->sig.rsa.sig, src->sig.rsa.sig);
break;
case PGP_PKA_DSA:
free_BN(&sig->info.sig.dsa.r);
free_BN(&sig->info.sig.dsa.s);
dup_BN(&dst->sig.dsa.r, src->sig.dsa.r);
dup_BN(&dst->sig.dsa.s, src->sig.dsa.s);
break;
case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
free_BN(&sig->info.sig.elgamal.r);
free_BN(&sig->info.sig.elgamal.s);
dup_BN(&dst->sig.elgamal.r, src->sig.elgamal.r);
dup_BN(&dst->sig.elgamal.s, src->sig.elgamal.s);
break;
case PGP_PKA_PRIVATE00:
@ -955,13 +1009,65 @@ sig_free(pgp_sig_t *sig)
case PGP_PKA_PRIVATE08:
case PGP_PKA_PRIVATE09:
case PGP_PKA_PRIVATE10:
pgp_data_free(&sig->info.sig.unknown);
pgp_data_dup(&dst->sig.unknown, &src->sig.unknown);
break;
default:
(void) fprintf(stderr, "sig_free: bad sig type\n");
(void) fprintf(stderr, "sig_dup: bad sig type\n");
}
}
/**
* \ingroup Core_Create
* \brief Free the memory used when parsing a signature
* \param sig
*/
void
pgp_free_sig_info(pgp_sig_info_t *info)
{
free(info->v4_hashed);
switch (info->key_alg) {
case PGP_PKA_RSA:
case PGP_PKA_RSA_SIGN_ONLY:
free_BN(&info->sig.rsa.sig);
break;
case PGP_PKA_DSA:
free_BN(&info->sig.dsa.r);
free_BN(&info->sig.dsa.s);
break;
case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
free_BN(&info->sig.elgamal.r);
free_BN(&info->sig.elgamal.s);
break;
case PGP_PKA_PRIVATE00:
case PGP_PKA_PRIVATE01:
case PGP_PKA_PRIVATE02:
case PGP_PKA_PRIVATE03:
case PGP_PKA_PRIVATE04:
case PGP_PKA_PRIVATE05:
case PGP_PKA_PRIVATE06:
case PGP_PKA_PRIVATE07:
case PGP_PKA_PRIVATE08:
case PGP_PKA_PRIVATE09:
case PGP_PKA_PRIVATE10:
pgp_data_free(&info->sig.unknown);
break;
default:
(void) fprintf(stderr, "info-free: bad info-type\n");
}
memset(info, 0, sizeof(pgp_sig_info_t));
}
static void
sig_free(pgp_sig_t *sig)
{
pgp_free_sig_info(&sig->info);
}
/**
\ingroup Core_Create
@ -1188,8 +1294,48 @@ pgp_pubkey_free(pgp_pubkey_t *p)
default:
(void) fprintf(stderr, "pgp_pubkey_free: bad alg\n");
}
memset(p, 0, sizeof(*p));
}
int
pgp_pubkey_dup(pgp_pubkey_t *dst, pgp_pubkey_t *src)
{
memcpy(dst, src, sizeof(*src));
switch (src->alg) {
case PGP_PKA_RSA:
case PGP_PKA_RSA_ENCRYPT_ONLY:
case PGP_PKA_RSA_SIGN_ONLY:
dup_BN(&dst->key.rsa.n, src->key.rsa.n);
dup_BN(&dst->key.rsa.e, src->key.rsa.e);
break;
case PGP_PKA_DSA:
dup_BN(&dst->key.dsa.p, src->key.dsa.p);
dup_BN(&dst->key.dsa.q, src->key.dsa.q);
dup_BN(&dst->key.dsa.g, src->key.dsa.g);
dup_BN(&dst->key.dsa.y, src->key.dsa.y);
break;
case PGP_PKA_ELGAMAL:
case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
dup_BN(&dst->key.elgamal.p, src->key.elgamal.p);
dup_BN(&dst->key.elgamal.g, src->key.elgamal.g);
dup_BN(&dst->key.elgamal.y, src->key.elgamal.y);
break;
case PGP_PKA_NOTHING:
/* nothing to dup */
break;
default:
(void) fprintf(stderr, "pgp_pubkey_dup: bad alg\n");
return 0;
}
/*TODO alloc error handling */
return 1;
}
/**
\ingroup Core_ReadPackets
*/
@ -1606,6 +1752,10 @@ parse_one_sig_subpacket(pgp_sig_t *sig,
sig->info.duration = pkt.u.ss_time;
sig->info.duration_set = 1;
}
if (pkt.tag == PGP_PTAG_SS_KEY_EXPIRY) {
sig->info.key_expiry = pkt.u.ss_time;
sig->info.key_expiry_set = 1;
}
break;
case PGP_PTAG_SS_TRUST:
@ -1653,11 +1803,17 @@ parse_one_sig_subpacket(pgp_sig_t *sig,
return 0;
}
pkt.u.ss_primary_userid = !!bools;
sig->info.primary_userid = pkt.u.ss_primary_userid;
break;
case PGP_PTAG_SS_KEY_FLAGS:
if (!read_data(&pkt.u.ss_key_flags, &subregion, stream)) {
return 0;
}
if(pkt.u.ss_key_flags.len > 0){
/* Only one byte is defined in rfc4880 for now */
sig->info.key_flags = pkt.u.ss_key_flags.contents[0];
sig->info.key_flags_set = 1;
}
break;
@ -1817,6 +1973,7 @@ parse_one_sig_subpacket(pgp_sig_t *sig,
PGP_ERROR_1(&stream->errors, PGP_E_R_UNCONSUMED_DATA,
"Unconsumed data (%d)",
subregion.length - subregion.readc);
pgp_parser_content_free(&pkt);
return 0;
}
CALLBACK(pkt.tag, &stream->cbinfo, &pkt);
@ -1968,24 +2125,24 @@ parse_v4_sig(pgp_region_t *region, pgp_stream_t *stream)
if (!stream->readinfo.accumulate) {
/* We must accumulate, else we can't check the signature */
fprintf(stderr, "*** ERROR: must set accumulate to 1\n");
return 0;
goto error_unalloc_v4_hashed;
}
(void) memcpy(pkt.u.sig.info.v4_hashed,
stream->readinfo.accumulated + pkt.u.sig.v4_hashstart,
pkt.u.sig.info.v4_hashlen);
if (!parse_sig_subpkts(&pkt.u.sig, region, stream)) {
return 0;
goto error_unalloc_v4_hashed;
}
if (!limread(pkt.u.sig.hash2, 2, region, stream)) {
return 0;
goto error_unalloc_v4_hashed;
}
switch (pkt.u.sig.info.key_alg) {
case PGP_PKA_RSA:
if (!limread_mpi(&pkt.u.sig.info.sig.rsa.sig, region, stream)) {
return 0;
goto error_unalloc_v4_hashed;
}
if (pgp_get_debug_level(__FILE__)) {
(void) fprintf(stderr, "parse_v4_sig: RSA: sig is\n");
@ -2004,7 +2161,7 @@ parse_v4_sig(pgp_region_t *region, pgp_stream_t *stream)
(void) fprintf(stderr,
"Error reading DSA r field in signature");
}
return 0;
goto error_unalloc_v4_hashed;
}
if (!limread_mpi(&pkt.u.sig.info.sig.dsa.s, region, stream)) {
ERRP(&stream->cbinfo, pkt,
@ -2017,7 +2174,7 @@ parse_v4_sig(pgp_region_t *region, pgp_stream_t *stream)
stream) ||
!limread_mpi(&pkt.u.sig.info.sig.elgamal.s, region,
stream)) {
return 0;
goto error_unalloc_v4_hashed;
}
break;
@ -2033,7 +2190,7 @@ parse_v4_sig(pgp_region_t *region, pgp_stream_t *stream)
case PGP_PKA_PRIVATE09:
case PGP_PKA_PRIVATE10:
if (!read_data(&pkt.u.sig.info.sig.unknown, region, stream)) {
return 0;
goto error_unalloc_v4_hashed;
}
break;
@ -2041,16 +2198,21 @@ parse_v4_sig(pgp_region_t *region, pgp_stream_t *stream)
PGP_ERROR_1(&stream->errors, PGP_E_ALG_UNSUPPORTED_SIGNATURE_ALG,
"Bad v4 signature key algorithm (%s)",
pgp_show_pka(pkt.u.sig.info.key_alg));
return 0;
goto error_unalloc_v4_hashed;
}
if (region->readc != region->length) {
PGP_ERROR_1(&stream->errors, PGP_E_R_UNCONSUMED_DATA,
"Unconsumed data (%d)",
region->length - region->readc);
return 0;
goto error_unalloc_v4_hashed;
}
CALLBACK(PGP_PTAG_CT_SIGNATURE_FOOTER, &stream->cbinfo, &pkt);
return 1;
error_unalloc_v4_hashed:
free(pkt.u.sig.info.v4_hashed);
return 0;
}
/**
@ -2306,6 +2468,50 @@ pgp_seckey_free(pgp_seckey_t *key)
pgp_show_pka(key->pubkey.alg));
}
free(key->checkhash);
pgp_pubkey_free(&key->pubkey);
memset(key, 0, sizeof(*key));
}
int
pgp_seckey_dup(pgp_seckey_t *dst, pgp_seckey_t *src)
{
memcpy(dst, src, sizeof(*src));
switch (src->pubkey.alg) {
case PGP_PKA_RSA:
case PGP_PKA_RSA_ENCRYPT_ONLY:
case PGP_PKA_RSA_SIGN_ONLY:
dup_BN(&dst->key.rsa.d, src->key.rsa.d);
dup_BN(&dst->key.rsa.p, src->key.rsa.p);
dup_BN(&dst->key.rsa.q, src->key.rsa.q);
dup_BN(&dst->key.rsa.u, src->key.rsa.u);
break;
case PGP_PKA_DSA:
dup_BN(&dst->key.dsa.x, src->key.dsa.x);
break;
default:
(void) fprintf(stderr,
"pgp_seckey_dup: Unknown algorithm: %d (%s)\n",
src->pubkey.alg,
pgp_show_pka(src->pubkey.alg));
return 0;
}
if(src->checkhash) {
if ((dst->checkhash = calloc(1, PGP_CHECKHASH_SIZE)) == NULL) {
(void) fprintf(stderr, "pgp_seckey_dup: bad alloc\n");
return 0;
}else{
memcpy(dst->checkhash, src->checkhash, PGP_CHECKHASH_SIZE);
}
}
pgp_pubkey_dup(&dst->pubkey, &src->pubkey);
/*TODO alloc error handling */
return 1;
}
static int
@ -2339,7 +2545,7 @@ consume_packet(pgp_region_t *region, pgp_stream_t *stream, unsigned warn)
* \brief Parse a secret key
*/
static int
parse_seckey(pgp_region_t *region, pgp_stream_t *stream)
parse_seckey(pgp_content_enum tag, pgp_region_t *region, pgp_stream_t *stream)
{
pgp_packet_t pkt;
pgp_region_t encregion;
@ -2364,9 +2570,14 @@ parse_seckey(pgp_region_t *region, pgp_stream_t *stream)
}
if (pgp_get_debug_level(__FILE__)) {
fprintf(stderr, "parse_seckey: public key parsed\n");
pgp_print_pubkey(&pkt.u.seckey.pubkey);
//pgp_print_pubkey(&pkt.u.seckey.pubkey);
}
//stream->reading_v3_secret = (pkt.u.seckey.pubkey.version != PGP_V4);
if (pkt.u.seckey.pubkey.version != PGP_V4){
(void) fprintf(stderr,
"parse_seckey: Only V4 is supported\n");
return 0;
}
stream->reading_v3_secret = (pkt.u.seckey.pubkey.version != PGP_V4);
if (!limread(&c, 1, region, stream)) {
return 0;
@ -2576,8 +2787,9 @@ parse_seckey(pgp_region_t *region, pgp_stream_t *stream)
if (pgp_get_debug_level(__FILE__)) {
fprintf(stderr, "parse_seckey: end of crypted passphrase\n");
}
if (pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED_AND_HASHED) {
/* XXX - Hard-coded SHA1 here ?? Check */
if (pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED_AND_HASHED) {
pkt.u.seckey.checkhash = calloc(1, PGP_SHA1_HASH_SIZE);
if (pkt.u.seckey.checkhash == NULL) {
(void) fprintf(stderr, "parse_seckey: bad alloc\n");
@ -2627,7 +2839,7 @@ parse_seckey(pgp_region_t *region, pgp_stream_t *stream)
if (pgp_get_debug_level(__FILE__)) {
(void) fprintf(stderr, "4 MPIs read\n");
}
stream->reading_v3_secret = 0;
//stream->reading_v3_secret = 0;
if (pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED_AND_HASHED) {
uint8_t hash[PGP_CHECKHASH_SIZE];
@ -2687,7 +2899,7 @@ parse_seckey(pgp_region_t *region, pgp_stream_t *stream)
if (!ret) {
return 0;
}
CALLBACK(PGP_PTAG_CT_SECRET_KEY, &stream->cbinfo, &pkt);
CALLBACK(tag, &stream->cbinfo, &pkt);
if (pgp_get_debug_level(__FILE__)) {
(void) fprintf(stderr, "--- end of parse_seckey\n\n");
}
@ -2869,6 +3081,7 @@ parse_pk_sesskey(pgp_region_t *region,
return 1;
}
#if 0
static int
decrypt_se_data(pgp_content_enum tag, pgp_region_t *region,
pgp_stream_t *stream)
@ -2928,6 +3141,7 @@ decrypt_se_data(pgp_content_enum tag, pgp_region_t *region,
return r;
}
#endif
static int
decrypt_se_ip_data(pgp_content_enum tag, pgp_region_t *region,
@ -2977,6 +3191,7 @@ decrypt_se_ip_data(pgp_content_enum tag, pgp_region_t *region,
return r;
}
#if 0
/**
\ingroup Core_ReadPackets
\brief Read a Symmetrically Encrypted packet
@ -2995,6 +3210,7 @@ parse_se_data(pgp_region_t *region, pgp_stream_t *stream)
*/
return decrypt_se_data(PGP_PTAG_CT_SE_DATA_BODY, region, stream);
}
#endif
/**
\ingroup Core_ReadPackets
@ -3021,7 +3237,7 @@ parse_se_ip_data(pgp_region_t *region, pgp_stream_t *stream)
if (pgp_get_debug_level(__FILE__)) {
(void) fprintf(stderr, "parse_se_ip_data: region %d,%d\n",
region->readc, region->length);
hexdump(stderr, "compressed region", stream->virtualpkt, stream->virtualc);
hexdump(stderr, "compressed region", stream->readinfo.virtualpkt, stream->readinfo.virtualc);
}
/*
* The content of an encrypted data packet is more OpenPGP packets
@ -3104,7 +3320,6 @@ parse_packet(pgp_stream_t *stream, uint32_t *pktlen)
} else {
unsigned rb;
rb = 0;
pkt.u.ptag.type = ((unsigned)ptag &
PGP_PTAG_OF_CONTENT_TAG_MASK)
>> PGP_PTAG_OF_CONTENT_TAG_SHIFT;
@ -3177,11 +3392,8 @@ parse_packet(pgp_stream_t *stream, uint32_t *pktlen)
break;
case PGP_PTAG_CT_SECRET_KEY:
ret = parse_seckey(&region, stream);
break;
case PGP_PTAG_CT_SECRET_SUBKEY:
ret = parse_seckey(&region, stream);
ret = parse_seckey((pgp_content_enum)pkt.u.ptag.type, &region, stream);
break;
case PGP_PTAG_CT_PK_SESSION_KEY:
@ -3189,7 +3401,9 @@ parse_packet(pgp_stream_t *stream, uint32_t *pktlen)
break;
case PGP_PTAG_CT_SE_DATA:
ret = parse_se_data(&region, stream);
// SE_DATA CURRENTLY BROKEN
ret = 0;
//ret = parse_se_data(&region, stream);
break;
case PGP_PTAG_CT_SE_IP_DATA:
@ -3347,11 +3561,15 @@ pgp_stream_delete(pgp_stream_t *stream)
{
pgp_cbdata_t *cbinfo;
pgp_cbdata_t *next;
pgp_cryptinfo_t *cryptinfo = &stream->cbinfo.cryptinfo;
for (cbinfo = stream->cbinfo.next; cbinfo; cbinfo = next) {
next = cbinfo->next;
free(cbinfo);
}
FREE_ARRAY(cryptinfo, recipients_key_ids);
if (stream->readinfo.destroyer) {
stream->readinfo.destroyer(&stream->readinfo);
}

View file

@ -52,7 +52,7 @@
* Creates printable text strings from packet contents
*
*/
#include "config-netpgp.h"
#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
@ -60,16 +60,16 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
__RCSID("$NetBSD: packet-show.c,v 1.21 2011/08/14 11:19:51 christos Exp $");
__RCSID("$NetBSD$");
#endif
#include <stdlib.h>
#include <string.h>
#include "packet-show.h"
#include "netpgp/packet-show.h"
#include "netpgpsdk.h"
#include "netpgpdefs.h"
#include "netpgp/netpgpsdk.h"
#include "netpgp/netpgpdefs.h"
/*
@ -271,45 +271,6 @@ static pgp_map_t compression_alg_map[] =
{0x00, NULL}, /* this is the end-of-array marker */
};
static pgp_bit_map_t ss_notation_map_byte0[] =
{
{0x80, "Human-readable"},
{0x00, NULL},
};
static pgp_bit_map_t *ss_notation_map[] =
{
ss_notation_map_byte0,
};
static pgp_bit_map_t ss_feature_map_byte0[] =
{
{0x01, "Modification Detection"},
{0x00, NULL},
};
static pgp_bit_map_t *ss_feature_map[] =
{
ss_feature_map_byte0,
};
static pgp_bit_map_t ss_key_flags_map[] =
{
{0x01, "May be used to certify other keys"},
{0x02, "May be used to sign data"},
{0x04, "May be used to encrypt communications"},
{0x08, "May be used to encrypt storage"},
{0x10, "Private component may have been split by a secret-sharing mechanism"},
{0x80, "Private component may be in possession of more than one person"},
{0x00, NULL},
};
static pgp_bit_map_t ss_key_server_prefs_map[] =
{
{0x80, "Key holder requests that this key only be modified or updated by the key holder or an administrator of the key server"},
{0x00, NULL},
};
/*
* Private functions
*/
@ -341,37 +302,6 @@ list_free(pgp_list_t *list)
list_init(list);
}
static unsigned
list_resize(pgp_list_t *list)
{
/*
* We only resize in one direction - upwards. Algorithm used : double
* the current size then add 1
*/
char **newstrings;
int newsize;
newsize = (list->size * 2) + 1;
newstrings = realloc(list->strings, newsize * sizeof(char *));
if (newstrings) {
list->strings = newstrings;
list->size = newsize;
return 1;
}
(void) fprintf(stderr, "list_resize - bad alloc\n");
return 0;
}
static unsigned
add_str(pgp_list_t *list, const char *str)
{
if (list->size == list->used && !list_resize(list)) {
return 0;
}
list->strings[list->used++] = __UNCONST(str);
return 1;
}
/* find a bitfield in a map - serial search */
static const char *
find_bitfield(pgp_bit_map_t *map, uint8_t octet)
@ -414,161 +344,6 @@ pgp_text_free(pgp_text_t *text)
free(text);
}
/* XXX: should this (and many others) be unsigned? */
/* ! generic function which adds text derived from single octet map to text */
static unsigned
add_str_from_octet_map(pgp_text_t *map, char *str, uint8_t octet)
{
if (str && !add_str(&map->known, str)) {
/*
* value recognised, but there was a problem adding it to the
* list
*/
/* XXX - should print out error msg here, Ben? - rachel */
return 0;
} else if (!str) {
/*
* value not recognised and there was a problem adding it to
* the unknown list
*/
unsigned len = 2 + 2 + 1; /* 2 for "0x", 2 for
* single octet in hex
* format, 1 for NUL */
if ((str = calloc(1, len)) == NULL) {
(void) fprintf(stderr, "add_str_from_octet_map: bad alloc\n");
return 0;
}
(void) snprintf(str, len, "0x%x", octet);
if (!add_str(&map->unknown, str)) {
return 0;
}
free(str);
}
return 1;
}
/* ! generic function which adds text derived from single bit map to text */
static unsigned
add_bitmap_entry(pgp_text_t *map, const char *str, uint8_t bit)
{
if (str && !add_str(&map->known, str)) {
/*
* value recognised, but there was a problem adding it to the
* list
*/
/* XXX - should print out error msg here, Ben? - rachel */
return 0;
} else if (!str) {
/*
* value not recognised and there was a problem adding it to
* the unknown list
* 2 chars of the string are the format definition, this will
* be replaced in the output by 2 chars of hex, so the length
* will be correct
*/
char *newstr;
if (pgp_asprintf(&newstr, "Unknown bit(0x%x)", bit) == -1) {
(void) fprintf(stderr, "add_bitmap_entry: bad alloc\n");
return 0;
}
if (!add_str(&map->unknown, newstr)) {
return 0;
}
free(newstr);
}
return 1;
}
/**
* Produce a structure containing human-readable textstrings
* representing the recognised and unrecognised contents
* of this byte array. text_fn() will be called on each octet in turn.
* Each octet will generate one string representing the whole byte.
*
*/
static pgp_text_t *
text_from_bytemapped_octets(const pgp_data_t *data,
const char *(*text_fn)(uint8_t octet))
{
pgp_text_t *text;
const char *str;
unsigned i;
/*
* ! allocate and initialise pgp_text_t structure to store derived
* strings
*/
if ((text = calloc(1, sizeof(*text))) == NULL) {
return NULL;
}
pgp_text_init(text);
/* ! for each octet in field ... */
for (i = 0; i < data->len; i++) {
/* ! derive string from octet */
str = (*text_fn) (data->contents[i]);
/* ! and add to text */
if (!add_str_from_octet_map(text, netpgp_strdup(str),
data->contents[i])) {
pgp_text_free(text);
return NULL;
}
}
/*
* ! All values have been added to either the known or the unknown
* list
*/
return text;
}
/**
* Produce a structure containing human-readable textstrings
* representing the recognised and unrecognised contents
* of this byte array, derived from each bit of each octet.
*
*/
static pgp_text_t *
showall_octets_bits(pgp_data_t *data, pgp_bit_map_t **map, size_t nmap)
{
pgp_text_t *text;
const char *str;
unsigned i;
uint8_t mask, bit;
int j = 0;
/*
* ! allocate and initialise pgp_text_t structure to store derived
* strings
*/
if ((text = calloc(1, sizeof(pgp_text_t))) == NULL) {
return NULL;
}
pgp_text_init(text);
/* ! for each octet in field ... */
for (i = 0; i < data->len; i++) {
/* ! for each bit in octet ... */
mask = 0x80;
for (j = 0; j < 8; j++, mask = (unsigned)mask >> 1) {
bit = data->contents[i] & mask;
if (bit) {
str = (i >= nmap) ? "Unknown" :
find_bitfield(map[i], bit);
if (!add_bitmap_entry(text, str, bit)) {
pgp_text_free(text);
return NULL;
}
}
}
}
return text;
}
/*
* Public Functions
*/
@ -655,22 +430,6 @@ pgp_show_ss_zpref(uint8_t octet)
return pgp_str_from_map(octet, compression_alg_map);
}
/**
* \ingroup Core_Print
*
* returns set of descriptions of the given Preferred Compression Algorithms
* \param ss_zpref Array of Preferred Compression Algorithms
* \return NULL if cannot allocate memory or other error
* \return pointer to structure, if no error
*/
pgp_text_t *
pgp_showall_ss_zpref(const pgp_data_t *ss_zpref)
{
return text_from_bytemapped_octets(ss_zpref,
&pgp_show_ss_zpref);
}
/**
* \ingroup Core_Print
*
@ -684,21 +443,6 @@ pgp_show_hash_alg(uint8_t hash)
return pgp_str_from_map(hash, hash_alg_map);
}
/**
* \ingroup Core_Print
*
* returns set of descriptions of the given Preferred Hash Algorithms
* \param ss_hashpref Array of Preferred Hash Algorithms
* \return NULL if cannot allocate memory or other error
* \return pointer to structure, if no error
*/
pgp_text_t *
pgp_showall_ss_hashpref(const pgp_data_t *ss_hashpref)
{
return text_from_bytemapped_octets(ss_hashpref,
&pgp_show_hash_alg);
}
const char *
pgp_show_symm_alg(uint8_t hash)
{
@ -717,76 +461,6 @@ pgp_show_ss_skapref(uint8_t octet)
return pgp_str_from_map(octet, symm_alg_map);
}
/**
* \ingroup Core_Print
*
* returns set of descriptions of the given Preferred Symmetric Key Algorithms
* \param ss_skapref Array of Preferred Symmetric Key Algorithms
* \return NULL if cannot allocate memory or other error
* \return pointer to structure, if no error
*/
pgp_text_t *
pgp_showall_ss_skapref(const pgp_data_t *ss_skapref)
{
return text_from_bytemapped_octets(ss_skapref,
&pgp_show_ss_skapref);
}
/**
* \ingroup Core_Print
* returns description of one SS Feature
* \param octet
* \return string or "Unknown"
*/
static const char *
show_ss_feature(uint8_t octet, unsigned offset)
{
if (offset >= PGP_ARRAY_SIZE(ss_feature_map)) {
return "Unknown";
}
return find_bitfield(ss_feature_map[offset], octet);
}
/**
* \ingroup Core_Print
*
* returns set of descriptions of the given SS Features
* \param ss_features Signature Sub-Packet Features
* \return NULL if cannot allocate memory or other error
* \return pointer to structure, if no error
*/
/* XXX: shouldn't this use show_all_octets_bits? */
pgp_text_t *
pgp_showall_ss_features(pgp_data_t ss_features)
{
pgp_text_t *text;
const char *str;
unsigned i;
uint8_t mask, bit;
int j;
if ((text = calloc(1, sizeof(*text))) == NULL) {
return NULL;
}
pgp_text_init(text);
for (i = 0; i < ss_features.len; i++) {
mask = 0x80;
for (j = 0; j < 8; j++, mask = (unsigned)mask >> 1) {
bit = ss_features.contents[i] & mask;
if (bit) {
str = show_ss_feature(bit, i);
if (!add_bitmap_entry(text, str, bit)) {
pgp_text_free(text);
return NULL;
}
}
}
}
return text;
}
/**
* \ingroup Core_Print
* returns description of SS Key Flag
@ -800,46 +474,6 @@ pgp_show_ss_key_flag(uint8_t octet, pgp_bit_map_t *map)
return find_bitfield(map, octet);
}
/**
* \ingroup Core_Print
*
* returns set of descriptions of the given Preferred Key Flags
* \param ss_key_flags Array of Key Flags
* \return NULL if cannot allocate memory or other error
* \return pointer to structure, if no error
*/
pgp_text_t *
pgp_showall_ss_key_flags(const pgp_data_t *ss_key_flags)
{
pgp_text_t *text;
const char *str;
uint8_t mask, bit;
int i;
if ((text = calloc(1, sizeof(*text))) == NULL) {
return NULL;
}
pgp_text_init(text);
/* xxx - TBD: extend to handle multiple octets of bits - rachel */
for (i = 0, mask = 0x80; i < 8; i++, mask = (unsigned)mask >> 1) {
bit = ss_key_flags->contents[0] & mask;
if (bit) {
str = pgp_show_ss_key_flag(bit, ss_key_flags_map);
if (!add_bitmap_entry(text, netpgp_strdup(str), bit)) {
pgp_text_free(text);
return NULL;
}
}
}
/*
* xxx - must add error text if more than one octet. Only one
* currently specified -- rachel
*/
return text;
}
/**
* \ingroup Core_Print
*
@ -855,60 +489,3 @@ pgp_show_keyserv_pref(uint8_t prefs, pgp_bit_map_t *map)
return find_bitfield(map, prefs);
}
/**
* \ingroup Core_Print
* returns set of descriptions of given Key Server Preferences
* \param ss_key_server_prefs
* \return NULL if cannot allocate memory or other error
* \return pointer to structure, if no error
*
*/
pgp_text_t *
pgp_show_keyserv_prefs(const pgp_data_t *prefs)
{
pgp_text_t *text;
const char *str;
uint8_t mask, bit;
int i = 0;
if ((text = calloc(1, sizeof(*text))) == NULL) {
return NULL;
}
pgp_text_init(text);
/* xxx - TBD: extend to handle multiple octets of bits - rachel */
for (i = 0, mask = 0x80; i < 8; i++, mask = (unsigned)mask >> 1) {
bit = prefs->contents[0] & mask;
if (bit) {
str = pgp_show_keyserv_pref(bit,
ss_key_server_prefs_map);
if (!add_bitmap_entry(text, netpgp_strdup(str), bit)) {
pgp_text_free(text);
return NULL;
}
}
}
/*
* xxx - must add error text if more than one octet. Only one
* currently specified -- rachel
*/
return text;
}
/**
* \ingroup Core_Print
*
* returns set of descriptions of the given SS Notation Data Flags
* \param ss_notation Signature Sub-Packet Notation Data
* \return NULL if cannot allocate memory or other error
* \return pointer to structure, if no error
*/
pgp_text_t *
pgp_showall_notation(pgp_ss_notation_t ss_notation)
{
return showall_octets_bits(&ss_notation.flags,
ss_notation_map,
PGP_ARRAY_SIZE(ss_notation_map));
}

View file

@ -46,7 +46,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "config-netpgp.h"
#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
@ -54,7 +54,7 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
__RCSID("$NetBSD: reader.c,v 1.49 2012/03/05 02:20:18 christos Exp $");
__RCSID("$NetBSD$");
#endif
#include <sys/types.h>
@ -120,39 +120,20 @@ __RCSID("$NetBSD: reader.c,v 1.49 2012/03/05 02:20:18 christos Exp $");
#include <limits.h>
#endif
#include "errors-netpgp.h"
#include "crypto-netpgp.h"
#include "create-netpgp.h"
#include "signature-netpgp.h"
#include "packet-netpgp.h"
#include "packet-parse.h"
#include "packet-show.h"
#include "keyring-netpgp.h"
#include "readerwriter-netpgp.h"
#include "netpgpsdk.h"
#include "netpgpdefs.h"
#include "netpgpdigest.h"
#include "netpgp/errors.h"
#include "netpgp/crypto.h"
#include "netpgp/create.h"
#include "netpgp/signature.h"
#include "netpgp/packet.h"
#include "netpgp/packet-parse.h"
#include "netpgp/packet-show.h"
#include "netpgp/packet.h"
#include "netpgp/keyring.h"
#include "netpgp/readerwriter.h"
#include "netpgp/netpgpsdk.h"
#include "netpgp/netpgpdefs.h"
#include "netpgp/netpgpdigest.h"
/* data from partial blocks is queued up in virtual block in stream */
static int
read_partial_data(pgp_stream_t *stream, void *dest, size_t length)
{
unsigned n;
if (pgp_get_debug_level(__FILE__)) {
(void) fprintf(stderr, "fd_reader: coalesced data, off %d\n",
stream->virtualoff);
}
n = MIN(stream->virtualc - stream->virtualoff, (unsigned)length);
(void) memcpy(dest, &stream->virtualpkt[stream->virtualoff], n);
stream->virtualoff += n;
if (stream->virtualoff == stream->virtualc) {
free(stream->virtualpkt);
stream->virtualpkt = NULL;
stream->virtualc = stream->virtualoff = 0;
}
return (int)n;
}
/* get a pass phrase from the user */
int
@ -233,6 +214,10 @@ pgp_reader_pop(pgp_stream_t *stream)
{
pgp_reader_t *next = stream->readinfo.next;
if (stream->readinfo.accumulate && stream->readinfo.asize > 0) {
free(stream->readinfo.accumulated);
}
stream->readinfo = *next;
free(next);
}
@ -448,6 +433,9 @@ read_char(pgp_stream_t *stream, dearmour_t *dearmour,
do {
if (dearmour->pushbackc) {
if (!dearmour->pushback) {
return -1;
}
c = dearmour->pushback[--dearmour->pushbackc];
if (dearmour->pushbackc == 0) {
free(dearmour->pushback);
@ -844,7 +832,7 @@ read4(pgp_stream_t *stream, dearmour_t *dearmour, pgp_error_t **errors,
pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo,
int *pc, unsigned *pn, uint32_t *pl)
{
int n, c;
int n = 0, c = 0;
uint32_t l = 0;
for (n = 0; n < 4; ++n) {
@ -1398,7 +1386,7 @@ typedef struct {
size_t off;
pgp_crypt_t *decrypt;
pgp_region_t *region;
unsigned prevplain:1;
// unsigned prevplain:1;
} encrypted_t;
static int
@ -1414,6 +1402,8 @@ encrypted_data_reader(pgp_stream_t *stream, void *dest,
encrypted = pgp_reader_get_arg(readinfo);
saved = (int)length;
#if 0
/*
* V3 MPIs have the count plain and the cipher is reset after each
* count
@ -1430,13 +1420,15 @@ encrypted_data_reader(pgp_stream_t *stream, void *dest,
readinfo->parent->reading_mpi_len) {
encrypted->prevplain = 1;
}
#endif
while (length > 0) {
if (encrypted->c) {
unsigned n;
/*
* if we are reading v3 we should never read
* more than we're asked for */
* more than we're asked for
if (length < encrypted->c &&
(readinfo->parent->reading_v3_secret ||
readinfo->parent->exact_read)) {
@ -1444,6 +1436,7 @@ encrypted_data_reader(pgp_stream_t *stream, void *dest,
"encrypted_data_reader: bad v3 read\n");
return 0;
}
*/
n = (int)MIN(length, encrypted->c);
(void) memcpy(dest,
encrypted->decrypted + encrypted->off, n);
@ -1475,18 +1468,19 @@ encrypted_data_reader(pgp_stream_t *stream, void *dest,
/*
* we can only read as much as we're asked for
* in v3 keys because they're partially
* unencrypted! */
* unencrypted!
if ((readinfo->parent->reading_v3_secret ||
readinfo->parent->exact_read) && n > length) {
n = (unsigned)length;
}
*/
if (!pgp_stacked_limited_read(stream, buffer, n,
encrypted->region, errors, readinfo, cbinfo)) {
return -1;
}
if (!readinfo->parent->reading_v3_secret ||
!readinfo->parent->reading_mpi_len) {
//if (!readinfo->parent->reading_v3_secret ||
// !readinfo->parent->reading_mpi_len) {
encrypted->c =
pgp_decrypt_se_ip(encrypted->decrypt,
encrypted->decrypted, buffer, n);
@ -1495,11 +1489,11 @@ encrypted_data_reader(pgp_stream_t *stream, void *dest,
hexdump(stderr, "encrypted", buffer, 16);
hexdump(stderr, "decrypted", encrypted->decrypted, 16);
}
} else {
(void) memcpy(
&encrypted->decrypted[encrypted->off], buffer, n);
encrypted->c = n;
}
//} else {
// (void) memcpy(
//&encrypted->decrypted[encrypted->off], buffer, n);
//encrypted->c = n;
//}
if (encrypted->c == 0) {
(void) fprintf(stderr,
@ -1780,11 +1774,9 @@ fd_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
__PGP_USED(cbinfo);
reader = pgp_reader_get_arg(readinfo);
if (!stream->coalescing && stream->virtualc && stream->virtualoff < stream->virtualc) {
n = read_partial_data(stream, dest, length);
} else {
n = (int)read(reader->fd, dest, length);
}
if (n == 0) {
return 0;
}
@ -1837,9 +1829,7 @@ mem_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors
__PGP_USED(cbinfo);
__PGP_USED(errors);
if (!stream->coalescing && stream->virtualc && stream->virtualoff < stream->virtualc) {
n = read_partial_data(stream, dest, length);
} else {
if (reader->offset + length > reader->length) {
n = (unsigned)(reader->length - reader->offset);
} else {
@ -1850,7 +1840,7 @@ mem_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors
}
memcpy(dest, reader->buffer + reader->offset, n);
reader->offset += n;
}
return n;
}
@ -2124,7 +2114,7 @@ pgp_litdata_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
if (pgp_get_debug_level(__FILE__)) {
printf("pgp_litdata_cb: ");
pgp_print_packet(&cbinfo->printstate, pkt);
//pgp_print_packet(&cbinfo->printstate, pkt);
}
/* Read data from packet into static buffer */
switch (pkt->tag) {
@ -2161,7 +2151,7 @@ pgp_pk_sesskey_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
io = cbinfo->io;
if (pgp_get_debug_level(__FILE__)) {
pgp_print_packet(&cbinfo->printstate, pkt);
//pgp_print_packet(&cbinfo->printstate, pkt);
}
/* Read data from packet into static buffer */
switch (pkt->tag) {
@ -2177,7 +2167,8 @@ pgp_pk_sesskey_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
from = 0;
cbinfo->cryptinfo.keydata =
pgp_getkeybyid(io, cbinfo->cryptinfo.secring,
content->pk_sesskey.key_id, &from, NULL);
content->pk_sesskey.key_id, &from, NULL, NULL,
0, 0); /* accepts revoked and expired */
if (!cbinfo->cryptinfo.keydata) {
break;
}
@ -2208,55 +2199,67 @@ pgp_cb_ret_t
pgp_get_seckey_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
{
const pgp_contents_t *content = &pkt->u;
const pgp_seckey_t *secret;
const pgp_key_t *pubkey;
const pgp_key_t *keypair;
pgp_seckey_t *secret;
// const pgp_key_t *pubkey;
//const pgp_key_t *keypair;
unsigned from;
pgp_io_t *io;
int i;
//int i;
pgp_cryptinfo_t *cryptinfo = &cbinfo->cryptinfo;
key_id_t *key_id;
io = cbinfo->io;
if (pgp_get_debug_level(__FILE__)) {
pgp_print_packet(&cbinfo->printstate, pkt);
//pgp_print_packet(&cbinfo->printstate, pkt);
}
switch (pkt->tag) {
case PGP_GET_SECKEY:
/* print key from pubring */
from = 0;
pubkey = pgp_getkeybyid(io, cbinfo->cryptinfo.pubring,
content->get_seckey.pk_sesskey->key_id,
&from, NULL);
/* validate key from secring */
// from = 0;
// pubkey = pgp_getkeybyid(io, cbinfo->cryptinfo.pubring,
// content->get_seckey.pk_sesskey->key_id,
// &from, NULL);
// /* validate key from secring */
EXPAND_ARRAY(cryptinfo, recipients_key_ids);
key_id = &cryptinfo->recipients_key_idss[cryptinfo->recipients_key_idsc++];
memcpy(key_id, content->get_seckey.pk_sesskey->key_id, sizeof(key_id_t));
from = 0;
cbinfo->cryptinfo.keydata =
pgp_getkeybyid(io, cbinfo->cryptinfo.secring,
content->get_seckey.pk_sesskey->key_id,
&from, NULL);
&from, NULL, &secret, 0, 0);
if (!cbinfo->cryptinfo.keydata ||
!secret ||
!pgp_is_key_secret(cbinfo->cryptinfo.keydata)) {
return (pgp_cb_ret_t)0;
}
keypair = cbinfo->cryptinfo.keydata;
if (pubkey == NULL) {
pubkey = keypair;
}
secret = NULL;
cbinfo->gotpass = 0;
for (i = 0 ; cbinfo->numtries == -1 || i < cbinfo->numtries ; i++) {
/* print out the user id */
pgp_print_keydata(io, cbinfo->cryptinfo.pubring, pubkey,
"signature ", &pubkey->key.pubkey, 0);
/* now decrypt key */
secret = pgp_decrypt_seckey(keypair, cbinfo->passfp);
if (secret != NULL) {
break;
}
(void) fprintf(io->errs, "Bad passphrase\n");
}
if (secret == NULL) {
(void) fprintf(io->errs, "Exhausted passphrase attempts\n");
return (pgp_cb_ret_t)PGP_RELEASE_MEMORY;
}
// FIXME : support encrypted seckeys again
// keypair = cbinfo->cryptinfo.keydata;
// if (pubkey == NULL) {
// pubkey = keypair;
// }
// secret = NULL;
// cbinfo->gotpass = 0;
// for (i = 0 ; cbinfo->numtries == -1 || i < cbinfo->numtries ; i++) {
// /* print out the user id */
// pgp_print_keydata(io, cbinfo->cryptinfo.pubring, pubkey,
// "signature ", &pubkey->key.pubkey, 0);
// /* now decrypt key */
// pgp_decrypt_seckey(keypair, cbinfo->passfp);
// if (secret != NULL) {
// break;
// }
// (void) fprintf(io->errs, "Bad passphrase\n");
// }
// if (secret == NULL) {
// (void) fprintf(io->errs, "Exhausted passphrase attempts\n");
// return (pgp_cb_ret_t)PGP_RELEASE_MEMORY;
// }
cbinfo->gotpass = 1;
*content->get_seckey.seckey = secret;
break;
@ -2268,39 +2271,6 @@ pgp_get_seckey_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
return PGP_RELEASE_MEMORY;
}
/**
\ingroup HighLevel_Callbacks
\brief Callback to use when you need to prompt user for passphrase
\param contents
\param cbinfo
*/
pgp_cb_ret_t
get_passphrase_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
{
const pgp_contents_t *content = &pkt->u;
pgp_io_t *io;
io = cbinfo->io;
if (pgp_get_debug_level(__FILE__)) {
pgp_print_packet(&cbinfo->printstate, pkt);
}
if (cbinfo->cryptinfo.keydata == NULL) {
(void) fprintf(io->errs, "get_passphrase_cb: NULL keydata\n");
} else {
pgp_print_keydata(io, cbinfo->cryptinfo.pubring, cbinfo->cryptinfo.keydata, "signature ",
&cbinfo->cryptinfo.keydata->key.pubkey, 0);
}
switch (pkt->tag) {
case PGP_GET_PASSPHRASE:
*(content->skey_passphrase.passphrase) =
netpgp_strdup(getpass("netpgp passphrase: "));
return PGP_KEEP_MEMORY;
default:
break;
}
return PGP_RELEASE_MEMORY;
}
unsigned
pgp_reader_set_accumulate(pgp_stream_t *stream, unsigned state)
{
@ -2363,15 +2333,12 @@ mmap_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **error
__PGP_USED(errors);
__PGP_USED(cbinfo);
if (!stream->coalescing && stream->virtualc && stream->virtualoff < stream->virtualc) {
n = read_partial_data(stream, dest, length);
} else {
n = (unsigned)MIN(length, (unsigned)(mem->size - mem->offset));
if (n > 0) {
(void) memcpy(dest, &cmem[(int)mem->offset], (unsigned)n);
mem->offset += n;
}
}
return (int)n;
}

View file

@ -49,7 +49,7 @@
/** \file
*/
#include "config-netpgp.h"
#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
@ -57,7 +57,7 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
__RCSID("$NetBSD: signature.c,v 1.34 2012/03/05 02:20:18 christos Exp $");
__RCSID("$NetBSD$");
#endif
#include <sys/types.h>
@ -77,29 +77,16 @@ __RCSID("$NetBSD: signature.c,v 1.34 2012/03/05 02:20:18 christos Exp $");
#include <openssl/dsa.h>
#endif
#include "signature-netpgp.h"
#include "crypto-netpgp.h"
#include "create-netpgp.h"
#include "netpgpsdk.h"
#include "readerwriter-netpgp.h"
#include "validate-netpgp.h"
#include "netpgpdefs.h"
#include "netpgpdigest.h"
#include "netpgp/signature.h"
#include "netpgp/crypto.h"
#include "netpgp/create.h"
#include "netpgp/netpgpsdk.h"
#include "netpgp/readerwriter.h"
#include "netpgp/validate.h"
#include "netpgp/netpgpdefs.h"
#include "netpgp/netpgpdigest.h"
/** \ingroup Core_Create
* needed for signature creation
*/
struct pgp_create_sig_t {
pgp_hash_t hash;
pgp_sig_t sig;
pgp_memory_t *mem;
pgp_output_t *output; /* how to do the writing */
unsigned hashoff; /* hashed count offset */
unsigned hashlen;
unsigned unhashoff;
};
/**
\ingroup Core_Signature
Creates new pgp_create_sig_t
@ -149,6 +136,11 @@ static uint8_t prefix_sha256[] = {
0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
};
static uint8_t prefix_sha512[] = {
0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
0x00, 0x04, 0x40
};
/* XXX: both this and verify would be clearer if the signature were */
/* treated as an MPI. */
@ -174,11 +166,16 @@ rsa_sign(pgp_hash_t *hash,
prefix = prefix_sha1;
prefixsize = sizeof(prefix_sha1);
expected = PGP_SHA1_HASH_SIZE;
} else {
} else if (strcmp(hash->name, "SHA256") == 0) {
hashsize = PGP_SHA256_HASH_SIZE + sizeof(prefix_sha256);
prefix = prefix_sha256;
prefixsize = sizeof(prefix_sha256);
expected = PGP_SHA256_HASH_SIZE;
} else {
hashsize = PGP_SHA512_HASH_SIZE + sizeof(prefix_sha512);
prefix = prefix_sha512;
prefixsize = sizeof(prefix_sha512);
expected = PGP_SHA512_HASH_SIZE;
}
keysize = (BN_num_bits(pubrsa->n) + 7) / 8;
if (keysize > sizeof(hashbuf)) {
@ -231,7 +228,7 @@ dsa_sign(pgp_hash_t *hash,
unsigned hashsize;
unsigned t;
uint8_t hashbuf[NETPGP_BUFSIZ];
DSA_SIG *dsasig;
pgp_dsa_sig_t *pgpdsasig;
/* hashsize must be "equal in size to the number of bits of q, */
/* the group generated by the DSA key's generator value */
@ -249,12 +246,18 @@ dsa_sign(pgp_hash_t *hash,
pgp_write(output, &hashbuf[0], 2);
/* write signature to buf */
dsasig = pgp_dsa_sign(hashbuf, hashsize, sdsa, dsa);
pgpdsasig = pgp_dsa_sign(hashbuf, hashsize, sdsa, dsa);
if(pgpdsasig == NULL)
return 0;
/* convert and write the sig out to memory */
pgp_write_mpi(output, dsasig->r);
pgp_write_mpi(output, dsasig->s);
DSA_SIG_free(dsasig);
pgp_write_mpi(output, pgpdsasig->r);
pgp_write_mpi(output, pgpdsasig->s);
BN_free(pgpdsasig->r);
BN_free(pgpdsasig->s);
free(pgpdsasig);
return 1;
}
@ -273,8 +276,6 @@ rsa_verify(pgp_hash_alg_t type,
uint8_t sigbuf[NETPGP_BUFSIZ];
uint8_t hashbuf_from_sig[NETPGP_BUFSIZ];
plen = 0;
prefix = (const uint8_t *) "";
keysize = BN_num_bytes(pubrsa->n);
/* RSA key can't be bigger than 65535 bits, so... */
if (keysize > sizeof(hashbuf_from_sig)) {
@ -315,6 +316,10 @@ rsa_verify(pgp_hash_alg_t type,
prefix = prefix_sha256;
plen = sizeof(prefix_sha256);
break;
case PGP_HASH_SHA512:
prefix = prefix_sha512;
plen = sizeof(prefix_sha512);
break;
default:
(void) fprintf(stderr, "Unknown hash algorithm: %d\n", type);
return 0;
@ -356,6 +361,7 @@ hash_add_key(pgp_hash_t *hash, const pgp_pubkey_t *key)
pgp_hash_add_int(hash, 0x99, 1);
pgp_hash_add_int(hash, (unsigned)len, 2);
hash->add(hash, pgp_mem_data(mem), (unsigned)len);
pgp_memory_free(mem);
}
@ -380,12 +386,11 @@ init_key_sig(pgp_hash_t *hash, const pgp_sig_t *sig,
}
static void
hash_add_trailer(pgp_hash_t *hash, const pgp_sig_t *sig,
const uint8_t *raw_packet)
hash_add_trailer(pgp_hash_t *hash, const pgp_sig_t *sig)
{
if (sig->info.version == PGP_V4) {
if (raw_packet) {
hash->add(hash, raw_packet + sig->v4_hashstart,
if (sig->info.v4_hashlen) {
hash->add(hash, sig->info.v4_hashed,
(unsigned)sig->info.v4_hashlen);
}
pgp_hash_add_int(hash, (unsigned)sig->info.version, 1);
@ -416,7 +421,7 @@ pgp_check_sig(const uint8_t *hash, unsigned length,
if (pgp_get_debug_level(__FILE__)) {
hexdump(stdout, "hash", hash, length);
}
ret = 0;
switch (sig->info.key_alg) {
case PGP_PKA_DSA:
ret = pgp_dsa_verify(hash, length, &sig->info.sig.dsa,
@ -452,10 +457,9 @@ hash_and_check_sig(pgp_hash_t *hash,
static unsigned
finalise_sig(pgp_hash_t *hash,
const pgp_sig_t *sig,
const pgp_pubkey_t *signer,
const uint8_t *raw_packet)
const pgp_pubkey_t *signer)
{
hash_add_trailer(hash, sig, raw_packet);
hash_add_trailer(hash, sig);
return hash_and_check_sig(hash, sig, signer);
}
@ -475,8 +479,7 @@ unsigned
pgp_check_useridcert_sig(const pgp_pubkey_t *key,
const uint8_t *id,
const pgp_sig_t *sig,
const pgp_pubkey_t *signer,
const uint8_t *raw_packet)
const pgp_pubkey_t *signer)
{
pgp_hash_t hash;
size_t userid_len;
@ -488,7 +491,7 @@ pgp_check_useridcert_sig(const pgp_pubkey_t *key,
pgp_hash_add_int(&hash, (unsigned)userid_len, 4);
}
hash.add(&hash, id, (unsigned)userid_len);
return finalise_sig(&hash, sig, signer, raw_packet);
return finalise_sig(&hash, sig, signer);
}
/**
@ -507,8 +510,7 @@ unsigned
pgp_check_userattrcert_sig(const pgp_pubkey_t *key,
const pgp_data_t *attribute,
const pgp_sig_t *sig,
const pgp_pubkey_t *signer,
const uint8_t *raw_packet)
const pgp_pubkey_t *signer)
{
pgp_hash_t hash;
@ -518,7 +520,7 @@ pgp_check_userattrcert_sig(const pgp_pubkey_t *key,
pgp_hash_add_int(&hash, (unsigned)attribute->len, 4);
}
hash.add(&hash, attribute->contents, (unsigned)attribute->len);
return finalise_sig(&hash, sig, signer, raw_packet);
return finalise_sig(&hash, sig, signer);
}
/**
@ -537,15 +539,14 @@ unsigned
pgp_check_subkey_sig(const pgp_pubkey_t *key,
const pgp_pubkey_t *subkey,
const pgp_sig_t *sig,
const pgp_pubkey_t *signer,
const uint8_t *raw_packet)
const pgp_pubkey_t *signer)
{
pgp_hash_t hash;
unsigned ret;
init_key_sig(&hash, sig, key);
hash_add_key(&hash, subkey);
ret = finalise_sig(&hash, sig, signer, raw_packet);
ret = finalise_sig(&hash, sig, signer);
return ret;
}
@ -563,14 +564,13 @@ pgp_check_subkey_sig(const pgp_pubkey_t *key,
unsigned
pgp_check_direct_sig(const pgp_pubkey_t *key,
const pgp_sig_t *sig,
const pgp_pubkey_t *signer,
const uint8_t *raw_packet)
const pgp_pubkey_t *signer)
{
pgp_hash_t hash;
unsigned ret;
init_key_sig(&hash, sig, key);
ret = finalise_sig(&hash, sig, signer, raw_packet);
ret = finalise_sig(&hash, sig, signer);
return ret;
}
@ -592,7 +592,7 @@ pgp_check_hash_sig(pgp_hash_t *hash,
const pgp_pubkey_t *signer)
{
return (sig->info.hash_alg == hash->alg) ?
finalise_sig(hash, sig, signer, NULL) :
finalise_sig(hash, sig, signer) :
0;
}
@ -649,6 +649,22 @@ pgp_sig_start_key_sig(pgp_create_sig_t *sig,
start_sig_in_mem(sig);
}
void
pgp_sig_start_key_rev(pgp_create_sig_t *sig,
const pgp_pubkey_t *key,
pgp_sig_type_t type)
{
sig->output = pgp_output_new();
sig->sig.info.version = PGP_V4;
sig->sig.info.hash_alg = PGP_HASH_SHA1;
sig->sig.info.key_alg = key->alg;
sig->sig.info.type = type;
sig->hashlen = (unsigned)-1;
init_key_sig(&sig->hash, &sig->sig, key);
start_sig_in_mem(sig);
}
/**
* \ingroup Core_Signature
*
@ -831,17 +847,100 @@ pgp_write_sig(pgp_output_t *output,
return ret;
}
/* add a time stamp to the output */
unsigned
pgp_add_time(pgp_create_sig_t *sig, int64_t when, const char *type)
pgp_add_creation_time(pgp_create_sig_t *sig, time_t when)
{
pgp_content_enum tag;
tag = (strcmp(type, "birth") == 0) ?
PGP_PTAG_SS_CREATION_TIME : PGP_PTAG_SS_EXPIRATION_TIME;
/* just do 32-bit timestamps for just now - it's in the protocol */
tag = PGP_PTAG_SS_CREATION_TIME;
sig->sig.info.birthtime = when;
sig->sig.info.birthtime_set = 1;
return pgp_write_ss_header(sig->output, 5, tag) &&
pgp_write_scalar(sig->output, (uint32_t)when, (unsigned)sizeof(uint32_t));
pgp_write_scalar(sig->output, (unsigned int)when, 4);
}
unsigned
pgp_add_sig_expiration_time(pgp_create_sig_t *sig, time_t duration)
{
pgp_content_enum tag;
tag = PGP_PTAG_SS_EXPIRATION_TIME;
sig->sig.info.duration = duration;
sig->sig.info.duration_set = 1;
return pgp_write_ss_header(sig->output, 5, tag) &&
pgp_write_scalar(sig->output, (unsigned int)duration, 4);
}
unsigned
pgp_add_key_expiration_time(pgp_create_sig_t *sig, time_t duration)
{
pgp_content_enum tag;
tag = PGP_PTAG_SS_KEY_EXPIRY;
sig->sig.info.key_expiry = duration;
sig->sig.info.key_expiry_set = 1;
return pgp_write_ss_header(sig->output, 5, tag) &&
pgp_write_scalar(sig->output, (unsigned int)duration, 4);
}
unsigned
pgp_add_key_flags(pgp_create_sig_t *sig, uint8_t flags)
{
pgp_content_enum tag;
tag = PGP_PTAG_SS_KEY_FLAGS;
sig->sig.info.key_flags = flags;
sig->sig.info.key_flags_set = 1;
return pgp_write_ss_header(sig->output, 2, tag) &&
pgp_write_scalar(sig->output, (unsigned int)flags, 1);
}
unsigned
pgp_add_key_prefs(pgp_create_sig_t *sig)
{
/* Mimic of GPG default settings, limited to supported algos */
return
/* Symmetric algo prefs */
pgp_write_ss_header(sig->output, 6, PGP_PTAG_SS_PREFERRED_SKA) &&
pgp_write_scalar(sig->output, PGP_SA_AES_256, 1) &&
pgp_write_scalar(sig->output, PGP_SA_AES_128, 1) &&
pgp_write_scalar(sig->output, PGP_SA_CAST5, 1) &&
pgp_write_scalar(sig->output, PGP_SA_TRIPLEDES, 1) &&
pgp_write_scalar(sig->output, PGP_SA_IDEA, 1) &&
/* Hash algo prefs */
pgp_write_ss_header(sig->output, 6, PGP_PTAG_SS_PREFERRED_HASH) &&
pgp_write_scalar(sig->output, PGP_HASH_SHA256, 1) &&
pgp_write_scalar(sig->output, PGP_HASH_SHA1, 1) &&
pgp_write_scalar(sig->output, PGP_HASH_SHA384, 1) &&
pgp_write_scalar(sig->output, PGP_HASH_SHA512, 1) &&
pgp_write_scalar(sig->output, PGP_HASH_SHA224, 1) &&
/* Compression algo prefs */
pgp_write_ss_header(sig->output, 3, PGP_PTAG_SS_PREF_COMPRESS) &&
pgp_write_scalar(sig->output, PGP_C_ZLIB, 1) &&
pgp_write_scalar(sig->output, PGP_C_BZIP2, 1);
}
unsigned
pgp_add_key_features(pgp_create_sig_t *sig)
{
pgp_content_enum tag;
tag = PGP_PTAG_SS_FEATURES;
return pgp_write_ss_header(sig->output, 2, tag) &&
pgp_write_scalar(sig->output, 0x01, 1);
}
/**
@ -877,6 +976,19 @@ pgp_add_primary_userid(pgp_create_sig_t *sig, unsigned primary)
pgp_write_scalar(sig->output, primary, 1);
}
unsigned
pgp_add_revocation_reason(
pgp_create_sig_t *sig,
uint8_t code, const char *reason)
{
size_t rlen = reason ? strlen(reason) : 0;
return pgp_write_ss_header(
sig->output, rlen + 1,
PGP_PTAG_SS_REVOCATION_REASON) &&
pgp_write_scalar(sig->output, code, 1) &&
pgp_write(sig->output, reason, (unsigned int)rlen);
}
/**
* \ingroup Core_Signature
*
@ -937,8 +1049,8 @@ pgp_sign_file(pgp_io_t *io,
const char *outname,
const pgp_seckey_t *seckey,
const char *hashname,
const int64_t from,
const uint64_t duration,
const time_t from,
const time_t duration,
const unsigned armored,
const unsigned cleartext,
const unsigned overwrite)
@ -958,7 +1070,6 @@ pgp_sign_file(pgp_io_t *io,
infile = NULL;
output = NULL;
hash = NULL;
fd_out = 0;
/* find the hash algorithm */
hash_alg = pgp_str_to_hash_alg(hashname);
@ -1006,8 +1117,8 @@ pgp_sign_file(pgp_io_t *io,
/* - creation time */
/* - key id */
ret = pgp_writer_use_armored_sig(output) &&
pgp_add_time(sig, (int64_t)from, "birth") &&
pgp_add_time(sig, (int64_t)duration, "expiration");
pgp_add_creation_time(sig, from) &&
pgp_add_sig_expiration_time(sig, duration);
if (ret == 0) {
pgp_teardown_file_write(output, fd_out);
return 0;
@ -1053,8 +1164,8 @@ pgp_sign_file(pgp_io_t *io,
#endif
/* add creation time to signature */
pgp_add_time(sig, (int64_t)from, "birth");
pgp_add_time(sig, (int64_t)duration, "expiration");
pgp_add_creation_time(sig, from);
pgp_add_sig_expiration_time(sig, duration);
/* add key id to signature */
pgp_keyid(keyid, PGP_KEY_ID_SIZE, &seckey->pubkey, hash_alg);
pgp_add_issuer_keyid(sig, keyid);
@ -1090,8 +1201,8 @@ pgp_sign_buf(pgp_io_t *io,
const void *input,
const size_t insize,
const pgp_seckey_t *seckey,
const int64_t from,
const uint64_t duration,
const time_t from,
const time_t duration,
const char *hashname,
const unsigned armored,
const unsigned cleartext)
@ -1111,7 +1222,6 @@ pgp_sign_buf(pgp_io_t *io,
output = NULL;
mem = pgp_memory_new();
hash = NULL;
ret = 0;
hash_alg = pgp_str_to_hash_alg(hashname);
if (hash_alg == PGP_HASH_UNKNOWN) {
@ -1147,8 +1257,8 @@ pgp_sign_buf(pgp_io_t *io,
ret = pgp_writer_push_clearsigned(output, sig) &&
pgp_write(output, input, (unsigned)insize) &&
pgp_writer_use_armored_sig(output) &&
pgp_add_time(sig, from, "birth") &&
pgp_add_time(sig, (int64_t)duration, "expiration");
pgp_add_creation_time(sig, from) &&
pgp_add_sig_expiration_time(sig, duration);
if (ret == 0) {
return NULL;
}
@ -1178,8 +1288,8 @@ pgp_sign_buf(pgp_io_t *io,
}
/* add creation time to signature */
pgp_add_time(sig, from, "birth");
pgp_add_time(sig, (int64_t)duration, "expiration");
pgp_add_creation_time(sig, from);
pgp_add_sig_expiration_time(sig, duration);
/* add key id to signature */
pgp_keyid(keyid, PGP_KEY_ID_SIZE, &seckey->pubkey, hash_alg);
pgp_add_issuer_keyid(sig, keyid);
@ -1200,10 +1310,10 @@ int
pgp_sign_detached(pgp_io_t *io,
const char *f,
char *sigfile,
pgp_seckey_t *seckey,
const pgp_seckey_t *seckey,
const char *hash,
const int64_t from,
const uint64_t duration,
const time_t from,
const time_t duration,
const unsigned armored, const unsigned overwrite)
{
pgp_create_sig_t *sig;
@ -1246,14 +1356,13 @@ pgp_sign_detached(pgp_io_t *io,
pgp_memory_free(mem);
/* calculate the signature */
pgp_add_time(sig, from, "birth");
pgp_add_time(sig, (int64_t)duration, "expiration");
pgp_add_creation_time(sig, from);
pgp_add_sig_expiration_time(sig, duration);
pgp_keyid(keyid, sizeof(keyid), &seckey->pubkey, hash_alg);
pgp_add_issuer_keyid(sig, keyid);
pgp_end_hashed_subpkts(sig);
pgp_write_sig(output, sig, &seckey->pubkey, seckey);
pgp_teardown_file_write(output, fd);
pgp_seckey_free(seckey);
return 1;
}

View file

@ -46,7 +46,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "config-netpgp.h"
#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
@ -54,11 +54,11 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
__RCSID("$NetBSD: symmetric.c,v 1.18 2010/11/07 08:39:59 agc Exp $");
__RCSID("$NetBSD$");
#endif
#include "crypto-netpgp.h"
#include "packet-show.h"
#include "netpgp/crypto.h"
#include "netpgp/packet-show.h"
#include <string.h>
@ -82,8 +82,8 @@ __RCSID("$NetBSD: symmetric.c,v 1.18 2010/11/07 08:39:59 agc Exp $");
#include <openssl/camellia.h>
#endif
#include "crypto-netpgp.h"
#include "netpgpdefs.h"
#include "netpgp/crypto.h"
#include "netpgp/netpgpdefs.h"
static void

View file

@ -46,7 +46,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "config-netpgp.h"
#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
@ -54,7 +54,7 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
__RCSID("$NetBSD: validate.c,v 1.44 2012/03/05 02:20:18 christos Exp $");
__RCSID("$NetBSD$");
#endif
#include <sys/types.h>
@ -72,76 +72,67 @@ __RCSID("$NetBSD: validate.c,v 1.44 2012/03/05 02:20:18 christos Exp $");
#include <fcntl.h>
#endif
#include "packet-parse.h"
#include "packet-show.h"
#include "keyring-netpgp.h"
#include "signature-netpgp.h"
#include "netpgpsdk.h"
#include "readerwriter-netpgp.h"
#include "netpgpdefs.h"
#include "memory-netpgp.h"
#include "packet-netpgp.h"
#include "crypto-netpgp.h"
#include "validate-netpgp.h"
#include "netpgp/packet-parse.h"
#include "netpgp/packet-show.h"
#include "netpgp/keyring.h"
#include "netpgp/signature.h"
#include "netpgp/netpgpsdk.h"
#include "netpgp/readerwriter.h"
#include "netpgp/netpgpdefs.h"
#include "netpgp/memory.h"
#include "netpgp/packet.h"
#include "netpgp/crypto.h"
#include "netpgp/validate.h"
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
static int
keydata_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
pgp_reader_t *readinfo,
pgp_cbdata_t *cbinfo)
{
validate_reader_t *reader = pgp_reader_get_arg(readinfo);
__PGP_USED(stream);
__PGP_USED(errors);
__PGP_USED(cbinfo);
if (reader->offset == reader->key->packets[reader->packet].length) {
reader->packet += 1;
reader->offset = 0;
}
if (reader->packet == reader->key->packetc) {
return 0;
}
/*
* we should never be asked to cross a packet boundary in a single
* read
*/
if (reader->key->packets[reader->packet].length <
reader->offset + length) {
(void) fprintf(stderr, "keydata_reader: weird length\n");
return 0;
}
(void) memcpy(dest,
&reader->key->packets[reader->packet].raw[reader->offset],
length);
reader->offset += (unsigned)length;
return (int)length;
}
// FIXME to support seckey decryption again.
//
// static int
// keydata_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
// pgp_reader_t *readinfo,
// pgp_cbdata_t *cbinfo)
// {
// validate_reader_t *reader = pgp_reader_get_arg(readinfo);
//
// __PGP_USED(stream);
// __PGP_USED(errors);
// __PGP_USED(cbinfo);
// if (reader->offset == reader->key->packets[reader->packet].length) {
// reader->packet += 1;
// reader->offset = 0;
// }
// if (reader->packet == reader->key->packetc) {
// return 0;
// }
//
// /*
// * we should never be asked to cross a packet boundary in a single
// * read
// */
// if (reader->key->packets[reader->packet].length <
// reader->offset + length) {
// (void) fprintf(stderr, "keydata_reader: weird length\n");
// return 0;
// }
//
// (void) memcpy(dest,
// &reader->key->packets[reader->packet].raw[reader->offset],
// length);
// reader->offset += (unsigned)length;
//
// return (int)length;
// }
static void
free_sig_info(pgp_sig_info_t *sig)
{
free(sig->v4_hashed);
pgp_free_sig_info(sig);
free(sig);
}
static void
copy_sig_info(pgp_sig_info_t *dst, const pgp_sig_info_t *src)
{
(void) memcpy(dst, src, sizeof(*src));
if ((dst->v4_hashed = calloc(1, src->v4_hashlen)) == NULL) {
(void) fprintf(stderr, "copy_sig_info: bad alloc\n");
} else {
(void) memcpy(dst->v4_hashed, src->v4_hashed, src->v4_hashlen);
}
}
static int
add_sig_to_list(const pgp_sig_info_t *sig, pgp_sig_info_t **sigs,
@ -232,16 +223,36 @@ check_binary_sig(const uint8_t *data,
return pgp_check_sig(hashout, n, sig, signer);
}
static void validate_key_cb_free (validate_key_cb_t *vdata){
/* Free according to previous allocated type */
if (vdata->type == PGP_PTAG_CT_PUBLIC_KEY) {
pgp_pubkey_free(&vdata->key.pubkey);
pgp_pubkey_free(&vdata->subkey.pubkey);
} else if (vdata->type == PGP_PTAG_CT_SECRET_KEY) {
pgp_seckey_free(&vdata->key.seckey);
if(vdata->subkey.seckey.pubkey.alg)
pgp_seckey_free(&vdata->subkey.seckey);
}
memset(&vdata->key, 0, sizeof(vdata->key));
memset(&vdata->subkey, 0, sizeof(vdata->subkey));
vdata->type = PGP_PTAG_CT_RESERVED; /* 0 */
pgp_userid_free(&vdata->userid);
pgp_data_free(&vdata->userattr);
if(vdata->valid_sig_info.key_alg) {
pgp_free_sig_info(&vdata->valid_sig_info);
}
}
pgp_cb_ret_t
pgp_validate_key_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
{
const pgp_contents_t *content = &pkt->u;
const pgp_key_t *signer;
validate_key_cb_t *key;
pgp_pubkey_t *sigkey;
validate_key_cb_t *vdata;
pgp_error_t **errors;
pgp_io_t *io;
unsigned from;
unsigned valid = 0;
io = cbinfo->io;
@ -249,175 +260,270 @@ pgp_validate_key_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
(void) fprintf(io->errs, "%s\n",
pgp_show_packet_tag(pkt->tag));
}
key = pgp_callback_arg(cbinfo);
vdata = pgp_callback_arg(cbinfo);
errors = pgp_callback_errors(cbinfo);
vdata->sig_is_valid &= pkt->tag == PGP_PARSER_PACKET_END;
switch (pkt->tag) {
case PGP_PTAG_CT_PUBLIC_KEY:
if (key->pubkey.version != 0) {
(void) fprintf(io->errs,
"pgp_validate_key_cb: version bad\n");
return PGP_FINISHED;
}
key->pubkey = content->pubkey;
return PGP_KEEP_MEMORY;
validate_key_cb_free(vdata);
vdata->key.pubkey = content->pubkey;
pgp_keyid(vdata->pubkeyid, PGP_KEY_ID_SIZE,
&vdata->key.pubkey, PGP_HASH_SHA1); /* TODO v3*/
case PGP_PTAG_CT_PUBLIC_SUBKEY:
if (key->subkey.version) {
pgp_pubkey_free(&key->subkey);
}
key->subkey = content->pubkey;
vdata->last_seen = LS_PRIMARY;
vdata->type = PGP_PTAG_CT_PUBLIC_KEY;
vdata->not_commited = 1;
return PGP_KEEP_MEMORY;
case PGP_PTAG_CT_SECRET_KEY:
key->seckey = content->seckey;
key->pubkey = key->seckey.pubkey;
/* TODO
* check pubkey seckey consistency */
validate_key_cb_free(vdata);
vdata->key.seckey = content->seckey;
pgp_keyid(vdata->pubkeyid, PGP_KEY_ID_SIZE,
&vdata->key.seckey.pubkey, PGP_HASH_SHA1); /* TODO v3*/
vdata->last_seen = LS_PRIMARY;
vdata->type = PGP_PTAG_CT_SECRET_KEY;
vdata->not_commited = 1;
return PGP_KEEP_MEMORY;
case PGP_PTAG_CT_PUBLIC_SUBKEY:
if(vdata->type == PGP_PTAG_CT_PUBLIC_KEY && (
vdata->last_seen == LS_ID ||
vdata->last_seen == LS_ATTRIBUTE)){
pgp_pubkey_free(&vdata->subkey.pubkey);
vdata->subkey.pubkey = content->pubkey;
vdata->last_seen = LS_SUBKEY;
return PGP_KEEP_MEMORY;
}else{
(void) fprintf(io->errs,
"pgp_validate_key_cb: unexpected public subkey packet");
vdata->last_seen = LS_UNKNOWN;
return PGP_RELEASE_MEMORY;
}
case PGP_PTAG_CT_SECRET_SUBKEY:
/* TODO
* check pubkey seckey consistency */
if(vdata->type == PGP_PTAG_CT_SECRET_KEY && (
vdata->last_seen == LS_ID ||
vdata->last_seen == LS_ATTRIBUTE)){
if(vdata->subkey.seckey.pubkey.alg)
pgp_seckey_free(&vdata->subkey.seckey);
vdata->subkey.seckey = content->seckey;
vdata->last_seen = LS_SUBKEY;
return PGP_KEEP_MEMORY;
}else{
(void) fprintf(io->errs,
"pgp_validate_key_cb: unexpected secret subkey packet");
vdata->last_seen = LS_UNKNOWN;
return PGP_RELEASE_MEMORY;
}
case PGP_PTAG_CT_USER_ID:
if (key->userid) {
pgp_userid_free(&key->userid);
if(vdata->last_seen == LS_PRIMARY ||
vdata->last_seen == LS_ATTRIBUTE ||
vdata->last_seen == LS_ID){
if (vdata->userid) {
pgp_userid_free(&vdata->userid);
}
key->userid = content->userid;
key->last_seen = ID;
vdata->userid = content->userid;
vdata->last_seen = LS_ID;
return PGP_KEEP_MEMORY;
}else{
(void) fprintf(io->errs,
"pgp_validate_key_cb: unexpected userID packet");
vdata->last_seen = LS_UNKNOWN;
return PGP_RELEASE_MEMORY;
}
case PGP_PTAG_CT_USER_ATTR:
if(vdata->last_seen == LS_PRIMARY ||
vdata->last_seen == LS_ATTRIBUTE ||
vdata->last_seen == LS_ID){
if (content->userattr.len == 0) {
(void) fprintf(io->errs,
"pgp_validate_key_cb: user attribute length 0");
return PGP_FINISHED;
vdata->last_seen = LS_UNKNOWN;
return PGP_RELEASE_MEMORY;
}
(void) fprintf(io->outs, "user attribute, length=%d\n",
(int) content->userattr.len);
if (key->userattr.len) {
pgp_data_free(&key->userattr);
if (vdata->userattr.len) {
pgp_data_free(&vdata->userattr);
}
key->userattr = content->userattr;
key->last_seen = ATTRIBUTE;
vdata->userattr = content->userattr;
vdata->last_seen = LS_ATTRIBUTE;
return PGP_KEEP_MEMORY;
case PGP_PTAG_CT_SIGNATURE: /* V3 sigs */
case PGP_PTAG_CT_SIGNATURE_FOOTER: /* V4 sigs */
from = 0;
signer = pgp_getkeybyid(io, key->keyring,
content->sig.info.signer_id,
&from, &sigkey);
if (!signer) {
if (!add_sig_to_list(&content->sig.info,
&key->result->unknown_sigs,
&key->result->unknownc)) {
}else{
(void) fprintf(io->errs,
"pgp_validate_key_cb: user attribute length 0");
"pgp_validate_key_cb: unexpected user attribute\n");
vdata->last_seen = LS_UNKNOWN;
return PGP_RELEASE_MEMORY;
}
case PGP_PTAG_CT_SIGNATURE: /* V3 sigs */
case PGP_PTAG_CT_SIGNATURE_FOOTER:{ /* V4 sigs */
pgp_pubkey_t *sigkey = NULL;
pgp_pubkey_t *primary_pubkey;
if(vdata->last_seen == LS_UNKNOWN)
break;
primary_pubkey =
(vdata->type == PGP_PTAG_CT_PUBLIC_KEY) ?
&vdata->key.pubkey:
&vdata->key.seckey.pubkey;
if(vdata->keyring){
unsigned from;
from = 0;
/* Returned key ignored, care about ID-targeted pubkey only */
pgp_getkeybyid(io, vdata->keyring,
content->sig.info.signer_id,
&from, &sigkey, NULL,
1, 0); /* reject revoked, accept expired */
} else {
/* If no keyring is given to check against
* then this is a self certification check.
* First ensure signature issuer ID is pubkey's ID*/
if(memcmp(vdata->pubkeyid,
content->sig.info.signer_id,
PGP_KEY_ID_SIZE) == 0){
sigkey = primary_pubkey;
}
}
if (!sigkey) {
if (vdata->result && !add_sig_to_list(&content->sig.info,
&vdata->result->unknown_sigs,
&vdata->result->unknownc)) {
(void) fprintf(io->errs,
"pgp_validate_key_cb: out of memory");
return PGP_FINISHED;
}
break;
}
if (sigkey == &signer->enckey) {
(void) fprintf(io->errs,
"WARNING: signature made with encryption key\n");
}
switch (content->sig.info.type) {
case PGP_CERT_GENERIC:
case PGP_CERT_PERSONA:
case PGP_CERT_CASUAL:
case PGP_CERT_POSITIVE:
case PGP_SIG_REV_CERT:
valid = (key->last_seen == ID) ?
pgp_check_useridcert_sig(&key->pubkey,
key->userid,
if(vdata->last_seen == LS_ID){
valid = pgp_check_useridcert_sig(
primary_pubkey,
vdata->userid,
&content->sig,
pgp_get_pubkey(signer),
key->reader->key->packets[
key->reader->packet].raw) :
pgp_check_userattrcert_sig(&key->pubkey,
&key->userattr,
sigkey);
} else if(vdata->last_seen == LS_ATTRIBUTE) {
valid = pgp_check_userattrcert_sig(
primary_pubkey,
&vdata->userattr,
&content->sig,
pgp_get_pubkey(signer),
key->reader->key->packets[
key->reader->packet].raw);
sigkey);
}
break;
case PGP_SIG_REV_SUBKEY:
case PGP_SIG_SUBKEY:
/*
* XXX: we should also check that the signer is the
* key we are validating, I think.
* we ensure that the signing key is the
* primary key we are validating, "vdata->pubkey".
*/
valid = pgp_check_subkey_sig(&key->pubkey,
&key->subkey,
if(vdata->last_seen == LS_SUBKEY &&
memcmp(vdata->pubkeyid,
content->sig.info.signer_id,
PGP_KEY_ID_SIZE) == 0 )
{
valid = pgp_check_subkey_sig(
primary_pubkey,
(vdata->type == PGP_PTAG_CT_PUBLIC_KEY) ?
&vdata->subkey.pubkey:
&vdata->subkey.seckey.pubkey,
&content->sig,
pgp_get_pubkey(signer),
key->reader->key->packets[
key->reader->packet].raw);
primary_pubkey);
}
break;
case PGP_SIG_REV_KEY:
case PGP_SIG_DIRECT:
valid = pgp_check_direct_sig(&key->pubkey,
if(vdata->last_seen == LS_PRIMARY){
valid = pgp_check_direct_sig(
primary_pubkey,
&content->sig,
pgp_get_pubkey(signer),
key->reader->key->packets[
key->reader->packet].raw);
sigkey);
}
break;
case PGP_SIG_STANDALONE:
case PGP_SIG_PRIMARY:
case PGP_SIG_REV_KEY:
case PGP_SIG_REV_SUBKEY:
case PGP_SIG_TIMESTAMP:
case PGP_SIG_3RD_PARTY:
if (vdata->result){
PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED,
"Sig Verification type 0x%02x not done yet\n",
content->sig.info.type);
break;
}
default:
if (vdata->result){
PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED,
"Unexpected signature type 0x%02x\n",
content->sig.info.type);
}
}
if (valid) {
if (!add_sig_to_list(&content->sig.info,
&key->result->valid_sigs,
&key->result->validc)) {
if (vdata->result && !add_sig_to_list(&content->sig.info,
&vdata->result->valid_sigs,
&vdata->result->validc)) {
PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED, "%s",
"Can't add good sig to list\n");
"Can't add valid sig to list\n");
}
} else {
vdata->sig_is_valid = 1;
copy_sig_info(&vdata->valid_sig_info,
&content->sig.info);
} else if (vdata->result){
PGP_ERROR_1(errors, PGP_E_V_BAD_SIGNATURE, "%s",
"Bad Sig");
if (!add_sig_to_list(&content->sig.info,
&key->result->invalid_sigs,
&key->result->invalidc)) {
&vdata->result->invalid_sigs,
&vdata->result->invalidc)) {
PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED, "%s",
"Can't add good sig to list\n");
"Can't add invalid sig to list\n");
}
}
break;
}
case PGP_PARSER_PACKET_END:
if(vdata->sig_is_valid){
pgp_cb_ret_t ret = PGP_RELEASE_MEMORY;
if(vdata->on_valid){
ret = vdata->on_valid(vdata, &content->packet);
}
vdata->sig_is_valid = 0;
vdata->not_commited = 0;
return ret;
}
return PGP_RELEASE_MEMORY;
/* ignore these */
case PGP_PARSER_PTAG:
case PGP_PTAG_CT_SIGNATURE_HEADER:
case PGP_PARSER_PACKET_END:
break;
case PGP_GET_PASSPHRASE:
if (key->getpassphrase) {
return key->getpassphrase(pkt, cbinfo);
}
break;
case PGP_PTAG_CT_TRUST:
/* 1 byte for level (depth), 1 byte for trust amount */
printf("trust dump\n");
printf("Got trust\n");
//hexdump(stdout, (const uint8_t *)content->trust.data, 10, " ");
//hexdump(stdout, (const uint8_t *)&content->ss_trust, 2, " ");
//printf("Trust level %d, amount %d\n", key->trust.level, key->trust.amount);
break;
// case PGP_GET_PASSPHRASE:
// if (vdata->getpassphrase) {
// return vdata->getpassphrase(pkt, cbinfo);
// }
// break;
default:
(void) fprintf(stderr, "unexpected tag=0x%x\n", pkt->tag);
return PGP_FINISHED;
// (void) fprintf(stderr, "unexpected tag=0x%x\n", pkt->tag);
return PGP_RELEASE_MEMORY;
}
return PGP_RELEASE_MEMORY;
}
@ -426,7 +532,7 @@ pgp_cb_ret_t
validate_data_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
{
const pgp_contents_t *content = &pkt->u;
const pgp_key_t *signer;
pgp_key_t *signer;
validate_data_cb_t *data;
pgp_pubkey_t *sigkey;
pgp_error_t **errors;
@ -480,9 +586,11 @@ validate_data_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
sizeof(content->sig.info.signer_id));
}
from = 0;
sigkey = NULL;
signer = pgp_getkeybyid(io, data->keyring,
content->sig.info.signer_id, &from, &sigkey);
if (!signer) {
content->sig.info.signer_id, &from, &sigkey, NULL,
0, 0); /* check neither revocation nor expiry */
if (!signer || !sigkey) {
PGP_ERROR_1(errors, PGP_E_V_UNKNOWN_SIGNER,
"%s", "Unknown Signer");
if (!add_sig_to_list(&content->sig.info,
@ -493,10 +601,6 @@ validate_data_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
}
break;
}
if (sigkey == &signer->enckey) {
(void) fprintf(io->errs,
"WARNING: signature made with encryption key\n");
}
if (content->sig.info.birthtime_set) {
data->result->birthtime = content->sig.info.birthtime;
}
@ -506,8 +610,8 @@ validate_data_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
switch (content->sig.info.type) {
case PGP_SIG_BINARY:
case PGP_SIG_TEXT:
if (pgp_mem_len(data->mem) == 0 &&
data->detachname) {
if (pgp_mem_len(data->mem) == 0){
if(data->detachname) {
/* check we have seen some data */
/* if not, need to read from detached name */
(void) fprintf(io->errs,
@ -515,6 +619,7 @@ validate_data_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
data->detachname);
data->mem = pgp_memory_new();
pgp_mem_readfile(data->mem, data->detachname);
}
}
if (pgp_get_debug_level(__FILE__)) {
hexdump(stderr, "sig dump", (const uint8_t *)(const void *)&content->sig,
@ -523,7 +628,7 @@ validate_data_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
valid = check_binary_sig(pgp_mem_data(data->mem),
(const unsigned)pgp_mem_len(data->mem),
&content->sig,
pgp_get_pubkey(signer));
sigkey);
break;
default:
@ -571,27 +676,6 @@ validate_data_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
return PGP_RELEASE_MEMORY;
}
static void
keydata_destroyer(pgp_reader_t *readinfo)
{
free(pgp_reader_get_arg(readinfo));
}
void
pgp_keydata_reader_set(pgp_stream_t *stream, const pgp_key_t *key)
{
validate_reader_t *data;
if ((data = calloc(1, sizeof(*data))) == NULL) {
(void) fprintf(stderr, "pgp_keydata_reader_set: bad alloc\n");
} else {
data->key = key;
data->packet = 0;
data->offset = 0;
pgp_reader_set(stream, keydata_reader, keydata_destroyer, data);
}
}
static char *
fmtsecs(int64_t n, char *buf, size_t size)
{
@ -669,81 +753,195 @@ validate_result_status(FILE *errs, const char *f, pgp_validation_t *val)
return val->validc && !val->invalidc && !val->unknownc;
}
/**
* \ingroup HighLevel_Verify
* \brief Validate all signatures on a single key against the given keyring
* \param result Where to put the result
* \param key Key to validate
* \param keyring Keyring to use for validation
* \param cb_get_passphrase Callback to use to get passphrase
* \return 1 if all signatures OK; else 0
* \note It is the caller's responsiblity to free result after use.
* \sa pgp_validate_result_free()
*/
typedef struct key_filter_cb_t{
pgp_keyring_t *destpubring;
pgp_keyring_t *destsecring;
pgp_key_t *pubkey;
pgp_key_t *seckey;
} key_filter_cb_t;
static pgp_cb_ret_t key_filter_cb (
validate_key_cb_t *vdata,
const pgp_subpacket_t *sigpkt)
{
pgp_key_t *pubkey;
pgp_key_t *seckey = NULL;
key_filter_cb_t *filter = vdata->on_valid_args;
if(vdata->not_commited){
if((filter->pubkey = pgp_ensure_pubkey(filter->destpubring,
(vdata->type == PGP_PTAG_CT_PUBLIC_KEY) ?
&vdata->key.pubkey :
&vdata->key.seckey.pubkey,
vdata->pubkeyid))==NULL){
return PGP_RELEASE_MEMORY;
}
filter->seckey = NULL;
if (vdata->type == PGP_PTAG_CT_SECRET_KEY && filter->destsecring) {
if((filter->seckey = pgp_ensure_seckey(
filter->destsecring,
&vdata->key.seckey,
vdata->pubkeyid))==NULL){
return PGP_RELEASE_MEMORY;
}
}
/* TODO get seckey by ID id even if given key is public
* in order to update uids an attributes from pubkey */
}
pubkey = filter->pubkey;
if(pubkey == NULL)
return PGP_RELEASE_MEMORY;
if (vdata->type == PGP_PTAG_CT_SECRET_KEY) {
seckey = filter->seckey;
}
switch(vdata->last_seen){
case LS_PRIMARY:
pgp_add_directsig(pubkey, sigpkt, &vdata->valid_sig_info);
if (seckey) {
pgp_add_directsig(seckey, sigpkt, &vdata->valid_sig_info);
}
break;
case LS_ID:
pgp_update_userid(pubkey, vdata->userid, sigpkt, &vdata->valid_sig_info);
if (seckey) {
pgp_update_userid(seckey, vdata->userid, sigpkt, &vdata->valid_sig_info);
}
break;
case LS_ATTRIBUTE:
/* TODO */
break;
case LS_SUBKEY:
pgp_update_subkey(pubkey,
vdata->type, &vdata->subkey,
sigpkt, &vdata->valid_sig_info);
if (seckey) {
pgp_update_subkey(seckey,
vdata->type, &vdata->subkey,
sigpkt, &vdata->valid_sig_info);
}
break;
default:
break;
}
return PGP_RELEASE_MEMORY;
}
unsigned
pgp_validate_key_sigs(pgp_validation_t *result,
const pgp_key_t *key,
const pgp_keyring_t *keyring,
pgp_cb_ret_t cb_get_passphrase(const pgp_packet_t *,
pgp_cbdata_t *))
pgp_filter_keys_fileread(
pgp_io_t *io,
pgp_keyring_t *destpubring,
pgp_keyring_t *destsecring,
pgp_keyring_t *certring,
const unsigned armour,
const char *filename)
{
pgp_stream_t *stream;
validate_key_cb_t keysigs;
const int printerrors = 1;
validate_key_cb_t vdata;
key_filter_cb_t filter;
unsigned res = 1;
int fd;
(void) memset(&keysigs, 0x0, sizeof(keysigs));
keysigs.result = result;
keysigs.getpassphrase = cb_get_passphrase;
(void) memset(&vdata, 0x0, sizeof(vdata));
vdata.result = NULL;
vdata.getpassphrase = NULL;
stream = pgp_new(sizeof(*stream));
/* pgp_parse_options(&opt,PGP_PTAG_CT_SIGNATURE,PGP_PARSE_PARSED); */
(void) memset(&filter, 0x0, sizeof(filter));
filter.destpubring = destpubring;
filter.destsecring = destsecring;
keysigs.keyring = keyring;
fd = pgp_setup_file_read(io,
&stream,filename,
&vdata,
pgp_validate_key_cb,
1);
pgp_set_callback(stream, pgp_validate_key_cb, &keysigs);
stream->readinfo.accumulate = 1;
pgp_keydata_reader_set(stream, key);
/* Note: Coverity incorrectly reports an error that keysigs.reader */
/* is never used. */
keysigs.reader = stream->readinfo.arg;
pgp_parse(stream, !printerrors);
pgp_pubkey_free(&keysigs.pubkey);
if (keysigs.subkey.version) {
pgp_pubkey_free(&keysigs.subkey);
if (fd < 0) {
perror(filename);
return 0;
}
pgp_userid_free(&keysigs.userid);
pgp_data_free(&keysigs.userattr);
pgp_parse_options(stream, PGP_PTAG_SS_ALL, PGP_PARSE_PARSED);
if (armour) {
pgp_reader_push_dearmour(stream);
}
vdata.keyring = certring;
vdata.on_valid = &key_filter_cb;
vdata.on_valid_args = &filter;
res = pgp_parse(stream, 0);
validate_key_cb_free(&vdata);
if (armour) {
pgp_reader_pop_dearmour(stream);
}
(void)close(fd);
pgp_stream_delete(stream);
return (!result->invalidc && !result->unknownc && result->validc);
return res;
}
/**
\ingroup HighLevel_Verify
\param result Where to put the result
\param ring Keyring to use
\param cb_get_passphrase Callback to use to get passphrase
\note It is the caller's responsibility to free result after use.
\sa pgp_validate_result_free()
*/
unsigned
pgp_validate_all_sigs(pgp_validation_t *result,
const pgp_keyring_t *ring,
pgp_cb_ret_t cb_get_passphrase(const pgp_packet_t *,
pgp_cbdata_t *))
pgp_filter_keys_from_mem(
pgp_io_t *io,
pgp_keyring_t *destpubring,
pgp_keyring_t *destsecring,
pgp_keyring_t *certring,
const unsigned armour,
pgp_memory_t *mem)
{
unsigned n;
pgp_stream_t *stream;
validate_key_cb_t vdata;
key_filter_cb_t filter;
unsigned res;
(void) memset(result, 0x0, sizeof(*result));
for (n = 0; n < ring->keyc; ++n) {
pgp_validate_key_sigs(result, &ring->keys[n], ring,
cb_get_passphrase);
(void) memset(&vdata, 0x0, sizeof(vdata));
vdata.result = NULL;
vdata.getpassphrase = NULL;
(void) memset(&filter, 0x0, sizeof(filter));
filter.destpubring = destpubring;
filter.destsecring = destsecring;
stream = pgp_new(sizeof(*stream));
pgp_parse_options(stream, PGP_PTAG_SS_ALL, PGP_PARSE_PARSED);
pgp_setup_memory_read(io, &stream, mem, &vdata, pgp_validate_key_cb, 1);
if (armour) {
pgp_reader_push_dearmour(stream);
}
return validate_result_status(stderr, "keyring", result);
vdata.keyring = certring;
vdata.on_valid = &key_filter_cb;
vdata.on_valid_args = &filter;
res = pgp_parse(stream, 0);
validate_key_cb_free(&vdata);
if (armour) {
pgp_reader_pop_dearmour(stream);
}
/* don't call teardown_memory_read because memory was passed in */
pgp_stream_delete(stream);
return res;
}
/**
@ -846,9 +1044,6 @@ pgp_validate_file(pgp_io_t *io,
validation.keyring = keyring;
validation.mem = pgp_memory_new();
pgp_memory_init(validation.mem, 128);
/* Note: Coverity incorrectly reports an error that validation.reader */
/* is never used. */
validation.reader = parse->readinfo.arg;
if (realarmour) {
pgp_reader_push_dearmour(parse);
@ -910,20 +1105,21 @@ pgp_validate_file(pgp_io_t *io,
\param mem Memory to be validated
\param user_says_armoured Treat data as armoured, if set
\param keyring Keyring to use
\param detachmem detached memory (free done in this call if provided)
\return 1 if signature validates successfully; 0 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
pgp_validate_result_free(result) after use.
*/
unsigned
pgp_validate_mem(pgp_io_t *io,
static inline unsigned
_pgp_validate_mem(pgp_io_t *io,
pgp_validation_t *result,
pgp_memory_t *mem,
pgp_memory_t **cat,
const int user_says_armoured,
const pgp_keyring_t *keyring)
const pgp_keyring_t *keyring,
pgp_memory_t *detachmem)
{
validate_data_cb_t validation;
pgp_stream_t *stream = NULL;
@ -931,15 +1127,17 @@ pgp_validate_mem(pgp_io_t *io,
int realarmour;
pgp_setup_memory_read(io, &stream, mem, &validation, validate_data_cb, 1);
/* Set verification reader and handling options */
(void) memset(&validation, 0x0, sizeof(validation));
validation.result = result;
validation.keyring = keyring;
if (detachmem) {
validation.mem = detachmem;
}else{
validation.mem = pgp_memory_new();
pgp_memory_init(validation.mem, 128);
/* Note: Coverity incorrectly reports an error that validation.reader */
/* is never used. */
validation.reader = stream->readinfo.arg;
}
if ((realarmour = user_says_armoured) != 0 ||
strncmp(pgp_mem_data(mem),
@ -969,3 +1167,39 @@ pgp_validate_mem(pgp_io_t *io,
return validate_result_status(io->errs, NULL, result);
}
unsigned
pgp_validate_mem(pgp_io_t *io,
pgp_validation_t *result,
pgp_memory_t *mem,
pgp_memory_t **cat,
const int user_says_armoured,
const pgp_keyring_t *keyring)
{
return _pgp_validate_mem(io,
result,
mem,
cat,
user_says_armoured,
keyring,
NULL);
}
unsigned
pgp_validate_mem_detached(pgp_io_t *io,
pgp_validation_t *result,
pgp_memory_t *mem,
pgp_memory_t **cat,
const int user_says_armoured,
const pgp_keyring_t *keyring,
pgp_memory_t *detachmem)
{
return _pgp_validate_mem(io,
result,
mem,
cat,
user_says_armoured,
keyring,
detachmem);
}

View file

@ -50,7 +50,7 @@
/** \file
* This file contains the base functions used by the writers.
*/
#include "config-netpgp.h"
#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
@ -58,7 +58,7 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
__RCSID("$NetBSD: writer.c,v 1.33 2012/03/05 02:20:18 christos Exp $");
__RCSID("$NetBSD$");
#endif
#include <sys/types.h>
@ -74,17 +74,17 @@ __RCSID("$NetBSD: writer.c,v 1.33 2012/03/05 02:20:18 christos Exp $");
#include <openssl/cast.h>
#endif
#include "create-netpgp.h"
#include "writer-netpgp.h"
#include "keyring-netpgp.h"
#include "signature-netpgp.h"
#include "packet-netpgp.h"
#include "packet-parse.h"
#include "readerwriter-netpgp.h"
#include "memory-netpgp.h"
#include "netpgpdefs.h"
#include "version-netpgp.h"
#include "netpgpdigest.h"
#include "netpgp/create.h"
#include "netpgp/writer.h"
#include "netpgp/keyring.h"
#include "netpgp/signature.h"
#include "netpgp/packet.h"
#include "netpgp/packet-parse.h"
#include "netpgp/readerwriter.h"
#include "netpgp/memory.h"
#include "netpgp/netpgpdefs.h"
#include "netpgp/version.h"
#include "netpgp/netpgpdigest.h"
/*
@ -285,11 +285,13 @@ pgp_writer_push(pgp_output_t *output,
{
pgp_writer_t *copy;
if ((copy = calloc(1, sizeof(*copy))) == NULL) {
(void) fprintf(stderr, "pgp_writer_push: bad alloc\n");
} else if (output->writer.writer == NULL) {
if (output->writer.writer == NULL) {
(void) fprintf(stderr, "pgp_writer_push: no orig writer\n");
} else {
if ((copy = calloc(1, sizeof(*copy))) == NULL) {
(void) fprintf(stderr, "pgp_writer_push: bad alloc\n");
return; /* TODO return error */
}
*copy = output->writer;
output->writer.next = copy;
@ -910,6 +912,7 @@ pgp_writer_push_armoured(pgp_output_t *output, pgp_armor_type_t type)
if ((base64 = calloc(1, sizeof(*base64))) == NULL) {
(void) fprintf(stderr,
"pgp_writer_push_armoured: bad alloc\n");
free(linebreak);
return;
}
base64->checksum = CRC24_INIT;
@ -1011,6 +1014,7 @@ pgp_push_enc_crypt(pgp_output_t *output, pgp_crypt_t *pgp_crypt)
typedef struct {
pgp_crypt_t *crypt;
unsigned raw;
} encrypt_se_ip_t;
static unsigned encrypt_se_ip_writer(const uint8_t *,
@ -1026,32 +1030,54 @@ static void encrypt_se_ip_destroyer(pgp_writer_t *);
\brief Push Encrypted SE IP Writer onto stack
*/
int
pgp_push_enc_se_ip(pgp_output_t *output, const pgp_key_t *pubkey, const char *cipher)
pgp_push_enc_se_ip(pgp_output_t *output, const pgp_keyring_t *pubkeys, const char *cipher, unsigned raw)
{
pgp_pk_sesskey_t *initial_sesskey = NULL;
pgp_pk_sesskey_t *encrypted_pk_sesskey;
encrypt_se_ip_t *se_ip;
pgp_crypt_t *encrypted;
uint8_t *iv;
unsigned n;
if ((se_ip = calloc(1, sizeof(*se_ip))) == NULL) {
(void) fprintf(stderr, "pgp_push_enc_se_ip: bad alloc\n");
return 0;
}
for (n = 0; n < pubkeys->keyc; ++n) {
/* Create and write encrypted PK session key */
if ((encrypted_pk_sesskey = pgp_create_pk_sesskey(pubkey, cipher)) == NULL) {
if ((encrypted_pk_sesskey =
pgp_create_pk_sesskey(&pubkeys->keys[n],
cipher, initial_sesskey)) == NULL) {
(void) fprintf(stderr, "pgp_push_enc_se_ip: null pk sesskey\n");
free(se_ip);
return 0;
}
if (initial_sesskey == NULL) {
initial_sesskey = encrypted_pk_sesskey;
}
pgp_write_pk_sesskey(output, encrypted_pk_sesskey);
if(encrypted_pk_sesskey != initial_sesskey){
free(encrypted_pk_sesskey);
}
}
if (initial_sesskey == NULL) {
(void) fprintf(stderr, "pgp_push_enc_se_ip: no sesskey\n");
free(se_ip);
return 0;
}
/* Setup the se_ip */
if ((encrypted = calloc(1, sizeof(*encrypted))) == NULL) {
free(se_ip);
(void) fprintf(stderr, "pgp_push_enc_se_ip: bad alloc\n");
return 0;
}
pgp_crypt_any(encrypted, encrypted_pk_sesskey->symm_alg);
pgp_crypt_any(encrypted, initial_sesskey->symm_alg);
if ((iv = calloc(1, encrypted->blocksize)) == NULL) {
free(se_ip);
free(encrypted);
@ -1059,16 +1085,17 @@ pgp_push_enc_se_ip(pgp_output_t *output, const pgp_key_t *pubkey, const char *ci
return 0;
}
encrypted->set_iv(encrypted, iv);
encrypted->set_crypt_key(encrypted, &encrypted_pk_sesskey->key[0]);
encrypted->set_crypt_key(encrypted, &initial_sesskey->key[0]);
pgp_encrypt_init(encrypted);
se_ip->crypt = encrypted;
se_ip->raw = raw;
/* And push writer on stack */
pgp_writer_push(output, encrypt_se_ip_writer, NULL,
encrypt_se_ip_destroyer, se_ip);
/* tidy up */
free(encrypted_pk_sesskey);
free(initial_sesskey);
free(iv);
return 1;
}
@ -1089,19 +1116,29 @@ encrypt_se_ip_writer(const uint8_t *src,
pgp_memory_t *localmem;
unsigned ret = 1;
const uint8_t *zsrc;
unsigned zsrclen;
pgp_setup_memory_write(&litoutput, &litmem, bufsz);
pgp_setup_memory_write(&zoutput, &zmem, bufsz);
pgp_setup_memory_write(&output, &localmem, bufsz);
if (!se_ip->raw) {
/* create literal data packet from source data */
pgp_write_litdata(litoutput, src, (const int)len, PGP_LDT_BINARY);
if (pgp_mem_len(litmem) <= len) {
(void) fprintf(stderr, "encrypt_se_ip_writer: bad len\n");
return 0;
}
zsrc = pgp_mem_data(litmem);
zsrclen = (unsigned)pgp_mem_len(litmem);
}else{
zsrc = src;
zsrclen = len;
}
/* create compressed packet from literal data packet */
pgp_writez(zoutput, pgp_mem_data(litmem), (unsigned)pgp_mem_len(litmem));
pgp_writez(zoutput, zsrc, zsrclen);
/* create SE IP packet set from this compressed literal data */
pgp_write_se_ip_pktset(output, pgp_mem_data(zmem),
@ -1379,6 +1416,60 @@ pgp_push_checksum_writer(pgp_output_t *output, pgp_seckey_t *seckey)
/**************************************************************************/
typedef struct {
uint16_t sum;
} sum16_t;
static unsigned
sum16_writer(const uint8_t *src,
const unsigned len,
pgp_error_t **errors,
pgp_writer_t *writer)
{
sum16_t *arg;
unsigned ret = 1;
int n;
arg = pgp_writer_get_arg(writer);
for (n = 0; n < len; ++n) {
arg->sum = (arg->sum + src[n]) & 0xffff;
}
/* write to next stacked writer */
ret = stacked_write(writer, src, len, errors);
/* tidy up and return */
return ret;
}
void
pgp_push_sum16_writer(pgp_output_t *output)
{
sum16_t *sum;
if ((sum = calloc(1, sizeof(*sum))) == NULL) {
(void) fprintf(stderr,
"pgp_push_sum16_writer: bad alloc\n");
} else {
pgp_writer_push(output, sum16_writer,
NULL, NULL, sum);
}
}
uint16_t
pgp_pop_sum16_writer(pgp_output_t *output)
{
uint16_t sum;
sum16_t *arg;
arg = pgp_writer_get_arg(&output->writer);
sum = arg->sum;
pgp_writer_pop(output);
free(arg);
return sum;
}
/**************************************************************************/
#define MAX_PARTIAL_DATA_LENGTH 1073741824
typedef struct {
@ -1412,7 +1503,7 @@ static void str_enc_se_ip_destroyer(pgp_writer_t *writer);
\param pubkey
*/
void
pgp_push_stream_enc_se_ip(pgp_output_t *output, const pgp_key_t *pubkey, const char *cipher)
pgp_push_stream_enc_se_ip(pgp_output_t *output, pgp_key_t *pubkey, const char *cipher)
{
pgp_pk_sesskey_t *encrypted_pk_sesskey;
str_enc_se_ip_t *se_ip;
@ -1425,7 +1516,7 @@ pgp_push_stream_enc_se_ip(pgp_output_t *output, const pgp_key_t *pubkey, const c
"pgp_push_stream_enc_se_ip: bad alloc\n");
return;
}
encrypted_pk_sesskey = pgp_create_pk_sesskey(pubkey, cipher);
encrypted_pk_sesskey = pgp_create_pk_sesskey(pubkey, cipher, NULL);
pgp_write_pk_sesskey(output, encrypted_pk_sesskey);
/* Setup the se_ip */
@ -1701,7 +1792,6 @@ str_enc_se_ip_writer(const uint8_t *src,
size_t datalength;
se_ip = pgp_writer_get_arg(writer);
ret = 1;
if (se_ip->litoutput == NULL) {
/* first literal data chunk is not yet written */

View file

@ -119,9 +119,10 @@ int mre2ee_driver_create_keypair(mrmailbox_t* mailbox, const char* addr, mrkey_t
/* generate keypair */
keypair = pgp_rsa_new_selfsign_key(2048/*bits*/, 65537UL/*e*/, (const uint8_t*)user_id, NULL, NULL);
/* get public key */
/* write public key */
keypair->type = PGP_PTAG_CT_PUBLIC_KEY; // TODO: this seems to me like a hack, PLUS: add a subkey
pgp_writer_set_memory(output1, mem1);
if( !pgp_write_xfer_pubkey(output1, keypair, 0/*armoured*/) ) {
if( !pgp_write_xfer_key(output1, keypair, 0/*armoured*/) ) {
goto cleanup;
}
@ -132,8 +133,9 @@ int mre2ee_driver_create_keypair(mrmailbox_t* mailbox, const char* addr, mrkey_t
mrkey_set_from_raw(ret_public_key, (const unsigned char*)mem1->buf, mem1->length, MR_PRIVATE);
/* write private key */
keypair->type = PGP_PTAG_CT_SECRET_KEY; // TODO: this seems to me like a hack
pgp_writer_set_memory(output2, mem2);
if( !pgp_write_xfer_seckey(output2, keypair, NULL, 0, 0/*armoured*/) ) {
if( !pgp_write_xfer_key(output2, keypair, 0/*armoured*/) ) {
goto cleanup;
}