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:
parent
15a4434013
commit
11157137ad
46 changed files with 4887 additions and 7217 deletions
|
@ -54,7 +54,7 @@
|
||||||
<Add directory="libs/libetpan/include" />
|
<Add directory="libs/libetpan/include" />
|
||||||
<Add directory="libs/libetpan/include/libetpan" />
|
<Add directory="libs/libetpan/include/libetpan" />
|
||||||
<Add directory="libs/sqlite" />
|
<Add directory="libs/sqlite" />
|
||||||
<Add directory="libs/netpgp" />
|
<Add directory="libs/netpgp/include" />
|
||||||
</Compiler>
|
</Compiler>
|
||||||
<Unit filename="README.md" />
|
<Unit filename="README.md" />
|
||||||
<Unit filename="libs/libetpan/src/data-types/base64.c">
|
<Unit filename="libs/libetpan/src/data-types/base64.c">
|
||||||
|
@ -372,58 +372,46 @@
|
||||||
<Unit filename="libs/libetpan/src/main/libetpan_version.c">
|
<Unit filename="libs/libetpan/src/main/libetpan_version.c">
|
||||||
<Option compilerVar="CC" />
|
<Option compilerVar="CC" />
|
||||||
</Unit>
|
</Unit>
|
||||||
<Unit filename="libs/netpgp/bufgap.c">
|
<Unit filename="libs/netpgp/src/compress.c">
|
||||||
<Option compilerVar="CC" />
|
<Option compilerVar="CC" />
|
||||||
</Unit>
|
</Unit>
|
||||||
<Unit filename="libs/netpgp/compress.c">
|
<Unit filename="libs/netpgp/src/create.c">
|
||||||
<Option compilerVar="CC" />
|
<Option compilerVar="CC" />
|
||||||
</Unit>
|
</Unit>
|
||||||
<Unit filename="libs/netpgp/create.c">
|
<Unit filename="libs/netpgp/src/crypto.c">
|
||||||
<Option compilerVar="CC" />
|
<Option compilerVar="CC" />
|
||||||
</Unit>
|
</Unit>
|
||||||
<Unit filename="libs/netpgp/crypto.c">
|
<Unit filename="libs/netpgp/src/keyring.c">
|
||||||
<Option compilerVar="CC" />
|
<Option compilerVar="CC" />
|
||||||
</Unit>
|
</Unit>
|
||||||
<Unit filename="libs/netpgp/keyring.c">
|
<Unit filename="libs/netpgp/src/misc.c">
|
||||||
<Option compilerVar="CC" />
|
<Option compilerVar="CC" />
|
||||||
</Unit>
|
</Unit>
|
||||||
<Unit filename="libs/netpgp/misc.c">
|
<Unit filename="libs/netpgp/src/netpgp.c">
|
||||||
<Option compilerVar="CC" />
|
<Option compilerVar="CC" />
|
||||||
</Unit>
|
</Unit>
|
||||||
<Unit filename="libs/netpgp/mj.c">
|
<Unit filename="libs/netpgp/src/openssl_crypto.c">
|
||||||
<Option compilerVar="CC" />
|
<Option compilerVar="CC" />
|
||||||
</Unit>
|
</Unit>
|
||||||
<Unit filename="libs/netpgp/netpgp.c">
|
<Unit filename="libs/netpgp/src/packet-parse.c">
|
||||||
<Option compilerVar="CC" />
|
<Option compilerVar="CC" />
|
||||||
</Unit>
|
</Unit>
|
||||||
<Unit filename="libs/netpgp/openssl_crypto.c">
|
<Unit filename="libs/netpgp/src/packet-show.c">
|
||||||
<Option compilerVar="CC" />
|
<Option compilerVar="CC" />
|
||||||
</Unit>
|
</Unit>
|
||||||
<Unit filename="libs/netpgp/packet-parse.c">
|
<Unit filename="libs/netpgp/src/reader.c">
|
||||||
<Option compilerVar="CC" />
|
<Option compilerVar="CC" />
|
||||||
</Unit>
|
</Unit>
|
||||||
<Unit filename="libs/netpgp/packet-print.c">
|
<Unit filename="libs/netpgp/src/signature.c">
|
||||||
<Option compilerVar="CC" />
|
<Option compilerVar="CC" />
|
||||||
</Unit>
|
</Unit>
|
||||||
<Unit filename="libs/netpgp/packet-show.c">
|
<Unit filename="libs/netpgp/src/symmetric.c">
|
||||||
<Option compilerVar="CC" />
|
<Option compilerVar="CC" />
|
||||||
</Unit>
|
</Unit>
|
||||||
<Unit filename="libs/netpgp/reader.c">
|
<Unit filename="libs/netpgp/src/validate.c">
|
||||||
<Option compilerVar="CC" />
|
<Option compilerVar="CC" />
|
||||||
</Unit>
|
</Unit>
|
||||||
<Unit filename="libs/netpgp/signature.c">
|
<Unit filename="libs/netpgp/src/writer.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">
|
|
||||||
<Option compilerVar="CC" />
|
<Option compilerVar="CC" />
|
||||||
</Unit>
|
</Unit>
|
||||||
<Unit filename="libs/sqlite/sqlite3.c">
|
<Unit filename="libs/sqlite/sqlite3.c">
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
#ifndef __NETPGP_EXTRA_H__
|
#ifndef __NETPGP_EXTRA_H__
|
||||||
#define __NETPGP_EXTRA_H__
|
#define __NETPGP_EXTRA_H__
|
||||||
|
|
||||||
|
#include "netpgp/config-netpgp.h"
|
||||||
#include <netpgp.h>
|
#include <netpgp.h>
|
||||||
#include "packet-parse.h"
|
#include "netpgp/packet-parse.h"
|
||||||
#include "errors-netpgp.h"
|
#include "netpgp/errors.h"
|
||||||
#include "netpgpdefs.h"
|
#include "netpgp/defs.h"
|
||||||
#include "crypto-netpgp.h"
|
#include "netpgp/crypto.h"
|
||||||
#include "create-netpgp.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);
|
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__
|
#endif // __NETPGP_EXTRA_H__
|
|
@ -57,9 +57,6 @@ typedef struct netpgp_t {
|
||||||
int netpgp_init(netpgp_t *);
|
int netpgp_init(netpgp_t *);
|
||||||
int netpgp_end(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 *);
|
const char *netpgp_get_info(const char *);
|
||||||
int netpgp_list_packets(netpgp_t *, char *, int, 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 *);
|
int netpgp_find_key(netpgp_t *, char *);
|
||||||
char *netpgp_get_key(netpgp_t *, const char *, const char *);
|
char *netpgp_get_key(netpgp_t *, const char *, const char *);
|
||||||
char *netpgp_export_key(netpgp_t *, 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_import_key(netpgp_t *, char *);
|
||||||
int netpgp_generate_key(netpgp_t *, char *, int);
|
int netpgp_generate_key(netpgp_t *, char *, int);
|
||||||
|
|
160
libs/netpgp/include/netpgp/config-pep.h
Normal file
160
libs/netpgp/include/netpgp/config-pep.h
Normal 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
|
|
@ -52,13 +52,13 @@
|
||||||
#ifndef CREATE_H_
|
#ifndef CREATE_H_
|
||||||
#define CREATE_H_
|
#define CREATE_H_
|
||||||
|
|
||||||
#include "types-netpgp.h"
|
#include "types.h"
|
||||||
#include "packet-netpgp.h"
|
#include "packet.h"
|
||||||
#include "crypto-netpgp.h"
|
#include "crypto.h"
|
||||||
#include "errors-netpgp.h"
|
#include "errors.h"
|
||||||
#include "keyring-netpgp.h"
|
#include "keyring.h"
|
||||||
#include "writer-netpgp.h"
|
#include "writer.h"
|
||||||
#include "memory-netpgp.h"
|
#include "memory.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \ingroup Create
|
* \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_calc_sesskey_checksum(pgp_pk_sesskey_t *, uint8_t *);
|
||||||
unsigned pgp_write_struct_userid(pgp_output_t *, const 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 *,
|
unsigned pgp_write_struct_seckey(const pgp_seckey_t *,
|
||||||
const uint8_t *,
|
const uint8_t *,
|
||||||
const size_t,
|
const size_t,
|
||||||
pgp_output_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 *,
|
unsigned pgp_write_one_pass_sig(pgp_output_t *,
|
||||||
const pgp_seckey_t *,
|
const pgp_seckey_t *,
|
||||||
const pgp_hash_alg_t,
|
const pgp_hash_alg_t,
|
||||||
|
@ -91,15 +97,11 @@ unsigned pgp_write_litdata(pgp_output_t *,
|
||||||
const uint8_t *,
|
const uint8_t *,
|
||||||
const int,
|
const int,
|
||||||
const pgp_litdata_enum);
|
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_pk_sesskey(pgp_output_t *, pgp_pk_sesskey_t *);
|
||||||
unsigned pgp_write_xfer_pubkey(pgp_output_t *,
|
unsigned pgp_write_xfer_key(pgp_output_t *output,
|
||||||
const pgp_key_t *, const unsigned);
|
const pgp_key_t *key,
|
||||||
unsigned pgp_write_xfer_seckey(pgp_output_t *,
|
const unsigned armoured);
|
||||||
const pgp_key_t *,
|
|
||||||
const uint8_t *,
|
|
||||||
const size_t,
|
|
||||||
const unsigned);
|
|
||||||
|
|
||||||
void pgp_fast_create_userid(uint8_t **, uint8_t *);
|
void pgp_fast_create_userid(uint8_t **, uint8_t *);
|
||||||
unsigned pgp_write_userid(const uint8_t *, pgp_output_t *);
|
unsigned pgp_write_userid(const uint8_t *, pgp_output_t *);
|
|
@ -53,9 +53,9 @@
|
||||||
#ifndef CRYPTO_H_
|
#ifndef CRYPTO_H_
|
||||||
#define CRYPTO_H_
|
#define CRYPTO_H_
|
||||||
|
|
||||||
#include "keyring-netpgp.h"
|
#include "keyring.h"
|
||||||
#include "packet-netpgp.h"
|
#include "packet.h"
|
||||||
#include "memory-netpgp.h"
|
#include "memory.h"
|
||||||
#include "packet-parse.h"
|
#include "packet-parse.h"
|
||||||
|
|
||||||
#include <openssl/dsa.h>
|
#include <openssl/dsa.h>
|
||||||
|
@ -100,6 +100,17 @@ struct pgp_crypt_t {
|
||||||
void *decrypt_key;
|
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_crypto_finish(void);
|
||||||
void pgp_hash_md5(pgp_hash_t *);
|
void pgp_hash_md5(pgp_hash_t *);
|
||||||
void pgp_hash_sha1(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_sha512(pgp_hash_t *);
|
||||||
void pgp_hash_sha384(pgp_hash_t *);
|
void pgp_hash_sha384(pgp_hash_t *);
|
||||||
void pgp_hash_sha224(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 *);
|
pgp_hash_alg_t pgp_str_to_hash_alg(const char *);
|
||||||
const char *pgp_text_from_hash(pgp_hash_t *);
|
const char *pgp_text_from_hash(pgp_hash_t *);
|
||||||
unsigned pgp_hash_size(pgp_hash_alg_t);
|
unsigned pgp_hash_size(pgp_hash_alg_t);
|
||||||
|
@ -190,8 +201,8 @@ unsigned pgp_decrypt_file(pgp_io_t *,
|
||||||
|
|
||||||
pgp_memory_t *
|
pgp_memory_t *
|
||||||
pgp_encrypt_buf(pgp_io_t *, const void *, const size_t,
|
pgp_encrypt_buf(pgp_io_t *, const void *, const size_t,
|
||||||
const pgp_key_t *,
|
const pgp_keyring_t *,
|
||||||
const unsigned, const char *);
|
const unsigned, const char *, unsigned);
|
||||||
pgp_memory_t *
|
pgp_memory_t *
|
||||||
pgp_decrypt_buf(pgp_io_t *,
|
pgp_decrypt_buf(pgp_io_t *,
|
||||||
const void *,
|
const void *,
|
||||||
|
@ -204,18 +215,35 @@ pgp_decrypt_buf(pgp_io_t *,
|
||||||
int,
|
int,
|
||||||
pgp_cbfunc_t *);
|
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 */
|
/* Keys */
|
||||||
pgp_key_t *pgp_rsa_new_selfsign_key(const int,
|
pgp_key_t *pgp_rsa_new_selfsign_key(const int,
|
||||||
const unsigned long, const uint8_t *, const char *,
|
const unsigned long, const uint8_t *, const char *,
|
||||||
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 *);
|
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_seckey_t *,
|
||||||
const pgp_dsa_pubkey_t *);
|
const pgp_dsa_pubkey_t *);
|
||||||
|
|
||||||
int openssl_read_pem_seckey(const char *, pgp_key_t *, const char *, int);
|
|
||||||
|
|
||||||
/** pgp_reader_t */
|
/** pgp_reader_t */
|
||||||
struct pgp_reader_t {
|
struct pgp_reader_t {
|
||||||
pgp_reader_func_t *reader; /* reader func to get parse data */
|
pgp_reader_func_t *reader; /* reader func to get parse data */
|
||||||
|
@ -228,6 +256,13 @@ struct pgp_reader_t {
|
||||||
unsigned position; /* reader-specific offset */
|
unsigned position; /* reader-specific offset */
|
||||||
pgp_reader_t *next;
|
pgp_reader_t *next;
|
||||||
pgp_stream_t *parent;/* parent parse_info structure */
|
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 {
|
struct pgp_cryptinfo_t {
|
||||||
char *passphrase;
|
char *passphrase;
|
||||||
pgp_keyring_t *secring;
|
pgp_keyring_t *secring;
|
||||||
const pgp_key_t *keydata;
|
pgp_key_t *keydata;
|
||||||
pgp_cbfunc_t *getpassphrase;
|
pgp_cbfunc_t *getpassphrase;
|
||||||
pgp_keyring_t *pubring;
|
pgp_keyring_t *pubring;
|
||||||
|
DYNARRAY(key_id_t, recipients_key_ids);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** pgp_cbdata_t */
|
/** pgp_cbdata_t */
|
||||||
|
@ -301,15 +337,10 @@ struct pgp_stream_t {
|
||||||
pgp_cryptinfo_t cryptinfo;
|
pgp_cryptinfo_t cryptinfo;
|
||||||
size_t hashc;
|
size_t hashc;
|
||||||
pgp_hashtype_t *hashes;
|
pgp_hashtype_t *hashes;
|
||||||
unsigned reading_v3_secret:1;
|
//unsigned reading_v3_secret:1;
|
||||||
unsigned reading_mpi_len:1;
|
//unsigned reading_mpi_len:1;
|
||||||
unsigned exact_read:1;
|
//unsigned exact_read:1;
|
||||||
unsigned partial_read:1;
|
|
||||||
unsigned coalescing:1;
|
|
||||||
/* used for partial length coalescing */
|
|
||||||
unsigned virtualc;
|
|
||||||
unsigned virtualoff;
|
|
||||||
uint8_t *virtualpkt;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* CRYPTO_H_ */
|
#endif /* CRYPTO_H_ */
|
|
@ -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.
|
* Copyright (c) 2009 The NetBSD Foundation, Inc.
|
206
libs/netpgp/include/netpgp/keyring.h
Normal file
206
libs/netpgp/include/netpgp/keyring.h
Normal 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_ */
|
|
@ -54,7 +54,7 @@
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include "packet-netpgp.h"
|
#include "packet.h"
|
||||||
|
|
||||||
/** pgp_memory_t
|
/** pgp_memory_t
|
||||||
*/
|
*/
|
|
@ -65,8 +65,4 @@ void *pgp_new(size_t);
|
||||||
} \
|
} \
|
||||||
} while(/* CONSTCOND */0)
|
} while(/* CONSTCOND */0)
|
||||||
|
|
||||||
#ifndef MIN
|
|
||||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* !NETPGPDEFS_H_ */
|
#endif /* !NETPGPDEFS_H_ */
|
|
@ -50,6 +50,7 @@
|
||||||
/* SHA1 Hash Size */
|
/* SHA1 Hash Size */
|
||||||
#define PGP_SHA1_HASH_SIZE SHA_DIGEST_LENGTH
|
#define PGP_SHA1_HASH_SIZE SHA_DIGEST_LENGTH
|
||||||
#define PGP_SHA256_HASH_SIZE SHA256_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
|
#define PGP_CHECKHASH_SIZE PGP_SHA1_HASH_SIZE
|
||||||
|
|
||||||
#endif /* NETPGPDIGEST_H_ */
|
#endif /* NETPGPDIGEST_H_ */
|
|
@ -29,34 +29,17 @@
|
||||||
#ifndef NETPGPSDK_H_
|
#ifndef NETPGPSDK_H_
|
||||||
#define NETPGPSDK_H_
|
#define NETPGPSDK_H_
|
||||||
|
|
||||||
#include "keyring-netpgp.h"
|
#include "keyring.h"
|
||||||
#include "crypto-netpgp.h"
|
#include "crypto.h"
|
||||||
#include "signature-netpgp.h"
|
#include "signature.h"
|
||||||
#include "packet-show.h"
|
#include "packet-show.h"
|
||||||
|
|
||||||
#ifndef __printflike
|
#ifndef __printflike
|
||||||
#define __printflike(n, m) __attribute__((format(printf,n,m)))
|
#define __printflike(n, m) __attribute__((format(printf,n,m)))
|
||||||
#endif
|
#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 *);
|
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
|
unsigned
|
||||||
pgp_validate_all_sigs(pgp_validation_t *,
|
pgp_validate_all_sigs(pgp_validation_t *,
|
||||||
const pgp_keyring_t *,
|
const pgp_keyring_t *,
|
||||||
|
@ -74,5 +57,4 @@ void netpgp_log(const char *, ...) __printflike(1, 2);
|
||||||
int netpgp_strcasecmp(const char *, const char *);
|
int netpgp_strcasecmp(const char *, const char *);
|
||||||
char *netpgp_strdup(const char *);
|
char *netpgp_strdup(const char *);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
133
libs/netpgp/include/netpgp/openssl11stub.h
Normal file
133
libs/netpgp/include/netpgp/openssl11stub.h
Normal 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;
|
||||||
|
}
|
||||||
|
|
|
@ -54,8 +54,8 @@
|
||||||
#ifndef PACKET_PARSE_H_
|
#ifndef PACKET_PARSE_H_
|
||||||
#define PACKET_PARSE_H_
|
#define PACKET_PARSE_H_
|
||||||
|
|
||||||
#include "types-netpgp.h"
|
#include "types.h"
|
||||||
#include "packet-netpgp.h"
|
#include "packet.h"
|
||||||
|
|
||||||
/** pgp_region_t */
|
/** pgp_region_t */
|
||||||
typedef struct 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 *,
|
unsigned pgp_writez(pgp_output_t *, const uint8_t *,
|
||||||
const unsigned);
|
const unsigned);
|
||||||
|
|
||||||
|
void
|
||||||
|
copy_sig_info(pgp_sig_info_t *dst, const pgp_sig_info_t *src);
|
||||||
|
|
||||||
#endif /* PACKET_PARSE_H_ */
|
#endif /* PACKET_PARSE_H_ */
|
|
@ -53,7 +53,7 @@
|
||||||
#ifndef PACKET_SHOW_H_
|
#ifndef PACKET_SHOW_H_
|
||||||
#define PACKET_SHOW_H_
|
#define PACKET_SHOW_H_
|
||||||
|
|
||||||
#include "packet-netpgp.h"
|
#include "packet.h"
|
||||||
|
|
||||||
/** pgp_list_t
|
/** 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_sig_type(pgp_sig_type_t);
|
||||||
const char *pgp_show_pka(pgp_pubkey_alg_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);
|
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_hash_alg(uint8_t);
|
||||||
const char *pgp_show_symm_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_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 *);
|
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 *);
|
const char *pgp_show_keyserv_pref(uint8_t, pgp_bit_map_t *);
|
||||||
|
|
||||||
pgp_text_t *pgp_showall_notation(pgp_ss_notation_t);
|
pgp_text_t *pgp_showall_notation(pgp_ss_notation_t);
|
|
@ -54,16 +54,16 @@
|
||||||
#ifndef PACKET_H_
|
#ifndef PACKET_H_
|
||||||
#define PACKET_H_
|
#define PACKET_H_
|
||||||
|
|
||||||
#include "config-netpgp.h"
|
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL_BN_H
|
#ifdef HAVE_OPENSSL_BN_H
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "types-netpgp.h"
|
#include <openssl/ossl_typ.h>
|
||||||
#include "errors-netpgp.h"
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "errors.h"
|
||||||
|
|
||||||
/* structure to keep track of printing state variables */
|
/* structure to keep track of printing state variables */
|
||||||
typedef struct pgp_printstate_t {
|
typedef struct pgp_printstate_t {
|
||||||
|
@ -620,6 +620,8 @@ typedef struct pgp_sig_info_t {
|
||||||
pgp_sig_type_t type; /* signature type value */
|
pgp_sig_type_t type; /* signature type value */
|
||||||
time_t birthtime; /* creation time of the signature */
|
time_t birthtime; /* creation time of the signature */
|
||||||
time_t duration; /* number of seconds it's valid for */
|
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
|
uint8_t signer_id[PGP_KEY_ID_SIZE]; /* Eight-octet key ID
|
||||||
* of signer */
|
* of signer */
|
||||||
pgp_pubkey_alg_t key_alg; /* public key algorithm number */
|
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 birthtime_set:1;
|
||||||
unsigned signer_id_set:1;
|
unsigned signer_id_set:1;
|
||||||
unsigned duration_set:1;
|
unsigned duration_set:1;
|
||||||
|
unsigned key_expiry_set:1;
|
||||||
|
unsigned key_flags_set:1;
|
||||||
|
unsigned primary_userid:1;
|
||||||
} pgp_sig_info_t;
|
} 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 */
|
/** Struct used when parsing a signature */
|
||||||
typedef struct pgp_sig_t {
|
typedef struct pgp_sig_t {
|
||||||
pgp_sig_info_t info; /* The signature information */
|
pgp_sig_info_t info; /* The signature information */
|
||||||
|
@ -789,9 +804,10 @@ typedef union {
|
||||||
} pgp_pk_sesskey_params_t;
|
} pgp_pk_sesskey_params_t;
|
||||||
|
|
||||||
/** pgp_pk_sesskey_t */
|
/** pgp_pk_sesskey_t */
|
||||||
|
typedef uint8_t key_id_t[PGP_KEY_ID_SIZE];
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned version;
|
unsigned version;
|
||||||
uint8_t key_id[PGP_KEY_ID_SIZE];
|
key_id_t key_id;
|
||||||
pgp_pubkey_alg_t alg;
|
pgp_pubkey_alg_t alg;
|
||||||
pgp_pk_sesskey_params_t params;
|
pgp_pk_sesskey_params_t params;
|
||||||
pgp_symm_alg_t symm_alg;
|
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_finish(void);
|
||||||
void pgp_pubkey_free(pgp_pubkey_t *);
|
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_userid_free(uint8_t **);
|
||||||
void pgp_data_free(pgp_data_t *);
|
void pgp_data_free(pgp_data_t *);
|
||||||
void pgp_sig_free(pgp_sig_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_subpacket_free(pgp_subpacket_t *);
|
||||||
void pgp_parser_content_free(pgp_packet_t *);
|
void pgp_parser_content_free(pgp_packet_t *);
|
||||||
void pgp_seckey_free(pgp_seckey_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 *);
|
void pgp_pk_sesskey_free(pgp_pk_sesskey_t *);
|
||||||
|
|
||||||
int pgp_print_packet(pgp_printstate_t *, const pgp_packet_t *);
|
|
||||||
|
|
||||||
#define DYNARRAY(type, arr) \
|
#define DYNARRAY(type, arr) \
|
||||||
unsigned arr##c; unsigned arr##vsize; type *arr##s
|
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)
|
} 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
|
/** pgp_keydata_key_t
|
||||||
*/
|
*/
|
||||||
typedef union {
|
typedef union {
|
||||||
|
@ -928,47 +959,59 @@ typedef union {
|
||||||
pgp_seckey_t seckey;
|
pgp_seckey_t seckey;
|
||||||
} pgp_keydata_key_t;
|
} pgp_keydata_key_t;
|
||||||
|
|
||||||
|
/** userid signature subpackets */
|
||||||
/* sigpacket_t */
|
typedef struct pgp_uidsig_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 {
|
|
||||||
uint32_t uid; /* index in userid array in key */
|
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 trustlevel; /* level of trust */
|
||||||
uint8_t trustamount; /* amount 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 */
|
/* describes a user's key */
|
||||||
struct pgp_key_t {
|
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_content_enum type; /* type of key */
|
||||||
pgp_keydata_key_t key; /* pubkey/seckey data */
|
pgp_keydata_key_t key; /* pubkey/seckey data */
|
||||||
pgp_pubkey_t sigkey; /* signature key */
|
|
||||||
uint8_t sigid[PGP_KEY_ID_SIZE];
|
DYNARRAY(pgp_directsig_t, directsig); /* direct signatures */
|
||||||
pgp_fingerprint_t sigfingerprint; /* pgp signature fingerprint */
|
|
||||||
pgp_pubkey_t enckey; /* encryption key */
|
DYNARRAY(uint8_t *, uid); /* array of user ids */
|
||||||
uint8_t encid[PGP_KEY_ID_SIZE];
|
DYNARRAY(pgp_uidsig_t, uidsig); /* array of signature for user ids */
|
||||||
pgp_fingerprint_t encfingerprint; /* pgp encryption id fingerprint */
|
|
||||||
uint32_t uid0; /* primary uid index in uids array */
|
/* TODO user attributes */
|
||||||
uint8_t revoked; /* key has been revoked */
|
|
||||||
pgp_revoke_t revocation; /* revocation reason */
|
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_ */
|
#endif /* PACKET_H_ */
|
|
@ -50,9 +50,9 @@
|
||||||
#ifndef READERWRITER_H_
|
#ifndef READERWRITER_H_
|
||||||
#define 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 */
|
/* if this is defined, we'll use mmap in preference to file ops */
|
||||||
#define USE_MMAP_FOR_FILES 1
|
#define USE_MMAP_FOR_FILES 1
|
||||||
|
@ -75,7 +75,7 @@ unsigned pgp_write_se_ip_pktset(pgp_output_t *, const uint8_t *,
|
||||||
const unsigned,
|
const unsigned,
|
||||||
pgp_crypt_t *);
|
pgp_crypt_t *);
|
||||||
void pgp_push_enc_crypt(pgp_output_t *, 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 */
|
/* Secret Key checksum */
|
||||||
void pgp_push_checksum_writer(pgp_output_t *, pgp_seckey_t *);
|
void pgp_push_checksum_writer(pgp_output_t *, pgp_seckey_t *);
|
|
@ -57,9 +57,9 @@
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
#include "packet-netpgp.h"
|
#include "packet.h"
|
||||||
#include "create-netpgp.h"
|
#include "create.h"
|
||||||
#include "memory-netpgp.h"
|
#include "memory.h"
|
||||||
|
|
||||||
typedef struct pgp_create_sig_t pgp_create_sig_t;
|
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 *,
|
unsigned pgp_check_useridcert_sig(const pgp_pubkey_t *,
|
||||||
const uint8_t *,
|
const uint8_t *,
|
||||||
const pgp_sig_t *,
|
const pgp_sig_t *,
|
||||||
const pgp_pubkey_t *,
|
const pgp_pubkey_t *);
|
||||||
const uint8_t *);
|
|
||||||
unsigned pgp_check_userattrcert_sig(const pgp_pubkey_t *,
|
unsigned pgp_check_userattrcert_sig(const pgp_pubkey_t *,
|
||||||
const pgp_data_t *,
|
const pgp_data_t *,
|
||||||
const pgp_sig_t *,
|
const pgp_sig_t *,
|
||||||
const pgp_pubkey_t *,
|
const pgp_pubkey_t *);
|
||||||
const uint8_t *);
|
|
||||||
unsigned pgp_check_subkey_sig(const pgp_pubkey_t *,
|
unsigned pgp_check_subkey_sig(const pgp_pubkey_t *,
|
||||||
const pgp_pubkey_t *,
|
const pgp_pubkey_t *,
|
||||||
const pgp_sig_t *,
|
const pgp_sig_t *,
|
||||||
const pgp_pubkey_t *,
|
const pgp_pubkey_t *);
|
||||||
const uint8_t *);
|
|
||||||
unsigned pgp_check_direct_sig(const pgp_pubkey_t *,
|
unsigned pgp_check_direct_sig(const pgp_pubkey_t *,
|
||||||
const pgp_sig_t *,
|
const pgp_sig_t *,
|
||||||
const pgp_pubkey_t *,
|
const pgp_pubkey_t *);
|
||||||
const uint8_t *);
|
|
||||||
unsigned pgp_check_hash_sig(pgp_hash_t *,
|
unsigned pgp_check_hash_sig(pgp_hash_t *,
|
||||||
const pgp_sig_t *,
|
const pgp_sig_t *,
|
||||||
const pgp_pubkey_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_end_hashed_subpkts(pgp_create_sig_t *);
|
||||||
unsigned pgp_write_sig(pgp_output_t *, pgp_create_sig_t *,
|
unsigned pgp_write_sig(pgp_output_t *, pgp_create_sig_t *,
|
||||||
const pgp_pubkey_t *, const pgp_seckey_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 *,
|
unsigned pgp_add_issuer_keyid(pgp_create_sig_t *,
|
||||||
const uint8_t *);
|
const uint8_t *);
|
||||||
void pgp_add_primary_userid(pgp_create_sig_t *, unsigned);
|
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 */
|
/* Standard Interface */
|
||||||
unsigned pgp_sign_file(pgp_io_t *,
|
unsigned pgp_sign_file(pgp_io_t *,
|
||||||
const char *,
|
const char *,
|
||||||
const char *,
|
const char *,
|
||||||
const pgp_seckey_t *,
|
const pgp_seckey_t *,
|
||||||
const char *,
|
const char *,
|
||||||
const int64_t,
|
const time_t,
|
||||||
const uint64_t,
|
const time_t,
|
||||||
const unsigned,
|
const unsigned,
|
||||||
const unsigned,
|
const unsigned,
|
||||||
const unsigned);
|
const unsigned);
|
||||||
|
@ -122,10 +130,10 @@ unsigned pgp_sign_file(pgp_io_t *,
|
||||||
int pgp_sign_detached(pgp_io_t *,
|
int pgp_sign_detached(pgp_io_t *,
|
||||||
const char *,
|
const char *,
|
||||||
char *,
|
char *,
|
||||||
pgp_seckey_t *,
|
const pgp_seckey_t *,
|
||||||
const char *,
|
const char *,
|
||||||
const int64_t,
|
const time_t,
|
||||||
const uint64_t,
|
const time_t,
|
||||||
const unsigned,
|
const unsigned,
|
||||||
const unsigned);
|
const unsigned);
|
||||||
|
|
||||||
|
@ -157,15 +165,33 @@ pgp_memory_t *pgp_sign_buf(pgp_io_t *,
|
||||||
const void *,
|
const void *,
|
||||||
const size_t,
|
const size_t,
|
||||||
const pgp_seckey_t *,
|
const pgp_seckey_t *,
|
||||||
const int64_t,
|
const time_t,
|
||||||
const uint64_t,
|
const time_t,
|
||||||
const char *,
|
const char *,
|
||||||
const unsigned,
|
const unsigned,
|
||||||
const unsigned);
|
const unsigned);
|
||||||
|
|
||||||
unsigned pgp_keyring_read_from_mem(pgp_io_t *,
|
/** \ingroup Core_Create
|
||||||
pgp_keyring_t *,
|
* needed for signature creation
|
||||||
const unsigned,
|
*/
|
||||||
pgp_memory_t *);
|
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_ */
|
#endif /* SIGNATURE_H_ */
|
|
@ -49,8 +49,6 @@
|
||||||
#ifndef TYPES_H_
|
#ifndef TYPES_H_
|
||||||
#define TYPES_H_
|
#define TYPES_H_
|
||||||
|
|
||||||
#include "config-netpgp.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_INTTYPES_H
|
#ifdef HAVE_INTTYPES_H
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#endif
|
#endif
|
|
@ -49,29 +49,36 @@
|
||||||
#ifndef VALIDATE_H_
|
#ifndef VALIDATE_H_
|
||||||
#define VALIDATE_H_ 1
|
#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 */
|
/** Struct used with the validate_key_cb callback */
|
||||||
typedef struct {
|
typedef struct validate_key_cb_t{
|
||||||
pgp_pubkey_t pubkey;
|
pgp_content_enum type; /* type of key */
|
||||||
pgp_pubkey_t subkey;
|
pgp_keydata_key_t key; /* pubkey/seckey data */
|
||||||
pgp_seckey_t seckey;
|
pgp_keydata_key_t subkey;
|
||||||
|
uint8_t pubkeyid[PGP_KEY_ID_SIZE];
|
||||||
enum {
|
enum {
|
||||||
ATTRIBUTE = 1,
|
LS_UNKNOWN = 0,
|
||||||
ID
|
LS_ATTRIBUTE,
|
||||||
|
LS_ID,
|
||||||
|
LS_SUBKEY,
|
||||||
|
LS_PRIMARY,
|
||||||
} last_seen;
|
} last_seen;
|
||||||
|
|
||||||
uint8_t *userid;
|
uint8_t *userid;
|
||||||
pgp_data_t userattr;
|
pgp_data_t userattr;
|
||||||
uint8_t hash[PGP_MAX_HASH_SIZE];
|
uint8_t hash[PGP_MAX_HASH_SIZE];
|
||||||
const pgp_keyring_t *keyring;
|
const pgp_keyring_t *keyring;
|
||||||
validate_reader_t *reader;
|
|
||||||
pgp_validation_t *result;
|
pgp_validation_t *result;
|
||||||
pgp_cb_ret_t(*getpassphrase) (const pgp_packet_t *,
|
pgp_cb_ret_t(*getpassphrase) (const pgp_packet_t *,
|
||||||
pgp_cbdata_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;
|
} validate_key_cb_t;
|
||||||
|
|
||||||
/** Struct use with the validate_data_cb callback */
|
/** Struct use with the validate_data_cb callback */
|
||||||
|
@ -87,13 +94,10 @@ typedef struct {
|
||||||
uint8_t hash[PGP_MAX_HASH_SIZE];
|
uint8_t hash[PGP_MAX_HASH_SIZE];
|
||||||
pgp_memory_t *mem;
|
pgp_memory_t *mem;
|
||||||
const pgp_keyring_t *keyring;
|
const pgp_keyring_t *keyring;
|
||||||
validate_reader_t *reader;/* reader-specific arg */
|
|
||||||
pgp_validation_t *result;
|
pgp_validation_t *result;
|
||||||
char *detachname;
|
char *detachname;
|
||||||
} validate_data_cb_t;
|
} 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 *);
|
pgp_cb_ret_t pgp_validate_key_cb(const pgp_packet_t *, pgp_cbdata_t *);
|
||||||
|
|
||||||
unsigned check_binary_sig(const uint8_t *,
|
unsigned check_binary_sig(const uint8_t *,
|
||||||
|
@ -115,6 +119,30 @@ unsigned pgp_validate_mem(pgp_io_t *,
|
||||||
const int,
|
const int,
|
||||||
const pgp_keyring_t *);
|
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_ */
|
#endif /* !VALIDATE_H_ */
|
|
@ -58,9 +58,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* development versions have .99 suffix */
|
/* 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 \
|
#define NETPGP_VERSION_STRING \
|
||||||
NETPGP_VERSION_CAT(NETPGP_BASE_VERSION, NETPGP_AUTOCONF_VERSION)
|
NETPGP_VERSION_CAT(NETPGP_BASE_VERSION, NETPGP_AUTOCONF_VERSION)
|
||||||
|
|
|
@ -53,11 +53,11 @@
|
||||||
#ifndef WRITER_H_
|
#ifndef WRITER_H_
|
||||||
#define WRITER_H_
|
#define WRITER_H_
|
||||||
|
|
||||||
#include "types-netpgp.h"
|
#include "types.h"
|
||||||
#include "packet-netpgp.h"
|
#include "packet.h"
|
||||||
#include "crypto-netpgp.h"
|
#include "crypto.h"
|
||||||
#include "errors-netpgp.h"
|
#include "errors.h"
|
||||||
#include "keyring-netpgp.h"
|
#include "keyring.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \ingroup Writer
|
* \ingroup Writer
|
||||||
|
@ -114,6 +114,10 @@ unsigned pgp_write_mpi(pgp_output_t *, const BIGNUM *);
|
||||||
void pgp_writer_info_delete(pgp_writer_t *);
|
void pgp_writer_info_delete(pgp_writer_t *);
|
||||||
unsigned pgp_writer_info_finalise(pgp_error_t **, 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_ */
|
#endif /* WRITER_H_ */
|
|
@ -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
653
libs/netpgp/mj.c
653
libs/netpgp/mj.c
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
|
|
1978
libs/netpgp/netpgp.c
1978
libs/netpgp/netpgp.c
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -49,7 +49,7 @@
|
||||||
|
|
||||||
/** \file
|
/** \file
|
||||||
*/
|
*/
|
||||||
#include "config-netpgp.h"
|
#include "netpgp/config-netpgp.h"
|
||||||
|
|
||||||
#ifdef HAVE_SYS_CDEFS_H
|
#ifdef HAVE_SYS_CDEFS_H
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
|
|
||||||
#if defined(__NetBSD__)
|
#if defined(__NetBSD__)
|
||||||
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
|
__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
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_ZLIB_H
|
#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 <string.h>
|
||||||
|
|
||||||
#include "packet-parse.h"
|
#include "netpgp/packet-parse.h"
|
||||||
#include "errors-netpgp.h"
|
#include "netpgp/errors.h"
|
||||||
#include "netpgpdefs.h"
|
#include "netpgp/netpgpdefs.h"
|
||||||
#include "crypto-netpgp.h"
|
#include "netpgp/crypto.h"
|
||||||
#include "memory-netpgp.h"
|
#include "netpgp/memory.h"
|
||||||
#include "writer-netpgp.h"
|
#include "netpgp/writer.h"
|
||||||
|
|
||||||
#define DECOMPRESS_BUFFER 1024
|
#define DECOMPRESS_BUFFER 1024
|
||||||
|
|
||||||
|
@ -188,8 +188,9 @@ zlib_compressed_data_reader(pgp_stream_t *stream, void *dest, size_t length,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
len = (size_t)(z->zstream.next_out - &z->out[z->offset]);
|
len = (size_t)(z->zstream.next_out - &z->out[z->offset]);
|
||||||
if (len > length) {
|
size_t left_in_cdest = length - cc;
|
||||||
len = length;
|
if (len > left_in_cdest) {
|
||||||
|
len = left_in_cdest;
|
||||||
}
|
}
|
||||||
(void) memcpy(&cdest[cc], &z->out[z->offset], len);
|
(void) memcpy(&cdest[cc], &z->out[z->offset], len);
|
||||||
z->offset += len;
|
z->offset += len;
|
|
@ -49,7 +49,7 @@
|
||||||
|
|
||||||
/** \file
|
/** \file
|
||||||
*/
|
*/
|
||||||
#include "config-netpgp.h"
|
#include "netpgp/config-netpgp.h"
|
||||||
|
|
||||||
#ifdef HAVE_SYS_CDEFS_H
|
#ifdef HAVE_SYS_CDEFS_H
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
|
|
||||||
#if defined(__NetBSD__)
|
#if defined(__NetBSD__)
|
||||||
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
|
__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
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#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>
|
#include <openssl/cast.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "create-netpgp.h"
|
#include "netpgp/create.h"
|
||||||
#include "keyring-netpgp.h"
|
#include "netpgp/keyring.h"
|
||||||
#include "packet-netpgp.h"
|
#include "netpgp/packet.h"
|
||||||
#include "signature-netpgp.h"
|
#include "netpgp/signature.h"
|
||||||
#include "writer-netpgp.h"
|
#include "netpgp/writer.h"
|
||||||
#include "readerwriter-netpgp.h"
|
#include "netpgp/readerwriter.h"
|
||||||
#include "memory-netpgp.h"
|
#include "netpgp/memory.h"
|
||||||
#include "netpgpdefs.h"
|
#include "netpgp/netpgpdefs.h"
|
||||||
#include "netpgpdigest.h"
|
#include "netpgp/netpgpdigest.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \ingroup Core_Create
|
* \ingroup Core_Create
|
||||||
|
@ -98,10 +98,10 @@ __RCSID("$NetBSD: create.c,v 1.38 2010/11/15 08:03:39 agc Exp $");
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
pgp_write_ss_header(pgp_output_t *output,
|
pgp_write_ss_header(pgp_output_t *output,
|
||||||
unsigned length,
|
size_t length,
|
||||||
pgp_content_enum type)
|
pgp_content_enum type)
|
||||||
{
|
{
|
||||||
return pgp_write_length(output, length) &&
|
return pgp_write_length(output, (unsigned int)length) &&
|
||||||
pgp_write_scalar(output, (unsigned)(type -
|
pgp_write_scalar(output, (unsigned)(type -
|
||||||
(unsigned)PGP_PTAG_SIG_SUBPKT_BASE), 1);
|
(unsigned)PGP_PTAG_SIG_SUBPKT_BASE), 1);
|
||||||
}
|
}
|
||||||
|
@ -176,6 +176,11 @@ pubkey_length(const pgp_pubkey_t *key)
|
||||||
case PGP_PKA_RSA:
|
case PGP_PKA_RSA:
|
||||||
return mpi_length(key->key.rsa.n) + mpi_length(key->key.rsa.e);
|
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:
|
default:
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
"pubkey_length: unknown key algorithm\n");
|
"pubkey_length: unknown key algorithm\n");
|
||||||
|
@ -188,7 +193,6 @@ seckey_length(const pgp_seckey_t *key)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
len = 0;
|
|
||||||
switch (key->pubkey.alg) {
|
switch (key->pubkey.alg) {
|
||||||
case PGP_PKA_DSA:
|
case PGP_PKA_DSA:
|
||||||
return (unsigned)(mpi_length(key->key.dsa.x) + pubkey_length(&key->pubkey));
|
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);
|
mpi_length(key->key.rsa.q) + mpi_length(key->key.rsa.u);
|
||||||
|
|
||||||
return (unsigned)(len + pubkey_length(&key->pubkey));
|
return (unsigned)(len + pubkey_length(&key->pubkey));
|
||||||
|
|
||||||
|
case PGP_PKA_ELGAMAL:
|
||||||
|
return (unsigned)(
|
||||||
|
mpi_length(key->key.dsa.x) + pubkey_length(&key->pubkey));
|
||||||
|
|
||||||
default:
|
default:
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
"seckey_length: unknown key algorithm\n");
|
"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
|
* Note that we support v3 keys here because they're needed for
|
||||||
* verification.
|
* verification.
|
||||||
*/
|
*/
|
||||||
unsigned
|
static unsigned
|
||||||
write_seckey_body(const pgp_seckey_t *key,
|
write_seckey_body(const pgp_seckey_t *key,
|
||||||
const uint8_t *passphrase,
|
const uint8_t *passphrase,
|
||||||
const size_t pplen,
|
const size_t pplen,
|
||||||
|
@ -285,17 +294,17 @@ write_seckey_body(const pgp_seckey_t *key,
|
||||||
pgp_hash_t hash;
|
pgp_hash_t hash;
|
||||||
unsigned done = 0;
|
unsigned done = 0;
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
uint8_t *hashed;
|
|
||||||
uint8_t sesskey[CAST_KEY_LENGTH];
|
uint8_t sesskey[CAST_KEY_LENGTH];
|
||||||
|
|
||||||
if (!write_pubkey_body(&key->pubkey, output)) {
|
if (!write_pubkey_body(&key->pubkey, output)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (key->s2k_usage != PGP_S2KU_ENCRYPTED_AND_HASHED) {
|
if (!pgp_write_scalar(output, (unsigned)key->s2k_usage, 1)) {
|
||||||
(void) fprintf(stderr, "write_seckey_body: s2k usage\n");
|
|
||||||
return 0;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,6 +374,7 @@ write_seckey_body(const pgp_seckey_t *key,
|
||||||
unsigned needed;
|
unsigned needed;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
uint8_t zero = 0;
|
uint8_t zero = 0;
|
||||||
|
uint8_t *hashed;
|
||||||
|
|
||||||
/* Hard-coded SHA1 for session key */
|
/* Hard-coded SHA1 for session key */
|
||||||
pgp_hash_any(&hash, PGP_HASH_SHA1);
|
pgp_hash_any(&hash, PGP_HASH_SHA1);
|
||||||
|
@ -377,6 +387,7 @@ write_seckey_body(const pgp_seckey_t *key,
|
||||||
}
|
}
|
||||||
if (!hash.init(&hash)) {
|
if (!hash.init(&hash)) {
|
||||||
(void) fprintf(stderr, "write_seckey_body: bad alloc\n");
|
(void) fprintf(stderr, "write_seckey_body: bad alloc\n");
|
||||||
|
free(hashed);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,6 +416,7 @@ write_seckey_body(const pgp_seckey_t *key,
|
||||||
(void) memcpy(&sesskey[i * hashsize],
|
(void) memcpy(&sesskey[i * hashsize],
|
||||||
hashed, (unsigned)size);
|
hashed, (unsigned)size);
|
||||||
done += (unsigned)size;
|
done += (unsigned)size;
|
||||||
|
free(hashed);
|
||||||
if (done > CAST_KEY_LENGTH) {
|
if (done > CAST_KEY_LENGTH) {
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
"write_seckey_body: short add\n");
|
"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");
|
(void) fprintf(stderr, "\nturning encryption on...\n");
|
||||||
}
|
}
|
||||||
pgp_push_enc_crypt(output, &crypted);
|
pgp_push_enc_crypt(output, &crypted);
|
||||||
|
}else{
|
||||||
|
pgp_push_sum16_writer(output);
|
||||||
|
}
|
||||||
|
|
||||||
switch (key->pubkey.alg) {
|
switch (key->pubkey.alg) {
|
||||||
case PGP_PKA_RSA:
|
case PGP_PKA_RSA:
|
||||||
|
@ -463,11 +478,19 @@ write_seckey_body(const pgp_seckey_t *key,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (key->s2k_usage != PGP_S2KU_NONE) {
|
||||||
|
|
||||||
if (!pgp_write(output, key->checkhash, PGP_CHECKHASH_SIZE)) {
|
if (!pgp_write(output, key->checkhash, PGP_CHECKHASH_SIZE)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pgp_writer_pop(output);
|
pgp_writer_pop(output);
|
||||||
|
}else{
|
||||||
|
uint16_t checksum = pgp_pop_sum16_writer(output);
|
||||||
|
if (!pgp_write_scalar(output, checksum, 2)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -480,13 +503,20 @@ write_seckey_body(const pgp_seckey_t *key,
|
||||||
* \return 1 if OK, otherwise 0
|
* \return 1 if OK, otherwise 0
|
||||||
*/
|
*/
|
||||||
unsigned
|
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)) &&
|
pgp_write_length(output, 1 + 4 + 1 + pubkey_length(key)) &&
|
||||||
write_pubkey_body(key, output);
|
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
|
\ingroup HighLevel_KeyWrite
|
||||||
|
@ -500,40 +530,104 @@ write_struct_pubkey(pgp_output_t *output, const pgp_pubkey_t *key)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
pgp_write_xfer_pubkey(pgp_output_t *output,
|
pgp_write_xfer_key(pgp_output_t *output,
|
||||||
const pgp_key_t *key,
|
const pgp_key_t *key,
|
||||||
const unsigned armoured)
|
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) {
|
if (armoured) {
|
||||||
pgp_writer_push_armoured(output, PGP_PGP_PUBLIC_KEY_BLOCK);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
/* TODO: revocation signatures go here */
|
if (!pgp_write_struct_seckey(&key->key.seckey, (const uint8_t *)"", 0, output)) {
|
||||||
|
|
||||||
/* user ids and corresponding signatures */
|
|
||||||
for (i = 0; i < key->uidc; i++) {
|
|
||||||
if (!pgp_write_struct_userid(output, key->uids[i])) {
|
|
||||||
return 0;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: user attributes and corresponding signatures */
|
/* TODO attibutes */
|
||||||
|
|
||||||
/*
|
/* Loop over key's subkeys */
|
||||||
* subkey packets and corresponding signatures and optional
|
subkeyp = key->subkeys;
|
||||||
* revocation
|
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) {
|
if (armoured) {
|
||||||
pgp_writer_info_finalise(&output->errors, &output->writer);
|
pgp_writer_info_finalise(&output->errors, &output->writer);
|
||||||
|
@ -554,53 +648,15 @@ pgp_write_xfer_pubkey(pgp_output_t *output,
|
||||||
\param output Output stream
|
\param output Output stream
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
/* TODO have encrypted key export again
|
||||||
unsigned
|
unsigned
|
||||||
pgp_write_xfer_seckey(pgp_output_t *output,
|
pgp_write_xfer_seckey(pgp_output_t *output,
|
||||||
const pgp_key_t *key,
|
const pgp_key_t *key,
|
||||||
const uint8_t *passphrase,
|
const uint8_t *passphrase,
|
||||||
const size_t pplen,
|
const size_t pplen,
|
||||||
unsigned armoured)
|
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
|
* \ingroup Core_WritePackets
|
||||||
* \brief Writes one RSA public key packet.
|
* \brief Writes one RSA public key packet.
|
||||||
|
@ -620,7 +676,7 @@ pgp_write_rsa_pubkey(time_t t, const BIGNUM *n,
|
||||||
pgp_pubkey_t key;
|
pgp_pubkey_t key;
|
||||||
|
|
||||||
pgp_fast_create_rsa_pubkey(&key, t, __UNCONST(n), __UNCONST(e));
|
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
|
* \return 1 if OK; else 0
|
||||||
*/
|
*/
|
||||||
unsigned
|
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 uint8_t *passphrase,
|
||||||
const size_t pplen,
|
const size_t pplen,
|
||||||
pgp_output_t *output)
|
pgp_output_t *output,
|
||||||
|
pgp_content_enum ptag)
|
||||||
{
|
{
|
||||||
int length = 0;
|
int length = 0;
|
||||||
|
|
||||||
|
@ -709,7 +766,7 @@ pgp_write_struct_seckey(const pgp_seckey_t *key,
|
||||||
/* Ref: RFC4880 Section 5.5.3 */
|
/* Ref: RFC4880 Section 5.5.3 */
|
||||||
|
|
||||||
/* pubkey, excluding MPIs */
|
/* pubkey, excluding MPIs */
|
||||||
length += 1 + 4 + 1 + 1;
|
length += 1 + 4 + 1;
|
||||||
|
|
||||||
/* s2k usage */
|
/* s2k usage */
|
||||||
length += 1;
|
length += 1;
|
||||||
|
@ -776,12 +833,21 @@ pgp_write_struct_seckey(const pgp_seckey_t *key,
|
||||||
/* secret key and public key MPIs */
|
/* secret key and public key MPIs */
|
||||||
length += (unsigned)seckey_length(key);
|
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,1+4+1+1+seckey_length(key)+2) && */
|
||||||
pgp_write_length(output, (unsigned)length) &&
|
pgp_write_length(output, (unsigned)length) &&
|
||||||
write_seckey_body(key, passphrase, pplen, output);
|
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
|
* \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
|
\note Currently hard-coded to use RSA
|
||||||
*/
|
*/
|
||||||
pgp_pk_sesskey_t *
|
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
|
* 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
|
* can be any, we're hardcoding RSA for now
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const pgp_pubkey_t *pubkey;
|
pgp_pubkey_t *pubkey;
|
||||||
pgp_pk_sesskey_t *sesskey;
|
pgp_pk_sesskey_t *sesskey;
|
||||||
pgp_symm_alg_t cipher;
|
pgp_symm_alg_t cipher;
|
||||||
const uint8_t *id;
|
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;
|
uint8_t *encoded_m_buf;
|
||||||
size_t sz_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_key_get_enckey(key, &id);
|
||||||
pubkey = pgp_get_pubkey(key);
|
|
||||||
id = key->sigid;
|
|
||||||
} else {
|
|
||||||
pubkey = &key->enckey;
|
|
||||||
id = key->encid;
|
|
||||||
}
|
|
||||||
/* allocate unencoded_m_buf here */
|
/* allocate unencoded_m_buf here */
|
||||||
(void) memset(&cipherinfo, 0x0, sizeof(cipherinfo));
|
(void) memset(&cipherinfo, 0x0, sizeof(cipherinfo));
|
||||||
pgp_crypt_any(&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->alg = pubkey->alg;
|
||||||
|
|
||||||
sesskey->symm_alg = cipher;
|
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);
|
pgp_random(sesskey->key, cipherinfo.keysize);
|
||||||
|
}
|
||||||
|
|
||||||
if (pgp_get_debug_level(__FILE__)) {
|
if (pgp_get_debug_level(__FILE__)) {
|
||||||
hexdump(stderr, "sesskey created", sesskey->key,
|
hexdump(stderr, "sesskey created", sesskey->key,
|
|
@ -46,7 +46,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#include "config-netpgp.h"
|
#include "netpgp/config-netpgp.h"
|
||||||
|
|
||||||
#ifdef HAVE_SYS_CDEFS_H
|
#ifdef HAVE_SYS_CDEFS_H
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
|
|
||||||
#if defined(__NetBSD__)
|
#if defined(__NetBSD__)
|
||||||
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
|
__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
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#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 <string.h>
|
||||||
|
|
||||||
#include "types-netpgp.h"
|
#include "netpgp/types.h"
|
||||||
#include "crypto-netpgp.h"
|
#include "netpgp/crypto.h"
|
||||||
#include "readerwriter-netpgp.h"
|
#include "netpgp/readerwriter.h"
|
||||||
#include "memory-netpgp.h"
|
#include "netpgp/memory.h"
|
||||||
#include "netpgpdefs.h"
|
#include "netpgp/netpgpdefs.h"
|
||||||
#include "signature-netpgp.h"
|
#include "netpgp/signature.h"
|
||||||
|
#include "netpgp/netpgpsdk.h"
|
||||||
|
#include "netpgp/validate.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\ingroup Core_MPI
|
\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__)) {
|
if (pgp_get_debug_level(__FILE__)) {
|
||||||
printf("write_parsed_cb: ");
|
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) {
|
if (pkt->tag != PGP_PTAG_CT_UNARMOURED_TEXT && cbinfo->printstate.skipping) {
|
||||||
puts("...end of skip");
|
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);
|
return pgp_get_seckey_cb(pkt, cbinfo);
|
||||||
|
|
||||||
case PGP_GET_PASSPHRASE:
|
case PGP_GET_PASSPHRASE:
|
||||||
|
if (cbinfo->cryptinfo.getpassphrase) {
|
||||||
return cbinfo->cryptinfo.getpassphrase(pkt, cbinfo);
|
return cbinfo->cryptinfo.getpassphrase(pkt, cbinfo);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case PGP_PTAG_CT_LITDATA_BODY:
|
case PGP_PTAG_CT_LITDATA_BODY:
|
||||||
return pgp_litdata_cb(pkt, cbinfo);
|
return pgp_litdata_cb(pkt, cbinfo);
|
||||||
|
@ -356,6 +361,7 @@ pgp_encrypt_file(pgp_io_t *io,
|
||||||
{
|
{
|
||||||
pgp_output_t *output;
|
pgp_output_t *output;
|
||||||
pgp_memory_t *inmem;
|
pgp_memory_t *inmem;
|
||||||
|
pgp_keyring_t *rcpts;
|
||||||
int fd_out;
|
int fd_out;
|
||||||
|
|
||||||
__PGP_USED(io);
|
__PGP_USED(io);
|
||||||
|
@ -374,11 +380,23 @@ pgp_encrypt_file(pgp_io_t *io,
|
||||||
pgp_writer_push_armor_msg(output);
|
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 */
|
/* 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);
|
pgp_memory_free(inmem);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
pgp_keyring_free(rcpts);
|
||||||
|
|
||||||
/* This does the writing */
|
/* This does the writing */
|
||||||
pgp_write(output, pgp_mem_data(inmem), (unsigned)pgp_mem_len(inmem));
|
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,
|
pgp_encrypt_buf(pgp_io_t *io,
|
||||||
const void *input,
|
const void *input,
|
||||||
const size_t insize,
|
const size_t insize,
|
||||||
const pgp_key_t *pubkey,
|
const pgp_keyring_t *pubkeys,
|
||||||
const unsigned use_armour,
|
const unsigned use_armour,
|
||||||
const char *cipher)
|
const char *cipher,
|
||||||
|
unsigned raw)
|
||||||
{
|
{
|
||||||
pgp_output_t *output;
|
pgp_output_t *output;
|
||||||
pgp_memory_t *outmem;
|
pgp_memory_t *outmem;
|
||||||
|
@ -417,7 +436,7 @@ pgp_encrypt_buf(pgp_io_t *io,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Push the encrypted writer */
|
/* 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 */
|
/* This does the writing */
|
||||||
pgp_write(output, input, (unsigned)insize);
|
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 */
|
/* if we didn't get the passphrase, return NULL */
|
||||||
return (parse->cbinfo.gotpass) ? outmem : 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
1644
libs/netpgp/src/keyring.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -49,7 +49,7 @@
|
||||||
|
|
||||||
/** \file
|
/** \file
|
||||||
*/
|
*/
|
||||||
#include "config-netpgp.h"
|
#include "netpgp/config-netpgp.h"
|
||||||
|
|
||||||
#ifdef HAVE_SYS_CDEFS_H
|
#ifdef HAVE_SYS_CDEFS_H
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
|
|
||||||
#if defined(__NetBSD__)
|
#if defined(__NetBSD__)
|
||||||
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
|
__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
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#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>
|
#include <openssl/rand.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "errors-netpgp.h"
|
#include "netpgp/errors.h"
|
||||||
#include "packet-netpgp.h"
|
#include "netpgp/packet.h"
|
||||||
#include "crypto-netpgp.h"
|
#include "netpgp/crypto.h"
|
||||||
#include "create-netpgp.h"
|
#include "netpgp/create.h"
|
||||||
#include "packet-parse.h"
|
#include "netpgp/packet-parse.h"
|
||||||
#include "packet-show.h"
|
#include "netpgp/packet-show.h"
|
||||||
#include "signature-netpgp.h"
|
#include "netpgp/signature.h"
|
||||||
#include "netpgpsdk.h"
|
#include "netpgp/netpgpsdk.h"
|
||||||
#include "netpgpdefs.h"
|
#include "netpgp/netpgpdefs.h"
|
||||||
#include "memory-netpgp.h"
|
#include "netpgp/memory.h"
|
||||||
#include "readerwriter-netpgp.h"
|
#include "netpgp/readerwriter.h"
|
||||||
#include "version-netpgp.h"
|
#include "netpgp/version.h"
|
||||||
#include "netpgpdigest.h"
|
#include "netpgp/netpgpdigest.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#define vsnprintf _vsnprintf
|
#define vsnprintf _vsnprintf
|
||||||
#endif
|
#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
|
/** \file
|
||||||
* \brief Error Handling
|
* \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 hash Hash to set up
|
||||||
\param alg Hash algorithm to use
|
\param alg Hash algorithm to use
|
||||||
*/
|
*/
|
||||||
void
|
unsigned
|
||||||
pgp_hash_any(pgp_hash_t *hash, pgp_hash_alg_t alg)
|
pgp_hash_any(pgp_hash_t *hash, pgp_hash_alg_t alg)
|
||||||
{
|
{
|
||||||
switch (alg) {
|
switch (alg) {
|
||||||
|
@ -627,7 +528,9 @@ pgp_hash_any(pgp_hash_t *hash, pgp_hash_alg_t alg)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
(void) fprintf(stderr, "pgp_hash_any: bad algorithm\n");
|
(void) fprintf(stderr, "pgp_hash_any: bad algorithm\n");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
570
libs/netpgp/src/netpgp.c
Normal file
570
libs/netpgp/src/netpgp.c
Normal 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;
|
||||||
|
}
|
|
@ -49,7 +49,7 @@
|
||||||
|
|
||||||
/** \file
|
/** \file
|
||||||
*/
|
*/
|
||||||
#include "config-netpgp.h"
|
#include "netpgp/config-netpgp.h"
|
||||||
|
|
||||||
#ifdef HAVE_SYS_CDEFS_H
|
#ifdef HAVE_SYS_CDEFS_H
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
|
|
||||||
#if defined(__NetBSD__)
|
#if defined(__NetBSD__)
|
||||||
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
|
__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
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL_DSA_H
|
#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>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "crypto-netpgp.h"
|
#include "netpgp/crypto.h"
|
||||||
#include "keyring-netpgp.h"
|
#include "netpgp/keyring.h"
|
||||||
#include "readerwriter-netpgp.h"
|
#include "netpgp/readerwriter.h"
|
||||||
#include "netpgpdefs.h"
|
#include "netpgp/netpgpdefs.h"
|
||||||
#include "netpgpdigest.h"
|
#include "netpgp/netpgpdigest.h"
|
||||||
#include "packet-netpgp.h"
|
#include "netpgp/packet.h"
|
||||||
|
#include "netpgp/openssl11stub.h"
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -95,12 +96,14 @@ test_seckey(const pgp_seckey_t *seckey)
|
||||||
{
|
{
|
||||||
RSA *test = RSA_new();
|
RSA *test = RSA_new();
|
||||||
|
|
||||||
test->n = BN_dup(seckey->pubkey.key.rsa.n);
|
RSA_set0_key(test,
|
||||||
test->e = BN_dup(seckey->pubkey.key.rsa.e);
|
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);
|
RSA_set0_factors(test,
|
||||||
test->p = BN_dup(seckey->key.rsa.p);
|
BN_dup(seckey->key.rsa.p),
|
||||||
test->q = BN_dup(seckey->key.rsa.q);
|
BN_dup(seckey->key.rsa.q));
|
||||||
|
|
||||||
if (RSA_check_key(test) != 1) {
|
if (RSA_check_key(test) != 1) {
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
|
@ -440,20 +443,25 @@ pgp_dsa_verify(const uint8_t *hash, size_t hash_length,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
osig = DSA_SIG_new();
|
osig = DSA_SIG_new();
|
||||||
osig->r = sig->r;
|
DSA_SIG_set0(osig,
|
||||||
osig->s = sig->s;
|
BN_dup(sig->r),
|
||||||
|
BN_dup(sig->s));
|
||||||
|
|
||||||
odsa = DSA_new();
|
odsa = DSA_new();
|
||||||
odsa->p = dsa->p;
|
DSA_set0_pqg(odsa,
|
||||||
odsa->q = dsa->q;
|
BN_dup(dsa->p),
|
||||||
odsa->g = dsa->g;
|
BN_dup(dsa->q),
|
||||||
odsa->pub_key = dsa->y;
|
BN_dup(dsa->g));
|
||||||
|
|
||||||
|
DSA_set0_key(odsa,
|
||||||
|
BN_dup(dsa->y),
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (pgp_get_debug_level(__FILE__)) {
|
if (pgp_get_debug_level(__FILE__)) {
|
||||||
hexdump(stderr, "input hash", hash, hash_length);
|
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;
|
hash_length = qlen;
|
||||||
}
|
}
|
||||||
ret = DSA_do_verify(hash, (int)hash_length, osig, odsa);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
odsa->p = odsa->q = odsa->g = odsa->pub_key = NULL;
|
|
||||||
DSA_free(odsa);
|
DSA_free(odsa);
|
||||||
|
|
||||||
osig->r = osig->s = NULL;
|
|
||||||
DSA_SIG_free(osig);
|
DSA_SIG_free(osig);
|
||||||
|
|
||||||
return (unsigned)ret;
|
return (unsigned)ret;
|
||||||
|
@ -493,12 +499,14 @@ pgp_rsa_public_decrypt(uint8_t *out,
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
orsa = RSA_new();
|
orsa = RSA_new();
|
||||||
orsa->n = pubkey->n;
|
RSA_set0_key(orsa,
|
||||||
orsa->e = pubkey->e;
|
BN_dup(pubkey->n),
|
||||||
|
BN_dup(pubkey->e),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
|
||||||
n = RSA_public_decrypt((int)length, in, out, orsa, RSA_NO_PADDING);
|
n = RSA_public_decrypt((int)length, in, out, orsa, RSA_NO_PADDING);
|
||||||
|
|
||||||
orsa->n = orsa->e = NULL;
|
|
||||||
RSA_free(orsa);
|
RSA_free(orsa);
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
|
@ -525,20 +533,19 @@ pgp_rsa_private_encrypt(uint8_t *out,
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
orsa = RSA_new();
|
orsa = RSA_new();
|
||||||
orsa->n = BN_dup(pubkey->n);
|
|
||||||
orsa->d = seckey->d;
|
RSA_set0_key(orsa,
|
||||||
orsa->p = seckey->q; /* p and q are round the other way in openssl */
|
BN_dup(pubkey->n),
|
||||||
orsa->q = seckey->p;
|
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 */
|
/* 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) {
|
if (RSA_check_key(orsa) != 1) {
|
||||||
(void) fprintf(stderr, "RSA_check_key is not set\n");
|
(void) fprintf(stderr, "RSA_check_key is not set\n");
|
||||||
return 0;
|
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);
|
n = RSA_private_encrypt((int)length, in, out, orsa, RSA_NO_PADDING);
|
||||||
|
|
||||||
orsa->n = orsa->d = orsa->p = orsa->q = NULL;
|
|
||||||
RSA_free(orsa);
|
RSA_free(orsa);
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
|
@ -575,13 +581,16 @@ pgp_rsa_private_decrypt(uint8_t *out,
|
||||||
char errbuf[1024];
|
char errbuf[1024];
|
||||||
|
|
||||||
keypair = RSA_new();
|
keypair = RSA_new();
|
||||||
keypair->n = pubkey->n; /* XXX: do we need n? */
|
RSA_set0_key(keypair,
|
||||||
keypair->d = seckey->d;
|
BN_dup(pubkey->n),
|
||||||
keypair->p = seckey->q;
|
BN_dup(pubkey->e),
|
||||||
keypair->q = seckey->p;
|
BN_dup(seckey->d));
|
||||||
|
|
||||||
|
RSA_set0_factors(keypair,
|
||||||
|
BN_dup(seckey->p),
|
||||||
|
BN_dup(seckey->q));
|
||||||
|
|
||||||
/* debug */
|
/* debug */
|
||||||
keypair->e = pubkey->e;
|
|
||||||
if (RSA_check_key(keypair) != 1) {
|
if (RSA_check_key(keypair) != 1) {
|
||||||
(void) fprintf(stderr, "RSA_check_key is not set\n");
|
(void) fprintf(stderr, "RSA_check_key is not set\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -601,7 +610,6 @@ pgp_rsa_private_decrypt(uint8_t *out,
|
||||||
ERR_error_string(err, &errbuf[0]);
|
ERR_error_string(err, &errbuf[0]);
|
||||||
(void) fprintf(stderr, "openssl error : %s\n", errbuf);
|
(void) fprintf(stderr, "openssl error : %s\n", errbuf);
|
||||||
}
|
}
|
||||||
keypair->n = keypair->d = keypair->p = keypair->q = NULL;
|
|
||||||
RSA_free(keypair);
|
RSA_free(keypair);
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
|
@ -627,8 +635,10 @@ pgp_rsa_public_encrypt(uint8_t *out,
|
||||||
/* printf("pgp_rsa_public_encrypt: length=%ld\n", length); */
|
/* printf("pgp_rsa_public_encrypt: length=%ld\n", length); */
|
||||||
|
|
||||||
orsa = RSA_new();
|
orsa = RSA_new();
|
||||||
orsa->n = pubkey->n;
|
RSA_set0_key(orsa,
|
||||||
orsa->e = pubkey->e;
|
BN_dup(pubkey->n),
|
||||||
|
BN_dup(pubkey->e),
|
||||||
|
NULL);
|
||||||
|
|
||||||
/* printf("len: %ld\n", length); */
|
/* printf("len: %ld\n", length); */
|
||||||
/* pgp_print_bn("n: ", orsa->n); */
|
/* 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);
|
fd_out = BIO_new_fd(fileno(stderr), BIO_NOCLOSE);
|
||||||
ERR_print_errors(fd_out);
|
ERR_print_errors(fd_out);
|
||||||
}
|
}
|
||||||
orsa->n = orsa->e = NULL;
|
|
||||||
RSA_free(orsa);
|
RSA_free(orsa);
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
|
@ -656,8 +665,8 @@ pgp_rsa_public_encrypt(uint8_t *out,
|
||||||
void
|
void
|
||||||
pgp_crypto_finish(void)
|
pgp_crypto_finish(void)
|
||||||
{
|
{
|
||||||
CRYPTO_cleanup_all_ex_data();
|
// No cleanup since OpenSSL 1.1.0
|
||||||
ERR_remove_state((unsigned long)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)
|
\note It is the caller's responsibility to call pgp_keydata_free(keydata)
|
||||||
*/
|
*/
|
||||||
unsigned
|
unsigned
|
||||||
rsa_generate_keypair(pgp_key_t *keydata,
|
pgp_rsa_generate_keypair(pgp_key_t *keydata,
|
||||||
const int numbits,
|
const int numbits,
|
||||||
const unsigned long e__,
|
const unsigned long e__,
|
||||||
const char *hashalg,
|
const char *hashalg,
|
||||||
const char *cipher)
|
const char *cipher,
|
||||||
|
const uint8_t *passphrase,
|
||||||
|
const size_t pplen)
|
||||||
{
|
{
|
||||||
pgp_seckey_t *seckey;
|
pgp_seckey_t *seckey;
|
||||||
RSA *rsa = RSA_new();
|
RSA *rsa;
|
||||||
BN_CTX *ctx;
|
BN_CTX *ctx;
|
||||||
pgp_output_t *output;
|
pgp_output_t *output;
|
||||||
pgp_memory_t *mem;
|
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();
|
ctx = BN_CTX_new();
|
||||||
pgp_keydata_init(keydata, PGP_PTAG_CT_SECRET_KEY);
|
pgp_keydata_init(keydata, PGP_PTAG_CT_SECRET_KEY);
|
||||||
|
@ -700,14 +717,29 @@ rsa_generate_keypair(pgp_key_t *keydata,
|
||||||
|
|
||||||
/* generate the key pair */
|
/* generate the key pair */
|
||||||
|
|
||||||
//rsa = RSA_generate_key(numbits, e, NULL, NULL);
|
BIGNUM *exp = BN_new();
|
||||||
/* generate key */
|
BN_set_word(exp, e__);
|
||||||
BIGNUM* e = BN_new();
|
/*
|
||||||
BN_set_word(e, e__);
|
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||||
if( RSA_generate_key_ex(rsa, numbits, e, 0) != 1 ) {
|
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;
|
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 */
|
/* populate pgp key from ssl key */
|
||||||
|
|
||||||
|
@ -716,11 +748,14 @@ rsa_generate_keypair(pgp_key_t *keydata,
|
||||||
seckey->pubkey.days_valid = 0;
|
seckey->pubkey.days_valid = 0;
|
||||||
seckey->pubkey.alg = PGP_PKA_RSA;
|
seckey->pubkey.alg = PGP_PKA_RSA;
|
||||||
|
|
||||||
seckey->pubkey.key.rsa.n = BN_dup(rsa->n);
|
RSA_get0_key(rsa, &_n, &_e, &_d);
|
||||||
seckey->pubkey.key.rsa.e = BN_dup(rsa->e);
|
|
||||||
|
|
||||||
seckey->s2k_usage = PGP_S2KU_ENCRYPTED_AND_HASHED;
|
seckey->pubkey.key.rsa.n = BN_dup(_n);
|
||||||
seckey->s2k_specifier = PGP_S2KS_SALTED;
|
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; */
|
/* seckey->s2k_specifier=PGP_S2KS_SIMPLE; */
|
||||||
if ((seckey->hash_alg = pgp_str_to_hash_alg(hashalg)) == PGP_HASH_UNKNOWN) {
|
if ((seckey->hash_alg = pgp_str_to_hash_alg(hashalg)) == PGP_HASH_UNKNOWN) {
|
||||||
seckey->hash_alg = PGP_HASH_SHA1;
|
seckey->hash_alg = PGP_HASH_SHA1;
|
||||||
|
@ -729,20 +764,22 @@ rsa_generate_keypair(pgp_key_t *keydata,
|
||||||
seckey->octetc = 0;
|
seckey->octetc = 0;
|
||||||
seckey->checksum = 0;
|
seckey->checksum = 0;
|
||||||
|
|
||||||
seckey->key.rsa.d = BN_dup(rsa->d);
|
RSA_get0_factors(rsa, &_p, &_q);
|
||||||
seckey->key.rsa.p = BN_dup(rsa->p);
|
seckey->key.rsa.d = BN_dup(_d);
|
||||||
seckey->key.rsa.q = BN_dup(rsa->q);
|
seckey->key.rsa.p = BN_dup(_p);
|
||||||
seckey->key.rsa.u = BN_mod_inverse(NULL, rsa->p, rsa->q, ctx);
|
seckey->key.rsa.q = BN_dup(_q);
|
||||||
|
seckey->key.rsa.u = BN_mod_inverse(NULL, _p, _q, ctx);
|
||||||
if (seckey->key.rsa.u == NULL) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
BN_CTX_free(ctx);
|
BN_CTX_free(ctx);
|
||||||
|
|
||||||
RSA_free(rsa);
|
RSA_free(rsa);
|
||||||
|
|
||||||
pgp_keyid(keydata->sigid, PGP_KEY_ID_SIZE, &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->sigfingerprint, &keydata->key.seckey.pubkey, seckey->hash_alg);
|
pgp_fingerprint(&keydata->pubkeyfpr, &keydata->key.seckey.pubkey, seckey->hash_alg);
|
||||||
|
|
||||||
/* Generate checksum */
|
/* Generate checksum */
|
||||||
|
|
||||||
|
@ -797,7 +834,7 @@ rsa_generate_keypair(pgp_key_t *keydata,
|
||||||
\return The new keypair or NULL
|
\return The new keypair or NULL
|
||||||
|
|
||||||
\note It is the caller's responsibility to call pgp_keydata_free(keydata)
|
\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()
|
\sa pgp_keydata_free()
|
||||||
*/
|
*/
|
||||||
pgp_key_t *
|
pgp_key_t *
|
||||||
|
@ -810,15 +847,16 @@ pgp_rsa_new_selfsign_key(const int numbits,
|
||||||
pgp_key_t *keydata;
|
pgp_key_t *keydata;
|
||||||
|
|
||||||
keydata = pgp_keydata_new();
|
keydata = pgp_keydata_new();
|
||||||
if (!rsa_generate_keypair(keydata, numbits, e, hashalg, cipher) ||
|
if (!pgp_rsa_generate_keypair(keydata, numbits, e, hashalg, cipher,
|
||||||
!pgp_add_selfsigned_userid(keydata, userid)) {
|
(const uint8_t *) "", (const size_t) 0) ||
|
||||||
|
!pgp_add_selfsigned_userid(keydata, NULL, userid, 0 /*never expire*/)) {
|
||||||
pgp_keydata_free(keydata);
|
pgp_keydata_free(keydata);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return keydata;
|
return keydata;
|
||||||
}
|
}
|
||||||
|
|
||||||
DSA_SIG *
|
pgp_dsa_sig_t *
|
||||||
pgp_dsa_sign(uint8_t *hashbuf,
|
pgp_dsa_sign(uint8_t *hashbuf,
|
||||||
unsigned hashsize,
|
unsigned hashsize,
|
||||||
const pgp_dsa_seckey_t *secdsa,
|
const pgp_dsa_seckey_t *secdsa,
|
||||||
|
@ -826,64 +864,37 @@ pgp_dsa_sign(uint8_t *hashbuf,
|
||||||
{
|
{
|
||||||
DSA_SIG *dsasig;
|
DSA_SIG *dsasig;
|
||||||
DSA *odsa;
|
DSA *odsa;
|
||||||
|
pgp_dsa_sig_t *pgpdsasig;
|
||||||
|
const BIGNUM *pr = NULL;
|
||||||
|
const BIGNUM *ps = NULL;
|
||||||
|
|
||||||
odsa = DSA_new();
|
odsa = DSA_new();
|
||||||
odsa->p = pubdsa->p;
|
DSA_set0_pqg(odsa,
|
||||||
odsa->q = pubdsa->q;
|
BN_dup(pubdsa->p),
|
||||||
odsa->g = pubdsa->g;
|
BN_dup(pubdsa->q),
|
||||||
odsa->pub_key = pubdsa->y;
|
BN_dup(pubdsa->g));
|
||||||
odsa->priv_key = secdsa->x;
|
|
||||||
|
DSA_set0_key(odsa,
|
||||||
|
BN_dup(pubdsa->y),
|
||||||
|
BN_dup(secdsa->x));
|
||||||
|
|
||||||
dsasig = DSA_do_sign(hashbuf, (int)hashsize, odsa);
|
dsasig = DSA_do_sign(hashbuf, (int)hashsize, odsa);
|
||||||
|
|
||||||
odsa->p = odsa->q = odsa->g = odsa->pub_key = odsa->priv_key = NULL;
|
|
||||||
DSA_free(odsa);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
DSA_SIG_free(dsasig);
|
||||||
openssl_read_pem_seckey(const char *f, pgp_key_t *key, const char *type, int verbose)
|
return pgpdsasig;
|
||||||
{
|
}
|
||||||
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
|
* Decide the number of bits in the random componont k
|
|
@ -50,7 +50,7 @@
|
||||||
/** \file
|
/** \file
|
||||||
* \brief Parser for OpenPGP packets
|
* \brief Parser for OpenPGP packets
|
||||||
*/
|
*/
|
||||||
#include "config-netpgp.h"
|
#include "netpgp/config-netpgp.h"
|
||||||
|
|
||||||
#ifdef HAVE_SYS_CDEFS_H
|
#ifdef HAVE_SYS_CDEFS_H
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
@ -58,7 +58,7 @@
|
||||||
|
|
||||||
#if defined(__NetBSD__)
|
#if defined(__NetBSD__)
|
||||||
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
|
__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
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#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>
|
#include <limits.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "packet-netpgp.h"
|
#include "netpgp/packet.h"
|
||||||
#include "packet-parse.h"
|
#include "netpgp/packet-parse.h"
|
||||||
#include "keyring-netpgp.h"
|
#include "netpgp/keyring.h"
|
||||||
#include "errors-netpgp.h"
|
#include "netpgp/errors.h"
|
||||||
#include "packet-show.h"
|
#include "netpgp/packet-show.h"
|
||||||
#include "create-netpgp.h"
|
#include "netpgp/create.h"
|
||||||
#include "readerwriter-netpgp.h"
|
#include "netpgp/readerwriter.h"
|
||||||
#include "netpgpdefs.h"
|
#include "netpgp/netpgpdefs.h"
|
||||||
#include "crypto-netpgp.h"
|
#include "netpgp/crypto.h"
|
||||||
#include "netpgpdigest.h"
|
#include "netpgp/netpgpdigest.h"
|
||||||
|
|
||||||
#define ERRP(cbinfo, cont, err) do { \
|
#define ERRP(cbinfo, cont, err) do { \
|
||||||
cont.u.error = err; \
|
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
|
* 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
|
* 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;) {
|
for (n = 0; n < length;) {
|
||||||
int r;
|
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);
|
readinfo, cbinfo);
|
||||||
|
}
|
||||||
if (r > (int)(length - n)) {
|
if (r > (int)(length - n)) {
|
||||||
(void) fprintf(stderr, "sub_base_read: bad read\n");
|
(void) fprintf(stderr, "sub_base_read: bad read\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -454,6 +483,7 @@ limread(uint8_t *dest, unsigned length,
|
||||||
&info->readinfo, &info->cbinfo);
|
&info->readinfo, &info->cbinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static unsigned
|
static unsigned
|
||||||
exact_limread(uint8_t *dest, unsigned len,
|
exact_limread(uint8_t *dest, unsigned len,
|
||||||
pgp_region_t *region,
|
pgp_region_t *region,
|
||||||
|
@ -466,6 +496,7 @@ exact_limread(uint8_t *dest, unsigned len,
|
||||||
stream->exact_read = 0;
|
stream->exact_read = 0;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Skip over length bytes of this packet.
|
/** 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 nonzero;
|
||||||
unsigned ret;
|
unsigned ret;
|
||||||
|
|
||||||
stream->reading_mpi_len = 1;
|
//stream->reading_mpi_len = 1;
|
||||||
ret = (unsigned)limread_scalar(&length, 2, region, stream);
|
ret = (unsigned)limread_scalar(&length, 2, region, stream);
|
||||||
|
|
||||||
stream->reading_mpi_len = 0;
|
//stream->reading_mpi_len = 0;
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -704,11 +735,12 @@ static void
|
||||||
streamread(pgp_stream_t *stream, unsigned c)
|
streamread(pgp_stream_t *stream, unsigned c)
|
||||||
{
|
{
|
||||||
int cc;
|
int cc;
|
||||||
|
pgp_reader_t *readinfo = &stream->readinfo;
|
||||||
|
|
||||||
stream->virtualpkt = realloc(stream->virtualpkt, stream->virtualc + c);
|
readinfo->virtualpkt = realloc(readinfo->virtualpkt, readinfo->virtualc + c);
|
||||||
cc = stream->readinfo.reader(stream, &stream->virtualpkt[stream->virtualc],
|
cc = readinfo->reader(stream, &readinfo->virtualpkt[readinfo->virtualc],
|
||||||
c, &stream->errors, &stream->readinfo, &stream->cbinfo);
|
c, &stream->errors, readinfo, &stream->cbinfo);
|
||||||
stream->virtualc += cc;
|
readinfo->virtualc += cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* coalesce all the partial blocks together */
|
/* coalesce all the partial blocks together */
|
||||||
|
@ -716,17 +748,20 @@ static int
|
||||||
coalesce_blocks(pgp_stream_t *stream, unsigned length)
|
coalesce_blocks(pgp_stream_t *stream, unsigned length)
|
||||||
{
|
{
|
||||||
unsigned c;
|
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 */
|
/* already read a partial block length - prime the array */
|
||||||
streamread(stream, length);
|
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 */
|
/* length we read is partial - add to end of array */
|
||||||
streamread(stream, c);
|
streamread(stream, c);
|
||||||
}
|
}
|
||||||
/* not partial - add the last extent to the end of the array */
|
/* not partial - add the last extent to the end of the array */
|
||||||
streamread(stream, c);
|
if(r > 0) streamread(stream, c);
|
||||||
stream->coalescing = 0;
|
readinfo->coalescing = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -744,8 +779,9 @@ static unsigned
|
||||||
read_new_length(unsigned *length, pgp_stream_t *stream)
|
read_new_length(unsigned *length, pgp_stream_t *stream)
|
||||||
{
|
{
|
||||||
uint8_t c;
|
uint8_t c;
|
||||||
|
pgp_reader_t *readinfo = &stream->readinfo;
|
||||||
|
|
||||||
stream->partial_read = 0;
|
readinfo->partial_read = 0;
|
||||||
if (base_read(&c, 1, stream) != 1) {
|
if (base_read(&c, 1, stream) != 1) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -766,13 +802,13 @@ read_new_length(unsigned *length, pgp_stream_t *stream)
|
||||||
}
|
}
|
||||||
if (c < 255) {
|
if (c < 255) {
|
||||||
/* 3. Partial Body Length */
|
/* 3. Partial Body Length */
|
||||||
stream->partial_read = 1;
|
readinfo->partial_read = 1;
|
||||||
*length = 1 << (c & 0x1f);
|
*length = 1 << (c & 0x1f);
|
||||||
if (!stream->coalescing) {
|
if (!readinfo->coalescing) {
|
||||||
/* we have been called from coalesce_blocks -
|
/* we have been called from coalesce_blocks -
|
||||||
* just return with the partial length */
|
* just return with the partial length */
|
||||||
coalesce_blocks(stream, *length);
|
coalesce_blocks(stream, *length);
|
||||||
*length = stream->virtualc;
|
*length = readinfo->virtualc;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -802,6 +838,7 @@ limited_read_new_length(unsigned *length, pgp_region_t *region,
|
||||||
pgp_stream_t *stream)
|
pgp_stream_t *stream)
|
||||||
{
|
{
|
||||||
uint8_t c = 0x0;
|
uint8_t c = 0x0;
|
||||||
|
pgp_reader_t *readinfo = &stream->readinfo;
|
||||||
|
|
||||||
if (!limread(&c, 1, region, stream)) {
|
if (!limread(&c, 1, region, stream)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -820,13 +857,13 @@ limited_read_new_length(unsigned *length, pgp_region_t *region,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (c < 255) {
|
if (c < 255) {
|
||||||
stream->partial_read = 1;
|
readinfo->partial_read = 1;
|
||||||
*length = 1 << (c & 0x1f);
|
*length = 1 << (c & 0x1f);
|
||||||
if (!stream->coalescing) {
|
if (!readinfo->coalescing) {
|
||||||
/* we have been called from coalesce_blocks -
|
/* we have been called from coalesce_blocks -
|
||||||
* just return with the partial length */
|
* just return with the partial length */
|
||||||
coalesce_blocks(stream, *length);
|
coalesce_blocks(stream, *length);
|
||||||
*length = stream->virtualc;
|
*length = readinfo->virtualc;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -845,6 +882,14 @@ pgp_data_free(pgp_data_t *data)
|
||||||
data->len = 0;
|
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
|
\ingroup Core_Create
|
||||||
\brief Free allocated memory
|
\brief Free allocated memory
|
||||||
|
@ -920,28 +965,37 @@ free_BN(BIGNUM **pp)
|
||||||
*pp = NULL;
|
*pp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* \ingroup Core_Create
|
|
||||||
* \brief Free the memory used when parsing a signature
|
|
||||||
* \param sig
|
|
||||||
*/
|
|
||||||
static void
|
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:
|
||||||
case PGP_PKA_RSA_SIGN_ONLY:
|
case PGP_PKA_RSA_SIGN_ONLY:
|
||||||
free_BN(&sig->info.sig.rsa.sig);
|
dup_BN(&dst->sig.rsa.sig, src->sig.rsa.sig);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PGP_PKA_DSA:
|
case PGP_PKA_DSA:
|
||||||
free_BN(&sig->info.sig.dsa.r);
|
dup_BN(&dst->sig.dsa.r, src->sig.dsa.r);
|
||||||
free_BN(&sig->info.sig.dsa.s);
|
dup_BN(&dst->sig.dsa.s, src->sig.dsa.s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
|
case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
|
||||||
free_BN(&sig->info.sig.elgamal.r);
|
dup_BN(&dst->sig.elgamal.r, src->sig.elgamal.r);
|
||||||
free_BN(&sig->info.sig.elgamal.s);
|
dup_BN(&dst->sig.elgamal.s, src->sig.elgamal.s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PGP_PKA_PRIVATE00:
|
case PGP_PKA_PRIVATE00:
|
||||||
|
@ -955,13 +1009,65 @@ sig_free(pgp_sig_t *sig)
|
||||||
case PGP_PKA_PRIVATE08:
|
case PGP_PKA_PRIVATE08:
|
||||||
case PGP_PKA_PRIVATE09:
|
case PGP_PKA_PRIVATE09:
|
||||||
case PGP_PKA_PRIVATE10:
|
case PGP_PKA_PRIVATE10:
|
||||||
pgp_data_free(&sig->info.sig.unknown);
|
pgp_data_dup(&dst->sig.unknown, &src->sig.unknown);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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
|
\ingroup Core_Create
|
||||||
|
@ -1188,8 +1294,48 @@ pgp_pubkey_free(pgp_pubkey_t *p)
|
||||||
default:
|
default:
|
||||||
(void) fprintf(stderr, "pgp_pubkey_free: bad alg\n");
|
(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
|
\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 = pkt.u.ss_time;
|
||||||
sig->info.duration_set = 1;
|
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;
|
break;
|
||||||
|
|
||||||
case PGP_PTAG_SS_TRUST:
|
case PGP_PTAG_SS_TRUST:
|
||||||
|
@ -1653,11 +1803,17 @@ parse_one_sig_subpacket(pgp_sig_t *sig,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
pkt.u.ss_primary_userid = !!bools;
|
pkt.u.ss_primary_userid = !!bools;
|
||||||
|
sig->info.primary_userid = pkt.u.ss_primary_userid;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PGP_PTAG_SS_KEY_FLAGS:
|
case PGP_PTAG_SS_KEY_FLAGS:
|
||||||
if (!read_data(&pkt.u.ss_key_flags, &subregion, stream)) {
|
if (!read_data(&pkt.u.ss_key_flags, &subregion, stream)) {
|
||||||
return 0;
|
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;
|
break;
|
||||||
|
|
||||||
|
@ -1817,6 +1973,7 @@ parse_one_sig_subpacket(pgp_sig_t *sig,
|
||||||
PGP_ERROR_1(&stream->errors, PGP_E_R_UNCONSUMED_DATA,
|
PGP_ERROR_1(&stream->errors, PGP_E_R_UNCONSUMED_DATA,
|
||||||
"Unconsumed data (%d)",
|
"Unconsumed data (%d)",
|
||||||
subregion.length - subregion.readc);
|
subregion.length - subregion.readc);
|
||||||
|
pgp_parser_content_free(&pkt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
CALLBACK(pkt.tag, &stream->cbinfo, &pkt);
|
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) {
|
if (!stream->readinfo.accumulate) {
|
||||||
/* We must accumulate, else we can't check the signature */
|
/* We must accumulate, else we can't check the signature */
|
||||||
fprintf(stderr, "*** ERROR: must set accumulate to 1\n");
|
fprintf(stderr, "*** ERROR: must set accumulate to 1\n");
|
||||||
return 0;
|
goto error_unalloc_v4_hashed;
|
||||||
}
|
}
|
||||||
(void) memcpy(pkt.u.sig.info.v4_hashed,
|
(void) memcpy(pkt.u.sig.info.v4_hashed,
|
||||||
stream->readinfo.accumulated + pkt.u.sig.v4_hashstart,
|
stream->readinfo.accumulated + pkt.u.sig.v4_hashstart,
|
||||||
pkt.u.sig.info.v4_hashlen);
|
pkt.u.sig.info.v4_hashlen);
|
||||||
|
|
||||||
if (!parse_sig_subpkts(&pkt.u.sig, region, stream)) {
|
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)) {
|
if (!limread(pkt.u.sig.hash2, 2, region, stream)) {
|
||||||
return 0;
|
goto error_unalloc_v4_hashed;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (pkt.u.sig.info.key_alg) {
|
switch (pkt.u.sig.info.key_alg) {
|
||||||
case PGP_PKA_RSA:
|
case PGP_PKA_RSA:
|
||||||
if (!limread_mpi(&pkt.u.sig.info.sig.rsa.sig, region, stream)) {
|
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__)) {
|
if (pgp_get_debug_level(__FILE__)) {
|
||||||
(void) fprintf(stderr, "parse_v4_sig: RSA: sig is\n");
|
(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,
|
(void) fprintf(stderr,
|
||||||
"Error reading DSA r field in signature");
|
"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)) {
|
if (!limread_mpi(&pkt.u.sig.info.sig.dsa.s, region, stream)) {
|
||||||
ERRP(&stream->cbinfo, pkt,
|
ERRP(&stream->cbinfo, pkt,
|
||||||
|
@ -2017,7 +2174,7 @@ parse_v4_sig(pgp_region_t *region, pgp_stream_t *stream)
|
||||||
stream) ||
|
stream) ||
|
||||||
!limread_mpi(&pkt.u.sig.info.sig.elgamal.s, region,
|
!limread_mpi(&pkt.u.sig.info.sig.elgamal.s, region,
|
||||||
stream)) {
|
stream)) {
|
||||||
return 0;
|
goto error_unalloc_v4_hashed;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2033,7 +2190,7 @@ parse_v4_sig(pgp_region_t *region, pgp_stream_t *stream)
|
||||||
case PGP_PKA_PRIVATE09:
|
case PGP_PKA_PRIVATE09:
|
||||||
case PGP_PKA_PRIVATE10:
|
case PGP_PKA_PRIVATE10:
|
||||||
if (!read_data(&pkt.u.sig.info.sig.unknown, region, stream)) {
|
if (!read_data(&pkt.u.sig.info.sig.unknown, region, stream)) {
|
||||||
return 0;
|
goto error_unalloc_v4_hashed;
|
||||||
}
|
}
|
||||||
break;
|
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,
|
PGP_ERROR_1(&stream->errors, PGP_E_ALG_UNSUPPORTED_SIGNATURE_ALG,
|
||||||
"Bad v4 signature key algorithm (%s)",
|
"Bad v4 signature key algorithm (%s)",
|
||||||
pgp_show_pka(pkt.u.sig.info.key_alg));
|
pgp_show_pka(pkt.u.sig.info.key_alg));
|
||||||
return 0;
|
goto error_unalloc_v4_hashed;
|
||||||
}
|
}
|
||||||
if (region->readc != region->length) {
|
if (region->readc != region->length) {
|
||||||
PGP_ERROR_1(&stream->errors, PGP_E_R_UNCONSUMED_DATA,
|
PGP_ERROR_1(&stream->errors, PGP_E_R_UNCONSUMED_DATA,
|
||||||
"Unconsumed data (%d)",
|
"Unconsumed data (%d)",
|
||||||
region->length - region->readc);
|
region->length - region->readc);
|
||||||
return 0;
|
goto error_unalloc_v4_hashed;
|
||||||
}
|
}
|
||||||
CALLBACK(PGP_PTAG_CT_SIGNATURE_FOOTER, &stream->cbinfo, &pkt);
|
CALLBACK(PGP_PTAG_CT_SIGNATURE_FOOTER, &stream->cbinfo, &pkt);
|
||||||
return 1;
|
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));
|
pgp_show_pka(key->pubkey.alg));
|
||||||
}
|
}
|
||||||
free(key->checkhash);
|
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
|
static int
|
||||||
|
@ -2339,7 +2545,7 @@ consume_packet(pgp_region_t *region, pgp_stream_t *stream, unsigned warn)
|
||||||
* \brief Parse a secret key
|
* \brief Parse a secret key
|
||||||
*/
|
*/
|
||||||
static int
|
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_packet_t pkt;
|
||||||
pgp_region_t encregion;
|
pgp_region_t encregion;
|
||||||
|
@ -2364,9 +2570,14 @@ parse_seckey(pgp_region_t *region, pgp_stream_t *stream)
|
||||||
}
|
}
|
||||||
if (pgp_get_debug_level(__FILE__)) {
|
if (pgp_get_debug_level(__FILE__)) {
|
||||||
fprintf(stderr, "parse_seckey: public key parsed\n");
|
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)) {
|
if (!limread(&c, 1, region, stream)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2576,8 +2787,9 @@ parse_seckey(pgp_region_t *region, pgp_stream_t *stream)
|
||||||
if (pgp_get_debug_level(__FILE__)) {
|
if (pgp_get_debug_level(__FILE__)) {
|
||||||
fprintf(stderr, "parse_seckey: end of crypted passphrase\n");
|
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 */
|
/* 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);
|
pkt.u.seckey.checkhash = calloc(1, PGP_SHA1_HASH_SIZE);
|
||||||
if (pkt.u.seckey.checkhash == NULL) {
|
if (pkt.u.seckey.checkhash == NULL) {
|
||||||
(void) fprintf(stderr, "parse_seckey: bad alloc\n");
|
(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__)) {
|
if (pgp_get_debug_level(__FILE__)) {
|
||||||
(void) fprintf(stderr, "4 MPIs read\n");
|
(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) {
|
if (pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED_AND_HASHED) {
|
||||||
uint8_t hash[PGP_CHECKHASH_SIZE];
|
uint8_t hash[PGP_CHECKHASH_SIZE];
|
||||||
|
@ -2687,7 +2899,7 @@ parse_seckey(pgp_region_t *region, pgp_stream_t *stream)
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
CALLBACK(PGP_PTAG_CT_SECRET_KEY, &stream->cbinfo, &pkt);
|
CALLBACK(tag, &stream->cbinfo, &pkt);
|
||||||
if (pgp_get_debug_level(__FILE__)) {
|
if (pgp_get_debug_level(__FILE__)) {
|
||||||
(void) fprintf(stderr, "--- end of parse_seckey\n\n");
|
(void) fprintf(stderr, "--- end of parse_seckey\n\n");
|
||||||
}
|
}
|
||||||
|
@ -2869,6 +3081,7 @@ parse_pk_sesskey(pgp_region_t *region,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static int
|
static int
|
||||||
decrypt_se_data(pgp_content_enum tag, pgp_region_t *region,
|
decrypt_se_data(pgp_content_enum tag, pgp_region_t *region,
|
||||||
pgp_stream_t *stream)
|
pgp_stream_t *stream)
|
||||||
|
@ -2928,6 +3141,7 @@ decrypt_se_data(pgp_content_enum tag, pgp_region_t *region,
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
decrypt_se_ip_data(pgp_content_enum tag, pgp_region_t *region,
|
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;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/**
|
/**
|
||||||
\ingroup Core_ReadPackets
|
\ingroup Core_ReadPackets
|
||||||
\brief Read a Symmetrically Encrypted packet
|
\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);
|
return decrypt_se_data(PGP_PTAG_CT_SE_DATA_BODY, region, stream);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\ingroup Core_ReadPackets
|
\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__)) {
|
if (pgp_get_debug_level(__FILE__)) {
|
||||||
(void) fprintf(stderr, "parse_se_ip_data: region %d,%d\n",
|
(void) fprintf(stderr, "parse_se_ip_data: region %d,%d\n",
|
||||||
region->readc, region->length);
|
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
|
* 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 {
|
} else {
|
||||||
unsigned rb;
|
unsigned rb;
|
||||||
|
|
||||||
rb = 0;
|
|
||||||
pkt.u.ptag.type = ((unsigned)ptag &
|
pkt.u.ptag.type = ((unsigned)ptag &
|
||||||
PGP_PTAG_OF_CONTENT_TAG_MASK)
|
PGP_PTAG_OF_CONTENT_TAG_MASK)
|
||||||
>> PGP_PTAG_OF_CONTENT_TAG_SHIFT;
|
>> PGP_PTAG_OF_CONTENT_TAG_SHIFT;
|
||||||
|
@ -3177,11 +3392,8 @@ parse_packet(pgp_stream_t *stream, uint32_t *pktlen)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PGP_PTAG_CT_SECRET_KEY:
|
case PGP_PTAG_CT_SECRET_KEY:
|
||||||
ret = parse_seckey(®ion, stream);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PGP_PTAG_CT_SECRET_SUBKEY:
|
case PGP_PTAG_CT_SECRET_SUBKEY:
|
||||||
ret = parse_seckey(®ion, stream);
|
ret = parse_seckey((pgp_content_enum)pkt.u.ptag.type, ®ion, stream);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PGP_PTAG_CT_PK_SESSION_KEY:
|
case PGP_PTAG_CT_PK_SESSION_KEY:
|
||||||
|
@ -3189,7 +3401,9 @@ parse_packet(pgp_stream_t *stream, uint32_t *pktlen)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PGP_PTAG_CT_SE_DATA:
|
case PGP_PTAG_CT_SE_DATA:
|
||||||
ret = parse_se_data(®ion, stream);
|
// SE_DATA CURRENTLY BROKEN
|
||||||
|
ret = 0;
|
||||||
|
//ret = parse_se_data(®ion, stream);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PGP_PTAG_CT_SE_IP_DATA:
|
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 *cbinfo;
|
||||||
pgp_cbdata_t *next;
|
pgp_cbdata_t *next;
|
||||||
|
pgp_cryptinfo_t *cryptinfo = &stream->cbinfo.cryptinfo;
|
||||||
|
|
||||||
for (cbinfo = stream->cbinfo.next; cbinfo; cbinfo = next) {
|
for (cbinfo = stream->cbinfo.next; cbinfo; cbinfo = next) {
|
||||||
next = cbinfo->next;
|
next = cbinfo->next;
|
||||||
free(cbinfo);
|
free(cbinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FREE_ARRAY(cryptinfo, recipients_key_ids);
|
||||||
|
|
||||||
if (stream->readinfo.destroyer) {
|
if (stream->readinfo.destroyer) {
|
||||||
stream->readinfo.destroyer(&stream->readinfo);
|
stream->readinfo.destroyer(&stream->readinfo);
|
||||||
}
|
}
|
|
@ -52,7 +52,7 @@
|
||||||
* Creates printable text strings from packet contents
|
* Creates printable text strings from packet contents
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include "config-netpgp.h"
|
#include "netpgp/config-netpgp.h"
|
||||||
|
|
||||||
#ifdef HAVE_SYS_CDEFS_H
|
#ifdef HAVE_SYS_CDEFS_H
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
@ -60,16 +60,16 @@
|
||||||
|
|
||||||
#if defined(__NetBSD__)
|
#if defined(__NetBSD__)
|
||||||
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
|
__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
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "packet-show.h"
|
#include "netpgp/packet-show.h"
|
||||||
|
|
||||||
#include "netpgpsdk.h"
|
#include "netpgp/netpgpsdk.h"
|
||||||
#include "netpgpdefs.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 */
|
{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
|
* Private functions
|
||||||
*/
|
*/
|
||||||
|
@ -341,37 +302,6 @@ list_free(pgp_list_t *list)
|
||||||
list_init(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 */
|
/* find a bitfield in a map - serial search */
|
||||||
static const char *
|
static const char *
|
||||||
find_bitfield(pgp_bit_map_t *map, uint8_t octet)
|
find_bitfield(pgp_bit_map_t *map, uint8_t octet)
|
||||||
|
@ -414,161 +344,6 @@ pgp_text_free(pgp_text_t *text)
|
||||||
free(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
|
* Public Functions
|
||||||
*/
|
*/
|
||||||
|
@ -655,22 +430,6 @@ pgp_show_ss_zpref(uint8_t octet)
|
||||||
return pgp_str_from_map(octet, compression_alg_map);
|
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
|
* \ingroup Core_Print
|
||||||
*
|
*
|
||||||
|
@ -684,21 +443,6 @@ pgp_show_hash_alg(uint8_t hash)
|
||||||
return pgp_str_from_map(hash, hash_alg_map);
|
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 *
|
const char *
|
||||||
pgp_show_symm_alg(uint8_t hash)
|
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);
|
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
|
* \ingroup Core_Print
|
||||||
* returns description of SS Key Flag
|
* 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);
|
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
|
* \ingroup Core_Print
|
||||||
*
|
*
|
||||||
|
@ -855,60 +489,3 @@ pgp_show_keyserv_pref(uint8_t prefs, pgp_bit_map_t *map)
|
||||||
return find_bitfield(map, prefs);
|
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));
|
|
||||||
}
|
|
|
@ -46,7 +46,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#include "config-netpgp.h"
|
#include "netpgp/config-netpgp.h"
|
||||||
|
|
||||||
#ifdef HAVE_SYS_CDEFS_H
|
#ifdef HAVE_SYS_CDEFS_H
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
|
|
||||||
#if defined(__NetBSD__)
|
#if defined(__NetBSD__)
|
||||||
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
|
__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
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#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>
|
#include <limits.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "errors-netpgp.h"
|
#include "netpgp/errors.h"
|
||||||
#include "crypto-netpgp.h"
|
#include "netpgp/crypto.h"
|
||||||
#include "create-netpgp.h"
|
#include "netpgp/create.h"
|
||||||
#include "signature-netpgp.h"
|
#include "netpgp/signature.h"
|
||||||
#include "packet-netpgp.h"
|
#include "netpgp/packet.h"
|
||||||
#include "packet-parse.h"
|
#include "netpgp/packet-parse.h"
|
||||||
#include "packet-show.h"
|
#include "netpgp/packet-show.h"
|
||||||
#include "keyring-netpgp.h"
|
#include "netpgp/packet.h"
|
||||||
#include "readerwriter-netpgp.h"
|
#include "netpgp/keyring.h"
|
||||||
#include "netpgpsdk.h"
|
#include "netpgp/readerwriter.h"
|
||||||
#include "netpgpdefs.h"
|
#include "netpgp/netpgpsdk.h"
|
||||||
#include "netpgpdigest.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 */
|
/* get a pass phrase from the user */
|
||||||
int
|
int
|
||||||
|
@ -233,6 +214,10 @@ pgp_reader_pop(pgp_stream_t *stream)
|
||||||
{
|
{
|
||||||
pgp_reader_t *next = stream->readinfo.next;
|
pgp_reader_t *next = stream->readinfo.next;
|
||||||
|
|
||||||
|
if (stream->readinfo.accumulate && stream->readinfo.asize > 0) {
|
||||||
|
free(stream->readinfo.accumulated);
|
||||||
|
}
|
||||||
|
|
||||||
stream->readinfo = *next;
|
stream->readinfo = *next;
|
||||||
free(next);
|
free(next);
|
||||||
}
|
}
|
||||||
|
@ -448,6 +433,9 @@ read_char(pgp_stream_t *stream, dearmour_t *dearmour,
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (dearmour->pushbackc) {
|
if (dearmour->pushbackc) {
|
||||||
|
if (!dearmour->pushback) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
c = dearmour->pushback[--dearmour->pushbackc];
|
c = dearmour->pushback[--dearmour->pushbackc];
|
||||||
if (dearmour->pushbackc == 0) {
|
if (dearmour->pushbackc == 0) {
|
||||||
free(dearmour->pushback);
|
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,
|
pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo,
|
||||||
int *pc, unsigned *pn, uint32_t *pl)
|
int *pc, unsigned *pn, uint32_t *pl)
|
||||||
{
|
{
|
||||||
int n, c;
|
int n = 0, c = 0;
|
||||||
uint32_t l = 0;
|
uint32_t l = 0;
|
||||||
|
|
||||||
for (n = 0; n < 4; ++n) {
|
for (n = 0; n < 4; ++n) {
|
||||||
|
@ -1398,7 +1386,7 @@ typedef struct {
|
||||||
size_t off;
|
size_t off;
|
||||||
pgp_crypt_t *decrypt;
|
pgp_crypt_t *decrypt;
|
||||||
pgp_region_t *region;
|
pgp_region_t *region;
|
||||||
unsigned prevplain:1;
|
// unsigned prevplain:1;
|
||||||
} encrypted_t;
|
} encrypted_t;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -1414,6 +1402,8 @@ encrypted_data_reader(pgp_stream_t *stream, void *dest,
|
||||||
|
|
||||||
encrypted = pgp_reader_get_arg(readinfo);
|
encrypted = pgp_reader_get_arg(readinfo);
|
||||||
saved = (int)length;
|
saved = (int)length;
|
||||||
|
|
||||||
|
#if 0
|
||||||
/*
|
/*
|
||||||
* V3 MPIs have the count plain and the cipher is reset after each
|
* V3 MPIs have the count plain and the cipher is reset after each
|
||||||
* count
|
* count
|
||||||
|
@ -1430,13 +1420,15 @@ encrypted_data_reader(pgp_stream_t *stream, void *dest,
|
||||||
readinfo->parent->reading_mpi_len) {
|
readinfo->parent->reading_mpi_len) {
|
||||||
encrypted->prevplain = 1;
|
encrypted->prevplain = 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
while (length > 0) {
|
while (length > 0) {
|
||||||
if (encrypted->c) {
|
if (encrypted->c) {
|
||||||
unsigned n;
|
unsigned n;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if we are reading v3 we should never read
|
* 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 &&
|
if (length < encrypted->c &&
|
||||||
(readinfo->parent->reading_v3_secret ||
|
(readinfo->parent->reading_v3_secret ||
|
||||||
readinfo->parent->exact_read)) {
|
readinfo->parent->exact_read)) {
|
||||||
|
@ -1444,6 +1436,7 @@ encrypted_data_reader(pgp_stream_t *stream, void *dest,
|
||||||
"encrypted_data_reader: bad v3 read\n");
|
"encrypted_data_reader: bad v3 read\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
n = (int)MIN(length, encrypted->c);
|
n = (int)MIN(length, encrypted->c);
|
||||||
(void) memcpy(dest,
|
(void) memcpy(dest,
|
||||||
encrypted->decrypted + encrypted->off, n);
|
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
|
* we can only read as much as we're asked for
|
||||||
* in v3 keys because they're partially
|
* in v3 keys because they're partially
|
||||||
* unencrypted! */
|
* unencrypted!
|
||||||
if ((readinfo->parent->reading_v3_secret ||
|
if ((readinfo->parent->reading_v3_secret ||
|
||||||
readinfo->parent->exact_read) && n > length) {
|
readinfo->parent->exact_read) && n > length) {
|
||||||
n = (unsigned)length;
|
n = (unsigned)length;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if (!pgp_stacked_limited_read(stream, buffer, n,
|
if (!pgp_stacked_limited_read(stream, buffer, n,
|
||||||
encrypted->region, errors, readinfo, cbinfo)) {
|
encrypted->region, errors, readinfo, cbinfo)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!readinfo->parent->reading_v3_secret ||
|
//if (!readinfo->parent->reading_v3_secret ||
|
||||||
!readinfo->parent->reading_mpi_len) {
|
// !readinfo->parent->reading_mpi_len) {
|
||||||
encrypted->c =
|
encrypted->c =
|
||||||
pgp_decrypt_se_ip(encrypted->decrypt,
|
pgp_decrypt_se_ip(encrypted->decrypt,
|
||||||
encrypted->decrypted, buffer, n);
|
encrypted->decrypted, buffer, n);
|
||||||
|
@ -1495,11 +1489,11 @@ encrypted_data_reader(pgp_stream_t *stream, void *dest,
|
||||||
hexdump(stderr, "encrypted", buffer, 16);
|
hexdump(stderr, "encrypted", buffer, 16);
|
||||||
hexdump(stderr, "decrypted", encrypted->decrypted, 16);
|
hexdump(stderr, "decrypted", encrypted->decrypted, 16);
|
||||||
}
|
}
|
||||||
} else {
|
//} else {
|
||||||
(void) memcpy(
|
// (void) memcpy(
|
||||||
&encrypted->decrypted[encrypted->off], buffer, n);
|
//&encrypted->decrypted[encrypted->off], buffer, n);
|
||||||
encrypted->c = n;
|
//encrypted->c = n;
|
||||||
}
|
//}
|
||||||
|
|
||||||
if (encrypted->c == 0) {
|
if (encrypted->c == 0) {
|
||||||
(void) fprintf(stderr,
|
(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);
|
__PGP_USED(cbinfo);
|
||||||
reader = pgp_reader_get_arg(readinfo);
|
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);
|
n = (int)read(reader->fd, dest, length);
|
||||||
}
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
return 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(cbinfo);
|
||||||
__PGP_USED(errors);
|
__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) {
|
if (reader->offset + length > reader->length) {
|
||||||
n = (unsigned)(reader->length - reader->offset);
|
n = (unsigned)(reader->length - reader->offset);
|
||||||
} else {
|
} 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);
|
memcpy(dest, reader->buffer + reader->offset, n);
|
||||||
reader->offset += n;
|
reader->offset += n;
|
||||||
}
|
|
||||||
return 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__)) {
|
if (pgp_get_debug_level(__FILE__)) {
|
||||||
printf("pgp_litdata_cb: ");
|
printf("pgp_litdata_cb: ");
|
||||||
pgp_print_packet(&cbinfo->printstate, pkt);
|
//pgp_print_packet(&cbinfo->printstate, pkt);
|
||||||
}
|
}
|
||||||
/* Read data from packet into static buffer */
|
/* Read data from packet into static buffer */
|
||||||
switch (pkt->tag) {
|
switch (pkt->tag) {
|
||||||
|
@ -2161,7 +2151,7 @@ pgp_pk_sesskey_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
|
||||||
|
|
||||||
io = cbinfo->io;
|
io = cbinfo->io;
|
||||||
if (pgp_get_debug_level(__FILE__)) {
|
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 */
|
/* Read data from packet into static buffer */
|
||||||
switch (pkt->tag) {
|
switch (pkt->tag) {
|
||||||
|
@ -2177,7 +2167,8 @@ pgp_pk_sesskey_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
|
||||||
from = 0;
|
from = 0;
|
||||||
cbinfo->cryptinfo.keydata =
|
cbinfo->cryptinfo.keydata =
|
||||||
pgp_getkeybyid(io, cbinfo->cryptinfo.secring,
|
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) {
|
if (!cbinfo->cryptinfo.keydata) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2208,55 +2199,67 @@ pgp_cb_ret_t
|
||||||
pgp_get_seckey_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
|
pgp_get_seckey_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
|
||||||
{
|
{
|
||||||
const pgp_contents_t *content = &pkt->u;
|
const pgp_contents_t *content = &pkt->u;
|
||||||
const pgp_seckey_t *secret;
|
pgp_seckey_t *secret;
|
||||||
const pgp_key_t *pubkey;
|
// const pgp_key_t *pubkey;
|
||||||
const pgp_key_t *keypair;
|
//const pgp_key_t *keypair;
|
||||||
unsigned from;
|
unsigned from;
|
||||||
pgp_io_t *io;
|
pgp_io_t *io;
|
||||||
int i;
|
//int i;
|
||||||
|
|
||||||
|
pgp_cryptinfo_t *cryptinfo = &cbinfo->cryptinfo;
|
||||||
|
key_id_t *key_id;
|
||||||
|
|
||||||
io = cbinfo->io;
|
io = cbinfo->io;
|
||||||
if (pgp_get_debug_level(__FILE__)) {
|
if (pgp_get_debug_level(__FILE__)) {
|
||||||
pgp_print_packet(&cbinfo->printstate, pkt);
|
//pgp_print_packet(&cbinfo->printstate, pkt);
|
||||||
}
|
}
|
||||||
switch (pkt->tag) {
|
switch (pkt->tag) {
|
||||||
case PGP_GET_SECKEY:
|
case PGP_GET_SECKEY:
|
||||||
/* print key from pubring */
|
/* print key from pubring */
|
||||||
from = 0;
|
// from = 0;
|
||||||
pubkey = pgp_getkeybyid(io, cbinfo->cryptinfo.pubring,
|
// pubkey = pgp_getkeybyid(io, cbinfo->cryptinfo.pubring,
|
||||||
content->get_seckey.pk_sesskey->key_id,
|
// content->get_seckey.pk_sesskey->key_id,
|
||||||
&from, NULL);
|
// &from, NULL);
|
||||||
/* validate key from secring */
|
// /* 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;
|
from = 0;
|
||||||
cbinfo->cryptinfo.keydata =
|
cbinfo->cryptinfo.keydata =
|
||||||
pgp_getkeybyid(io, cbinfo->cryptinfo.secring,
|
pgp_getkeybyid(io, cbinfo->cryptinfo.secring,
|
||||||
content->get_seckey.pk_sesskey->key_id,
|
content->get_seckey.pk_sesskey->key_id,
|
||||||
&from, NULL);
|
&from, NULL, &secret, 0, 0);
|
||||||
if (!cbinfo->cryptinfo.keydata ||
|
if (!cbinfo->cryptinfo.keydata ||
|
||||||
|
!secret ||
|
||||||
!pgp_is_key_secret(cbinfo->cryptinfo.keydata)) {
|
!pgp_is_key_secret(cbinfo->cryptinfo.keydata)) {
|
||||||
return (pgp_cb_ret_t)0;
|
return (pgp_cb_ret_t)0;
|
||||||
}
|
}
|
||||||
keypair = cbinfo->cryptinfo.keydata;
|
|
||||||
if (pubkey == NULL) {
|
// FIXME : support encrypted seckeys again
|
||||||
pubkey = keypair;
|
// keypair = cbinfo->cryptinfo.keydata;
|
||||||
}
|
// if (pubkey == NULL) {
|
||||||
secret = NULL;
|
// pubkey = keypair;
|
||||||
cbinfo->gotpass = 0;
|
// }
|
||||||
for (i = 0 ; cbinfo->numtries == -1 || i < cbinfo->numtries ; i++) {
|
// secret = NULL;
|
||||||
/* print out the user id */
|
// cbinfo->gotpass = 0;
|
||||||
pgp_print_keydata(io, cbinfo->cryptinfo.pubring, pubkey,
|
// for (i = 0 ; cbinfo->numtries == -1 || i < cbinfo->numtries ; i++) {
|
||||||
"signature ", &pubkey->key.pubkey, 0);
|
// /* print out the user id */
|
||||||
/* now decrypt key */
|
// pgp_print_keydata(io, cbinfo->cryptinfo.pubring, pubkey,
|
||||||
secret = pgp_decrypt_seckey(keypair, cbinfo->passfp);
|
// "signature ", &pubkey->key.pubkey, 0);
|
||||||
if (secret != NULL) {
|
// /* now decrypt key */
|
||||||
break;
|
// pgp_decrypt_seckey(keypair, cbinfo->passfp);
|
||||||
}
|
// if (secret != NULL) {
|
||||||
(void) fprintf(io->errs, "Bad passphrase\n");
|
// break;
|
||||||
}
|
// }
|
||||||
if (secret == NULL) {
|
// (void) fprintf(io->errs, "Bad passphrase\n");
|
||||||
(void) fprintf(io->errs, "Exhausted passphrase attempts\n");
|
// }
|
||||||
return (pgp_cb_ret_t)PGP_RELEASE_MEMORY;
|
// if (secret == NULL) {
|
||||||
}
|
// (void) fprintf(io->errs, "Exhausted passphrase attempts\n");
|
||||||
|
// return (pgp_cb_ret_t)PGP_RELEASE_MEMORY;
|
||||||
|
// }
|
||||||
|
|
||||||
cbinfo->gotpass = 1;
|
cbinfo->gotpass = 1;
|
||||||
*content->get_seckey.seckey = secret;
|
*content->get_seckey.seckey = secret;
|
||||||
break;
|
break;
|
||||||
|
@ -2268,39 +2271,6 @@ pgp_get_seckey_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
|
||||||
return PGP_RELEASE_MEMORY;
|
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
|
unsigned
|
||||||
pgp_reader_set_accumulate(pgp_stream_t *stream, unsigned state)
|
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(errors);
|
||||||
__PGP_USED(cbinfo);
|
__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));
|
n = (unsigned)MIN(length, (unsigned)(mem->size - mem->offset));
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
(void) memcpy(dest, &cmem[(int)mem->offset], (unsigned)n);
|
(void) memcpy(dest, &cmem[(int)mem->offset], (unsigned)n);
|
||||||
mem->offset += n;
|
mem->offset += n;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return (int)n;
|
return (int)n;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
|
|
||||||
/** \file
|
/** \file
|
||||||
*/
|
*/
|
||||||
#include "config-netpgp.h"
|
#include "netpgp/config-netpgp.h"
|
||||||
|
|
||||||
#ifdef HAVE_SYS_CDEFS_H
|
#ifdef HAVE_SYS_CDEFS_H
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
|
|
||||||
#if defined(__NetBSD__)
|
#if defined(__NetBSD__)
|
||||||
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
|
__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
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#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>
|
#include <openssl/dsa.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "signature-netpgp.h"
|
#include "netpgp/signature.h"
|
||||||
#include "crypto-netpgp.h"
|
#include "netpgp/crypto.h"
|
||||||
#include "create-netpgp.h"
|
#include "netpgp/create.h"
|
||||||
#include "netpgpsdk.h"
|
#include "netpgp/netpgpsdk.h"
|
||||||
#include "readerwriter-netpgp.h"
|
#include "netpgp/readerwriter.h"
|
||||||
#include "validate-netpgp.h"
|
#include "netpgp/validate.h"
|
||||||
#include "netpgpdefs.h"
|
#include "netpgp/netpgpdefs.h"
|
||||||
#include "netpgpdigest.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
|
\ingroup Core_Signature
|
||||||
Creates new pgp_create_sig_t
|
Creates new pgp_create_sig_t
|
||||||
|
@ -149,6 +136,11 @@ static uint8_t prefix_sha256[] = {
|
||||||
0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
|
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 */
|
/* XXX: both this and verify would be clearer if the signature were */
|
||||||
/* treated as an MPI. */
|
/* treated as an MPI. */
|
||||||
|
@ -174,11 +166,16 @@ rsa_sign(pgp_hash_t *hash,
|
||||||
prefix = prefix_sha1;
|
prefix = prefix_sha1;
|
||||||
prefixsize = sizeof(prefix_sha1);
|
prefixsize = sizeof(prefix_sha1);
|
||||||
expected = PGP_SHA1_HASH_SIZE;
|
expected = PGP_SHA1_HASH_SIZE;
|
||||||
} else {
|
} else if (strcmp(hash->name, "SHA256") == 0) {
|
||||||
hashsize = PGP_SHA256_HASH_SIZE + sizeof(prefix_sha256);
|
hashsize = PGP_SHA256_HASH_SIZE + sizeof(prefix_sha256);
|
||||||
prefix = prefix_sha256;
|
prefix = prefix_sha256;
|
||||||
prefixsize = sizeof(prefix_sha256);
|
prefixsize = sizeof(prefix_sha256);
|
||||||
expected = PGP_SHA256_HASH_SIZE;
|
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;
|
keysize = (BN_num_bits(pubrsa->n) + 7) / 8;
|
||||||
if (keysize > sizeof(hashbuf)) {
|
if (keysize > sizeof(hashbuf)) {
|
||||||
|
@ -231,7 +228,7 @@ dsa_sign(pgp_hash_t *hash,
|
||||||
unsigned hashsize;
|
unsigned hashsize;
|
||||||
unsigned t;
|
unsigned t;
|
||||||
uint8_t hashbuf[NETPGP_BUFSIZ];
|
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, */
|
/* hashsize must be "equal in size to the number of bits of q, */
|
||||||
/* the group generated by the DSA key's generator value */
|
/* 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);
|
pgp_write(output, &hashbuf[0], 2);
|
||||||
|
|
||||||
/* write signature to buf */
|
/* 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 */
|
/* convert and write the sig out to memory */
|
||||||
pgp_write_mpi(output, dsasig->r);
|
pgp_write_mpi(output, pgpdsasig->r);
|
||||||
pgp_write_mpi(output, dsasig->s);
|
pgp_write_mpi(output, pgpdsasig->s);
|
||||||
DSA_SIG_free(dsasig);
|
|
||||||
|
BN_free(pgpdsasig->r);
|
||||||
|
BN_free(pgpdsasig->s);
|
||||||
|
free(pgpdsasig);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,8 +276,6 @@ rsa_verify(pgp_hash_alg_t type,
|
||||||
uint8_t sigbuf[NETPGP_BUFSIZ];
|
uint8_t sigbuf[NETPGP_BUFSIZ];
|
||||||
uint8_t hashbuf_from_sig[NETPGP_BUFSIZ];
|
uint8_t hashbuf_from_sig[NETPGP_BUFSIZ];
|
||||||
|
|
||||||
plen = 0;
|
|
||||||
prefix = (const uint8_t *) "";
|
|
||||||
keysize = BN_num_bytes(pubrsa->n);
|
keysize = BN_num_bytes(pubrsa->n);
|
||||||
/* RSA key can't be bigger than 65535 bits, so... */
|
/* RSA key can't be bigger than 65535 bits, so... */
|
||||||
if (keysize > sizeof(hashbuf_from_sig)) {
|
if (keysize > sizeof(hashbuf_from_sig)) {
|
||||||
|
@ -315,6 +316,10 @@ rsa_verify(pgp_hash_alg_t type,
|
||||||
prefix = prefix_sha256;
|
prefix = prefix_sha256;
|
||||||
plen = sizeof(prefix_sha256);
|
plen = sizeof(prefix_sha256);
|
||||||
break;
|
break;
|
||||||
|
case PGP_HASH_SHA512:
|
||||||
|
prefix = prefix_sha512;
|
||||||
|
plen = sizeof(prefix_sha512);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
(void) fprintf(stderr, "Unknown hash algorithm: %d\n", type);
|
(void) fprintf(stderr, "Unknown hash algorithm: %d\n", type);
|
||||||
return 0;
|
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, 0x99, 1);
|
||||||
pgp_hash_add_int(hash, (unsigned)len, 2);
|
pgp_hash_add_int(hash, (unsigned)len, 2);
|
||||||
hash->add(hash, pgp_mem_data(mem), (unsigned)len);
|
hash->add(hash, pgp_mem_data(mem), (unsigned)len);
|
||||||
|
|
||||||
pgp_memory_free(mem);
|
pgp_memory_free(mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,12 +386,11 @@ init_key_sig(pgp_hash_t *hash, const pgp_sig_t *sig,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hash_add_trailer(pgp_hash_t *hash, const pgp_sig_t *sig,
|
hash_add_trailer(pgp_hash_t *hash, const pgp_sig_t *sig)
|
||||||
const uint8_t *raw_packet)
|
|
||||||
{
|
{
|
||||||
if (sig->info.version == PGP_V4) {
|
if (sig->info.version == PGP_V4) {
|
||||||
if (raw_packet) {
|
if (sig->info.v4_hashlen) {
|
||||||
hash->add(hash, raw_packet + sig->v4_hashstart,
|
hash->add(hash, sig->info.v4_hashed,
|
||||||
(unsigned)sig->info.v4_hashlen);
|
(unsigned)sig->info.v4_hashlen);
|
||||||
}
|
}
|
||||||
pgp_hash_add_int(hash, (unsigned)sig->info.version, 1);
|
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__)) {
|
if (pgp_get_debug_level(__FILE__)) {
|
||||||
hexdump(stdout, "hash", hash, length);
|
hexdump(stdout, "hash", hash, length);
|
||||||
}
|
}
|
||||||
ret = 0;
|
|
||||||
switch (sig->info.key_alg) {
|
switch (sig->info.key_alg) {
|
||||||
case PGP_PKA_DSA:
|
case PGP_PKA_DSA:
|
||||||
ret = pgp_dsa_verify(hash, length, &sig->info.sig.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
|
static unsigned
|
||||||
finalise_sig(pgp_hash_t *hash,
|
finalise_sig(pgp_hash_t *hash,
|
||||||
const pgp_sig_t *sig,
|
const pgp_sig_t *sig,
|
||||||
const pgp_pubkey_t *signer,
|
const pgp_pubkey_t *signer)
|
||||||
const uint8_t *raw_packet)
|
|
||||||
{
|
{
|
||||||
hash_add_trailer(hash, sig, raw_packet);
|
hash_add_trailer(hash, sig);
|
||||||
return hash_and_check_sig(hash, sig, signer);
|
return hash_and_check_sig(hash, sig, signer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -475,8 +479,7 @@ unsigned
|
||||||
pgp_check_useridcert_sig(const pgp_pubkey_t *key,
|
pgp_check_useridcert_sig(const pgp_pubkey_t *key,
|
||||||
const uint8_t *id,
|
const uint8_t *id,
|
||||||
const pgp_sig_t *sig,
|
const pgp_sig_t *sig,
|
||||||
const pgp_pubkey_t *signer,
|
const pgp_pubkey_t *signer)
|
||||||
const uint8_t *raw_packet)
|
|
||||||
{
|
{
|
||||||
pgp_hash_t hash;
|
pgp_hash_t hash;
|
||||||
size_t userid_len;
|
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);
|
pgp_hash_add_int(&hash, (unsigned)userid_len, 4);
|
||||||
}
|
}
|
||||||
hash.add(&hash, id, (unsigned)userid_len);
|
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,
|
pgp_check_userattrcert_sig(const pgp_pubkey_t *key,
|
||||||
const pgp_data_t *attribute,
|
const pgp_data_t *attribute,
|
||||||
const pgp_sig_t *sig,
|
const pgp_sig_t *sig,
|
||||||
const pgp_pubkey_t *signer,
|
const pgp_pubkey_t *signer)
|
||||||
const uint8_t *raw_packet)
|
|
||||||
{
|
{
|
||||||
pgp_hash_t hash;
|
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);
|
pgp_hash_add_int(&hash, (unsigned)attribute->len, 4);
|
||||||
}
|
}
|
||||||
hash.add(&hash, attribute->contents, (unsigned)attribute->len);
|
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,
|
pgp_check_subkey_sig(const pgp_pubkey_t *key,
|
||||||
const pgp_pubkey_t *subkey,
|
const pgp_pubkey_t *subkey,
|
||||||
const pgp_sig_t *sig,
|
const pgp_sig_t *sig,
|
||||||
const pgp_pubkey_t *signer,
|
const pgp_pubkey_t *signer)
|
||||||
const uint8_t *raw_packet)
|
|
||||||
{
|
{
|
||||||
pgp_hash_t hash;
|
pgp_hash_t hash;
|
||||||
unsigned ret;
|
unsigned ret;
|
||||||
|
|
||||||
init_key_sig(&hash, sig, key);
|
init_key_sig(&hash, sig, key);
|
||||||
hash_add_key(&hash, subkey);
|
hash_add_key(&hash, subkey);
|
||||||
ret = finalise_sig(&hash, sig, signer, raw_packet);
|
ret = finalise_sig(&hash, sig, signer);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,14 +564,13 @@ pgp_check_subkey_sig(const pgp_pubkey_t *key,
|
||||||
unsigned
|
unsigned
|
||||||
pgp_check_direct_sig(const pgp_pubkey_t *key,
|
pgp_check_direct_sig(const pgp_pubkey_t *key,
|
||||||
const pgp_sig_t *sig,
|
const pgp_sig_t *sig,
|
||||||
const pgp_pubkey_t *signer,
|
const pgp_pubkey_t *signer)
|
||||||
const uint8_t *raw_packet)
|
|
||||||
{
|
{
|
||||||
pgp_hash_t hash;
|
pgp_hash_t hash;
|
||||||
unsigned ret;
|
unsigned ret;
|
||||||
|
|
||||||
init_key_sig(&hash, sig, key);
|
init_key_sig(&hash, sig, key);
|
||||||
ret = finalise_sig(&hash, sig, signer, raw_packet);
|
ret = finalise_sig(&hash, sig, signer);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -592,7 +592,7 @@ pgp_check_hash_sig(pgp_hash_t *hash,
|
||||||
const pgp_pubkey_t *signer)
|
const pgp_pubkey_t *signer)
|
||||||
{
|
{
|
||||||
return (sig->info.hash_alg == hash->alg) ?
|
return (sig->info.hash_alg == hash->alg) ?
|
||||||
finalise_sig(hash, sig, signer, NULL) :
|
finalise_sig(hash, sig, signer) :
|
||||||
0;
|
0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -649,6 +649,22 @@ pgp_sig_start_key_sig(pgp_create_sig_t *sig,
|
||||||
start_sig_in_mem(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
|
* \ingroup Core_Signature
|
||||||
*
|
*
|
||||||
|
@ -831,17 +847,100 @@ pgp_write_sig(pgp_output_t *output,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add a time stamp to the output */
|
|
||||||
unsigned
|
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;
|
pgp_content_enum tag;
|
||||||
|
|
||||||
tag = (strcmp(type, "birth") == 0) ?
|
tag = PGP_PTAG_SS_CREATION_TIME;
|
||||||
PGP_PTAG_SS_CREATION_TIME : PGP_PTAG_SS_EXPIRATION_TIME;
|
|
||||||
/* just do 32-bit timestamps for just now - it's in the protocol */
|
sig->sig.info.birthtime = when;
|
||||||
|
sig->sig.info.birthtime_set = 1;
|
||||||
|
|
||||||
return pgp_write_ss_header(sig->output, 5, tag) &&
|
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);
|
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
|
* \ingroup Core_Signature
|
||||||
*
|
*
|
||||||
|
@ -937,8 +1049,8 @@ pgp_sign_file(pgp_io_t *io,
|
||||||
const char *outname,
|
const char *outname,
|
||||||
const pgp_seckey_t *seckey,
|
const pgp_seckey_t *seckey,
|
||||||
const char *hashname,
|
const char *hashname,
|
||||||
const int64_t from,
|
const time_t from,
|
||||||
const uint64_t duration,
|
const time_t duration,
|
||||||
const unsigned armored,
|
const unsigned armored,
|
||||||
const unsigned cleartext,
|
const unsigned cleartext,
|
||||||
const unsigned overwrite)
|
const unsigned overwrite)
|
||||||
|
@ -958,7 +1070,6 @@ pgp_sign_file(pgp_io_t *io,
|
||||||
infile = NULL;
|
infile = NULL;
|
||||||
output = NULL;
|
output = NULL;
|
||||||
hash = NULL;
|
hash = NULL;
|
||||||
fd_out = 0;
|
|
||||||
|
|
||||||
/* find the hash algorithm */
|
/* find the hash algorithm */
|
||||||
hash_alg = pgp_str_to_hash_alg(hashname);
|
hash_alg = pgp_str_to_hash_alg(hashname);
|
||||||
|
@ -1006,8 +1117,8 @@ pgp_sign_file(pgp_io_t *io,
|
||||||
/* - creation time */
|
/* - creation time */
|
||||||
/* - key id */
|
/* - key id */
|
||||||
ret = pgp_writer_use_armored_sig(output) &&
|
ret = pgp_writer_use_armored_sig(output) &&
|
||||||
pgp_add_time(sig, (int64_t)from, "birth") &&
|
pgp_add_creation_time(sig, from) &&
|
||||||
pgp_add_time(sig, (int64_t)duration, "expiration");
|
pgp_add_sig_expiration_time(sig, duration);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
pgp_teardown_file_write(output, fd_out);
|
pgp_teardown_file_write(output, fd_out);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1053,8 +1164,8 @@ pgp_sign_file(pgp_io_t *io,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* add creation time to signature */
|
/* add creation time to signature */
|
||||||
pgp_add_time(sig, (int64_t)from, "birth");
|
pgp_add_creation_time(sig, from);
|
||||||
pgp_add_time(sig, (int64_t)duration, "expiration");
|
pgp_add_sig_expiration_time(sig, duration);
|
||||||
/* add key id to signature */
|
/* add key id to signature */
|
||||||
pgp_keyid(keyid, PGP_KEY_ID_SIZE, &seckey->pubkey, hash_alg);
|
pgp_keyid(keyid, PGP_KEY_ID_SIZE, &seckey->pubkey, hash_alg);
|
||||||
pgp_add_issuer_keyid(sig, keyid);
|
pgp_add_issuer_keyid(sig, keyid);
|
||||||
|
@ -1090,8 +1201,8 @@ pgp_sign_buf(pgp_io_t *io,
|
||||||
const void *input,
|
const void *input,
|
||||||
const size_t insize,
|
const size_t insize,
|
||||||
const pgp_seckey_t *seckey,
|
const pgp_seckey_t *seckey,
|
||||||
const int64_t from,
|
const time_t from,
|
||||||
const uint64_t duration,
|
const time_t duration,
|
||||||
const char *hashname,
|
const char *hashname,
|
||||||
const unsigned armored,
|
const unsigned armored,
|
||||||
const unsigned cleartext)
|
const unsigned cleartext)
|
||||||
|
@ -1111,7 +1222,6 @@ pgp_sign_buf(pgp_io_t *io,
|
||||||
output = NULL;
|
output = NULL;
|
||||||
mem = pgp_memory_new();
|
mem = pgp_memory_new();
|
||||||
hash = NULL;
|
hash = NULL;
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
hash_alg = pgp_str_to_hash_alg(hashname);
|
hash_alg = pgp_str_to_hash_alg(hashname);
|
||||||
if (hash_alg == PGP_HASH_UNKNOWN) {
|
if (hash_alg == PGP_HASH_UNKNOWN) {
|
||||||
|
@ -1147,8 +1257,8 @@ pgp_sign_buf(pgp_io_t *io,
|
||||||
ret = pgp_writer_push_clearsigned(output, sig) &&
|
ret = pgp_writer_push_clearsigned(output, sig) &&
|
||||||
pgp_write(output, input, (unsigned)insize) &&
|
pgp_write(output, input, (unsigned)insize) &&
|
||||||
pgp_writer_use_armored_sig(output) &&
|
pgp_writer_use_armored_sig(output) &&
|
||||||
pgp_add_time(sig, from, "birth") &&
|
pgp_add_creation_time(sig, from) &&
|
||||||
pgp_add_time(sig, (int64_t)duration, "expiration");
|
pgp_add_sig_expiration_time(sig, duration);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1178,8 +1288,8 @@ pgp_sign_buf(pgp_io_t *io,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add creation time to signature */
|
/* add creation time to signature */
|
||||||
pgp_add_time(sig, from, "birth");
|
pgp_add_creation_time(sig, from);
|
||||||
pgp_add_time(sig, (int64_t)duration, "expiration");
|
pgp_add_sig_expiration_time(sig, duration);
|
||||||
/* add key id to signature */
|
/* add key id to signature */
|
||||||
pgp_keyid(keyid, PGP_KEY_ID_SIZE, &seckey->pubkey, hash_alg);
|
pgp_keyid(keyid, PGP_KEY_ID_SIZE, &seckey->pubkey, hash_alg);
|
||||||
pgp_add_issuer_keyid(sig, keyid);
|
pgp_add_issuer_keyid(sig, keyid);
|
||||||
|
@ -1200,10 +1310,10 @@ int
|
||||||
pgp_sign_detached(pgp_io_t *io,
|
pgp_sign_detached(pgp_io_t *io,
|
||||||
const char *f,
|
const char *f,
|
||||||
char *sigfile,
|
char *sigfile,
|
||||||
pgp_seckey_t *seckey,
|
const pgp_seckey_t *seckey,
|
||||||
const char *hash,
|
const char *hash,
|
||||||
const int64_t from,
|
const time_t from,
|
||||||
const uint64_t duration,
|
const time_t duration,
|
||||||
const unsigned armored, const unsigned overwrite)
|
const unsigned armored, const unsigned overwrite)
|
||||||
{
|
{
|
||||||
pgp_create_sig_t *sig;
|
pgp_create_sig_t *sig;
|
||||||
|
@ -1246,14 +1356,13 @@ pgp_sign_detached(pgp_io_t *io,
|
||||||
pgp_memory_free(mem);
|
pgp_memory_free(mem);
|
||||||
|
|
||||||
/* calculate the signature */
|
/* calculate the signature */
|
||||||
pgp_add_time(sig, from, "birth");
|
pgp_add_creation_time(sig, from);
|
||||||
pgp_add_time(sig, (int64_t)duration, "expiration");
|
pgp_add_sig_expiration_time(sig, duration);
|
||||||
pgp_keyid(keyid, sizeof(keyid), &seckey->pubkey, hash_alg);
|
pgp_keyid(keyid, sizeof(keyid), &seckey->pubkey, hash_alg);
|
||||||
pgp_add_issuer_keyid(sig, keyid);
|
pgp_add_issuer_keyid(sig, keyid);
|
||||||
pgp_end_hashed_subpkts(sig);
|
pgp_end_hashed_subpkts(sig);
|
||||||
pgp_write_sig(output, sig, &seckey->pubkey, seckey);
|
pgp_write_sig(output, sig, &seckey->pubkey, seckey);
|
||||||
pgp_teardown_file_write(output, fd);
|
pgp_teardown_file_write(output, fd);
|
||||||
pgp_seckey_free(seckey);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
|
@ -46,7 +46,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#include "config-netpgp.h"
|
#include "netpgp/config-netpgp.h"
|
||||||
|
|
||||||
#ifdef HAVE_SYS_CDEFS_H
|
#ifdef HAVE_SYS_CDEFS_H
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
@ -54,11 +54,11 @@
|
||||||
|
|
||||||
#if defined(__NetBSD__)
|
#if defined(__NetBSD__)
|
||||||
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
|
__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
|
#endif
|
||||||
|
|
||||||
#include "crypto-netpgp.h"
|
#include "netpgp/crypto.h"
|
||||||
#include "packet-show.h"
|
#include "netpgp/packet-show.h"
|
||||||
|
|
||||||
#include <string.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>
|
#include <openssl/camellia.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "crypto-netpgp.h"
|
#include "netpgp/crypto.h"
|
||||||
#include "netpgpdefs.h"
|
#include "netpgp/netpgpdefs.h"
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
|
@ -46,7 +46,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#include "config-netpgp.h"
|
#include "netpgp/config-netpgp.h"
|
||||||
|
|
||||||
#ifdef HAVE_SYS_CDEFS_H
|
#ifdef HAVE_SYS_CDEFS_H
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
|
|
||||||
#if defined(__NetBSD__)
|
#if defined(__NetBSD__)
|
||||||
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
|
__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
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#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>
|
#include <fcntl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "packet-parse.h"
|
#include "netpgp/packet-parse.h"
|
||||||
#include "packet-show.h"
|
#include "netpgp/packet-show.h"
|
||||||
#include "keyring-netpgp.h"
|
#include "netpgp/keyring.h"
|
||||||
#include "signature-netpgp.h"
|
#include "netpgp/signature.h"
|
||||||
#include "netpgpsdk.h"
|
#include "netpgp/netpgpsdk.h"
|
||||||
#include "readerwriter-netpgp.h"
|
#include "netpgp/readerwriter.h"
|
||||||
#include "netpgpdefs.h"
|
#include "netpgp/netpgpdefs.h"
|
||||||
#include "memory-netpgp.h"
|
#include "netpgp/memory.h"
|
||||||
#include "packet-netpgp.h"
|
#include "netpgp/packet.h"
|
||||||
#include "crypto-netpgp.h"
|
#include "netpgp/crypto.h"
|
||||||
#include "validate-netpgp.h"
|
#include "netpgp/validate.h"
|
||||||
|
|
||||||
#ifdef HAVE_FCNTL_H
|
#ifdef HAVE_FCNTL_H
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// FIXME to support seckey decryption again.
|
||||||
static int
|
//
|
||||||
keydata_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
|
// static int
|
||||||
pgp_reader_t *readinfo,
|
// keydata_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
|
||||||
pgp_cbdata_t *cbinfo)
|
// pgp_reader_t *readinfo,
|
||||||
{
|
// pgp_cbdata_t *cbinfo)
|
||||||
validate_reader_t *reader = pgp_reader_get_arg(readinfo);
|
// {
|
||||||
|
// validate_reader_t *reader = pgp_reader_get_arg(readinfo);
|
||||||
__PGP_USED(stream);
|
//
|
||||||
__PGP_USED(errors);
|
// __PGP_USED(stream);
|
||||||
__PGP_USED(cbinfo);
|
// __PGP_USED(errors);
|
||||||
if (reader->offset == reader->key->packets[reader->packet].length) {
|
// __PGP_USED(cbinfo);
|
||||||
reader->packet += 1;
|
// if (reader->offset == reader->key->packets[reader->packet].length) {
|
||||||
reader->offset = 0;
|
// reader->packet += 1;
|
||||||
}
|
// reader->offset = 0;
|
||||||
if (reader->packet == reader->key->packetc) {
|
// }
|
||||||
return 0;
|
// if (reader->packet == reader->key->packetc) {
|
||||||
}
|
// return 0;
|
||||||
|
// }
|
||||||
/*
|
//
|
||||||
* we should never be asked to cross a packet boundary in a single
|
// /*
|
||||||
* read
|
// * we should never be asked to cross a packet boundary in a single
|
||||||
*/
|
// * read
|
||||||
if (reader->key->packets[reader->packet].length <
|
// */
|
||||||
reader->offset + length) {
|
// if (reader->key->packets[reader->packet].length <
|
||||||
(void) fprintf(stderr, "keydata_reader: weird length\n");
|
// reader->offset + length) {
|
||||||
return 0;
|
// (void) fprintf(stderr, "keydata_reader: weird length\n");
|
||||||
}
|
// return 0;
|
||||||
|
// }
|
||||||
(void) memcpy(dest,
|
//
|
||||||
&reader->key->packets[reader->packet].raw[reader->offset],
|
// (void) memcpy(dest,
|
||||||
length);
|
// &reader->key->packets[reader->packet].raw[reader->offset],
|
||||||
reader->offset += (unsigned)length;
|
// length);
|
||||||
|
// reader->offset += (unsigned)length;
|
||||||
return (int)length;
|
//
|
||||||
}
|
// return (int)length;
|
||||||
|
// }
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_sig_info(pgp_sig_info_t *sig)
|
free_sig_info(pgp_sig_info_t *sig)
|
||||||
{
|
{
|
||||||
free(sig->v4_hashed);
|
pgp_free_sig_info(sig);
|
||||||
free(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
|
static int
|
||||||
add_sig_to_list(const pgp_sig_info_t *sig, pgp_sig_info_t **sigs,
|
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);
|
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_cb_ret_t
|
||||||
pgp_validate_key_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
|
pgp_validate_key_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
|
||||||
{
|
{
|
||||||
const pgp_contents_t *content = &pkt->u;
|
const pgp_contents_t *content = &pkt->u;
|
||||||
const pgp_key_t *signer;
|
validate_key_cb_t *vdata;
|
||||||
validate_key_cb_t *key;
|
|
||||||
pgp_pubkey_t *sigkey;
|
|
||||||
pgp_error_t **errors;
|
pgp_error_t **errors;
|
||||||
pgp_io_t *io;
|
pgp_io_t *io;
|
||||||
unsigned from;
|
|
||||||
unsigned valid = 0;
|
unsigned valid = 0;
|
||||||
|
|
||||||
io = cbinfo->io;
|
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",
|
(void) fprintf(io->errs, "%s\n",
|
||||||
pgp_show_packet_tag(pkt->tag));
|
pgp_show_packet_tag(pkt->tag));
|
||||||
}
|
}
|
||||||
key = pgp_callback_arg(cbinfo);
|
vdata = pgp_callback_arg(cbinfo);
|
||||||
errors = pgp_callback_errors(cbinfo);
|
errors = pgp_callback_errors(cbinfo);
|
||||||
|
|
||||||
|
vdata->sig_is_valid &= pkt->tag == PGP_PARSER_PACKET_END;
|
||||||
|
|
||||||
switch (pkt->tag) {
|
switch (pkt->tag) {
|
||||||
case PGP_PTAG_CT_PUBLIC_KEY:
|
case PGP_PTAG_CT_PUBLIC_KEY:
|
||||||
if (key->pubkey.version != 0) {
|
validate_key_cb_free(vdata);
|
||||||
(void) fprintf(io->errs,
|
vdata->key.pubkey = content->pubkey;
|
||||||
"pgp_validate_key_cb: version bad\n");
|
pgp_keyid(vdata->pubkeyid, PGP_KEY_ID_SIZE,
|
||||||
return PGP_FINISHED;
|
&vdata->key.pubkey, PGP_HASH_SHA1); /* TODO v3*/
|
||||||
}
|
|
||||||
key->pubkey = content->pubkey;
|
|
||||||
return PGP_KEEP_MEMORY;
|
|
||||||
|
|
||||||
case PGP_PTAG_CT_PUBLIC_SUBKEY:
|
vdata->last_seen = LS_PRIMARY;
|
||||||
if (key->subkey.version) {
|
vdata->type = PGP_PTAG_CT_PUBLIC_KEY;
|
||||||
pgp_pubkey_free(&key->subkey);
|
vdata->not_commited = 1;
|
||||||
}
|
|
||||||
key->subkey = content->pubkey;
|
|
||||||
return PGP_KEEP_MEMORY;
|
return PGP_KEEP_MEMORY;
|
||||||
|
|
||||||
case PGP_PTAG_CT_SECRET_KEY:
|
case PGP_PTAG_CT_SECRET_KEY:
|
||||||
key->seckey = content->seckey;
|
/* TODO
|
||||||
key->pubkey = key->seckey.pubkey;
|
* 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;
|
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:
|
case PGP_PTAG_CT_USER_ID:
|
||||||
if (key->userid) {
|
if(vdata->last_seen == LS_PRIMARY ||
|
||||||
pgp_userid_free(&key->userid);
|
vdata->last_seen == LS_ATTRIBUTE ||
|
||||||
|
vdata->last_seen == LS_ID){
|
||||||
|
if (vdata->userid) {
|
||||||
|
pgp_userid_free(&vdata->userid);
|
||||||
}
|
}
|
||||||
key->userid = content->userid;
|
vdata->userid = content->userid;
|
||||||
key->last_seen = ID;
|
vdata->last_seen = LS_ID;
|
||||||
return PGP_KEEP_MEMORY;
|
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:
|
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) {
|
if (content->userattr.len == 0) {
|
||||||
(void) fprintf(io->errs,
|
(void) fprintf(io->errs,
|
||||||
"pgp_validate_key_cb: user attribute length 0");
|
"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",
|
(void) fprintf(io->outs, "user attribute, length=%d\n",
|
||||||
(int) content->userattr.len);
|
(int) content->userattr.len);
|
||||||
if (key->userattr.len) {
|
if (vdata->userattr.len) {
|
||||||
pgp_data_free(&key->userattr);
|
pgp_data_free(&vdata->userattr);
|
||||||
}
|
}
|
||||||
key->userattr = content->userattr;
|
vdata->userattr = content->userattr;
|
||||||
key->last_seen = ATTRIBUTE;
|
vdata->last_seen = LS_ATTRIBUTE;
|
||||||
return PGP_KEEP_MEMORY;
|
return PGP_KEEP_MEMORY;
|
||||||
|
}else{
|
||||||
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)) {
|
|
||||||
(void) fprintf(io->errs,
|
(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;
|
return PGP_FINISHED;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (sigkey == &signer->enckey) {
|
|
||||||
(void) fprintf(io->errs,
|
|
||||||
"WARNING: signature made with encryption key\n");
|
|
||||||
}
|
|
||||||
switch (content->sig.info.type) {
|
switch (content->sig.info.type) {
|
||||||
case PGP_CERT_GENERIC:
|
case PGP_CERT_GENERIC:
|
||||||
case PGP_CERT_PERSONA:
|
case PGP_CERT_PERSONA:
|
||||||
case PGP_CERT_CASUAL:
|
case PGP_CERT_CASUAL:
|
||||||
case PGP_CERT_POSITIVE:
|
case PGP_CERT_POSITIVE:
|
||||||
case PGP_SIG_REV_CERT:
|
case PGP_SIG_REV_CERT:
|
||||||
valid = (key->last_seen == ID) ?
|
if(vdata->last_seen == LS_ID){
|
||||||
pgp_check_useridcert_sig(&key->pubkey,
|
valid = pgp_check_useridcert_sig(
|
||||||
key->userid,
|
primary_pubkey,
|
||||||
|
vdata->userid,
|
||||||
&content->sig,
|
&content->sig,
|
||||||
pgp_get_pubkey(signer),
|
sigkey);
|
||||||
key->reader->key->packets[
|
} else if(vdata->last_seen == LS_ATTRIBUTE) {
|
||||||
key->reader->packet].raw) :
|
valid = pgp_check_userattrcert_sig(
|
||||||
pgp_check_userattrcert_sig(&key->pubkey,
|
primary_pubkey,
|
||||||
&key->userattr,
|
&vdata->userattr,
|
||||||
&content->sig,
|
&content->sig,
|
||||||
pgp_get_pubkey(signer),
|
sigkey);
|
||||||
key->reader->key->packets[
|
}
|
||||||
key->reader->packet].raw);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PGP_SIG_REV_SUBKEY:
|
||||||
case PGP_SIG_SUBKEY:
|
case PGP_SIG_SUBKEY:
|
||||||
/*
|
/*
|
||||||
* XXX: we should also check that the signer is the
|
* we ensure that the signing key is the
|
||||||
* key we are validating, I think.
|
* primary key we are validating, "vdata->pubkey".
|
||||||
*/
|
*/
|
||||||
valid = pgp_check_subkey_sig(&key->pubkey,
|
if(vdata->last_seen == LS_SUBKEY &&
|
||||||
&key->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,
|
&content->sig,
|
||||||
pgp_get_pubkey(signer),
|
primary_pubkey);
|
||||||
key->reader->key->packets[
|
}
|
||||||
key->reader->packet].raw);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PGP_SIG_REV_KEY:
|
||||||
case PGP_SIG_DIRECT:
|
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,
|
&content->sig,
|
||||||
pgp_get_pubkey(signer),
|
sigkey);
|
||||||
key->reader->key->packets[
|
}
|
||||||
key->reader->packet].raw);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PGP_SIG_STANDALONE:
|
case PGP_SIG_STANDALONE:
|
||||||
case PGP_SIG_PRIMARY:
|
case PGP_SIG_PRIMARY:
|
||||||
case PGP_SIG_REV_KEY:
|
|
||||||
case PGP_SIG_REV_SUBKEY:
|
|
||||||
case PGP_SIG_TIMESTAMP:
|
case PGP_SIG_TIMESTAMP:
|
||||||
case PGP_SIG_3RD_PARTY:
|
case PGP_SIG_3RD_PARTY:
|
||||||
|
if (vdata->result){
|
||||||
PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED,
|
PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED,
|
||||||
"Sig Verification type 0x%02x not done yet\n",
|
"Sig Verification type 0x%02x not done yet\n",
|
||||||
content->sig.info.type);
|
content->sig.info.type);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if (vdata->result){
|
||||||
PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED,
|
PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED,
|
||||||
"Unexpected signature type 0x%02x\n",
|
"Unexpected signature type 0x%02x\n",
|
||||||
content->sig.info.type);
|
content->sig.info.type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (!add_sig_to_list(&content->sig.info,
|
if (vdata->result && !add_sig_to_list(&content->sig.info,
|
||||||
&key->result->valid_sigs,
|
&vdata->result->valid_sigs,
|
||||||
&key->result->validc)) {
|
&vdata->result->validc)) {
|
||||||
PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED, "%s",
|
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",
|
PGP_ERROR_1(errors, PGP_E_V_BAD_SIGNATURE, "%s",
|
||||||
"Bad Sig");
|
"Bad Sig");
|
||||||
if (!add_sig_to_list(&content->sig.info,
|
if (!add_sig_to_list(&content->sig.info,
|
||||||
&key->result->invalid_sigs,
|
&vdata->result->invalid_sigs,
|
||||||
&key->result->invalidc)) {
|
&vdata->result->invalidc)) {
|
||||||
PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED, "%s",
|
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;
|
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 */
|
/* ignore these */
|
||||||
case PGP_PARSER_PTAG:
|
case PGP_PARSER_PTAG:
|
||||||
case PGP_PTAG_CT_SIGNATURE_HEADER:
|
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:
|
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;
|
break;
|
||||||
|
|
||||||
|
// case PGP_GET_PASSPHRASE:
|
||||||
|
// if (vdata->getpassphrase) {
|
||||||
|
// return vdata->getpassphrase(pkt, cbinfo);
|
||||||
|
// }
|
||||||
|
// break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
(void) fprintf(stderr, "unexpected tag=0x%x\n", pkt->tag);
|
// (void) fprintf(stderr, "unexpected tag=0x%x\n", pkt->tag);
|
||||||
return PGP_FINISHED;
|
return PGP_RELEASE_MEMORY;
|
||||||
}
|
}
|
||||||
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)
|
validate_data_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
|
||||||
{
|
{
|
||||||
const pgp_contents_t *content = &pkt->u;
|
const pgp_contents_t *content = &pkt->u;
|
||||||
const pgp_key_t *signer;
|
pgp_key_t *signer;
|
||||||
validate_data_cb_t *data;
|
validate_data_cb_t *data;
|
||||||
pgp_pubkey_t *sigkey;
|
pgp_pubkey_t *sigkey;
|
||||||
pgp_error_t **errors;
|
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));
|
sizeof(content->sig.info.signer_id));
|
||||||
}
|
}
|
||||||
from = 0;
|
from = 0;
|
||||||
|
sigkey = NULL;
|
||||||
signer = pgp_getkeybyid(io, data->keyring,
|
signer = pgp_getkeybyid(io, data->keyring,
|
||||||
content->sig.info.signer_id, &from, &sigkey);
|
content->sig.info.signer_id, &from, &sigkey, NULL,
|
||||||
if (!signer) {
|
0, 0); /* check neither revocation nor expiry */
|
||||||
|
if (!signer || !sigkey) {
|
||||||
PGP_ERROR_1(errors, PGP_E_V_UNKNOWN_SIGNER,
|
PGP_ERROR_1(errors, PGP_E_V_UNKNOWN_SIGNER,
|
||||||
"%s", "Unknown Signer");
|
"%s", "Unknown Signer");
|
||||||
if (!add_sig_to_list(&content->sig.info,
|
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;
|
break;
|
||||||
}
|
}
|
||||||
if (sigkey == &signer->enckey) {
|
|
||||||
(void) fprintf(io->errs,
|
|
||||||
"WARNING: signature made with encryption key\n");
|
|
||||||
}
|
|
||||||
if (content->sig.info.birthtime_set) {
|
if (content->sig.info.birthtime_set) {
|
||||||
data->result->birthtime = content->sig.info.birthtime;
|
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) {
|
switch (content->sig.info.type) {
|
||||||
case PGP_SIG_BINARY:
|
case PGP_SIG_BINARY:
|
||||||
case PGP_SIG_TEXT:
|
case PGP_SIG_TEXT:
|
||||||
if (pgp_mem_len(data->mem) == 0 &&
|
if (pgp_mem_len(data->mem) == 0){
|
||||||
data->detachname) {
|
if(data->detachname) {
|
||||||
/* check we have seen some data */
|
/* check we have seen some data */
|
||||||
/* if not, need to read from detached name */
|
/* if not, need to read from detached name */
|
||||||
(void) fprintf(io->errs,
|
(void) fprintf(io->errs,
|
||||||
|
@ -515,6 +619,7 @@ validate_data_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
|
||||||
data->detachname);
|
data->detachname);
|
||||||
data->mem = pgp_memory_new();
|
data->mem = pgp_memory_new();
|
||||||
pgp_mem_readfile(data->mem, data->detachname);
|
pgp_mem_readfile(data->mem, data->detachname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (pgp_get_debug_level(__FILE__)) {
|
if (pgp_get_debug_level(__FILE__)) {
|
||||||
hexdump(stderr, "sig dump", (const uint8_t *)(const void *)&content->sig,
|
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),
|
valid = check_binary_sig(pgp_mem_data(data->mem),
|
||||||
(const unsigned)pgp_mem_len(data->mem),
|
(const unsigned)pgp_mem_len(data->mem),
|
||||||
&content->sig,
|
&content->sig,
|
||||||
pgp_get_pubkey(signer));
|
sigkey);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -571,27 +676,6 @@ validate_data_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
|
||||||
return PGP_RELEASE_MEMORY;
|
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 *
|
static char *
|
||||||
fmtsecs(int64_t n, char *buf, size_t size)
|
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;
|
return val->validc && !val->invalidc && !val->unknownc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
typedef struct key_filter_cb_t{
|
||||||
* \ingroup HighLevel_Verify
|
pgp_keyring_t *destpubring;
|
||||||
* \brief Validate all signatures on a single key against the given keyring
|
pgp_keyring_t *destsecring;
|
||||||
* \param result Where to put the result
|
pgp_key_t *pubkey;
|
||||||
* \param key Key to validate
|
pgp_key_t *seckey;
|
||||||
* \param keyring Keyring to use for validation
|
} key_filter_cb_t;
|
||||||
* \param cb_get_passphrase Callback to use to get passphrase
|
|
||||||
* \return 1 if all signatures OK; else 0
|
static pgp_cb_ret_t key_filter_cb (
|
||||||
* \note It is the caller's responsiblity to free result after use.
|
validate_key_cb_t *vdata,
|
||||||
* \sa pgp_validate_result_free()
|
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
|
unsigned
|
||||||
pgp_validate_key_sigs(pgp_validation_t *result,
|
pgp_filter_keys_fileread(
|
||||||
const pgp_key_t *key,
|
pgp_io_t *io,
|
||||||
const pgp_keyring_t *keyring,
|
pgp_keyring_t *destpubring,
|
||||||
pgp_cb_ret_t cb_get_passphrase(const pgp_packet_t *,
|
pgp_keyring_t *destsecring,
|
||||||
pgp_cbdata_t *))
|
pgp_keyring_t *certring,
|
||||||
|
const unsigned armour,
|
||||||
|
const char *filename)
|
||||||
{
|
{
|
||||||
pgp_stream_t *stream;
|
pgp_stream_t *stream;
|
||||||
validate_key_cb_t keysigs;
|
validate_key_cb_t vdata;
|
||||||
const int printerrors = 1;
|
key_filter_cb_t filter;
|
||||||
|
unsigned res = 1;
|
||||||
|
int fd;
|
||||||
|
|
||||||
(void) memset(&keysigs, 0x0, sizeof(keysigs));
|
(void) memset(&vdata, 0x0, sizeof(vdata));
|
||||||
keysigs.result = result;
|
vdata.result = NULL;
|
||||||
keysigs.getpassphrase = cb_get_passphrase;
|
vdata.getpassphrase = NULL;
|
||||||
|
|
||||||
stream = pgp_new(sizeof(*stream));
|
(void) memset(&filter, 0x0, sizeof(filter));
|
||||||
/* pgp_parse_options(&opt,PGP_PTAG_CT_SIGNATURE,PGP_PARSE_PARSED); */
|
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);
|
if (fd < 0) {
|
||||||
stream->readinfo.accumulate = 1;
|
perror(filename);
|
||||||
pgp_keydata_reader_set(stream, key);
|
return 0;
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
}
|
||||||
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);
|
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
|
unsigned
|
||||||
pgp_validate_all_sigs(pgp_validation_t *result,
|
pgp_filter_keys_from_mem(
|
||||||
const pgp_keyring_t *ring,
|
pgp_io_t *io,
|
||||||
pgp_cb_ret_t cb_get_passphrase(const pgp_packet_t *,
|
pgp_keyring_t *destpubring,
|
||||||
pgp_cbdata_t *))
|
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));
|
(void) memset(&vdata, 0x0, sizeof(vdata));
|
||||||
for (n = 0; n < ring->keyc; ++n) {
|
vdata.result = NULL;
|
||||||
pgp_validate_key_sigs(result, &ring->keys[n], ring,
|
vdata.getpassphrase = NULL;
|
||||||
cb_get_passphrase);
|
|
||||||
|
(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.keyring = keyring;
|
||||||
validation.mem = pgp_memory_new();
|
validation.mem = pgp_memory_new();
|
||||||
pgp_memory_init(validation.mem, 128);
|
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) {
|
if (realarmour) {
|
||||||
pgp_reader_push_dearmour(parse);
|
pgp_reader_push_dearmour(parse);
|
||||||
|
@ -910,20 +1105,21 @@ pgp_validate_file(pgp_io_t *io,
|
||||||
\param mem Memory to be validated
|
\param mem Memory to be validated
|
||||||
\param user_says_armoured Treat data as armoured, if set
|
\param user_says_armoured Treat data as armoured, if set
|
||||||
\param keyring Keyring to use
|
\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
|
\return 1 if signature validates successfully; 0 if not
|
||||||
\note After verification, result holds the details of all keys which
|
\note After verification, result holds the details of all keys which
|
||||||
have passed, failed and not been recognised.
|
have passed, failed and not been recognised.
|
||||||
\note It is the caller's responsiblity to call
|
\note It is the caller's responsiblity to call
|
||||||
pgp_validate_result_free(result) after use.
|
pgp_validate_result_free(result) after use.
|
||||||
*/
|
*/
|
||||||
|
static inline unsigned
|
||||||
unsigned
|
_pgp_validate_mem(pgp_io_t *io,
|
||||||
pgp_validate_mem(pgp_io_t *io,
|
|
||||||
pgp_validation_t *result,
|
pgp_validation_t *result,
|
||||||
pgp_memory_t *mem,
|
pgp_memory_t *mem,
|
||||||
pgp_memory_t **cat,
|
pgp_memory_t **cat,
|
||||||
const int user_says_armoured,
|
const int user_says_armoured,
|
||||||
const pgp_keyring_t *keyring)
|
const pgp_keyring_t *keyring,
|
||||||
|
pgp_memory_t *detachmem)
|
||||||
{
|
{
|
||||||
validate_data_cb_t validation;
|
validate_data_cb_t validation;
|
||||||
pgp_stream_t *stream = NULL;
|
pgp_stream_t *stream = NULL;
|
||||||
|
@ -931,15 +1127,17 @@ pgp_validate_mem(pgp_io_t *io,
|
||||||
int realarmour;
|
int realarmour;
|
||||||
|
|
||||||
pgp_setup_memory_read(io, &stream, mem, &validation, validate_data_cb, 1);
|
pgp_setup_memory_read(io, &stream, mem, &validation, validate_data_cb, 1);
|
||||||
|
|
||||||
/* Set verification reader and handling options */
|
/* Set verification reader and handling options */
|
||||||
(void) memset(&validation, 0x0, sizeof(validation));
|
(void) memset(&validation, 0x0, sizeof(validation));
|
||||||
validation.result = result;
|
validation.result = result;
|
||||||
validation.keyring = keyring;
|
validation.keyring = keyring;
|
||||||
|
if (detachmem) {
|
||||||
|
validation.mem = detachmem;
|
||||||
|
}else{
|
||||||
validation.mem = pgp_memory_new();
|
validation.mem = pgp_memory_new();
|
||||||
pgp_memory_init(validation.mem, 128);
|
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 ||
|
if ((realarmour = user_says_armoured) != 0 ||
|
||||||
strncmp(pgp_mem_data(mem),
|
strncmp(pgp_mem_data(mem),
|
||||||
|
@ -969,3 +1167,39 @@ pgp_validate_mem(pgp_io_t *io,
|
||||||
|
|
||||||
return validate_result_status(io->errs, NULL, result);
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
/** \file
|
/** \file
|
||||||
* This file contains the base functions used by the writers.
|
* This file contains the base functions used by the writers.
|
||||||
*/
|
*/
|
||||||
#include "config-netpgp.h"
|
#include "netpgp/config-netpgp.h"
|
||||||
|
|
||||||
#ifdef HAVE_SYS_CDEFS_H
|
#ifdef HAVE_SYS_CDEFS_H
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
@ -58,7 +58,7 @@
|
||||||
|
|
||||||
#if defined(__NetBSD__)
|
#if defined(__NetBSD__)
|
||||||
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
|
__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
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#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>
|
#include <openssl/cast.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "create-netpgp.h"
|
#include "netpgp/create.h"
|
||||||
#include "writer-netpgp.h"
|
#include "netpgp/writer.h"
|
||||||
#include "keyring-netpgp.h"
|
#include "netpgp/keyring.h"
|
||||||
#include "signature-netpgp.h"
|
#include "netpgp/signature.h"
|
||||||
#include "packet-netpgp.h"
|
#include "netpgp/packet.h"
|
||||||
#include "packet-parse.h"
|
#include "netpgp/packet-parse.h"
|
||||||
#include "readerwriter-netpgp.h"
|
#include "netpgp/readerwriter.h"
|
||||||
#include "memory-netpgp.h"
|
#include "netpgp/memory.h"
|
||||||
#include "netpgpdefs.h"
|
#include "netpgp/netpgpdefs.h"
|
||||||
#include "version-netpgp.h"
|
#include "netpgp/version.h"
|
||||||
#include "netpgpdigest.h"
|
#include "netpgp/netpgpdigest.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -285,11 +285,13 @@ pgp_writer_push(pgp_output_t *output,
|
||||||
{
|
{
|
||||||
pgp_writer_t *copy;
|
pgp_writer_t *copy;
|
||||||
|
|
||||||
if ((copy = calloc(1, sizeof(*copy))) == NULL) {
|
if (output->writer.writer == NULL) {
|
||||||
(void) fprintf(stderr, "pgp_writer_push: bad alloc\n");
|
|
||||||
} else if (output->writer.writer == NULL) {
|
|
||||||
(void) fprintf(stderr, "pgp_writer_push: no orig writer\n");
|
(void) fprintf(stderr, "pgp_writer_push: no orig writer\n");
|
||||||
} else {
|
} else {
|
||||||
|
if ((copy = calloc(1, sizeof(*copy))) == NULL) {
|
||||||
|
(void) fprintf(stderr, "pgp_writer_push: bad alloc\n");
|
||||||
|
return; /* TODO return error */
|
||||||
|
}
|
||||||
*copy = output->writer;
|
*copy = output->writer;
|
||||||
output->writer.next = copy;
|
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) {
|
if ((base64 = calloc(1, sizeof(*base64))) == NULL) {
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
"pgp_writer_push_armoured: bad alloc\n");
|
"pgp_writer_push_armoured: bad alloc\n");
|
||||||
|
free(linebreak);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
base64->checksum = CRC24_INIT;
|
base64->checksum = CRC24_INIT;
|
||||||
|
@ -1011,6 +1014,7 @@ pgp_push_enc_crypt(pgp_output_t *output, pgp_crypt_t *pgp_crypt)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
pgp_crypt_t *crypt;
|
pgp_crypt_t *crypt;
|
||||||
|
unsigned raw;
|
||||||
} encrypt_se_ip_t;
|
} encrypt_se_ip_t;
|
||||||
|
|
||||||
static unsigned encrypt_se_ip_writer(const uint8_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
|
\brief Push Encrypted SE IP Writer onto stack
|
||||||
*/
|
*/
|
||||||
int
|
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;
|
pgp_pk_sesskey_t *encrypted_pk_sesskey;
|
||||||
encrypt_se_ip_t *se_ip;
|
encrypt_se_ip_t *se_ip;
|
||||||
pgp_crypt_t *encrypted;
|
pgp_crypt_t *encrypted;
|
||||||
uint8_t *iv;
|
uint8_t *iv;
|
||||||
|
unsigned n;
|
||||||
|
|
||||||
if ((se_ip = calloc(1, sizeof(*se_ip))) == NULL) {
|
if ((se_ip = calloc(1, sizeof(*se_ip))) == NULL) {
|
||||||
(void) fprintf(stderr, "pgp_push_enc_se_ip: bad alloc\n");
|
(void) fprintf(stderr, "pgp_push_enc_se_ip: bad alloc\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (n = 0; n < pubkeys->keyc; ++n) {
|
||||||
/* Create and write encrypted PK session key */
|
/* 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");
|
(void) fprintf(stderr, "pgp_push_enc_se_ip: null pk sesskey\n");
|
||||||
|
free(se_ip);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (initial_sesskey == NULL) {
|
||||||
|
initial_sesskey = encrypted_pk_sesskey;
|
||||||
|
}
|
||||||
|
|
||||||
pgp_write_pk_sesskey(output, 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 */
|
/* Setup the se_ip */
|
||||||
if ((encrypted = calloc(1, sizeof(*encrypted))) == NULL) {
|
if ((encrypted = calloc(1, sizeof(*encrypted))) == NULL) {
|
||||||
free(se_ip);
|
free(se_ip);
|
||||||
(void) fprintf(stderr, "pgp_push_enc_se_ip: bad alloc\n");
|
(void) fprintf(stderr, "pgp_push_enc_se_ip: bad alloc\n");
|
||||||
return 0;
|
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) {
|
if ((iv = calloc(1, encrypted->blocksize)) == NULL) {
|
||||||
free(se_ip);
|
free(se_ip);
|
||||||
free(encrypted);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
encrypted->set_iv(encrypted, iv);
|
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);
|
pgp_encrypt_init(encrypted);
|
||||||
|
|
||||||
se_ip->crypt = encrypted;
|
se_ip->crypt = encrypted;
|
||||||
|
se_ip->raw = raw;
|
||||||
|
|
||||||
/* And push writer on stack */
|
/* And push writer on stack */
|
||||||
pgp_writer_push(output, encrypt_se_ip_writer, NULL,
|
pgp_writer_push(output, encrypt_se_ip_writer, NULL,
|
||||||
encrypt_se_ip_destroyer, se_ip);
|
encrypt_se_ip_destroyer, se_ip);
|
||||||
/* tidy up */
|
/* tidy up */
|
||||||
free(encrypted_pk_sesskey);
|
free(initial_sesskey);
|
||||||
free(iv);
|
free(iv);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1089,19 +1116,29 @@ encrypt_se_ip_writer(const uint8_t *src,
|
||||||
pgp_memory_t *localmem;
|
pgp_memory_t *localmem;
|
||||||
unsigned ret = 1;
|
unsigned ret = 1;
|
||||||
|
|
||||||
|
const uint8_t *zsrc;
|
||||||
|
unsigned zsrclen;
|
||||||
|
|
||||||
pgp_setup_memory_write(&litoutput, &litmem, bufsz);
|
pgp_setup_memory_write(&litoutput, &litmem, bufsz);
|
||||||
pgp_setup_memory_write(&zoutput, &zmem, bufsz);
|
pgp_setup_memory_write(&zoutput, &zmem, bufsz);
|
||||||
pgp_setup_memory_write(&output, &localmem, bufsz);
|
pgp_setup_memory_write(&output, &localmem, bufsz);
|
||||||
|
|
||||||
|
if (!se_ip->raw) {
|
||||||
/* create literal data packet from source data */
|
/* create literal data packet from source data */
|
||||||
pgp_write_litdata(litoutput, src, (const int)len, PGP_LDT_BINARY);
|
pgp_write_litdata(litoutput, src, (const int)len, PGP_LDT_BINARY);
|
||||||
if (pgp_mem_len(litmem) <= len) {
|
if (pgp_mem_len(litmem) <= len) {
|
||||||
(void) fprintf(stderr, "encrypt_se_ip_writer: bad len\n");
|
(void) fprintf(stderr, "encrypt_se_ip_writer: bad len\n");
|
||||||
return 0;
|
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 */
|
/* 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 */
|
/* create SE IP packet set from this compressed literal data */
|
||||||
pgp_write_se_ip_pktset(output, pgp_mem_data(zmem),
|
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
|
#define MAX_PARTIAL_DATA_LENGTH 1073741824
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -1412,7 +1503,7 @@ static void str_enc_se_ip_destroyer(pgp_writer_t *writer);
|
||||||
\param pubkey
|
\param pubkey
|
||||||
*/
|
*/
|
||||||
void
|
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;
|
pgp_pk_sesskey_t *encrypted_pk_sesskey;
|
||||||
str_enc_se_ip_t *se_ip;
|
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");
|
"pgp_push_stream_enc_se_ip: bad alloc\n");
|
||||||
return;
|
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);
|
pgp_write_pk_sesskey(output, encrypted_pk_sesskey);
|
||||||
|
|
||||||
/* Setup the se_ip */
|
/* Setup the se_ip */
|
||||||
|
@ -1701,7 +1792,6 @@ str_enc_se_ip_writer(const uint8_t *src,
|
||||||
size_t datalength;
|
size_t datalength;
|
||||||
|
|
||||||
se_ip = pgp_writer_get_arg(writer);
|
se_ip = pgp_writer_get_arg(writer);
|
||||||
ret = 1;
|
|
||||||
if (se_ip->litoutput == NULL) {
|
if (se_ip->litoutput == NULL) {
|
||||||
/* first literal data chunk is not yet written */
|
/* first literal data chunk is not yet written */
|
||||||
|
|
|
@ -119,9 +119,10 @@ int mre2ee_driver_create_keypair(mrmailbox_t* mailbox, const char* addr, mrkey_t
|
||||||
/* generate keypair */
|
/* generate keypair */
|
||||||
keypair = pgp_rsa_new_selfsign_key(2048/*bits*/, 65537UL/*e*/, (const uint8_t*)user_id, NULL, NULL);
|
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);
|
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;
|
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);
|
mrkey_set_from_raw(ret_public_key, (const unsigned char*)mem1->buf, mem1->length, MR_PRIVATE);
|
||||||
|
|
||||||
/* write private key */
|
/* write private key */
|
||||||
|
keypair->type = PGP_PTAG_CT_SECRET_KEY; // TODO: this seems to me like a hack
|
||||||
pgp_writer_set_memory(output2, mem2);
|
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;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue