diff --git a/deltachat-core.cbp b/deltachat-core.cbp
index ad49f236..8bb5c742 100644
--- a/deltachat-core.cbp
+++ b/deltachat-core.cbp
@@ -54,7 +54,7 @@
-
+
@@ -372,58 +372,46 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/libs/netpgp/netpgp-extra.h b/libs/netpgp/include/netpgp-extra.h
similarity index 58%
rename from libs/netpgp/netpgp-extra.h
rename to libs/netpgp/include/netpgp-extra.h
index 9f5bd73c..e981c89a 100644
--- a/libs/netpgp/netpgp-extra.h
+++ b/libs/netpgp/include/netpgp-extra.h
@@ -1,12 +1,13 @@
#ifndef __NETPGP_EXTRA_H__
#define __NETPGP_EXTRA_H__
+#include "netpgp/config-netpgp.h"
#include
-#include "packet-parse.h"
-#include "errors-netpgp.h"
-#include "netpgpdefs.h"
-#include "crypto-netpgp.h"
-#include "create-netpgp.h"
+#include "netpgp/packet-parse.h"
+#include "netpgp/errors.h"
+#include "netpgp/defs.h"
+#include "netpgp/crypto.h"
+#include "netpgp/create.h"
unsigned rsa_generate_keypair(pgp_key_t *keydata, const int numbits, const unsigned long e, const char *hashalg, const char *cipher);
#endif // __NETPGP_EXTRA_H__
diff --git a/libs/netpgp/netpgp.h b/libs/netpgp/include/netpgp.h
similarity index 97%
rename from libs/netpgp/netpgp.h
rename to libs/netpgp/include/netpgp.h
index 0378697e..3a3c239e 100644
--- a/libs/netpgp/netpgp.h
+++ b/libs/netpgp/include/netpgp.h
@@ -57,9 +57,6 @@ typedef struct netpgp_t {
int netpgp_init(netpgp_t *);
int netpgp_end(netpgp_t *);
-/* debugging, reflection and information */
-int netpgp_set_debug(const char *);
-int netpgp_get_debug(const char *);
const char *netpgp_get_info(const char *);
int netpgp_list_packets(netpgp_t *, char *, int, char *);
@@ -78,6 +75,8 @@ int netpgp_list_keys_json(netpgp_t *, char **, const int);
int netpgp_find_key(netpgp_t *, char *);
char *netpgp_get_key(netpgp_t *, const char *, const char *);
char *netpgp_export_key(netpgp_t *, char *);
+int netpgp_save_secring(netpgp_t *);
+int netpgp_save_pubring(netpgp_t *);
int netpgp_import_key(netpgp_t *, char *);
int netpgp_generate_key(netpgp_t *, char *, int);
diff --git a/libs/netpgp/config-netpgp.h b/libs/netpgp/include/netpgp/config-netpgp.h
similarity index 100%
rename from libs/netpgp/config-netpgp.h
rename to libs/netpgp/include/netpgp/config-netpgp.h
diff --git a/libs/netpgp/config-original-as-configured-for-ubuntu-16.04-64bit.h b/libs/netpgp/include/netpgp/config-original-as-configured-for-ubuntu-16.04-64bit.h
similarity index 100%
rename from libs/netpgp/config-original-as-configured-for-ubuntu-16.04-64bit.h
rename to libs/netpgp/include/netpgp/config-original-as-configured-for-ubuntu-16.04-64bit.h
diff --git a/libs/netpgp/include/netpgp/config-pep.h b/libs/netpgp/include/netpgp/config-pep.h
new file mode 100644
index 00000000..f9cc1f72
--- /dev/null
+++ b/libs/netpgp/include/netpgp/config-pep.h
@@ -0,0 +1,160 @@
+//
+// config.h
+// netpgp
+
+#ifndef netpgp_config_h
+#define netpgp_config_h
+
+/* Define to 1 if you have the header file. */
+#define HAVE_BZLIB_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_COMMONCRYPTO_COMMONDIGEST_H 1
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_DIRECT_H */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_DMALLOC_H */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the 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 header file. */
+/* #undef HAVE_MALLOC_H */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_OPENSSL_AES_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_OPENSSL_BN_H 1
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_OPENSSL_CAMELLIA_H */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_OPENSSL_CAST_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_OPENSSL_DES_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_OPENSSL_DSA_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_OPENSSL_ERR_H 1
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_OPENSSL_IDEA_H */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_OPENSSL_MD5_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_OPENSSL_RAND_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_OPENSSL_RSA_H 1
+
+/* Define to 1 if you have the 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 header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_CDEFS_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_FILE_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_MMAN_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_UIO_H 1
+
+/* Define to 1 if you have the 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 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 "
+
+/* 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
diff --git a/libs/netpgp/create-netpgp.h b/libs/netpgp/include/netpgp/create.h
similarity index 84%
rename from libs/netpgp/create-netpgp.h
rename to libs/netpgp/include/netpgp/create.h
index 733422c1..3db88c23 100644
--- a/libs/netpgp/create-netpgp.h
+++ b/libs/netpgp/include/netpgp/create.h
@@ -52,13 +52,13 @@
#ifndef CREATE_H_
#define CREATE_H_
-#include "types-netpgp.h"
-#include "packet-netpgp.h"
-#include "crypto-netpgp.h"
-#include "errors-netpgp.h"
-#include "keyring-netpgp.h"
-#include "writer-netpgp.h"
-#include "memory-netpgp.h"
+#include "types.h"
+#include "packet.h"
+#include "crypto.h"
+#include "errors.h"
+#include "keyring.h"
+#include "writer.h"
+#include "memory.h"
/**
* \ingroup Create
@@ -78,28 +78,30 @@ void pgp_build_pubkey(pgp_memory_t *, const pgp_pubkey_t *, unsigned);
unsigned pgp_calc_sesskey_checksum(pgp_pk_sesskey_t *, uint8_t *);
unsigned pgp_write_struct_userid(pgp_output_t *, const uint8_t *);
-unsigned pgp_write_ss_header(pgp_output_t *, unsigned, pgp_content_enum);
+unsigned pgp_write_ss_header(pgp_output_t *, size_t, pgp_content_enum);
+unsigned pgp_write_struct_seckey_ptag(const pgp_seckey_t *key,
+ const uint8_t *passphrase,
+ const size_t pplen,
+ pgp_output_t *output,
+ pgp_content_enum ptag);
unsigned pgp_write_struct_seckey(const pgp_seckey_t *,
const uint8_t *,
const size_t,
pgp_output_t *);
+unsigned pgp_write_struct_pubkey(pgp_output_t *, const pgp_pubkey_t *);
unsigned pgp_write_one_pass_sig(pgp_output_t *,
const pgp_seckey_t *,
const pgp_hash_alg_t,
const pgp_sig_type_t);
-unsigned pgp_write_litdata(pgp_output_t *,
+unsigned pgp_write_litdata(pgp_output_t *,
const uint8_t *,
const int,
const pgp_litdata_enum);
-pgp_pk_sesskey_t *pgp_create_pk_sesskey(const pgp_key_t *, const char *);
+pgp_pk_sesskey_t *pgp_create_pk_sesskey(pgp_key_t *, const char *, pgp_pk_sesskey_t *);
unsigned pgp_write_pk_sesskey(pgp_output_t *, pgp_pk_sesskey_t *);
-unsigned pgp_write_xfer_pubkey(pgp_output_t *,
- const pgp_key_t *, const unsigned);
-unsigned pgp_write_xfer_seckey(pgp_output_t *,
- const pgp_key_t *,
- const uint8_t *,
- const size_t,
- const unsigned);
+unsigned pgp_write_xfer_key(pgp_output_t *output,
+ const pgp_key_t *key,
+ const unsigned armoured);
void pgp_fast_create_userid(uint8_t **, uint8_t *);
unsigned pgp_write_userid(const uint8_t *, pgp_output_t *);
diff --git a/libs/netpgp/crypto-netpgp.h b/libs/netpgp/include/netpgp/crypto.h
similarity index 88%
rename from libs/netpgp/crypto-netpgp.h
rename to libs/netpgp/include/netpgp/crypto.h
index 8f0239bc..f1e874b3 100644
--- a/libs/netpgp/crypto-netpgp.h
+++ b/libs/netpgp/include/netpgp/crypto.h
@@ -53,9 +53,9 @@
#ifndef CRYPTO_H_
#define CRYPTO_H_
-#include "keyring-netpgp.h"
-#include "packet-netpgp.h"
-#include "memory-netpgp.h"
+#include "keyring.h"
+#include "packet.h"
+#include "memory.h"
#include "packet-parse.h"
#include
@@ -100,6 +100,17 @@ struct pgp_crypt_t {
void *decrypt_key;
};
+typedef struct pgp_validation_t {
+ unsigned validc;
+ pgp_sig_info_t *valid_sigs;
+ unsigned invalidc;
+ pgp_sig_info_t *invalid_sigs;
+ unsigned unknownc;
+ pgp_sig_info_t *unknown_sigs;
+ time_t birthtime;
+ time_t duration;
+} pgp_validation_t;
+
void pgp_crypto_finish(void);
void pgp_hash_md5(pgp_hash_t *);
void pgp_hash_sha1(pgp_hash_t *);
@@ -107,7 +118,7 @@ void pgp_hash_sha256(pgp_hash_t *);
void pgp_hash_sha512(pgp_hash_t *);
void pgp_hash_sha384(pgp_hash_t *);
void pgp_hash_sha224(pgp_hash_t *);
-void pgp_hash_any(pgp_hash_t *, pgp_hash_alg_t);
+unsigned pgp_hash_any(pgp_hash_t *, pgp_hash_alg_t);
pgp_hash_alg_t pgp_str_to_hash_alg(const char *);
const char *pgp_text_from_hash(pgp_hash_t *);
unsigned pgp_hash_size(pgp_hash_alg_t);
@@ -190,8 +201,8 @@ unsigned pgp_decrypt_file(pgp_io_t *,
pgp_memory_t *
pgp_encrypt_buf(pgp_io_t *, const void *, const size_t,
- const pgp_key_t *,
- const unsigned, const char *);
+ const pgp_keyring_t *,
+ const unsigned, const char *, unsigned);
pgp_memory_t *
pgp_decrypt_buf(pgp_io_t *,
const void *,
@@ -204,18 +215,35 @@ pgp_decrypt_buf(pgp_io_t *,
int,
pgp_cbfunc_t *);
+pgp_memory_t *
+pgp_decrypt_and_validate_buf(pgp_io_t *io,
+ pgp_validation_t *result,
+ const void *input,
+ const size_t insize,
+ pgp_keyring_t *secring,
+ pgp_keyring_t *pubring,
+ const unsigned use_armour,
+ key_id_t **recipients_key_ids,
+ unsigned *recipients_count);
+
/* Keys */
pgp_key_t *pgp_rsa_new_selfsign_key(const int,
const unsigned long, const uint8_t *, const char *,
const char *);
+unsigned pgp_rsa_generate_keypair(pgp_key_t *,
+ const int,
+ const unsigned long,
+ const char *,
+ const char *,
+ const uint8_t *,
+ const size_t);
+
int pgp_dsa_size(const pgp_dsa_pubkey_t *);
-DSA_SIG *pgp_dsa_sign(uint8_t *, unsigned,
+pgp_dsa_sig_t *pgp_dsa_sign(uint8_t *, unsigned,
const pgp_dsa_seckey_t *,
const pgp_dsa_pubkey_t *);
-int openssl_read_pem_seckey(const char *, pgp_key_t *, const char *, int);
-
/** pgp_reader_t */
struct pgp_reader_t {
pgp_reader_func_t *reader; /* reader func to get parse data */
@@ -228,6 +256,13 @@ struct pgp_reader_t {
unsigned position; /* reader-specific offset */
pgp_reader_t *next;
pgp_stream_t *parent;/* parent parse_info structure */
+
+ unsigned partial_read:1;
+ unsigned coalescing:1;
+ /* used for partial length coalescing */
+ unsigned virtualc;
+ unsigned virtualoff;
+ uint8_t *virtualpkt;
};
@@ -237,9 +272,10 @@ struct pgp_reader_t {
struct pgp_cryptinfo_t {
char *passphrase;
pgp_keyring_t *secring;
- const pgp_key_t *keydata;
+ pgp_key_t *keydata;
pgp_cbfunc_t *getpassphrase;
pgp_keyring_t *pubring;
+ DYNARRAY(key_id_t, recipients_key_ids);
};
/** pgp_cbdata_t */
@@ -301,15 +337,10 @@ struct pgp_stream_t {
pgp_cryptinfo_t cryptinfo;
size_t hashc;
pgp_hashtype_t *hashes;
- unsigned reading_v3_secret:1;
- unsigned reading_mpi_len:1;
- unsigned exact_read:1;
- unsigned partial_read:1;
- unsigned coalescing:1;
- /* used for partial length coalescing */
- unsigned virtualc;
- unsigned virtualoff;
- uint8_t *virtualpkt;
+ //unsigned reading_v3_secret:1;
+ //unsigned reading_mpi_len:1;
+ //unsigned exact_read:1;
+
};
#endif /* CRYPTO_H_ */
diff --git a/libs/netpgp/defs-netpgp.h b/libs/netpgp/include/netpgp/defs.h
similarity index 98%
rename from libs/netpgp/defs-netpgp.h
rename to libs/netpgp/include/netpgp/defs.h
index 2c62eb8d..760f1d30 100644
--- a/libs/netpgp/defs-netpgp.h
+++ b/libs/netpgp/include/netpgp/defs.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.
diff --git a/libs/netpgp/errors-netpgp.h b/libs/netpgp/include/netpgp/errors.h
similarity index 100%
rename from libs/netpgp/errors-netpgp.h
rename to libs/netpgp/include/netpgp/errors.h
diff --git a/libs/netpgp/include/netpgp/keyring.h b/libs/netpgp/include/netpgp/keyring.h
new file mode 100644
index 00000000..db6291b9
--- /dev/null
+++ b/libs/netpgp/include/netpgp/keyring.h
@@ -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_ */
diff --git a/libs/netpgp/memory-netpgp.h b/libs/netpgp/include/netpgp/memory.h
similarity index 99%
rename from libs/netpgp/memory-netpgp.h
rename to libs/netpgp/include/netpgp/memory.h
index 9641b063..d8bd5763 100644
--- a/libs/netpgp/memory-netpgp.h
+++ b/libs/netpgp/include/netpgp/memory.h
@@ -54,7 +54,7 @@
#include
-#include "packet-netpgp.h"
+#include "packet.h"
/** pgp_memory_t
*/
diff --git a/libs/netpgp/netpgpdefs.h b/libs/netpgp/include/netpgp/netpgpdefs.h
similarity index 97%
rename from libs/netpgp/netpgpdefs.h
rename to libs/netpgp/include/netpgp/netpgpdefs.h
index d2c3ee27..37b2bf7f 100644
--- a/libs/netpgp/netpgpdefs.h
+++ b/libs/netpgp/include/netpgp/netpgpdefs.h
@@ -65,8 +65,4 @@ void *pgp_new(size_t);
} \
} while(/* CONSTCOND */0)
-#ifndef MIN
-#define MIN(x, y) (((x) < (y)) ? (x) : (y))
-#endif
-
#endif /* !NETPGPDEFS_H_ */
diff --git a/libs/netpgp/netpgpdigest.h b/libs/netpgp/include/netpgp/netpgpdigest.h
similarity index 97%
rename from libs/netpgp/netpgpdigest.h
rename to libs/netpgp/include/netpgp/netpgpdigest.h
index 3b15a25b..be776c45 100644
--- a/libs/netpgp/netpgpdigest.h
+++ b/libs/netpgp/include/netpgp/netpgpdigest.h
@@ -50,6 +50,7 @@
/* SHA1 Hash Size */
#define PGP_SHA1_HASH_SIZE SHA_DIGEST_LENGTH
#define PGP_SHA256_HASH_SIZE SHA256_DIGEST_LENGTH
+#define PGP_SHA512_HASH_SIZE SHA512_DIGEST_LENGTH
#define PGP_CHECKHASH_SIZE PGP_SHA1_HASH_SIZE
#endif /* NETPGPDIGEST_H_ */
diff --git a/libs/netpgp/netpgpsdk.h b/libs/netpgp/include/netpgp/netpgpsdk.h
similarity index 81%
rename from libs/netpgp/netpgpsdk.h
rename to libs/netpgp/include/netpgp/netpgpsdk.h
index 12ba9684..4747b260 100644
--- a/libs/netpgp/netpgpsdk.h
+++ b/libs/netpgp/include/netpgp/netpgpsdk.h
@@ -29,34 +29,17 @@
#ifndef NETPGPSDK_H_
#define NETPGPSDK_H_
-#include "keyring-netpgp.h"
-#include "crypto-netpgp.h"
-#include "signature-netpgp.h"
+#include "keyring.h"
+#include "crypto.h"
+#include "signature.h"
#include "packet-show.h"
#ifndef __printflike
#define __printflike(n, m) __attribute__((format(printf,n,m)))
#endif
-typedef struct pgp_validation_t {
- unsigned validc;
- pgp_sig_info_t *valid_sigs;
- unsigned invalidc;
- pgp_sig_info_t *invalid_sigs;
- unsigned unknownc;
- pgp_sig_info_t *unknown_sigs;
- time_t birthtime;
- time_t duration;
-} pgp_validation_t;
-
void pgp_validate_result_free(pgp_validation_t *);
-unsigned
-pgp_validate_key_sigs(pgp_validation_t *,
- const pgp_key_t *,
- const pgp_keyring_t *,
- pgp_cb_ret_t cb(const pgp_packet_t *, pgp_cbdata_t *));
-
unsigned
pgp_validate_all_sigs(pgp_validation_t *,
const pgp_keyring_t *,
@@ -74,5 +57,4 @@ void netpgp_log(const char *, ...) __printflike(1, 2);
int netpgp_strcasecmp(const char *, const char *);
char *netpgp_strdup(const char *);
-
#endif
diff --git a/libs/netpgp/include/netpgp/openssl11stub.h b/libs/netpgp/include/netpgp/openssl11stub.h
new file mode 100644
index 00000000..5d759ff8
--- /dev/null
+++ b/libs/netpgp/include/netpgp/openssl11stub.h
@@ -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;
+}
+
diff --git a/libs/netpgp/packet-parse.h b/libs/netpgp/include/netpgp/packet-parse.h
similarity index 98%
rename from libs/netpgp/packet-parse.h
rename to libs/netpgp/include/netpgp/packet-parse.h
index ee4381b5..0406ff03 100644
--- a/libs/netpgp/packet-parse.h
+++ b/libs/netpgp/include/netpgp/packet-parse.h
@@ -54,8 +54,8 @@
#ifndef PACKET_PARSE_H_
#define PACKET_PARSE_H_
-#include "types-netpgp.h"
-#include "packet-netpgp.h"
+#include "types.h"
+#include "packet.h"
/** pgp_region_t */
typedef struct pgp_region_t {
@@ -166,4 +166,7 @@ int pgp_decompress(pgp_region_t *, pgp_stream_t *,
unsigned pgp_writez(pgp_output_t *, const uint8_t *,
const unsigned);
+void
+copy_sig_info(pgp_sig_info_t *dst, const pgp_sig_info_t *src);
+
#endif /* PACKET_PARSE_H_ */
diff --git a/libs/netpgp/packet-show.h b/libs/netpgp/include/netpgp/packet-show.h
similarity index 93%
rename from libs/netpgp/packet-show.h
rename to libs/netpgp/include/netpgp/packet-show.h
index d567f56b..02172707 100644
--- a/libs/netpgp/packet-show.h
+++ b/libs/netpgp/include/netpgp/packet-show.h
@@ -53,7 +53,7 @@
#ifndef PACKET_SHOW_H_
#define PACKET_SHOW_H_
-#include "packet-netpgp.h"
+#include "packet.h"
/** pgp_list_t
*/
@@ -86,10 +86,8 @@ const char *pgp_show_ss_type(pgp_content_enum);
const char *pgp_show_sig_type(pgp_sig_type_t);
const char *pgp_show_pka(pgp_pubkey_alg_t);
-pgp_text_t *pgp_showall_ss_zpref(const pgp_data_t *);
const char *pgp_show_ss_zpref(uint8_t);
-pgp_text_t *pgp_showall_ss_hashpref(const pgp_data_t *);
const char *pgp_show_hash_alg(uint8_t);
const char *pgp_show_symm_alg(uint8_t);
@@ -100,10 +98,8 @@ const char *pgp_show_ss_rr_code(pgp_ss_rr_code_t);
pgp_text_t *pgp_showall_ss_features(pgp_data_t);
-pgp_text_t *pgp_showall_ss_key_flags(const pgp_data_t *);
const char *pgp_show_ss_key_flag(uint8_t, pgp_bit_map_t *);
-pgp_text_t *pgp_show_keyserv_prefs(const pgp_data_t *);
const char *pgp_show_keyserv_pref(uint8_t, pgp_bit_map_t *);
pgp_text_t *pgp_showall_notation(pgp_ss_notation_t);
diff --git a/libs/netpgp/packet-netpgp.h b/libs/netpgp/include/netpgp/packet.h
similarity index 93%
rename from libs/netpgp/packet-netpgp.h
rename to libs/netpgp/include/netpgp/packet.h
index 1f38fbe9..d8d01719 100644
--- a/libs/netpgp/packet-netpgp.h
+++ b/libs/netpgp/include/netpgp/packet.h
@@ -54,16 +54,16 @@
#ifndef PACKET_H_
#define PACKET_H_
-#include "config-netpgp.h"
-
#include
#ifdef HAVE_OPENSSL_BN_H
#include
#endif
-#include "types-netpgp.h"
-#include "errors-netpgp.h"
+#include
+
+#include "types.h"
+#include "errors.h"
/* structure to keep track of printing state variables */
typedef struct pgp_printstate_t {
@@ -620,6 +620,8 @@ typedef struct pgp_sig_info_t {
pgp_sig_type_t type; /* signature type value */
time_t birthtime; /* creation time of the signature */
time_t duration; /* number of seconds it's valid for */
+ time_t key_expiry; /* number of seconds key is valid for */
+ uint8_t key_flags;
uint8_t signer_id[PGP_KEY_ID_SIZE]; /* Eight-octet key ID
* of signer */
pgp_pubkey_alg_t key_alg; /* public key algorithm number */
@@ -635,8 +637,21 @@ typedef struct pgp_sig_info_t {
unsigned birthtime_set:1;
unsigned signer_id_set:1;
unsigned duration_set:1;
+ unsigned key_expiry_set:1;
+ unsigned key_flags_set:1;
+ unsigned primary_userid:1;
} pgp_sig_info_t;
+typedef enum {
+ PGP_KEYFLAG_CERT_KEYS = 0x01,
+ PGP_KEYFLAG_SIGN_DATA = 0x02,
+ PGP_KEYFLAG_ENC_COMM = 0x04,
+ PGP_KEYFLAG_ENC_STORAGE = 0x08,
+ PGP_KEYFLAG_SPLIT = 0x10,
+ PGP_KEYFLAG_AUTH = 0x20,
+ PGP_KEYFLAG_GROUP = 0x80
+} pgp_key_flags_t;
+
/** Struct used when parsing a signature */
typedef struct pgp_sig_t {
pgp_sig_info_t info; /* The signature information */
@@ -789,9 +804,10 @@ typedef union {
} pgp_pk_sesskey_params_t;
/** pgp_pk_sesskey_t */
+typedef uint8_t key_id_t[PGP_KEY_ID_SIZE];
typedef struct {
unsigned version;
- uint8_t key_id[PGP_KEY_ID_SIZE];
+ key_id_t key_id;
pgp_pubkey_alg_t alg;
pgp_pk_sesskey_params_t params;
pgp_symm_alg_t symm_alg;
@@ -886,6 +902,7 @@ int pgp_fingerprint(pgp_fingerprint_t *, const pgp_pubkey_t *, pgp_hash_alg_t);
void pgp_finish(void);
void pgp_pubkey_free(pgp_pubkey_t *);
+int pgp_pubkey_dup(pgp_pubkey_t *,pgp_pubkey_t *);
void pgp_userid_free(uint8_t **);
void pgp_data_free(pgp_data_t *);
void pgp_sig_free(pgp_sig_t *);
@@ -896,10 +913,9 @@ void pgp_ss_sig_target_free(pgp_ss_sig_target_t *);
void pgp_subpacket_free(pgp_subpacket_t *);
void pgp_parser_content_free(pgp_packet_t *);
void pgp_seckey_free(pgp_seckey_t *);
+int pgp_seckey_dup(pgp_seckey_t *,pgp_seckey_t *);
void pgp_pk_sesskey_free(pgp_pk_sesskey_t *);
-int pgp_print_packet(pgp_printstate_t *, const pgp_packet_t *);
-
#define DYNARRAY(type, arr) \
unsigned arr##c; unsigned arr##vsize; type *arr##s
@@ -921,6 +937,21 @@ int pgp_print_packet(pgp_printstate_t *, const pgp_packet_t *);
} \
} while(/*CONSTCOND*/0)
+#define FREE_ARRAY(str, arr) do { \
+ if (str->arr##s) { \
+ free(str->arr##s); \
+ str->arr##s = NULL; \
+ str->arr##vsize = 0; \
+ str->arr##c = 0; \
+ } \
+} while(/*CONSTCOND*/0)
+
+#define INIT_ARRAY(str, arr) do { \
+ str->arr##s = NULL; \
+ str->arr##vsize = 0; \
+ str->arr##c = 0; \
+} while(/*CONSTCOND*/0)
+
/** pgp_keydata_key_t
*/
typedef union {
@@ -928,47 +959,59 @@ typedef union {
pgp_seckey_t seckey;
} pgp_keydata_key_t;
-
-/* sigpacket_t */
-typedef struct {
- uint8_t **userid;
- pgp_subpacket_t *packet;
-} sigpacket_t;
-
-/* user revocation info */
-typedef struct pgp_revoke_t {
- uint32_t uid; /* index in uid array */
- uint8_t code; /* revocation code */
- char *reason; /* c'mon, spill the beans */
-} pgp_revoke_t;
-
-/** signature subpackets */
-typedef struct pgp_subsig_t {
+/** userid signature subpackets */
+typedef struct pgp_uidsig_t {
uint32_t uid; /* index in userid array in key */
- pgp_sig_t sig; /* trust signature */
+ pgp_sig_info_t siginfo;
uint8_t trustlevel; /* level of trust */
uint8_t trustamount; /* amount of trust */
-} pgp_subsig_t;
+ pgp_subpacket_t packet;
+} pgp_uidsig_t;
+
+/** subkey signature subpackets */
+typedef struct pgp_subkeysig_t {
+ uint32_t subkey; /* index of subkey in array */
+ pgp_sig_info_t siginfo;
+ pgp_subpacket_t packet;
+} pgp_subkeysig_t;
+
+typedef struct pgp_subkey_t {
+ pgp_keydata_key_t key; /* pubkey/seckey data */
+ uint8_t id[PGP_KEY_ID_SIZE];
+} pgp_subkey_t;
+
+typedef struct pgp_directsig_t {
+ pgp_sig_info_t siginfo;
+ pgp_subpacket_t packet;
+} pgp_directsig_t;
/* describes a user's key */
struct pgp_key_t {
- DYNARRAY(uint8_t *, uid); /* array of user ids */
- DYNARRAY(pgp_subpacket_t, packet); /* array of raw subpackets */
- DYNARRAY(pgp_subsig_t, subsig); /* array of signature subkeys */
- DYNARRAY(pgp_revoke_t, revoke); /* array of signature revocations */
pgp_content_enum type; /* type of key */
pgp_keydata_key_t key; /* pubkey/seckey data */
- pgp_pubkey_t sigkey; /* signature key */
- uint8_t sigid[PGP_KEY_ID_SIZE];
- pgp_fingerprint_t sigfingerprint; /* pgp signature fingerprint */
- pgp_pubkey_t enckey; /* encryption key */
- uint8_t encid[PGP_KEY_ID_SIZE];
- pgp_fingerprint_t encfingerprint; /* pgp encryption id fingerprint */
- uint32_t uid0; /* primary uid index in uids array */
- uint8_t revoked; /* key has been revoked */
- pgp_revoke_t revocation; /* revocation reason */
+
+ DYNARRAY(pgp_directsig_t, directsig); /* direct signatures */
+
+ DYNARRAY(uint8_t *, uid); /* array of user ids */
+ DYNARRAY(pgp_uidsig_t, uidsig); /* array of signature for user ids */
+
+ /* TODO user attributes */
+
+ DYNARRAY(pgp_subkey_t, subkey); /* array of subkeys */
+ DYNARRAY(pgp_subkeysig_t, subkeysig); /* array of sigs for subkeys */
+
+ uint8_t pubkeyid[PGP_KEY_ID_SIZE];
+ pgp_fingerprint_t pubkeyfpr; /* pgp signature fingerprint */
};
-#define MDC_PKT_TAG 0xd3
+typedef enum {
+ PGP_VALID,
+ PGP_WEAK,
+ PGP_TOOSHORT,
+ PGP_INVALID,
+ PGP_EXPIRED,
+ PGP_REVOKED
+} pgp_key_rating_t;
+#define MDC_PKT_TAG 0xd3
#endif /* PACKET_H_ */
diff --git a/libs/netpgp/readerwriter-netpgp.h b/libs/netpgp/include/netpgp/readerwriter.h
similarity index 97%
rename from libs/netpgp/readerwriter-netpgp.h
rename to libs/netpgp/include/netpgp/readerwriter.h
index 303cf23a..51029f5f 100644
--- a/libs/netpgp/readerwriter-netpgp.h
+++ b/libs/netpgp/include/netpgp/readerwriter.h
@@ -50,9 +50,9 @@
#ifndef READERWRITER_H_
#define READERWRITER_H_
-#include "create-netpgp.h"
+#include "create.h"
-#include "memory-netpgp.h"
+#include "memory.h"
/* if this is defined, we'll use mmap in preference to file ops */
#define USE_MMAP_FOR_FILES 1
@@ -75,7 +75,7 @@ unsigned pgp_write_se_ip_pktset(pgp_output_t *, const uint8_t *,
const unsigned,
pgp_crypt_t *);
void pgp_push_enc_crypt(pgp_output_t *, pgp_crypt_t *);
-int pgp_push_enc_se_ip(pgp_output_t *, const pgp_key_t *, const char *);
+int pgp_push_enc_se_ip(pgp_output_t *, const pgp_keyring_t *, const char *, unsigned);
/* Secret Key checksum */
void pgp_push_checksum_writer(pgp_output_t *, pgp_seckey_t *);
diff --git a/libs/netpgp/signature-netpgp.h b/libs/netpgp/include/netpgp/signature.h
similarity index 80%
rename from libs/netpgp/signature-netpgp.h
rename to libs/netpgp/include/netpgp/signature.h
index 895f472c..0606623d 100644
--- a/libs/netpgp/signature-netpgp.h
+++ b/libs/netpgp/include/netpgp/signature.h
@@ -57,9 +57,9 @@
#include
-#include "packet-netpgp.h"
-#include "create-netpgp.h"
-#include "memory-netpgp.h"
+#include "packet.h"
+#include "create.h"
+#include "memory.h"
typedef struct pgp_create_sig_t pgp_create_sig_t;
@@ -69,22 +69,18 @@ void pgp_create_sig_delete(pgp_create_sig_t *);
unsigned pgp_check_useridcert_sig(const pgp_pubkey_t *,
const uint8_t *,
const pgp_sig_t *,
- const pgp_pubkey_t *,
- const uint8_t *);
+ const pgp_pubkey_t *);
unsigned pgp_check_userattrcert_sig(const pgp_pubkey_t *,
const pgp_data_t *,
const pgp_sig_t *,
- const pgp_pubkey_t *,
- const uint8_t *);
+ const pgp_pubkey_t *);
unsigned pgp_check_subkey_sig(const pgp_pubkey_t *,
const pgp_pubkey_t *,
const pgp_sig_t *,
- const pgp_pubkey_t *,
- const uint8_t *);
+ const pgp_pubkey_t *);
unsigned pgp_check_direct_sig(const pgp_pubkey_t *,
const pgp_sig_t *,
- const pgp_pubkey_t *,
- const uint8_t *);
+ const pgp_pubkey_t *);
unsigned pgp_check_hash_sig(pgp_hash_t *,
const pgp_sig_t *,
const pgp_pubkey_t *);
@@ -102,19 +98,31 @@ pgp_hash_t *pgp_sig_get_hash(pgp_create_sig_t *);
unsigned pgp_end_hashed_subpkts(pgp_create_sig_t *);
unsigned pgp_write_sig(pgp_output_t *, pgp_create_sig_t *,
const pgp_pubkey_t *, const pgp_seckey_t *);
-unsigned pgp_add_time(pgp_create_sig_t *, int64_t, const char *);
unsigned pgp_add_issuer_keyid(pgp_create_sig_t *,
const uint8_t *);
void pgp_add_primary_userid(pgp_create_sig_t *, unsigned);
+unsigned
+pgp_add_creation_time(pgp_create_sig_t *sig, time_t when);
+unsigned
+pgp_add_sig_expiration_time(pgp_create_sig_t *sig, time_t duration);
+unsigned
+pgp_add_key_expiration_time(pgp_create_sig_t *sig, time_t duration);
+unsigned
+pgp_add_key_flags(pgp_create_sig_t *sig, uint8_t flags);
+unsigned
+pgp_add_key_prefs(pgp_create_sig_t *sig);
+unsigned
+pgp_add_key_features(pgp_create_sig_t *sig);
+
/* Standard Interface */
unsigned pgp_sign_file(pgp_io_t *,
const char *,
const char *,
const pgp_seckey_t *,
const char *,
- const int64_t,
- const uint64_t,
+ const time_t,
+ const time_t,
const unsigned,
const unsigned,
const unsigned);
@@ -122,10 +130,10 @@ unsigned pgp_sign_file(pgp_io_t *,
int pgp_sign_detached(pgp_io_t *,
const char *,
char *,
- pgp_seckey_t *,
+ const pgp_seckey_t *,
const char *,
- const int64_t,
- const uint64_t,
+ const time_t,
+ const time_t,
const unsigned,
const unsigned);
@@ -157,15 +165,33 @@ pgp_memory_t *pgp_sign_buf(pgp_io_t *,
const void *,
const size_t,
const pgp_seckey_t *,
- const int64_t,
- const uint64_t,
+ const time_t,
+ const time_t,
const char *,
const unsigned,
const unsigned);
-unsigned pgp_keyring_read_from_mem(pgp_io_t *,
- pgp_keyring_t *,
- const unsigned,
- pgp_memory_t *);
+/** \ingroup Core_Create
+ * needed for signature creation
+ */
+struct pgp_create_sig_t {
+ pgp_hash_t hash;
+ pgp_sig_t sig;
+ pgp_memory_t *mem;
+ pgp_output_t *output; /* how to do the writing */
+ unsigned hashoff; /* hashed count offset */
+ unsigned hashlen;
+ unsigned unhashoff;
+};
+
+void
+pgp_sig_start_key_rev(pgp_create_sig_t *sig,
+ const pgp_pubkey_t *key,
+ pgp_sig_type_t type);
+
+unsigned
+pgp_add_revocation_reason(
+ pgp_create_sig_t *sig,
+ uint8_t code, const char *reason);
#endif /* SIGNATURE_H_ */
diff --git a/libs/netpgp/types-netpgp.h b/libs/netpgp/include/netpgp/types.h
similarity index 99%
rename from libs/netpgp/types-netpgp.h
rename to libs/netpgp/include/netpgp/types.h
index c4ee1d1c..cc03f7b0 100644
--- a/libs/netpgp/types-netpgp.h
+++ b/libs/netpgp/include/netpgp/types.h
@@ -49,8 +49,6 @@
#ifndef TYPES_H_
#define TYPES_H_
-#include "config-netpgp.h"
-
#ifdef HAVE_INTTYPES_H
#include
#endif
diff --git a/libs/netpgp/validate-netpgp.h b/libs/netpgp/include/netpgp/validate.h
similarity index 71%
rename from libs/netpgp/validate-netpgp.h
rename to libs/netpgp/include/netpgp/validate.h
index e28ec30c..44455a33 100644
--- a/libs/netpgp/validate-netpgp.h
+++ b/libs/netpgp/include/netpgp/validate.h
@@ -49,29 +49,36 @@
#ifndef VALIDATE_H_
#define VALIDATE_H_ 1
-typedef struct {
- const pgp_key_t *key;
- unsigned packet;
- unsigned offset;
-} validate_reader_t;
-
/** Struct used with the validate_key_cb callback */
-typedef struct {
- pgp_pubkey_t pubkey;
- pgp_pubkey_t subkey;
- pgp_seckey_t seckey;
+typedef struct validate_key_cb_t{
+ pgp_content_enum type; /* type of key */
+ pgp_keydata_key_t key; /* pubkey/seckey data */
+ pgp_keydata_key_t subkey;
+ uint8_t pubkeyid[PGP_KEY_ID_SIZE];
enum {
- ATTRIBUTE = 1,
- ID
+ LS_UNKNOWN = 0,
+ LS_ATTRIBUTE,
+ LS_ID,
+ LS_SUBKEY,
+ LS_PRIMARY,
} last_seen;
+
uint8_t *userid;
pgp_data_t userattr;
uint8_t hash[PGP_MAX_HASH_SIZE];
const pgp_keyring_t *keyring;
- validate_reader_t *reader;
pgp_validation_t *result;
pgp_cb_ret_t(*getpassphrase) (const pgp_packet_t *,
pgp_cbdata_t *);
+
+ unsigned not_commited; /* tells on_valid it is first commit of that key */
+ pgp_sig_info_t valid_sig_info; /* store last valid sig info */
+ unsigned sig_is_valid; /* condition to call on_valid at packet end */
+ pgp_cb_ret_t(*on_valid) ( /* callback for action on valid sig */
+ struct validate_key_cb_t *, /* this struct */
+ const pgp_subpacket_t *); /* sig packet */
+ void *on_valid_args; /* pointer to argument for on_valid callback */
+
} validate_key_cb_t;
/** Struct use with the validate_data_cb callback */
@@ -87,13 +94,10 @@ typedef struct {
uint8_t hash[PGP_MAX_HASH_SIZE];
pgp_memory_t *mem;
const pgp_keyring_t *keyring;
- validate_reader_t *reader;/* reader-specific arg */
pgp_validation_t *result;
char *detachname;
} validate_data_cb_t;
-void pgp_keydata_reader_set(pgp_stream_t *, const pgp_key_t *);
-
pgp_cb_ret_t pgp_validate_key_cb(const pgp_packet_t *, pgp_cbdata_t *);
unsigned check_binary_sig(const uint8_t *,
@@ -115,6 +119,30 @@ unsigned pgp_validate_mem(pgp_io_t *,
const int,
const pgp_keyring_t *);
-pgp_cb_ret_t validate_data_cb(const pgp_packet_t *, pgp_cbdata_t *);
+unsigned pgp_validate_mem_detached(pgp_io_t *,
+ pgp_validation_t *,
+ pgp_memory_t *,
+ pgp_memory_t **,
+ const int,
+ const pgp_keyring_t *,
+ pgp_memory_t *);
+pgp_cb_ret_t validate_data_cb(const pgp_packet_t *, pgp_cbdata_t *);
+void pgp_free_sig_info(pgp_sig_info_t *);
+
+unsigned
+pgp_filter_keys_fileread(pgp_io_t *io,
+ pgp_keyring_t *destpubring,
+ pgp_keyring_t *destsecring,
+ pgp_keyring_t *certring,
+ const unsigned armour,
+ const char *filename);
+
+unsigned
+pgp_filter_keys_from_mem(pgp_io_t *io,
+ pgp_keyring_t *destpubring,
+ pgp_keyring_t *destsecring,
+ pgp_keyring_t *certring,
+ const unsigned armour,
+ pgp_memory_t *mem);
#endif /* !VALIDATE_H_ */
diff --git a/libs/netpgp/version-netpgp.h b/libs/netpgp/include/netpgp/version.h
similarity index 96%
rename from libs/netpgp/version-netpgp.h
rename to libs/netpgp/include/netpgp/version.h
index 984a9e95..6ecec0cf 100644
--- a/libs/netpgp/version-netpgp.h
+++ b/libs/netpgp/include/netpgp/version.h
@@ -58,9 +58,9 @@
#endif
/* development versions have .99 suffix */
-#define NETPGP_BASE_VERSION "3.99.17"
+#define NETPGP_BASE_VERSION "3.99.99"
-#define NETPGP_VERSION_CAT(a, b) "NetPGP portable " a "/[" b "]"
+#define NETPGP_VERSION_CAT(a, b) "NetPGP for pEp " a "/[" b "]"
#define NETPGP_VERSION_STRING \
NETPGP_VERSION_CAT(NETPGP_BASE_VERSION, NETPGP_AUTOCONF_VERSION)
diff --git a/libs/netpgp/writer-netpgp.h b/libs/netpgp/include/netpgp/writer.h
similarity index 93%
rename from libs/netpgp/writer-netpgp.h
rename to libs/netpgp/include/netpgp/writer.h
index 1d903620..632eeeb6 100644
--- a/libs/netpgp/writer-netpgp.h
+++ b/libs/netpgp/include/netpgp/writer.h
@@ -53,11 +53,11 @@
#ifndef WRITER_H_
#define WRITER_H_
-#include "types-netpgp.h"
-#include "packet-netpgp.h"
-#include "crypto-netpgp.h"
-#include "errors-netpgp.h"
-#include "keyring-netpgp.h"
+#include "types.h"
+#include "packet.h"
+#include "crypto.h"
+#include "errors.h"
+#include "keyring.h"
/**
* \ingroup Writer
@@ -69,7 +69,7 @@ typedef unsigned pgp_writer_func_t(const uint8_t *,
unsigned,
pgp_error_t **,
pgp_writer_t *);
-typedef unsigned
+typedef unsigned
pgp_writer_finaliser_t(pgp_error_t **, pgp_writer_t *);
typedef void pgp_writer_destroyer_t(pgp_writer_t *);
@@ -114,6 +114,10 @@ unsigned pgp_write_mpi(pgp_output_t *, const BIGNUM *);
void pgp_writer_info_delete(pgp_writer_t *);
unsigned pgp_writer_info_finalise(pgp_error_t **, pgp_writer_t *);
-void pgp_push_stream_enc_se_ip(pgp_output_t *, const pgp_key_t *, const char *);
+void pgp_push_stream_enc_se_ip(pgp_output_t *, pgp_key_t *, const char *);
+
+void pgp_push_sum16_writer(pgp_output_t *output);
+
+uint16_t pgp_pop_sum16_writer(pgp_output_t *output);
#endif /* WRITER_H_ */
diff --git a/libs/netpgp/keyring-netpgp.h b/libs/netpgp/keyring-netpgp.h
deleted file mode 100644
index 70dc45f4..00000000
--- a/libs/netpgp/keyring-netpgp.h
+++ /dev/null
@@ -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_ */
diff --git a/libs/netpgp/keyring.c b/libs/netpgp/keyring.c
deleted file mode 100644
index 2d4e26bd..00000000
--- a/libs/netpgp/keyring.c
+++ /dev/null
@@ -1,1151 +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
- */
-#include "config-netpgp.h"
-
-#ifdef HAVE_SYS_CDEFS_H
-#include
-#endif
-
-#if defined(__NetBSD__)
-__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: keyring.c,v 1.50 2011/06/25 00:37:44 agc Exp $");
-#endif
-
-#ifdef HAVE_FCNTL_H
-#include
-#endif
-
-#include
-#include
-#include
-
-#ifdef HAVE_TERMIOS_H
-#include
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include
-#endif
-
-#include "types-netpgp.h"
-#include "keyring-netpgp.h"
-#include "packet-parse.h"
-#include "signature-netpgp.h"
-#include "netpgpsdk.h"
-#include "readerwriter-netpgp.h"
-#include "netpgpdefs.h"
-#include "packet-netpgp.h"
-#include "crypto-netpgp.h"
-#include "validate-netpgp.h"
-#include "netpgpdefs.h"
-#include "netpgpdigest.h"
-
-
-
-/**
- \ingroup HighLevel_Keyring
-
- \brief Creates a new pgp_key_t struct
-
- \return A new pgp_key_t struct, initialised to zero.
-
- \note The returned pgp_key_t struct must be freed after use with pgp_keydata_free.
-*/
-
-pgp_key_t *
-pgp_keydata_new(void)
-{
- return calloc(1, sizeof(pgp_key_t));
-}
-
-
-/**
- \ingroup HighLevel_Keyring
-
- \brief Frees keydata and its memory
-
- \param keydata Key to be freed.
-
- \note This frees the keydata itself, as well as any other memory alloc-ed by it.
-*/
-void
-pgp_keydata_free(pgp_key_t *keydata)
-{
- unsigned n;
-
- for (n = 0; n < keydata->uidc; ++n) {
- pgp_userid_free(&keydata->uids[n]);
- }
- free(keydata->uids);
- keydata->uids = NULL;
- keydata->uidc = 0;
-
- for (n = 0; n < keydata->packetc; ++n) {
- pgp_subpacket_free(&keydata->packets[n]);
- }
- free(keydata->packets);
- keydata->packets = NULL;
- keydata->packetc = 0;
-
- if (keydata->type == PGP_PTAG_CT_PUBLIC_KEY) {
- pgp_pubkey_free(&keydata->key.pubkey);
- } else {
- pgp_seckey_free(&keydata->key.seckey);
- }
-
- free(keydata);
-}
-
-/**
- \ingroup HighLevel_KeyGeneral
-
- \brief Returns the public key in the given keydata.
- \param keydata
-
- \return Pointer to public key
-
- \note This is not a copy, do not free it after use.
-*/
-
-const pgp_pubkey_t *
-pgp_get_pubkey(const pgp_key_t *keydata)
-{
- return (keydata->type == PGP_PTAG_CT_PUBLIC_KEY) ?
- &keydata->key.pubkey :
- &keydata->key.seckey.pubkey;
-}
-
-/**
-\ingroup HighLevel_KeyGeneral
-
-\brief Check whether this is a secret key or not.
-*/
-
-unsigned
-pgp_is_key_secret(const pgp_key_t *data)
-{
- return data->type != PGP_PTAG_CT_PUBLIC_KEY;
-}
-
-/**
- \ingroup HighLevel_KeyGeneral
-
- \brief Returns the secret key in the given keydata.
-
- \note This is not a copy, do not free it after use.
-
- \note This returns a const. If you need to be able to write to this
- pointer, use pgp_get_writable_seckey
-*/
-
-const pgp_seckey_t *
-pgp_get_seckey(const pgp_key_t *data)
-{
- return (data->type == PGP_PTAG_CT_SECRET_KEY) ?
- &data->key.seckey : NULL;
-}
-
-/**
- \ingroup HighLevel_KeyGeneral
-
- \brief Returns the secret key in the given keydata.
-
- \note This is not a copy, do not free it after use.
-
- \note If you do not need to be able to modify this key, there is an
- equivalent read-only function pgp_get_seckey.
-*/
-
-pgp_seckey_t *
-pgp_get_writable_seckey(pgp_key_t *data)
-{
- return (data->type == PGP_PTAG_CT_SECRET_KEY) ?
- &data->key.seckey : NULL;
-}
-
-/* utility function to zero out memory */
-void
-pgp_forget(void *vp, unsigned size)
-{
- (void) memset(vp, 0x0, size);
-}
-
-typedef struct {
- FILE *passfp;
- const pgp_key_t *key;
- char *passphrase;
- pgp_seckey_t *seckey;
-} decrypt_t;
-
-static pgp_cb_ret_t
-decrypt_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
-{
- const pgp_contents_t *content = &pkt->u;
- decrypt_t *decrypt;
- char pass[MAX_PASSPHRASE_LENGTH];
-
- decrypt = pgp_callback_arg(cbinfo);
- switch (pkt->tag) {
- case PGP_PARSER_PTAG:
- case PGP_PTAG_CT_USER_ID:
- case PGP_PTAG_CT_SIGNATURE:
- case PGP_PTAG_CT_SIGNATURE_HEADER:
- case PGP_PTAG_CT_SIGNATURE_FOOTER:
- case PGP_PTAG_CT_TRUST:
- break;
-
- case PGP_GET_PASSPHRASE:
- (void) pgp_getpassphrase(decrypt->passfp, pass, sizeof(pass));
- *content->skey_passphrase.passphrase = netpgp_strdup(pass);
- pgp_forget(pass, (unsigned)sizeof(pass));
- return PGP_KEEP_MEMORY;
-
- case PGP_PARSER_ERRCODE:
- switch (content->errcode.errcode) {
- case PGP_E_P_MPI_FORMAT_ERROR:
- /* Generally this means a bad passphrase */
- fprintf(stderr, "Bad passphrase!\n");
- return PGP_RELEASE_MEMORY;
-
- case PGP_E_P_PACKET_CONSUMED:
- /* And this is because of an error we've accepted */
- return PGP_RELEASE_MEMORY;
- default:
- break;
- }
- (void) fprintf(stderr, "parse error: %s\n",
- pgp_errcode(content->errcode.errcode));
- return PGP_FINISHED;
-
- case PGP_PARSER_ERROR:
- fprintf(stderr, "parse error: %s\n", content->error);
- return PGP_FINISHED;
-
- case PGP_PTAG_CT_SECRET_KEY:
- if ((decrypt->seckey = calloc(1, sizeof(*decrypt->seckey))) == NULL) {
- (void) fprintf(stderr, "decrypt_cb: bad alloc\n");
- return PGP_FINISHED;
- }
- decrypt->seckey->checkhash = calloc(1, PGP_CHECKHASH_SIZE);
- *decrypt->seckey = content->seckey;
- return PGP_KEEP_MEMORY;
-
- case PGP_PARSER_PACKET_END:
- /* nothing to do */
- break;
-
- default:
- fprintf(stderr, "Unexpected tag %d (0x%x)\n", pkt->tag,
- pkt->tag);
- return PGP_FINISHED;
- }
-
- return PGP_RELEASE_MEMORY;
-}
-
-/**
-\ingroup Core_Keys
-\brief Decrypts secret key from given keydata with given passphrase
-\param key Key from which to get secret key
-\param passphrase Passphrase to use to decrypt secret key
-\return secret key
-*/
-pgp_seckey_t *
-pgp_decrypt_seckey(const pgp_key_t *key, void *passfp)
-{
- pgp_stream_t *stream;
- const int printerrors = 1;
- decrypt_t decrypt;
-
- (void) memset(&decrypt, 0x0, sizeof(decrypt));
- decrypt.key = key;
- decrypt.passfp = passfp;
- stream = pgp_new(sizeof(*stream));
- pgp_keydata_reader_set(stream, key);
- pgp_set_callback(stream, decrypt_cb, &decrypt);
- stream->readinfo.accumulate = 1;
- pgp_parse(stream, !printerrors);
- return decrypt.seckey;
-}
-
-/**
-\ingroup Core_Keys
-\brief Set secret key in content
-\param content Content to be set
-\param key Keydata to get secret key from
-*/
-void
-pgp_set_seckey(pgp_contents_t *cont, const pgp_key_t *key)
-{
- *cont->get_seckey.seckey = &key->key.seckey;
-}
-
-/**
-\ingroup Core_Keys
-\brief Get Key ID from keydata
-\param key Keydata to get Key ID from
-\return Pointer to Key ID inside keydata
-*/
-const uint8_t *
-pgp_get_key_id(const pgp_key_t *key)
-{
- return key->sigid;
-}
-
-/**
-\ingroup Core_Keys
-\brief How many User IDs in this key?
-\param key Keydata to check
-\return Num of user ids
-*/
-unsigned
-pgp_get_userid_count(const pgp_key_t *key)
-{
- return key->uidc;
-}
-
-/**
-\ingroup Core_Keys
-\brief Get indexed user id from key
-\param key Key to get user id from
-\param index Which key to get
-\return Pointer to requested user id
-*/
-const uint8_t *
-pgp_get_userid(const pgp_key_t *key, unsigned subscript)
-{
- return key->uids[subscript];
-}
-
-/**
- \ingroup HighLevel_Supported
- \brief Checks whether key's algorithm and type are supported by OpenPGP::SDK
- \param keydata Key to be checked
- \return 1 if key algorithm and type are supported by OpenPGP::SDK; 0 if not
-*/
-
-unsigned
-pgp_is_key_supported(const pgp_key_t *key)
-{
- if (key->type == PGP_PTAG_CT_PUBLIC_KEY) {
- switch(key->key.pubkey.alg) {
- case PGP_PKA_RSA:
- case PGP_PKA_DSA:
- case PGP_PKA_ELGAMAL:
- return 1;
- default:
- break;
- }
- }
- return 0;
-}
-
-/* \todo check where userid pointers are copied */
-/**
-\ingroup Core_Keys
-\brief Copy user id, including contents
-\param dst Destination User ID
-\param src Source User ID
-\note If dst already has a userid, it will be freed.
-*/
-static uint8_t *
-copy_userid(uint8_t **dst, const uint8_t *src)
-{
- size_t len;
-
- len = strlen((const char *) src);
- if (*dst) {
- free(*dst);
- }
- if ((*dst = calloc(1, len + 1)) == NULL) {
- (void) fprintf(stderr, "copy_userid: bad alloc\n");
- } else {
- (void) memcpy(*dst, src, len);
- }
- return *dst;
-}
-
-/* \todo check where pkt pointers are copied */
-/**
-\ingroup Core_Keys
-\brief Copy packet, including contents
-\param dst Destination packet
-\param src Source packet
-\note If dst already has a packet, it will be freed.
-*/
-static pgp_subpacket_t *
-copy_packet(pgp_subpacket_t *dst, const pgp_subpacket_t *src)
-{
- if (dst->raw) {
- free(dst->raw);
- }
- if ((dst->raw = calloc(1, src->length)) == NULL) {
- (void) fprintf(stderr, "copy_packet: bad alloc\n");
- } else {
- dst->length = src->length;
- (void) memcpy(dst->raw, src->raw, src->length);
- }
- return dst;
-}
-
-/**
-\ingroup Core_Keys
-\brief Add User ID to key
-\param key Key to which to add User ID
-\param userid User ID to add
-\return Pointer to new User ID
-*/
-uint8_t *
-pgp_add_userid(pgp_key_t *key, const uint8_t *userid)
-{
- uint8_t **uidp;
-
- EXPAND_ARRAY(key, uid);
- /* initialise new entry in array */
- uidp = &key->uids[key->uidc++];
- *uidp = NULL;
- /* now copy it */
- return copy_userid(uidp, userid);
-}
-
-void print_packet_hex(const pgp_subpacket_t *pkt);
-
-/**
-\ingroup Core_Keys
-\brief Add packet to key
-\param keydata Key to which to add packet
-\param packet Packet to add
-\return Pointer to new packet
-*/
-pgp_subpacket_t *
-pgp_add_subpacket(pgp_key_t *keydata, const pgp_subpacket_t *packet)
-{
- pgp_subpacket_t *subpktp;
-
- EXPAND_ARRAY(keydata, packet);
- /* initialise new entry in array */
- subpktp = &keydata->packets[keydata->packetc++];
- subpktp->length = 0;
- subpktp->raw = NULL;
- /* now copy it */
- return copy_packet(subpktp, packet);
-}
-
-/**
-\ingroup Core_Keys
-\brief Add selfsigned User ID to key
-\param keydata Key to which to add user ID
-\param userid Self-signed User ID to add
-\return 1 if OK; else 0
-*/
-unsigned
-pgp_add_selfsigned_userid(pgp_key_t *key, const uint8_t *userid)
-{
- pgp_create_sig_t *sig;
- pgp_subpacket_t sigpacket;
- pgp_memory_t *mem_userid = NULL;
- pgp_output_t *useridoutput = NULL;
- pgp_memory_t *mem_sig = NULL;
- pgp_output_t *sigoutput = NULL;
-
- /*
- * create signature packet for this userid
- */
-
- /* create userid pkt */
- pgp_setup_memory_write(&useridoutput, &mem_userid, 128);
- pgp_write_struct_userid(useridoutput, userid);
-
- /* create sig for this pkt */
- sig = pgp_create_sig_new();
- pgp_sig_start_key_sig(sig, &key->key.seckey.pubkey, userid, PGP_CERT_POSITIVE);
- pgp_add_time(sig, (int64_t)time(NULL), "birth");
- pgp_add_issuer_keyid(sig, key->sigid);
- pgp_add_primary_userid(sig, 1);
- pgp_end_hashed_subpkts(sig);
-
- pgp_setup_memory_write(&sigoutput, &mem_sig, 128);
- pgp_write_sig(sigoutput, sig, &key->key.seckey.pubkey, &key->key.seckey);
-
- /* add this packet to key */
- sigpacket.length = pgp_mem_len(mem_sig);
- sigpacket.raw = pgp_mem_data(mem_sig);
-
- /* add userid to key */
- (void) pgp_add_userid(key, userid);
- (void) pgp_add_subpacket(key, &sigpacket);
-
- /* cleanup */
- pgp_create_sig_delete(sig);
- pgp_output_delete(useridoutput);
- pgp_output_delete(sigoutput);
- pgp_memory_free(mem_userid);
- pgp_memory_free(mem_sig);
-
- return 1;
-}
-
-/**
-\ingroup Core_Keys
-\brief Initialise pgp_key_t
-\param keydata Keydata to initialise
-\param type PGP_PTAG_CT_PUBLIC_KEY or PGP_PTAG_CT_SECRET_KEY
-*/
-void
-pgp_keydata_init(pgp_key_t *keydata, const pgp_content_enum type)
-{
- if (keydata->type != PGP_PTAG_CT_RESERVED) {
- (void) fprintf(stderr,
- "pgp_keydata_init: wrong keydata type\n");
- } else if (type != PGP_PTAG_CT_PUBLIC_KEY &&
- type != PGP_PTAG_CT_SECRET_KEY) {
- (void) fprintf(stderr, "pgp_keydata_init: wrong type\n");
- } else {
- keydata->type = type;
- }
-}
-
-/* used to point to data during keyring read */
-typedef struct keyringcb_t {
- pgp_keyring_t *keyring; /* the keyring we're reading */
-} keyringcb_t;
-
-
-static pgp_cb_ret_t
-cb_keyring_read(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
-{
- pgp_keyring_t *keyring;
- pgp_revoke_t *revocation;
- pgp_key_t *key;
- keyringcb_t *cb;
-
- cb = pgp_callback_arg(cbinfo);
- keyring = cb->keyring;
- switch (pkt->tag) {
- case PGP_PARSER_PTAG:
- case PGP_PTAG_CT_ENCRYPTED_SECRET_KEY:
- /* we get these because we didn't prompt */
- break;
- case PGP_PTAG_CT_SIGNATURE_HEADER:
- key = &keyring->keys[keyring->keyc - 1];
- EXPAND_ARRAY(key, subsig);
- key->subsigs[key->subsigc].uid = key->uidc - 1;
- (void) memcpy(&key->subsigs[key->subsigc].sig, &pkt->u.sig,
- sizeof(pkt->u.sig));
- key->subsigc += 1;
- break;
- case PGP_PTAG_CT_SIGNATURE:
- key = &keyring->keys[keyring->keyc - 1];
- EXPAND_ARRAY(key, subsig);
- key->subsigs[key->subsigc].uid = key->uidc - 1;
- (void) memcpy(&key->subsigs[key->subsigc].sig, &pkt->u.sig,
- sizeof(pkt->u.sig));
- key->subsigc += 1;
- break;
- case PGP_PTAG_CT_TRUST:
- key = &keyring->keys[keyring->keyc - 1];
- key->subsigs[key->subsigc - 1].trustlevel = pkt->u.ss_trust.level;
- key->subsigs[key->subsigc - 1].trustamount = pkt->u.ss_trust.amount;
- break;
- case PGP_PTAG_SS_KEY_EXPIRY:
- EXPAND_ARRAY(keyring, key);
- if (keyring->keyc > 0) {
- keyring->keys[keyring->keyc - 1].key.pubkey.duration = pkt->u.ss_time;
- }
- break;
- case PGP_PTAG_SS_ISSUER_KEY_ID:
- key = &keyring->keys[keyring->keyc - 1];
- (void) memcpy(&key->subsigs[key->subsigc - 1].sig.info.signer_id,
- pkt->u.ss_issuer,
- sizeof(pkt->u.ss_issuer));
- key->subsigs[key->subsigc - 1].sig.info.signer_id_set = 1;
- break;
- case PGP_PTAG_SS_CREATION_TIME:
- key = &keyring->keys[keyring->keyc - 1];
- key->subsigs[key->subsigc - 1].sig.info.birthtime = pkt->u.ss_time;
- key->subsigs[key->subsigc - 1].sig.info.birthtime_set = 1;
- break;
- case PGP_PTAG_SS_EXPIRATION_TIME:
- key = &keyring->keys[keyring->keyc - 1];
- key->subsigs[key->subsigc - 1].sig.info.duration = pkt->u.ss_time;
- key->subsigs[key->subsigc - 1].sig.info.duration_set = 1;
- break;
- case PGP_PTAG_SS_PRIMARY_USER_ID:
- key = &keyring->keys[keyring->keyc - 1];
- key->uid0 = key->uidc - 1;
- break;
- case PGP_PTAG_SS_REVOCATION_REASON:
- key = &keyring->keys[keyring->keyc - 1];
- if (key->uidc == 0) {
- /* revoke whole key */
- key->revoked = 1;
- revocation = &key->revocation;
- } else {
- /* revoke the user id */
- EXPAND_ARRAY(key, revoke);
- revocation = &key->revokes[key->revokec];
- key->revokes[key->revokec].uid = key->uidc - 1;
- key->revokec += 1;
- }
- revocation->code = pkt->u.ss_revocation.code;
- revocation->reason = netpgp_strdup(pgp_show_ss_rr_code(pkt->u.ss_revocation.code));
- break;
- case PGP_PTAG_CT_SIGNATURE_FOOTER:
- case PGP_PARSER_ERRCODE:
- break;
-
- default:
- break;
- }
-
- return PGP_RELEASE_MEMORY;
-}
-
-/**
- \ingroup HighLevel_KeyringRead
-
- \brief Reads a keyring from a file
-
- \param keyring Pointer to an existing pgp_keyring_t struct
- \param armour 1 if file is armoured; else 0
- \param filename Filename of keyring to be read
-
- \return pgp 1 if OK; 0 on error
-
- \note Keyring struct must already exist.
-
- \note Can be used with either a public or secret keyring.
-
- \note You must call pgp_keyring_free() after usage to free alloc-ed memory.
-
- \note If you call this twice on the same keyring struct, without calling
- pgp_keyring_free() between these calls, you will introduce a memory leak.
-
- \sa pgp_keyring_read_from_mem()
- \sa pgp_keyring_free()
-
-*/
-
-unsigned
-pgp_keyring_fileread(pgp_keyring_t *keyring,
- const unsigned armour,
- const char *filename)
-{
- pgp_stream_t *stream;
- keyringcb_t cb;
- unsigned res = 1;
- int fd;
-
- (void) memset(&cb, 0x0, sizeof(cb));
- cb.keyring = keyring;
- stream = pgp_new(sizeof(*stream));
-
- /* add this for the moment, */
- /*
- * \todo need to fix the problems with reading signature subpackets
- * later
- */
-
- /* pgp_parse_options(parse,PGP_PTAG_SS_ALL,PGP_PARSE_RAW); */
- pgp_parse_options(stream, PGP_PTAG_SS_ALL, PGP_PARSE_PARSED);
-
-#ifdef O_BINARY
- fd = open(filename, O_RDONLY | O_BINARY);
-#else
- fd = open(filename, O_RDONLY);
-#endif
- if (fd < 0) {
- pgp_stream_delete(stream);
- perror(filename);
- return 0;
- }
-#ifdef USE_MMAP_FOR_FILES
- pgp_reader_set_mmap(stream, fd);
-#else
- pgp_reader_set_fd(stream, fd);
-#endif
-
- pgp_set_callback(stream, cb_keyring_read, &cb);
-
- if (armour) {
- pgp_reader_push_dearmour(stream);
- }
- res = pgp_parse_and_accumulate(keyring, stream);
- pgp_print_errors(pgp_stream_get_errors(stream));
-
- if (armour) {
- pgp_reader_pop_dearmour(stream);
- }
-
- (void)close(fd);
-
- pgp_stream_delete(stream);
-
- return res;
-}
-
-/**
- \ingroup HighLevel_KeyringRead
-
- \brief Reads a keyring from memory
-
- \param keyring Pointer to existing pgp_keyring_t struct
- \param armour 1 if file is armoured; else 0
- \param mem Pointer to a pgp_memory_t struct containing keyring to be read
-
- \return pgp 1 if OK; 0 on error
-
- \note Keyring struct must already exist.
-
- \note Can be used with either a public or secret keyring.
-
- \note You must call pgp_keyring_free() after usage to free alloc-ed memory.
-
- \note If you call this twice on the same keyring struct, without calling
- pgp_keyring_free() between these calls, you will introduce a memory leak.
-
- \sa pgp_keyring_fileread
- \sa pgp_keyring_free
-*/
-unsigned
-pgp_keyring_read_from_mem(pgp_io_t *io,
- pgp_keyring_t *keyring,
- const unsigned armour,
- pgp_memory_t *mem)
-{
- pgp_stream_t *stream;
- const unsigned noaccum = 0;
- keyringcb_t cb;
- unsigned res;
-
- (void) memset(&cb, 0x0, sizeof(cb));
- cb.keyring = keyring;
- stream = pgp_new(sizeof(*stream));
- pgp_parse_options(stream, PGP_PTAG_SS_ALL, PGP_PARSE_PARSED);
- pgp_setup_memory_read(io, &stream, mem, &cb, cb_keyring_read,
- noaccum);
- if (armour) {
- pgp_reader_push_dearmour(stream);
- }
- res = (unsigned)pgp_parse_and_accumulate(keyring, stream);
- pgp_print_errors(pgp_stream_get_errors(stream));
- if (armour) {
- pgp_reader_pop_dearmour(stream);
- }
- /* don't call teardown_memory_read because memory was passed in */
- pgp_stream_delete(stream);
- return res;
-}
-
-/**
- \ingroup HighLevel_KeyringRead
-
- \brief Frees keyring's contents (but not keyring itself)
-
- \param keyring Keyring whose data is to be freed
-
- \note This does not free keyring itself, just the memory alloc-ed in it.
- */
-void
-pgp_keyring_free(pgp_keyring_t *keyring)
-{
- (void)free(keyring->keys);
- keyring->keys = NULL;
- keyring->keyc = keyring->keyvsize = 0;
-}
-
-/**
- \ingroup HighLevel_KeyringFind
-
- \brief Finds key in keyring from its Key ID
-
- \param keyring Keyring to be searched
- \param keyid ID of required key
-
- \return Pointer to key, if found; NULL, if not found
-
- \note This returns a pointer to the key inside the given keyring,
- not a copy. Do not free it after use.
-
-*/
-const pgp_key_t *
-pgp_getkeybyid(pgp_io_t *io, const pgp_keyring_t *keyring,
- const uint8_t *keyid, unsigned *from, pgp_pubkey_t **pubkey)
-{
- uint8_t nullid[PGP_KEY_ID_SIZE];
-
- (void) memset(nullid, 0x0, sizeof(nullid));
- for ( ; keyring && *from < keyring->keyc; *from += 1) {
- if (pgp_get_debug_level(__FILE__)) {
- hexdump(io->errs, "keyring keyid", keyring->keys[*from].sigid, PGP_KEY_ID_SIZE);
- hexdump(io->errs, "keyid", keyid, PGP_KEY_ID_SIZE);
- }
- if (memcmp(keyring->keys[*from].sigid, keyid, PGP_KEY_ID_SIZE) == 0 ||
- memcmp(&keyring->keys[*from].sigid[PGP_KEY_ID_SIZE / 2],
- keyid, PGP_KEY_ID_SIZE / 2) == 0) {
- if (pubkey) {
- *pubkey = &keyring->keys[*from].key.pubkey;
- }
- return &keyring->keys[*from];
- }
- if (memcmp(&keyring->keys[*from].encid, nullid, sizeof(nullid)) == 0) {
- continue;
- }
- if (memcmp(&keyring->keys[*from].encid, keyid, PGP_KEY_ID_SIZE) == 0 ||
- memcmp(&keyring->keys[*from].encid[PGP_KEY_ID_SIZE / 2], keyid, PGP_KEY_ID_SIZE / 2) == 0) {
- if (pubkey) {
- *pubkey = &keyring->keys[*from].enckey;
- }
- return &keyring->keys[*from];
- }
- }
- return NULL;
-}
-
-/* convert a string keyid into a binary keyid */
-static void
-str2keyid(const char *userid, uint8_t *keyid, size_t len)
-{
- static const char *uppers = "0123456789ABCDEF";
- static const char *lowers = "0123456789abcdef";
- const char *hi;
- const char *lo;
- uint8_t hichar;
- uint8_t lochar;
- size_t j;
- int i;
-
- for (i = 0, j = 0 ; j < len && userid[i] && userid[i + 1] ; i += 2, j++) {
- if ((hi = strchr(uppers, userid[i])) == NULL) {
- if ((hi = strchr(lowers, userid[i])) == NULL) {
- break;
- }
- hichar = (uint8_t)(hi - lowers);
- } else {
- hichar = (uint8_t)(hi - uppers);
- }
- if ((lo = strchr(uppers, userid[i + 1])) == NULL) {
- if ((lo = strchr(lowers, userid[i + 1])) == NULL) {
- break;
- }
- lochar = (uint8_t)(lo - lowers);
- } else {
- lochar = (uint8_t)(lo - uppers);
- }
- keyid[j] = (hichar << 4) | (lochar);
- }
- keyid[j] = 0x0;
-}
-
-/* return the next key which matches, starting searching at *from */
-static const pgp_key_t *
-getkeybyname(pgp_io_t *io,
- const pgp_keyring_t *keyring,
- const char *name,
- unsigned *from)
-{
- const pgp_key_t *kp;
- uint8_t **uidp;
- unsigned i = 0;
- pgp_key_t *keyp;
- unsigned savedstart;
- regex_t r;
- uint8_t keyid[PGP_KEY_ID_SIZE + 1];
- size_t len;
-
- if (!keyring || !name || !from) {
- return NULL;
- }
- len = strlen(name);
- if (pgp_get_debug_level(__FILE__)) {
- (void) fprintf(io->outs, "[%u] name '%s', len %zu\n",
- *from, name, len);
- }
- /* first try name as a keyid */
- (void) memset(keyid, 0x0, sizeof(keyid));
- str2keyid(name, keyid, sizeof(keyid));
- if (pgp_get_debug_level(__FILE__)) {
- hexdump(io->outs, "keyid", keyid, 4);
- }
- savedstart = *from;
- if ((kp = pgp_getkeybyid(io, keyring, keyid, from, NULL)) != NULL) {
- return kp;
- }
- *from = savedstart;
- if (pgp_get_debug_level(__FILE__)) {
- (void) fprintf(io->outs, "regex match '%s' from %u\n",
- name, *from);
- }
- /* match on full name or email address as a NOSUB, ICASE regexp */
- (void) regcomp(&r, name, REG_EXTENDED | REG_ICASE);
- for (keyp = &keyring->keys[*from]; *from < keyring->keyc; *from += 1, keyp++) {
- uidp = keyp->uids;
- for (i = 0 ; i < keyp->uidc; i++, uidp++) {
- if (regexec(&r, (char *)*uidp, 0, NULL, 0) == 0) {
- if (pgp_get_debug_level(__FILE__)) {
- (void) fprintf(io->outs,
- "MATCHED keyid \"%s\" len %" PRIsize "u\n",
- (char *) *uidp, len);
- }
- regfree(&r);
- return keyp;
- }
- }
- }
- regfree(&r);
- return NULL;
-}
-
-/**
- \ingroup HighLevel_KeyringFind
-
- \brief Finds key from its User ID
-
- \param keyring Keyring to be searched
- \param userid User ID of required key
-
- \return Pointer to Key, if found; NULL, if not found
-
- \note This returns a pointer to the key inside the keyring, not a
- copy. Do not free it.
-
-*/
-const pgp_key_t *
-pgp_getkeybyname(pgp_io_t *io,
- const pgp_keyring_t *keyring,
- const char *name)
-{
- unsigned from;
-
- from = 0;
- return getkeybyname(io, keyring, name, &from);
-}
-
-const pgp_key_t *
-pgp_getnextkeybyname(pgp_io_t *io,
- const pgp_keyring_t *keyring,
- const char *name,
- unsigned *n)
-{
- return getkeybyname(io, keyring, name, n);
-}
-
-/**
- \ingroup HighLevel_KeyringList
-
- \brief Prints all keys in keyring to stdout.
-
- \param keyring Keyring to use
-
- \return none
-*/
-int
-pgp_keyring_list(pgp_io_t *io, const pgp_keyring_t *keyring, const int psigs)
-{
- pgp_key_t *key;
- unsigned n;
-
- (void) fprintf(io->res, "%u key%s\n", keyring->keyc,
- (keyring->keyc == 1) ? "" : "s");
- for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) {
- if (pgp_is_key_secret(key)) {
- pgp_print_keydata(io, keyring, key, "sec",
- &key->key.seckey.pubkey, 0);
- } else {
- pgp_print_keydata(io, keyring, key, "signature ", &key->key.pubkey, psigs);
- }
- (void) fputc('\n', io->res);
- }
- return 1;
-}
-
-int
-pgp_keyring_json(pgp_io_t *io, const pgp_keyring_t *keyring, mj_t *obj, const int psigs)
-{
- pgp_key_t *key;
- unsigned n;
-
- (void) memset(obj, 0x0, sizeof(*obj));
- mj_create(obj, "array");
- obj->size = keyring->keyvsize;
- if (pgp_get_debug_level(__FILE__)) {
- (void) fprintf(io->errs, "pgp_keyring_json: vsize %u\n", obj->size);
- }
- if ((obj->value.v = calloc(sizeof(*obj->value.v), obj->size)) == NULL) {
- (void) fprintf(io->errs, "calloc failure\n");
- return 0;
- }
- for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) {
- if (pgp_is_key_secret(key)) {
- pgp_sprint_mj(io, keyring, key, &obj->value.v[obj->c],
- "sec", &key->key.seckey.pubkey, psigs);
- } else {
- pgp_sprint_mj(io, keyring, key, &obj->value.v[obj->c],
- "signature ", &key->key.pubkey, psigs);
- }
- if (obj->value.v[obj->c].type != 0) {
- obj->c += 1;
- }
- }
- if (pgp_get_debug_level(__FILE__)) {
- char *s;
-
- mj_asprint(&s, obj, MJ_JSON_ENCODE);
- (void) fprintf(stderr, "pgp_keyring_json: '%s'\n", s);
- free(s);
- }
- return 1;
-}
-
-
-/* this interface isn't right - hook into callback for getting passphrase */
-char *
-pgp_export_key(pgp_io_t *io, const pgp_key_t *keydata, uint8_t *passphrase)
-{
- pgp_output_t *output;
- pgp_memory_t *mem;
- char *cp;
-
- __PGP_USED(io);
- pgp_setup_memory_write(&output, &mem, 128);
- if (keydata->type == PGP_PTAG_CT_PUBLIC_KEY) {
- pgp_write_xfer_pubkey(output, keydata, 1);
- } else {
- pgp_write_xfer_seckey(output, keydata, passphrase,
- strlen((char *)passphrase), 1);
- }
- cp = netpgp_strdup(pgp_mem_data(mem));
- pgp_teardown_memory_write(output, mem);
- return cp;
-}
-
-/* add a key to a public keyring */
-int
-pgp_add_to_pubring(pgp_keyring_t *keyring, const pgp_pubkey_t *pubkey, pgp_content_enum tag)
-{
- pgp_key_t *key;
- time_t duration;
-
- if (pgp_get_debug_level(__FILE__)) {
- fprintf(stderr, "pgp_add_to_pubring (type %u)\n", tag);
- }
- switch(tag) {
- case PGP_PTAG_CT_PUBLIC_KEY:
- EXPAND_ARRAY(keyring, key);
- key = &keyring->keys[keyring->keyc++];
- duration = key->key.pubkey.duration;
- (void) memset(key, 0x0, sizeof(*key));
- key->type = tag;
- pgp_keyid(key->sigid, PGP_KEY_ID_SIZE, pubkey, keyring->hashtype);
- pgp_fingerprint(&key->sigfingerprint, pubkey, keyring->hashtype);
- key->key.pubkey = *pubkey;
- key->key.pubkey.duration = duration;
- return 1;
- case PGP_PTAG_CT_PUBLIC_SUBKEY:
- /* subkey is not the first */
- key = &keyring->keys[keyring->keyc - 1];
- pgp_keyid(key->encid, PGP_KEY_ID_SIZE, pubkey, keyring->hashtype);
- duration = key->key.pubkey.duration;
- (void) memcpy(&key->enckey, pubkey, sizeof(key->enckey));
- key->enckey.duration = duration;
- return 1;
- default:
- return 0;
- }
-}
-
-/* add a key to a secret keyring */
-int
-pgp_add_to_secring(pgp_keyring_t *keyring, const pgp_seckey_t *seckey)
-{
- const pgp_pubkey_t *pubkey;
- pgp_key_t *key;
-
- if (pgp_get_debug_level(__FILE__)) {
- fprintf(stderr, "pgp_add_to_secring\n");
- }
- if (keyring->keyc > 0) {
- key = &keyring->keys[keyring->keyc - 1];
- if (pgp_get_debug_level(__FILE__) &&
- key->key.pubkey.alg == PGP_PKA_DSA &&
- seckey->pubkey.alg == PGP_PKA_ELGAMAL) {
- fprintf(stderr, "pgp_add_to_secring: found elgamal seckey\n");
- }
- }
- EXPAND_ARRAY(keyring, key);
- key = &keyring->keys[keyring->keyc++];
- (void) memset(key, 0x0, sizeof(*key));
- pubkey = &seckey->pubkey;
- pgp_keyid(key->sigid, PGP_KEY_ID_SIZE, pubkey, keyring->hashtype);
- pgp_fingerprint(&key->sigfingerprint, pubkey, keyring->hashtype);
- key->type = PGP_PTAG_CT_SECRET_KEY;
- key->key.seckey = *seckey;
- if (pgp_get_debug_level(__FILE__)) {
- fprintf(stderr, "pgp_add_to_secring: keyc %u\n", keyring->keyc);
- }
- return 1;
-}
-
-/* append one keyring to another */
-int
-pgp_append_keyring(pgp_keyring_t *keyring, pgp_keyring_t *newring)
-{
- unsigned i;
-
- for (i = 0 ; i < newring->keyc ; i++) {
- EXPAND_ARRAY(keyring, key);
- (void) memcpy(&keyring->keys[keyring->keyc], &newring->keys[i],
- sizeof(newring->keys[i]));
- keyring->keyc += 1;
- }
- return 1;
-}
diff --git a/libs/netpgp/mj.c b/libs/netpgp/mj.c
deleted file mode 100644
index 3396303b..00000000
--- a/libs/netpgp/mj.c
+++ /dev/null
@@ -1,653 +0,0 @@
-/*-
- * Copyright (c) 2010 Alistair Crooks
- * 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
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#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;
- }
-}
diff --git a/libs/netpgp/mj.h b/libs/netpgp/mj.h
deleted file mode 100644
index b22913bd..00000000
--- a/libs/netpgp/mj.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*-
- * Copyright (c) 2010,2011 Alistair Crooks
- * 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
diff --git a/libs/netpgp/netpgp.c b/libs/netpgp/netpgp.c
deleted file mode 100644
index 706dc6b8..00000000
--- a/libs/netpgp/netpgp.c
+++ /dev/null
@@ -1,1978 +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.
- */
-#include "config-netpgp.h"
-
-#ifdef HAVE_SYS_CDEFS_H
-#include
-#endif
-
-#if defined(__NetBSD__)
-__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: netpgp.c,v 1.96 2012/02/22 06:58:54 agc Exp $");
-#endif
-
-#include
-#include
-#include
-#include
-
-#ifdef HAVE_SYS_RESOURCE_H
-#include
-#endif
-
-#ifdef HAVE_FCNTL_H
-#include
-#endif
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#ifdef HAVE_UNISTD_H
-#include
-#endif
-
-#include
-
-#ifdef HAVE_LIMITS_H
-#include
-#endif
-
-#include
-
-#include "packet-netpgp.h"
-#include "packet-parse.h"
-#include "keyring-netpgp.h"
-#include "errors-netpgp.h"
-#include "packet-show.h"
-#include "create-netpgp.h"
-#include "netpgpsdk.h"
-#include "memory-netpgp.h"
-#include "validate-netpgp.h"
-#include "readerwriter-netpgp.h"
-#include "netpgpdefs.h"
-#include "crypto-netpgp.h"
-//#include "ssh2pgp.h"
-#include "defs-netpgp.h"
-
-#if defined(ANDROID) || defined(__ANDROID__)
-char * getpass (const char *prompt)
-{
- return strdup("foo");
-}
-#endif
-
-/* read any gpg config file */
-#if 0 //////
-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;
-}
-#endif //////
-
-/* small function to pretty print an 8-character raw userid */
-static char *
-userid_to_id(const uint8_t *userid, char *id)
-{
- static const char *hexes = "0123456789abcdef";
- int i;
-
- for (i = 0; i < 8 ; i++) {
- id[i * 2] = hexes[(unsigned)(userid[i] & 0xf0) >> 4];
- id[(i * 2) + 1] = hexes[userid[i] & 0xf];
- }
- id[8 * 2] = 0x0;
- return id;
-}
-
-/* print out the successful signature information */
-static void
-resultp(pgp_io_t *io,
- const char *f,
- pgp_validation_t *res,
- pgp_keyring_t *ring)
-{
- const pgp_key_t *key;
- pgp_pubkey_t *sigkey;
- unsigned from;
- unsigned i;
- time_t t;
- char id[MAX_ID_LENGTH + 1];
-
- for (i = 0; i < res->validc; i++) {
- (void) fprintf(io->res,
- "Good signature for %s made %s",
- (f) ? f : "",
- ctime(&res->valid_sigs[i].birthtime));
- if (res->duration > 0) {
- t = res->birthtime + res->duration;
- (void) fprintf(io->res, "Valid until %s", ctime(&t));
- }
- (void) fprintf(io->res,
- "using %s key %s\n",
- pgp_show_pka(res->valid_sigs[i].key_alg),
- userid_to_id(res->valid_sigs[i].signer_id, id));
- from = 0;
- key = pgp_getkeybyid(io, ring,
- (const uint8_t *) res->valid_sigs[i].signer_id,
- &from, &sigkey);
- if (sigkey == &key->enckey) {
- (void) fprintf(io->res,
- "WARNING: signature for %s made with encryption key\n",
- (f) ? f : "");
- }
- pgp_print_keydata(io, ring, key, "signature ", &key->key.pubkey, 0);
- }
-}
-
-/* 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 */
-#if 0 //////
-static void *
-readkeyring(netpgp_t *netpgp, const char *name)
-{
- pgp_keyring_t *keyring;
- const unsigned noarmor = 0;
- char f[MAXPATHLEN];
- char *filename;
- char *homedir;
-
- homedir = netpgp_getvar(netpgp, "homedir");
- if ((filename = netpgp_getvar(netpgp, name)) == NULL) {
- (void) snprintf(f, sizeof(f), "%s/%s.gpg", homedir, name);
- filename = f;
- }
- if ((keyring = calloc(1, sizeof(*keyring))) == NULL) {
- (void) fprintf(stderr, "readkeyring: bad alloc\n");
- return NULL;
- }
- if (!pgp_keyring_fileread(keyring, noarmor, filename)) {
- free(keyring);
- (void) fprintf(stderr, "Can't read %s %s\n", name, filename);
- return NULL;
- }
- netpgp_setvar(netpgp, name, filename);
- return keyring;
-}
-#endif //////
-
-/* read keys from ssh key files */
-#if 0 //////
-static int
-readsshkeys(netpgp_t *netpgp, char *homedir, const char *needseckey)
-{
- pgp_keyring_t *pubring;
- pgp_keyring_t *secring;
- struct stat st;
- unsigned hashtype;
- char *hash;
- char f[MAXPATHLEN];
- char *filename;
-
- if ((filename = netpgp_getvar(netpgp, "sshkeyfile")) == NULL) {
- /* set reasonable default for RSA key */
- (void) snprintf(f, sizeof(f), "%s/id_rsa.pub", homedir);
- filename = f;
- } else if (strcmp(&filename[strlen(filename) - 4], ".pub") != 0) {
- /* got ssh keys, check for pub file name */
- (void) snprintf(f, sizeof(f), "%s.pub", filename);
- filename = f;
- }
- /* check the pub file exists */
- if (stat(filename, &st) != 0) {
- (void) fprintf(stderr, "readsshkeys: bad pubkey filename '%s'\n", filename);
- return 0;
- }
- if ((pubring = calloc(1, sizeof(*pubring))) == NULL) {
- (void) fprintf(stderr, "readsshkeys: bad alloc\n");
- return 0;
- }
- /* openssh2 keys use md5 by default */
- hashtype = PGP_HASH_MD5;
- if ((hash = netpgp_getvar(netpgp, "hash")) != NULL) {
- /* openssh 2 hasn't really caught up to anything else yet */
- if (netpgp_strcasecmp(hash, "md5") == 0) {
- hashtype = PGP_HASH_MD5;
- } else if (netpgp_strcasecmp(hash, "sha1") == 0) {
- hashtype = PGP_HASH_SHA1;
- } else if (netpgp_strcasecmp(hash, "sha256") == 0) {
- hashtype = PGP_HASH_SHA256;
- }
- }
- if (!pgp_ssh2_readkeys(netpgp->io, pubring, NULL, filename, NULL, hashtype)) {
- free(pubring);
- (void) fprintf(stderr, "readsshkeys: can't read %s\n",
- filename);
- return 0;
- }
- if (netpgp->pubring == NULL) {
- netpgp->pubring = pubring;
- } else {
- pgp_append_keyring(netpgp->pubring, pubring);
- }
- if (needseckey) {
- netpgp_setvar(netpgp, "sshpubfile", filename);
- /* try to take the ".pub" off the end */
- if (filename == f) {
- f[strlen(f) - 4] = 0x0;
- } else {
- (void) snprintf(f, sizeof(f), "%.*s",
- (int)strlen(filename) - 4, filename);
- filename = f;
- }
- if ((secring = calloc(1, sizeof(*secring))) == NULL) {
- free(pubring);
- (void) fprintf(stderr, "readsshkeys: bad alloc\n");
- return 0;
- }
- if (!pgp_ssh2_readkeys(netpgp->io, pubring, secring, NULL, filename, hashtype)) {
- free(pubring);
- free(secring);
- (void) fprintf(stderr, "readsshkeys: can't read sec %s\n", filename);
- return 0;
- }
- netpgp->secring = secring;
- netpgp_setvar(netpgp, "sshsecfile", filename);
- }
- return 1;
-}
-#endif //////
-
-/* get the uid of the first key in the keyring */
-#if 0 //////
-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].sigid;
- 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;
-}
-#endif //////
-
-/* find the time - in a specific %Y-%m-%d format - using a regexp */
-static int
-grabdate(char *s, int64_t *t)
-{
- static regex_t r;
- static int compiled;
- regmatch_t matches[10];
- struct tm tm;
-
- if (!compiled) {
- compiled = 1;
- (void) regcomp(&r, "([0-9][0-9][0-9][0-9])[-/]([0-9][0-9])[-/]([0-9][0-9])", REG_EXTENDED);
- }
- if (regexec(&r, s, 10, matches, 0) == 0) {
- (void) memset(&tm, 0x0, sizeof(tm));
- tm.tm_year = (int)strtol(&s[(int)matches[1].rm_so], NULL, 10);
- tm.tm_mon = (int)strtol(&s[(int)matches[2].rm_so], NULL, 10) - 1;
- tm.tm_mday = (int)strtol(&s[(int)matches[3].rm_so], NULL, 10);
- *t = mktime(&tm);
- return 1;
- }
- return 0;
-}
-
-/* get expiration in seconds */
-static uint64_t
-get_duration(char *s)
-{
- uint64_t now;
- int64_t t;
- char *mult;
-
- if (s == NULL) {
- return 0;
- }
- now = (uint64_t)strtoull(s, NULL, 10);
- if ((mult = strchr("hdwmy", s[strlen(s) - 1])) != NULL) {
- switch(*mult) {
- case 'h':
- return now * 60 * 60;
- case 'd':
- return now * 60 * 60 * 24;
- case 'w':
- return now * 60 * 60 * 24 * 7;
- case 'm':
- return now * 60 * 60 * 24 * 31;
- case 'y':
- return now * 60 * 60 * 24 * 365;
- }
- }
- if (grabdate(s, &t)) {
- return t;
- }
- return (uint64_t)strtoll(s, NULL, 10);
-}
-
-/* get birthtime in seconds */
-static int64_t
-get_birthtime(char *s)
-{
- int64_t t;
-
- if (s == NULL) {
- return time(NULL);
- }
- if (grabdate(s, &t)) {
- return t;
- }
- return (uint64_t)strtoll(s, NULL, 10);
-}
-
-/* resolve the userid */
-static const pgp_key_t *
-resolve_userid(netpgp_t *netpgp, const pgp_keyring_t *keyring, const char *userid)
-{
- const pgp_key_t *key;
- pgp_io_t *io;
-
- if (userid == NULL) {
- userid = netpgp_getvar(netpgp, "userid");
- if (userid == NULL)
- return NULL;
- } else if (userid[0] == '0' && userid[1] == 'x') {
- userid += 2;
- }
- io = netpgp->io;
- if ((key = pgp_getkeybyname(io, keyring, userid)) == NULL) {
- (void) fprintf(io->errs, "Can't find key '%s'\n", userid);
- }
- return key;
-}
-
-/* append a key to a keyring */
-#if 0 //////
-static int
-appendkey(pgp_io_t *io, pgp_key_t *key, char *ringfile)
-{
- pgp_output_t *create;
- const unsigned noarmor = 0;
- int fd;
-
- if ((fd = pgp_setup_file_append(&create, ringfile)) < 0) {
- fd = pgp_setup_file_write(&create, ringfile, 0);
- }
- if (fd < 0) {
- (void) fprintf(io->errs, "can't open pubring '%s'\n", ringfile);
- return 0;
- }
- if (!pgp_write_xfer_pubkey(create, key, noarmor)) {
- (void) fprintf(io->errs, "Cannot write pubkey\n");
- return 0;
- }
- pgp_teardown_file_write(create, fd);
- return 1;
-}
-#endif //////
-
-/* return 1 if the file contains ascii-armoured text */
-static unsigned
-isarmoured(pgp_io_t *io, const char *f, const void *memory, const char *text)
-{
- regmatch_t matches[10];
- unsigned armoured;
- regex_t r;
- FILE *fp;
- char buf[BUFSIZ];
-
- armoured = 0;
- (void) regcomp(&r, text, REG_EXTENDED);
- if (f) {
- if ((fp = fopen(f, "r")) == NULL) {
- (void) fprintf(io->errs, "isarmoured: can't open '%s'\n", f);
- regfree(&r);
- return 0;
- }
- if (fgets(buf, (int)sizeof(buf), fp) != NULL) {
- if (regexec(&r, buf, 10, matches, 0) == 0) {
- armoured = 1;
- }
- }
- (void) fclose(fp);
- } else {
- if (regexec(&r, memory, 10, matches, 0) == 0) {
- armoured = 1;
- }
- }
- regfree(&r);
- return armoured;
-}
-
-/* vararg print function */
-static void
-p(FILE *fp, const char *s, ...)
-{
- va_list args;
-
- va_start(args, s);
- while (s != NULL) {
- (void) fprintf(fp, "%s", s);
- s = va_arg(args, char *);
- }
- va_end(args);
-}
-
-/* print a JSON object to the FILE stream */
-static void
-pobj(FILE *fp, mj_t *obj, int depth)
-{
- unsigned i;
- char *s;
-
- if (obj == NULL) {
- (void) fprintf(stderr, "No object found\n");
- return;
- }
- for (i = 0 ; i < (unsigned)depth ; i++) {
- p(fp, " ", NULL);
- }
- switch(obj->type) {
- case MJ_NULL:
- case MJ_FALSE:
- case MJ_TRUE:
- p(fp, (obj->type == MJ_NULL) ? "null" : (obj->type == MJ_FALSE) ? "false" : "true", NULL);
- break;
- case MJ_NUMBER:
- p(fp, obj->value.s, NULL);
- break;
- case MJ_STRING:
- if ((i = mj_asprint(&s, obj, MJ_HUMAN)) > 2) {
- (void) fprintf(fp, "%.*s", (int)i - 2, &s[1]);
- free(s);
- }
- break;
- case MJ_ARRAY:
- for (i = 0 ; i < obj->c ; i++) {
- pobj(fp, &obj->value.v[i], depth + 1);
- if (i < obj->c - 1) {
- (void) fprintf(fp, ", ");
- }
- }
- (void) fprintf(fp, "\n");
- break;
- case MJ_OBJECT:
- for (i = 0 ; i < obj->c ; i += 2) {
- pobj(fp, &obj->value.v[i], depth + 1);
- p(fp, ": ", NULL);
- pobj(fp, &obj->value.v[i + 1], 0);
- if (i < obj->c - 1) {
- p(fp, ", ", NULL);
- }
- }
- p(fp, "\n", NULL);
- break;
- default:
- break;
- }
-}
-
-/* return the time as a string */
-static char *
-ptimestr(char *dest, size_t size, time_t t)
-{
- struct tm *tm;
-
- tm = gmtime(&t);
- (void) snprintf(dest, size, "%04d-%02d-%02d",
- tm->tm_year + 1900,
- tm->tm_mon + 1,
- tm->tm_mday);
- return dest;
-}
-
-/* format a JSON object */
-static void
-format_json_key(FILE *fp, mj_t *obj, const int psigs)
-{
- int64_t birthtime;
- int64_t duration;
- time_t now;
- char tbuf[32];
- char *s;
- mj_t *sub;
- int i;
-
- if (pgp_get_debug_level(__FILE__)) {
- mj_asprint(&s, obj, MJ_HUMAN);
- (void) fprintf(stderr, "formatobj: json is '%s'\n", s);
- free(s);
- }
- if (obj->c == 2 && obj->value.v[1].type == MJ_STRING &&
- strcmp(obj->value.v[1].value.s, "[REVOKED]") == 0) {
- /* whole key has been rovoked - just return */
- return;
- }
- pobj(fp, &obj->value.v[mj_object_find(obj, "header", 0, 2) + 1], 0);
- p(fp, " ", NULL);
- pobj(fp, &obj->value.v[mj_object_find(obj, "key bits", 0, 2) + 1], 0);
- p(fp, "/", NULL);
- pobj(fp, &obj->value.v[mj_object_find(obj, "pka", 0, 2) + 1], 0);
- p(fp, " ", NULL);
- pobj(fp, &obj->value.v[mj_object_find(obj, "key id", 0, 2) + 1], 0);
- birthtime = (int64_t)strtoll(obj->value.v[mj_object_find(obj, "birthtime", 0, 2) + 1].value.s, NULL, 10);
- p(fp, " ", ptimestr(tbuf, sizeof(tbuf), birthtime), NULL);
- duration = (int64_t)strtoll(obj->value.v[mj_object_find(obj, "duration", 0, 2) + 1].value.s, NULL, 10);
- if (duration > 0) {
- now = time(NULL);
- p(fp, " ", (birthtime + duration < now) ? "[EXPIRED " : "[EXPIRES ",
- ptimestr(tbuf, sizeof(tbuf), birthtime + duration), "]", NULL);
- }
- p(fp, "\n", "Key fingerprint: ", NULL);
- pobj(fp, &obj->value.v[mj_object_find(obj, "fingerprint", 0, 2) + 1], 0);
- p(fp, "\n", NULL);
- /* go to field after \"duration\" */
- for (i = mj_object_find(obj, "duration", 0, 2) + 2; i < mj_arraycount(obj) ; i += 2) {
- if (strcmp(obj->value.v[i].value.s, "uid") == 0) {
- sub = &obj->value.v[i + 1];
- p(fp, "uid", NULL);
- pobj(fp, &sub->value.v[0], (psigs) ? 4 : 14); /* human name */
- pobj(fp, &sub->value.v[1], 1); /* any revocation */
- p(fp, "\n", NULL);
- } else if (strcmp(obj->value.v[i].value.s, "encryption") == 0) {
- sub = &obj->value.v[i + 1];
- p(fp, "encryption", NULL);
- pobj(fp, &sub->value.v[0], 1); /* size */
- p(fp, "/", NULL);
- pobj(fp, &sub->value.v[1], 0); /* alg */
- p(fp, " ", NULL);
- pobj(fp, &sub->value.v[2], 0); /* id */
- p(fp, " ", ptimestr(tbuf, sizeof(tbuf),
- (time_t)strtoll(sub->value.v[3].value.s, NULL, 10)),
- "\n", NULL);
- } else if (strcmp(obj->value.v[i].value.s, "sig") == 0) {
- sub = &obj->value.v[i + 1];
- p(fp, "sig", NULL);
- pobj(fp, &sub->value.v[0], 8); /* size */
- p(fp, " ", ptimestr(tbuf, sizeof(tbuf),
- (time_t)strtoll(sub->value.v[1].value.s, NULL, 10)),
- " ", NULL); /* time */
- pobj(fp, &sub->value.v[2], 0); /* human name */
- p(fp, "\n", NULL);
- } else {
- fprintf(stderr, "weird '%s'\n", obj->value.v[i].value.s);
- pobj(fp, &obj->value.v[i], 0); /* human name */
- }
- }
- p(fp, "\n", NULL);
-}
-
-/* save a pgp pubkey to a temp file */
-static int
-savepubkey(char *res, char *f, size_t size)
-{
- size_t len;
- int cc;
- int wc;
- int fd;
-
- (void) snprintf(f, size, "/tmp/pgp2ssh.XXXXXXX");
- if ((fd = mkstemp(f)) < 0) {
- (void) fprintf(stderr, "can't create temp file '%s'\n", f);
- return 0;
- }
- len = strlen(res);
- for (cc = 0 ; (wc = (int)write(fd, &res[cc], len - (size_t)cc)) > 0 ; cc += wc) {
- }
- (void) close(fd);
- return 1;
-}
-
-/* format a uint32_t */
-static int
-formatu32(uint8_t *buffer, uint32_t value)
-{
- buffer[0] = (uint8_t)(value >> 24) & 0xff;
- buffer[1] = (uint8_t)(value >> 16) & 0xff;
- buffer[2] = (uint8_t)(value >> 8) & 0xff;
- buffer[3] = (uint8_t)value & 0xff;
- return sizeof(uint32_t);
-}
-
-/* format a string as (len, string) */
-static int
-formatstring(char *buffer, const uint8_t *s, size_t len)
-{
- int cc;
-
- cc = formatu32((uint8_t *)buffer, (uint32_t)len);
- (void) memcpy(&buffer[cc], s, len);
- return cc + (int)len;
-}
-
-/* format a bignum, checking for "interesting" high bit values */
-static int
-formatbignum(char *buffer, BIGNUM *bn)
-{
- size_t len;
- uint8_t *cp;
- int cc;
-
- len = (size_t) BN_num_bytes(bn);
- if ((cp = calloc(1, len + 1)) == NULL) {
- (void) fprintf(stderr, "calloc failure in formatbignum\n");
- return 0;
- }
- (void) BN_bn2bin(bn, cp + 1);
- cp[0] = 0x0;
- cc = (cp[1] & 0x80) ? formatstring(buffer, cp, len + 1) : formatstring(buffer, &cp[1], len);
- free(cp);
- return cc;
-}
-
-#define MAX_PASSPHRASE_ATTEMPTS 3
-#define INFINITE_ATTEMPTS -1
-
-/* get the passphrase from the user */
-#if 0 //////
-static int
-find_passphrase(FILE *passfp, const char *id, char *passphrase, size_t size, int attempts)
-{
- char prompt[BUFSIZ];
- char buf[128];
- char *cp;
- int cc;
- int i;
-
- if (passfp) {
- if (fgets(passphrase, (int)size, passfp) == NULL) {
- return 0;
- }
- return (int)strlen(passphrase);
- }
- for (i = 0 ; i < attempts ; i++) {
- (void) snprintf(prompt, sizeof(prompt), "Enter passphrase for %.16s: ", id);
- if ((cp = getpass(prompt)) == NULL) {
- break;
- }
- cc = snprintf(buf, sizeof(buf), "%s", cp);
- (void) snprintf(prompt, sizeof(prompt), "Repeat passphrase for %.16s: ", id);
- if ((cp = getpass(prompt)) == NULL) {
- break;
- }
- cc = snprintf(passphrase, size, "%s", cp);
- if (strcmp(buf, passphrase) == 0) {
- (void) memset(buf, 0x0, sizeof(buf));
- return cc;
- }
- }
- (void) memset(buf, 0x0, sizeof(buf));
- (void) memset(passphrase, 0x0, size);
- return 0;
-}
-#endif //////
-
-/***************************************************************************/
-/* exported functions start here */
-/***************************************************************************/
-
-/* initialise a netpgp_t structure */
-#if 0 //////
-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;
- int last;
-
-#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, "") == 0) {
- io->outs = stderr;
- }
- io->errs = stderr;
- if ((stream = netpgp_getvar(netpgp, "errs")) != NULL &&
- strcmp(stream, "") == 0) {
- io->errs = stdout;
- }
- if ((results = netpgp_getvar(netpgp, "res")) == NULL) {
- io->res = io->errs;
- } else if (strcmp(results, "") == 0) {
- io->res = stdout;
- } else if (strcmp(results, "") == 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_getvar(netpgp, "ssh keys") == NULL) {
- /* read from ordinary pgp keyrings */
- netpgp->pubring = readkeyring(netpgp, "pubring");
- if (netpgp->pubring == NULL) {
- (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 */
- netpgp->secring = readkeyring(netpgp, "secring");
- if (netpgp->secring == NULL) {
- (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;
- }
- } else {
- /* read from ssh keys */
- last = (netpgp->pubring != NULL);
- if (!readsshkeys(netpgp, homedir, netpgp_getvar(netpgp, "need seckey"))) {
- (void) fprintf(io->errs, "Can't read ssh keys\n");
- return 0;
- }
- if ((userid = netpgp_getvar(netpgp, "userid")) == NULL) {
- get_first_ring(netpgp->pubring, id, sizeof(id), last);
- netpgp_setvar(netpgp, "userid", userid = id);
- }
- if (userid == NULL) {
- if (netpgp_getvar(netpgp, "need userid") != NULL) {
- (void) fprintf(io->errs,
- "Cannot find user id\n");
- return 0;
- }
- } else {
- (void) netpgp_setvar(netpgp, "userid", userid);
- }
- }
- t = time(NULL);
- netpgp_setvar(netpgp, "initialised", ctime(&t));
- return 1;
-}
-#endif //////
-
-/* 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;
-}
-
-/* list the keys in a keyring */
-int
-netpgp_list_keys(netpgp_t *netpgp, const int psigs)
-{
- if (netpgp->pubring == NULL) {
- (void) fprintf(stderr, "No keyring\n");
- return 0;
- }
- return pgp_keyring_list(netpgp->io, netpgp->pubring, psigs);
-}
-
-/* list the keys in a keyring, returning a JSON encoded string */
-int
-netpgp_list_keys_json(netpgp_t *netpgp, char **json, const int psigs)
-{
- mj_t obj;
- int ret;
-
- if (netpgp->pubring == NULL) {
- (void) fprintf(stderr, "No keyring\n");
- return 0;
- }
- (void) memset(&obj, 0x0, sizeof(obj));
- if (!pgp_keyring_json(netpgp->io, netpgp->pubring, &obj, psigs)) {
- (void) fprintf(stderr, "No keys in keyring\n");
- return 0;
- }
- ret = mj_asprint(json, &obj, MJ_JSON_ENCODE);
- mj_delete(&obj);
- return ret;
-}
-
-DEFINE_ARRAY(strings_t, char *);
-
-#ifndef HKP_VERSION
-#define HKP_VERSION 1
-#endif
-
-/* find and list some keys in a keyring */
-int
-netpgp_match_keys(netpgp_t *netpgp, char *name, const char *fmt, void *vp, const int psigs)
-{
- const pgp_key_t *key;
- unsigned k;
- strings_t pubs;
- FILE *fp = (FILE *)vp;
-
- if (name[0] == '0' && name[1] == 'x') {
- name += 2;
- }
- (void) memset(&pubs, 0x0, sizeof(pubs));
- k = 0;
- do {
- key = pgp_getnextkeybyname(netpgp->io, netpgp->pubring,
- name, &k);
- if (key != NULL) {
- ALLOC(char *, pubs.v, pubs.size, pubs.c, 10, 10,
- "netpgp_match_keys", return 0);
- if (strcmp(fmt, "mr") == 0) {
- pgp_hkp_sprint_keydata(netpgp->io, netpgp->pubring,
- key, &pubs.v[pubs.c],
- &key->key.pubkey, psigs);
- } else {
- pgp_sprint_keydata(netpgp->io, netpgp->pubring,
- key, &pubs.v[pubs.c],
- "signature ",
- &key->key.pubkey, psigs);
- }
- if (pubs.v[pubs.c] != NULL) {
- pubs.c += 1;
- }
- k += 1;
- }
- } while (key != NULL);
- if (strcmp(fmt, "mr") == 0) {
- (void) fprintf(fp, "info:%d:%d\n", HKP_VERSION, pubs.c);
- } else {
- (void) fprintf(fp, "%d key%s found\n", pubs.c,
- (pubs.c == 1) ? "" : "s");
- }
- for (k = 0 ; k < pubs.c ; k++) {
- (void) fprintf(fp, "%s%s", pubs.v[k], (k < pubs.c - 1) ? "\n" : "");
- free(pubs.v[k]);
- }
- free(pubs.v);
- return pubs.c;
-}
-
-/* find and list some keys in a keyring - return JSON string */
-int
-netpgp_match_keys_json(netpgp_t *netpgp, char **json, char *name, const char *fmt, const int psigs)
-{
- const pgp_key_t *key;
- unsigned k;
- mj_t id_array;
- char *newkey;
- int ret;
-
- if (name[0] == '0' && name[1] == 'x') {
- name += 2;
- }
- (void) memset(&id_array, 0x0, sizeof(id_array));
- k = 0;
- *json = NULL;
- mj_create(&id_array, "array");
- do {
- key = pgp_getnextkeybyname(netpgp->io, netpgp->pubring,
- name, &k);
- if (key != NULL) {
- if (strcmp(fmt, "mr") == 0) {
- pgp_hkp_sprint_keydata(netpgp->io, netpgp->pubring,
- key, &newkey,
- &key->key.pubkey, 0);
- if (newkey) {
- printf("%s\n", newkey);
- free(newkey);
- }
- } else {
- ALLOC(mj_t, id_array.value.v, id_array.size,
- id_array.c, 10, 10, "netpgp_match_keys_json", return 0);
- pgp_sprint_mj(netpgp->io, netpgp->pubring,
- key, &id_array.value.v[id_array.c++],
- "signature ",
- &key->key.pubkey, psigs);
- }
- k += 1;
- }
- } while (key != NULL);
- ret = mj_asprint(json, &id_array, MJ_JSON_ENCODE);
- mj_delete(&id_array);
- return ret;
-}
-
-/* find and list some public keys in a keyring */
-int
-netpgp_match_pubkeys(netpgp_t *netpgp, char *name, void *vp)
-{
- const pgp_key_t *key;
- unsigned k;
- ssize_t cc;
- char out[1024 * 64];
- FILE *fp = (FILE *)vp;
-
- k = 0;
- do {
- key = pgp_getnextkeybyname(netpgp->io, netpgp->pubring,
- name, &k);
- if (key != NULL) {
- cc = pgp_sprint_pubkey(key, out, sizeof(out));
- (void) fprintf(fp, "%.*s", (int)cc, out);
- k += 1;
- }
- } while (key != NULL);
- return k;
-}
-
-/* find a key in a keyring */
-int
-netpgp_find_key(netpgp_t *netpgp, char *id)
-{
- pgp_io_t *io;
-
- io = netpgp->io;
- if (id == NULL) {
- (void) fprintf(io->errs, "NULL id to search for\n");
- return 0;
- }
- return pgp_getkeybyname(netpgp->io, netpgp->pubring, id) != NULL;
-}
-
-/* get a key in a keyring */
-char *
-netpgp_get_key(netpgp_t *netpgp, const char *name, const char *fmt)
-{
- const pgp_key_t *key;
- char *newkey;
-
- if ((key = resolve_userid(netpgp, netpgp->pubring, name)) == NULL) {
- return NULL;
- }
- if (strcmp(fmt, "mr") == 0) {
- return (pgp_hkp_sprint_keydata(netpgp->io, netpgp->pubring,
- key, &newkey,
- &key->key.pubkey,
- netpgp_getvar(netpgp, "subkey sigs") != NULL) > 0) ? newkey : NULL;
- }
- return (pgp_sprint_keydata(netpgp->io, netpgp->pubring,
- key, &newkey, "signature",
- &key->key.pubkey,
- netpgp_getvar(netpgp, "subkey sigs") != NULL) > 0) ? newkey : NULL;
-}
-
-/* export a given key */
-char *
-netpgp_export_key(netpgp_t *netpgp, char *name)
-{
- const pgp_key_t *key;
- pgp_io_t *io;
-
- io = netpgp->io;
- if ((key = resolve_userid(netpgp, netpgp->pubring, name)) == NULL) {
- return NULL;
- }
- return pgp_export_key(io, key, NULL);
-}
-
-#define IMPORT_ARMOR_HEAD "-----BEGIN PGP PUBLIC KEY BLOCK-----"
-
-/* import a key into our keyring */
-int
-netpgp_import_key(netpgp_t *netpgp, char *f)
-{
- pgp_io_t *io;
- unsigned realarmor;
- int done;
-
- io = netpgp->io;
- realarmor = isarmoured(io, f, NULL, IMPORT_ARMOR_HEAD);
- done = pgp_keyring_fileread(netpgp->pubring, realarmor, f);
- if (!done) {
- (void) fprintf(io->errs, "Cannot import key from file %s\n", f);
- return 0;
- }
- return pgp_keyring_list(io, netpgp->pubring, 0);
-}
-
-#define ID_OFFSET 38
-
-/* generate a new key */
-#if 0 //////
-int
-netpgp_generate_key(netpgp_t *netpgp, char *id, int numbits)
-{
- pgp_output_t *create;
- const unsigned noarmor = 0;
- pgp_key_t *key;
- pgp_io_t *io;
- uint8_t *uid;
- char passphrase[128];
- char newid[1024];
- char filename[MAXPATHLEN];
- char dir[MAXPATHLEN];
- char *cp;
- char *ringfile;
- char *numtries;
- int attempts;
- int passc;
- int fd;
- int cc;
-
- uid = NULL;
- io = netpgp->io;
- /* generate a new key */
- if (id) {
- (void) snprintf(newid, sizeof(newid), "%s", id);
- } else {
- (void) snprintf(newid, sizeof(newid),
- "RSA %d-bit key <%s@localhost>", numbits, getenv("LOGNAME"));
- }
- uid = (uint8_t *)newid;
- key = pgp_rsa_new_selfsign_key(numbits, 65537UL, uid,
- netpgp_getvar(netpgp, "hash"),
- netpgp_getvar(netpgp, "cipher"));
- if (key == NULL) {
- (void) fprintf(io->errs, "Cannot generate key\n");
- return 0;
- }
- cp = NULL;
- pgp_sprint_keydata(netpgp->io, NULL, key, &cp, "signature ", &key->key.seckey.pubkey, 0);
- (void) fprintf(stdout, "%s", cp);
- /* write public key */
- cc = snprintf(dir, sizeof(dir), "%s/%.16s", netpgp_getvar(netpgp, "homedir"), &cp[ID_OFFSET]);
- netpgp_setvar(netpgp, "generated userid", &dir[cc - 16]);
- if (mkdir(dir, 0700) < 0) {
- (void) fprintf(io->errs, "can't mkdir '%s'\n", dir);
- return 0;
- }
- (void) fprintf(io->errs, "netpgp: generated keys in directory %s\n", dir);
- (void) snprintf(ringfile = filename, sizeof(filename), "%s/pubring.gpg", dir);
- if (!appendkey(io, key, ringfile)) {
- (void) fprintf(io->errs, "Cannot write pubkey to '%s'\n", ringfile);
- return 0;
- }
- if (netpgp->pubring != NULL) {
- pgp_keyring_free(netpgp->pubring);
- }
- /* write secret key */
- (void) snprintf(ringfile = filename, sizeof(filename), "%s/secring.gpg", dir);
- if ((fd = pgp_setup_file_append(&create, ringfile)) < 0) {
- fd = pgp_setup_file_write(&create, ringfile, 0);
- }
- if (fd < 0) {
- (void) fprintf(io->errs, "can't append secring '%s'\n", ringfile);
- return 0;
- }
- /* get the passphrase */
- if ((numtries = netpgp_getvar(netpgp, "numtries")) == NULL ||
- (attempts = atoi(numtries)) <= 0) {
- attempts = MAX_PASSPHRASE_ATTEMPTS;
- } else if (strcmp(numtries, "unlimited") == 0) {
- attempts = INFINITE_ATTEMPTS;
- }
- passc = find_passphrase(netpgp->passfp, &cp[ID_OFFSET], passphrase, sizeof(passphrase), attempts);
- if (!pgp_write_xfer_seckey(create, key, (uint8_t *)passphrase, (const unsigned)passc, noarmor)) {
- (void) fprintf(io->errs, "Cannot write seckey\n");
- return 0;
- }
- pgp_teardown_file_write(create, fd);
- if (netpgp->secring != NULL) {
- pgp_keyring_free(netpgp->secring);
- }
- pgp_keydata_free(key);
- free(cp);
- return 1;
-}
-#endif //////
-
-/* encrypt a file */
-int
-netpgp_encrypt_file(netpgp_t *netpgp,
- const char *userid,
- const char *f,
- char *out,
- int armored)
-{
- const pgp_key_t *key;
- const unsigned overwrite = 1;
- const char *suffix;
- pgp_io_t *io;
- char outname[MAXPATHLEN];
-
- io = netpgp->io;
- if (f == NULL) {
- (void) fprintf(io->errs,
- "netpgp_encrypt_file: no filename specified\n");
- return 0;
- }
- suffix = (armored) ? ".asc" : ".gpg";
- /* get key with which to sign */
- if ((key = resolve_userid(netpgp, netpgp->pubring, userid)) == NULL) {
- return 0;
- }
- if (out == NULL) {
- (void) snprintf(outname, sizeof(outname), "%s%s", f, suffix);
- out = outname;
- }
- return (int)pgp_encrypt_file(io, f, out, key, (unsigned)armored,
- overwrite, netpgp_getvar(netpgp, "cipher"));
-}
-
-#define ARMOR_HEAD "-----BEGIN PGP MESSAGE-----"
-
-/* decrypt a file */
-int
-netpgp_decrypt_file(netpgp_t *netpgp, const char *f, char *out, int armored)
-{
- const unsigned overwrite = 1;
- pgp_io_t *io;
- unsigned realarmor;
- unsigned sshkeys;
- char *numtries;
- int attempts;
-
- __PGP_USED(armored);
- io = netpgp->io;
- if (f == NULL) {
- (void) fprintf(io->errs,
- "netpgp_decrypt_file: no filename specified\n");
- return 0;
- }
- realarmor = isarmoured(io, f, NULL, ARMOR_HEAD);
- sshkeys = (unsigned)(netpgp_getvar(netpgp, "ssh keys") != NULL);
- if ((numtries = netpgp_getvar(netpgp, "numtries")) == NULL ||
- (attempts = atoi(numtries)) <= 0) {
- attempts = MAX_PASSPHRASE_ATTEMPTS;
- } else if (strcmp(numtries, "unlimited") == 0) {
- attempts = INFINITE_ATTEMPTS;
- }
- return pgp_decrypt_file(netpgp->io, f, out, netpgp->secring,
- netpgp->pubring,
- realarmor, overwrite, sshkeys,
- netpgp->passfp, attempts, get_passphrase_cb);
-}
-
-/* sign a file */
-int
-netpgp_sign_file(netpgp_t *netpgp,
- const char *userid,
- const char *f,
- char *out,
- int armored,
- int cleartext,
- int detached)
-{
- const pgp_key_t *keypair;
- const pgp_key_t *pubkey;
- const unsigned overwrite = 1;
- pgp_seckey_t *seckey;
- const char *hashalg;
- pgp_io_t *io;
- char *numtries;
- int attempts;
- int ret;
- int i;
-
- io = netpgp->io;
- if (f == NULL) {
- (void) fprintf(io->errs,
- "netpgp_sign_file: no filename specified\n");
- return 0;
- }
- /* get key with which to sign */
- if ((keypair = resolve_userid(netpgp, netpgp->secring, userid)) == NULL) {
- return 0;
- }
- ret = 1;
- if ((numtries = netpgp_getvar(netpgp, "numtries")) == NULL ||
- (attempts = atoi(numtries)) <= 0) {
- attempts = MAX_PASSPHRASE_ATTEMPTS;
- } else if (strcmp(numtries, "unlimited") == 0) {
- attempts = INFINITE_ATTEMPTS;
- }
- for (i = 0, seckey = NULL ; !seckey && (i < attempts || attempts == INFINITE_ATTEMPTS) ; i++) {
- if (netpgp->passfp == NULL) {
- /* print out the user id */
- pubkey = pgp_getkeybyname(io, netpgp->pubring, userid);
- if (pubkey == NULL) {
- (void) fprintf(io->errs,
- "netpgp: warning - using pubkey from secring\n");
- pgp_print_keydata(io, netpgp->pubring, keypair, "signature ",
- &keypair->key.seckey.pubkey, 0);
- } else {
- pgp_print_keydata(io, netpgp->pubring, pubkey, "signature ",
- &pubkey->key.pubkey, 0);
- }
- }
- if (netpgp_getvar(netpgp, "ssh keys") == NULL) {
- /* now decrypt key */
- seckey = pgp_decrypt_seckey(keypair, netpgp->passfp);
- if (seckey == NULL) {
- (void) fprintf(io->errs, "Bad passphrase\n");
- }
- } else {
- pgp_keyring_t *secring;
-
- secring = netpgp->secring;
- seckey = &secring->keys[0].key.seckey;
- }
- }
- if (seckey == NULL) {
- (void) fprintf(io->errs, "Bad passphrase\n");
- return 0;
- }
- /* sign file */
- hashalg = netpgp_getvar(netpgp, "hash");
- if (seckey->pubkey.alg == PGP_PKA_DSA) {
- hashalg = "sha1";
- }
- if (detached) {
- ret = pgp_sign_detached(io, f, out, seckey, hashalg,
- get_birthtime(netpgp_getvar(netpgp, "birthtime")),
- get_duration(netpgp_getvar(netpgp, "duration")),
- (unsigned)armored,
- overwrite);
- } else {
- ret = pgp_sign_file(io, f, out, seckey, hashalg,
- get_birthtime(netpgp_getvar(netpgp, "birthtime")),
- get_duration(netpgp_getvar(netpgp, "duration")),
- (unsigned)armored, (unsigned)cleartext,
- overwrite);
- }
- pgp_forget(seckey, (unsigned)sizeof(*seckey));
- return ret;
-}
-
-#define ARMOR_SIG_HEAD "-----BEGIN PGP (SIGNATURE|SIGNED MESSAGE)-----"
-
-/* verify a file */
-int
-netpgp_verify_file(netpgp_t *netpgp, const char *in, const char *out, int armored)
-{
- pgp_validation_t result;
- pgp_io_t *io;
- unsigned realarmor;
-
- __PGP_USED(armored);
- (void) memset(&result, 0x0, sizeof(result));
- io = netpgp->io;
- if (in == NULL) {
- (void) fprintf(io->errs,
- "netpgp_verify_file: no filename specified\n");
- return 0;
- }
- realarmor = isarmoured(io, in, NULL, ARMOR_SIG_HEAD);
- if (pgp_validate_file(io, &result, in, out, (const int)realarmor, netpgp->pubring)) {
- resultp(io, in, &result, netpgp->pubring);
- return 1;
- }
- if (result.validc + result.invalidc + result.unknownc == 0) {
- (void) fprintf(io->errs,
- "\"%s\": No signatures found - is this a signed file?\n",
- in);
- } else if (result.invalidc == 0 && result.unknownc == 0) {
- (void) fprintf(io->errs,
- "\"%s\": file verification failure: invalid signature time\n", in);
- } else {
- (void) fprintf(io->errs,
-"\"%s\": verification failure: %u invalid signatures, %u unknown signatures\n",
- in, result.invalidc, result.unknownc);
- }
- return 0;
-}
-
-/* sign some memory */
-int
-netpgp_sign_memory(netpgp_t *netpgp,
- const char *userid,
- char *mem,
- size_t size,
- char *out,
- size_t outsize,
- const unsigned armored,
- const unsigned cleartext)
-{
- const pgp_key_t *keypair;
- const pgp_key_t *pubkey;
- pgp_seckey_t *seckey;
- pgp_memory_t *signedmem;
- const char *hashalg;
- pgp_io_t *io;
- char *numtries;
- int attempts;
- int ret;
- int i;
-
- io = netpgp->io;
- if (mem == NULL) {
- (void) fprintf(io->errs,
- "netpgp_sign_memory: no memory to sign\n");
- return 0;
- }
- if ((keypair = resolve_userid(netpgp, netpgp->secring, userid)) == NULL) {
- return 0;
- }
- ret = 1;
- if ((numtries = netpgp_getvar(netpgp, "numtries")) == NULL ||
- (attempts = atoi(numtries)) <= 0) {
- attempts = MAX_PASSPHRASE_ATTEMPTS;
- } else if (strcmp(numtries, "unlimited") == 0) {
- attempts = INFINITE_ATTEMPTS;
- }
- for (i = 0, seckey = NULL ; !seckey && (i < attempts || attempts == INFINITE_ATTEMPTS) ; i++) {
- if (netpgp->passfp == NULL) {
- /* print out the user id */
- pubkey = pgp_getkeybyname(io, netpgp->pubring, userid);
- if (pubkey == NULL) {
- (void) fprintf(io->errs,
- "netpgp: warning - using pubkey from secring\n");
- pgp_print_keydata(io, netpgp->pubring, keypair, "signature ",
- &keypair->key.seckey.pubkey, 0);
- } else {
- pgp_print_keydata(io, netpgp->pubring, pubkey, "signature ",
- &pubkey->key.pubkey, 0);
- }
- }
- /* now decrypt key */
- seckey = pgp_decrypt_seckey(keypair, netpgp->passfp);
- if (seckey == NULL) {
- (void) fprintf(io->errs, "Bad passphrase\n");
- }
- }
- if (seckey == NULL) {
- (void) fprintf(io->errs, "Bad passphrase\n");
- return 0;
- }
- /* sign file */
- (void) memset(out, 0x0, outsize);
- hashalg = netpgp_getvar(netpgp, "hash");
- if (seckey->pubkey.alg == PGP_PKA_DSA) {
- hashalg = "sha1";
- }
- signedmem = pgp_sign_buf(io, mem, size, seckey,
- get_birthtime(netpgp_getvar(netpgp, "birthtime")),
- get_duration(netpgp_getvar(netpgp, "duration")),
- hashalg, armored, cleartext);
- if (signedmem) {
- size_t m;
-
- m = MIN(pgp_mem_len(signedmem), outsize);
- (void) memcpy(out, pgp_mem_data(signedmem), m);
- pgp_memory_free(signedmem);
- ret = (int)m;
- } else {
- ret = 0;
- }
- pgp_forget(seckey, (unsigned)sizeof(*seckey));
- return ret;
-}
-
-/* verify memory */
-int
-netpgp_verify_memory(netpgp_t *netpgp, const void *in, const size_t size,
- void *out, size_t outsize, const int armored)
-{
- pgp_validation_t result;
- pgp_memory_t *signedmem;
- pgp_memory_t *cat;
- pgp_io_t *io;
- size_t m;
- int ret;
-
- (void) memset(&result, 0x0, sizeof(result));
- io = netpgp->io;
- if (in == NULL) {
- (void) fprintf(io->errs,
- "netpgp_verify_memory: no memory to verify\n");
- return 0;
- }
- signedmem = pgp_memory_new();
- pgp_memory_add(signedmem, in, size);
- if (out) {
- cat = pgp_memory_new();
- }
- ret = pgp_validate_mem(io, &result, signedmem,
- (out) ? &cat : NULL,
- armored, netpgp->pubring);
- /* signedmem is freed from pgp_validate_mem */
- if (ret) {
- resultp(io, "", &result, netpgp->pubring);
- if (out) {
- m = MIN(pgp_mem_len(cat), outsize);
- (void) memcpy(out, pgp_mem_data(cat), m);
- pgp_memory_free(cat);
- } else {
- m = 1;
- }
- return (int)m;
- }
- if (result.validc + result.invalidc + result.unknownc == 0) {
- (void) fprintf(io->errs,
- "No signatures found - is this memory signed?\n");
- } else if (result.invalidc == 0 && result.unknownc == 0) {
- (void) fprintf(io->errs,
- "memory verification failure: invalid signature time\n");
- } else {
- (void) fprintf(io->errs,
-"memory verification failure: %u invalid signatures, %u unknown signatures\n",
- result.invalidc, result.unknownc);
- }
- return 0;
-}
-
-/* encrypt some memory */
-int
-netpgp_encrypt_memory(netpgp_t *netpgp,
- const char *userid,
- void *in,
- const size_t insize,
- char *out,
- size_t outsize,
- int armored)
-{
- const pgp_key_t *keypair;
- pgp_memory_t *enc;
- pgp_io_t *io;
- size_t m;
-
- io = netpgp->io;
- if (in == NULL) {
- (void) fprintf(io->errs,
- "netpgp_encrypt_buf: no memory to encrypt\n");
- return 0;
- }
- if ((keypair = resolve_userid(netpgp, netpgp->pubring, userid)) == NULL) {
- return 0;
- }
- if (in == out) {
- (void) fprintf(io->errs,
- "netpgp_encrypt_buf: input and output bufs need to be different\n");
- return 0;
- }
- if (outsize < insize) {
- (void) fprintf(io->errs,
- "netpgp_encrypt_buf: input size is larger than output size\n");
- return 0;
- }
- enc = pgp_encrypt_buf(io, in, insize, keypair, (unsigned)armored,
- netpgp_getvar(netpgp, "cipher"));
- m = MIN(pgp_mem_len(enc), outsize);
- (void) memcpy(out, pgp_mem_data(enc), m);
- pgp_memory_free(enc);
- return (int)m;
-}
-
-/* decrypt a chunk of memory */
-int
-netpgp_decrypt_memory(netpgp_t *netpgp, const void *input, const size_t insize,
- char *out, size_t outsize, const int armored)
-{
- pgp_memory_t *mem;
- pgp_io_t *io;
- unsigned realarmour;
- unsigned sshkeys;
- size_t m;
- char *numtries;
- int attempts;
-
- __PGP_USED(armored);
- io = netpgp->io;
- if (input == NULL) {
- (void) fprintf(io->errs,
- "netpgp_decrypt_memory: no memory\n");
- return 0;
- }
- realarmour = isarmoured(io, NULL, input, ARMOR_HEAD);
- sshkeys = (unsigned)(netpgp_getvar(netpgp, "ssh keys") != NULL);
- if ((numtries = netpgp_getvar(netpgp, "numtries")) == NULL ||
- (attempts = atoi(numtries)) <= 0) {
- attempts = MAX_PASSPHRASE_ATTEMPTS;
- } else if (strcmp(numtries, "unlimited") == 0) {
- attempts = INFINITE_ATTEMPTS;
- }
- mem = pgp_decrypt_buf(netpgp->io, input, insize, netpgp->secring,
- netpgp->pubring,
- realarmour, sshkeys,
- netpgp->passfp,
- attempts,
- get_passphrase_cb);
- if (mem == NULL) {
- return -1;
- }
- m = MIN(pgp_mem_len(mem), outsize);
- (void) memcpy(out, pgp_mem_data(mem), m);
- pgp_memory_free(mem);
- return (int)m;
-}
-
-/* wrappers for the ops_debug_level functions we added to openpgpsdk */
-
-/* set the debugging level per filename */
-int
-netpgp_set_debug(const char *f)
-{
- return pgp_set_debug_level(f);
-}
-
-/* get the debugging level per filename */
-int
-netpgp_get_debug(const char *f)
-{
- return pgp_get_debug_level(f);
-}
-
-/* return the version for the library */
-const char *
-netpgp_get_info(const char *type)
-{
- return pgp_get_info(type);
-}
-
-/* list all the packets in a file */
-int
-netpgp_list_packets(netpgp_t *netpgp, char *f, int armor, char *pubringname)
-{
- pgp_keyring_t *keyring;
- const unsigned noarmor = 0;
- struct stat st;
- pgp_io_t *io;
- char ringname[MAXPATHLEN];
- char *homedir;
- int ret;
-
- io = netpgp->io;
- if (f == NULL) {
- (void) fprintf(io->errs, "No file containing packets\n");
- return 0;
- }
- if (stat(f, &st) < 0) {
- (void) fprintf(io->errs, "No such file '%s'\n", f);
- return 0;
- }
- homedir = netpgp_getvar(netpgp, "homedir");
- if (pubringname == NULL) {
- (void) snprintf(ringname, sizeof(ringname),
- "%s/pubring.gpg", homedir);
- pubringname = ringname;
- }
- if ((keyring = calloc(1, sizeof(*keyring))) == NULL) {
- (void) fprintf(io->errs, "netpgp_list_packets: bad alloc\n");
- return 0;
- }
- if (!pgp_keyring_fileread(keyring, noarmor, pubringname)) {
- free(keyring);
- (void) fprintf(io->errs, "Cannot read pub keyring %s\n",
- pubringname);
- return 0;
- }
- netpgp->pubring = keyring;
- netpgp_setvar(netpgp, "pubring", pubringname);
- ret = pgp_list_packets(io, f, (unsigned)armor,
- netpgp->secring,
- netpgp->pubring,
- netpgp->passfp,
- get_passphrase_cb);
- free(keyring);
- return ret;
-}
-
-/* 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;
-}
-
-/* validate all sigs in the pub keyring */
-int
-netpgp_validate_sigs(netpgp_t *netpgp)
-{
- pgp_validation_t result;
-
- return (int)pgp_validate_all_sigs(&result, netpgp->pubring, NULL);
-}
-
-/* print the json out on 'fp' */
-int
-netpgp_format_json(void *vp, const char *json, const int psigs)
-{
- mj_t ids;
- FILE *fp;
- int from;
- int idc;
- int tok;
- int to;
- int i;
-
- if ((fp = (FILE *)vp) == NULL || json == NULL) {
- return 0;
- }
- /* ids is an array of strings, each containing 1 entry */
- (void) memset(&ids, 0x0, sizeof(ids));
- from = to = tok = 0;
- /* convert from string into an mj structure */
- (void) mj_parse(&ids, json, &from, &to, &tok);
- if ((idc = mj_arraycount(&ids)) == 1 && strchr(json, '{') == NULL) {
- idc = 0;
- }
- (void) fprintf(fp, "%d key%s found\n", idc, (idc == 1) ? "" : "s");
- for (i = 0 ; i < idc ; i++) {
- format_json_key(fp, &ids.value.v[i], psigs);
- }
- /* clean up */
- mj_delete(&ids);
- return idc;
-}
-
-/* find a key in keyring, and write it in ssh format */
-int
-netpgp_write_sshkey(netpgp_t *netpgp, char *s, const char *userid, char *out, size_t size)
-{
- const pgp_key_t *key;
- pgp_keyring_t *keyring;
- pgp_io_t *io;
- unsigned k;
- size_t cc;
- char f[MAXPATHLEN];
-
- keyring = NULL;
- io = NULL;
- cc = 0;
- if ((io = calloc(1, sizeof(pgp_io_t))) == NULL) {
- (void) fprintf(stderr, "netpgp_save_sshpub: bad alloc 1\n");
- goto done;
- }
- io->outs = stdout;
- io->errs = stderr;
- io->res = stderr;
- netpgp->io = io;
- /* write new to temp file */
- savepubkey(s, f, sizeof(f));
- if ((keyring = calloc(1, sizeof(*keyring))) == NULL) {
- (void) fprintf(stderr, "netpgp_save_sshpub: bad alloc 2\n");
- goto done;
- }
- if (!pgp_keyring_fileread(netpgp->pubring = keyring, 1, f)) {
- (void) fprintf(stderr, "can't import key\n");
- goto done;
- }
- /* get rsa key */
- k = 0;
- key = pgp_getnextkeybyname(netpgp->io, netpgp->pubring, userid, &k);
- if (key == NULL) {
- (void) fprintf(stderr, "no key found for '%s'\n", userid);
- goto done;
- }
- if (key->key.pubkey.alg != PGP_PKA_RSA) {
- /* we're not interested in supporting DSA either :-) */
- (void) fprintf(stderr, "key not RSA '%s'\n", userid);
- goto done;
- }
- /* XXX - check trust sigs */
- /* XXX - check expiry */
- /* XXX - check start */
- /* XXX - check not weak key */
- /* get rsa e and n */
- (void) memset(out, 0x0, size);
- cc = formatstring((char *)out, (const uint8_t *)"ssh-rsa", 7);
- cc += formatbignum((char *)&out[cc], key->key.pubkey.key.rsa.e);
- cc += formatbignum((char *)&out[cc], key->key.pubkey.key.rsa.n);
-done:
- if (io) {
- free(io);
- }
- if (keyring) {
- free(keyring);
- }
- return (int)cc;
-}
diff --git a/libs/netpgp/packet-print.c b/libs/netpgp/packet-print.c
deleted file mode 100644
index adb7e47d..00000000
--- a/libs/netpgp/packet-print.c
+++ /dev/null
@@ -1,1456 +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 \brief Standard API print functions
- */
-#include "config-netpgp.h"
-
-#ifdef HAVE_SYS_CDEFS_H
-#include
-#endif
-
-#if defined(__NetBSD__)
-__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: packet-print.c,v 1.42 2012/02/22 06:29:40 agc Exp $");
-#endif
-
-#include
-#include
-
-#ifdef HAVE_UNISTD_H
-#include
-#endif
-
-#include "crypto-netpgp.h"
-#include "keyring-netpgp.h"
-#include "packet-show.h"
-#include "signature-netpgp.h"
-#include "readerwriter-netpgp.h"
-#include "netpgpdefs.h"
-#include "netpgpsdk.h"
-#include "packet-netpgp.h"
-#include "netpgpdigest.h"
-#include "mj.h"
-
-/* static functions */
-
-static void
-print_indent(int indent)
-{
- int i;
-
- for (i = 0; i < indent; i++) {
- printf(" ");
- }
-}
-
-static void
-print_name(int indent, const char *name)
-{
- print_indent(indent);
- if (name) {
- printf("%s: ", name);
- }
-}
-
-static void
-print_hexdump(int indent, const char *name, const uint8_t *data, unsigned len)
-{
- print_name(indent, name);
- hexdump(stdout, NULL, data, len);
-}
-
-static void
-hexdump_data(int indent, const char *name, const uint8_t *data, unsigned len)
-{
- print_name(indent, name);
- hexdump(stdout, NULL, data, len);
-}
-
-static void
-print_uint(int indent, const char *name, unsigned val)
-{
- print_name(indent, name);
- printf("%u\n", val);
-}
-
-static void
-showtime(const char *name, time_t t)
-{
- printf("%s=%" PRItime "d (%.24s)", name, (long long) t, ctime(&t));
-}
-
-static void
-print_time(int indent, const char *name, time_t t)
-{
- print_indent(indent);
- printf("%s: ", name);
- showtime("time", t);
- printf("\n");
-}
-
-static void
-print_string_and_value(int indent, const char *name, const char *str, uint8_t value)
-{
- print_name(indent, name);
- printf("%s (0x%x)\n", str, value);
-}
-
-static void
-print_tagname(int indent, const char *str)
-{
- print_indent(indent);
- printf("%s packet\n", str);
-}
-
-static void
-print_data(int indent, const char *name, const pgp_data_t *data)
-{
- print_hexdump(indent, name, data->contents, (unsigned)data->len);
-}
-
-static void
-print_bn(int indent, const char *name, const BIGNUM *bn)
-{
- print_indent(indent);
- printf("%s=", name);
- if (bn) {
- BN_print_fp(stdout, bn);
- putchar('\n');
- } else {
- puts("(unset)");
- }
-}
-
-static void
-print_packet_hex(const pgp_subpacket_t *pkt)
-{
- hexdump(stdout, "packet contents:", pkt->raw, pkt->length);
-}
-
-static void
-print_escaped(const uint8_t *data, size_t length)
-{
- while (length-- > 0) {
- if ((*data >= 0x20 && *data < 0x7f && *data != '%') ||
- *data == '\n') {
- putchar(*data);
- } else {
- printf("%%%02x", *data);
- }
- ++data;
- }
-}
-
-static void
-print_string(int indent, const char *name, const char *str)
-{
- print_name(indent, name);
- print_escaped((const uint8_t *) str, strlen(str));
- putchar('\n');
-}
-
-static void
-print_utf8_string(int indent, const char *name, const uint8_t *str)
-{
- /* \todo Do this better for non-English character sets */
- print_string(indent, name, (const char *) str);
-}
-
-static void
-print_duration(int indent, const char *name, time_t t)
-{
- int mins, hours, days, years;
-
- print_indent(indent);
- printf("%s: ", name);
- printf("duration %" PRItime "d seconds", (long long) t);
-
- mins = (int)(t / 60);
- hours = mins / 60;
- days = hours / 24;
- years = days / 365;
-
- printf(" (approx. ");
- if (years) {
- printf("%d %s", years, years == 1 ? "year" : "years");
- } else if (days) {
- printf("%d %s", days, days == 1 ? "day" : "days");
- } else if (hours) {
- printf("%d %s", hours, hours == 1 ? "hour" : "hours");
- }
- printf(")\n");
-}
-
-static void
-print_boolean(int indent, const char *name, uint8_t boolval)
-{
- print_name(indent, name);
- printf("%s\n", (boolval) ? "Yes" : "No");
-}
-
-static void
-print_text_breakdown(int indent, pgp_text_t *text)
-{
- const char *prefix = ".. ";
- unsigned i;
-
- /* these were recognised */
- for (i = 0; i < text->known.used; i++) {
- print_indent(indent);
- printf("%s", prefix);
- printf("%s\n", text->known.strings[i]);
- }
- /*
- * these were not recognised. the strings will contain the hex value
- * of the unrecognised value in string format - see
- * process_octet_str()
- */
- if (text->unknown.used) {
- printf("\n");
- print_indent(indent);
- printf("Not Recognised: ");
- }
- for (i = 0; i < text->unknown.used; i++) {
- print_indent(indent);
- printf("%s", prefix);
- printf("%s\n", text->unknown.strings[i]);
- }
-}
-
-static void
-print_headers(const pgp_headers_t *h)
-{
- unsigned i;
-
- for (i = 0; i < h->headerc; ++i) {
- printf("%s=%s\n", h->headers[i].key, h->headers[i].value);
- }
-}
-
-static void
-print_block(int indent, const char *name, const uint8_t *str, size_t length)
-{
- int o = (int)length;
-
- print_indent(indent);
- printf(">>>>> %s >>>>>\n", name);
-
- print_indent(indent);
- for (; length > 0; --length) {
- if (*str >= 0x20 && *str < 0x7f && *str != '%') {
- putchar(*str);
- } else if (*str == '\n') {
- putchar(*str);
- print_indent(indent);
- } else {
- printf("%%%02x", *str);
- }
- ++str;
- }
- if (o && str[-1] != '\n') {
- putchar('\n');
- print_indent(indent);
- fputs("[no newline]", stdout);
- } else {
- print_indent(indent);
- }
- printf("<<<<< %s <<<<<\n", name);
-}
-
-/* return the number of bits in the public key */
-static int
-numkeybits(const pgp_pubkey_t *pubkey)
-{
- switch(pubkey->alg) {
- case PGP_PKA_RSA:
- case PGP_PKA_RSA_ENCRYPT_ONLY:
- case PGP_PKA_RSA_SIGN_ONLY:
- return BN_num_bytes(pubkey->key.rsa.n) * 8;
- case PGP_PKA_DSA:
- switch(BN_num_bytes(pubkey->key.dsa.q)) {
- case 20:
- return 1024;
- case 28:
- return 2048;
- case 32:
- return 3072;
- default:
- return 0;
- }
- case PGP_PKA_ELGAMAL:
- return BN_num_bytes(pubkey->key.elgamal.y) * 8;
- default:
- return -1;
- }
-}
-
-/* return the hexdump as a string */
-static char *
-strhexdump(char *dest, const uint8_t *src, size_t length, const char *sep)
-{
- unsigned i;
- int n;
-
- for (n = 0, i = 0 ; i < length ; i += 2) {
- n += snprintf(&dest[n], 3, "%02x", *src++);
- n += snprintf(&dest[n], 10, "%02x%s", *src++, sep);
- }
- return dest;
-}
-
-/* return the time as a string */
-static char *
-ptimestr(char *dest, size_t size, time_t t)
-{
- struct tm *tm;
-
- tm = gmtime(&t);
- (void) snprintf(dest, size, "%04d-%02d-%02d",
- tm->tm_year + 1900,
- tm->tm_mon + 1,
- tm->tm_mday);
- return dest;
-}
-
-/* print the sub key binding signature info */
-static int
-psubkeybinding(char *buf, size_t size, const pgp_key_t *key, const char *expired)
-{
- char keyid[512];
- char t[32];
-
- return snprintf(buf, size, "encryption %d/%s %s %s %s\n",
- numkeybits(&key->enckey),
- pgp_show_pka(key->enckey.alg),
- strhexdump(keyid, key->encid, PGP_KEY_ID_SIZE, ""),
- ptimestr(t, sizeof(t), key->enckey.birthtime),
- expired);
-}
-
-static int
-isrevoked(const pgp_key_t *key, unsigned uid)
-{
- unsigned r;
-
- for (r = 0 ; r < key->revokec ; r++) {
- if (key->revokes[r].uid == uid) {
- return r;
- }
- }
- return -1;
-}
-
-#ifndef KB
-#define KB(x) ((x) * 1024)
-#endif
-
-/* print into a string (malloc'ed) the pubkeydata */
-int
-pgp_sprint_keydata(pgp_io_t *io, const pgp_keyring_t *keyring,
- const pgp_key_t *key, char **buf, const char *header,
- const pgp_pubkey_t *pubkey, const int psigs)
-{
- const pgp_key_t *trustkey;
- unsigned from;
- unsigned i;
- unsigned j;
- time_t now;
- char uidbuf[KB(128)];
- char keyid[PGP_KEY_ID_SIZE * 3];
- char fp[(PGP_FINGERPRINT_SIZE * 3) + 1];
- char expired[128];
- char t[32];
- int cc;
- int n;
- int r;
-
- if (key == NULL || key->revoked) {
- return -1;
- }
- now = time(NULL);
- if (pubkey->duration > 0) {
- cc = snprintf(expired, sizeof(expired),
- (pubkey->birthtime + pubkey->duration < now) ?
- "[EXPIRED " : "[EXPIRES ");
- ptimestr(&expired[cc], sizeof(expired) - cc,
- pubkey->birthtime + pubkey->duration);
- cc += 10;
- cc += snprintf(&expired[cc], sizeof(expired) - cc, "]");
- } else {
- expired[0] = 0x0;
- }
- for (i = 0, n = 0; i < key->uidc; i++) {
- if ((r = isrevoked(key, i)) >= 0 &&
- key->revokes[r].code == PGP_REVOCATION_COMPROMISED) {
- continue;
- }
- n += snprintf(&uidbuf[n], sizeof(uidbuf) - n, "uid%s%s%s\n",
- (psigs) ? " " : " ",
- key->uids[i],
- (isrevoked(key, i) >= 0) ? " [REVOKED]" : "");
- for (j = 0 ; j < key->subsigc ; j++) {
- if (psigs) {
- if (key->subsigs[j].uid != i) {
- continue;
- }
- } else {
- if (!(key->subsigs[j].sig.info.version == 4 &&
- key->subsigs[j].sig.info.type == PGP_SIG_SUBKEY &&
- i == key->uidc - 1)) {
- continue;
- }
- }
- from = 0;
- trustkey = pgp_getkeybyid(io, keyring, key->subsigs[j].sig.info.signer_id, &from, NULL);
- if (key->subsigs[j].sig.info.version == 4 &&
- key->subsigs[j].sig.info.type == PGP_SIG_SUBKEY) {
- psubkeybinding(&uidbuf[n], sizeof(uidbuf) - n, key, expired);
- } else {
- n += snprintf(&uidbuf[n], sizeof(uidbuf) - n,
- "sig %s %s %s\n",
- strhexdump(keyid, key->subsigs[j].sig.info.signer_id, PGP_KEY_ID_SIZE, ""),
- ptimestr(t, sizeof(t), key->subsigs[j].sig.info.birthtime),
- (trustkey) ? (char *)trustkey->uids[trustkey->uid0] : "[unknown]");
- }
- }
- }
- return pgp_asprintf(buf, "%s %d/%s %s %s %s\nKey fingerprint: %s\n%s",
- header,
- numkeybits(pubkey),
- pgp_show_pka(pubkey->alg),
- strhexdump(keyid, key->sigid, PGP_KEY_ID_SIZE, ""),
- ptimestr(t, sizeof(t), pubkey->birthtime),
- expired,
- strhexdump(fp, key->sigfingerprint.fingerprint, key->sigfingerprint.length, " "),
- uidbuf);
-}
-
-/* return the key info as a JSON encoded string */
-int
-pgp_sprint_mj(pgp_io_t *io, const pgp_keyring_t *keyring,
- const pgp_key_t *key, mj_t *keyjson, const char *header,
- const pgp_pubkey_t *pubkey, const int psigs)
-{
- const pgp_key_t *trustkey;
- unsigned from;
- unsigned i;
- unsigned j;
- mj_t sub_obj;
- char keyid[PGP_KEY_ID_SIZE * 3];
- char fp[(PGP_FINGERPRINT_SIZE * 3) + 1];
- int r;
-
- if (key == NULL || key->revoked) {
- return -1;
- }
- (void) memset(keyjson, 0x0, sizeof(*keyjson));
- mj_create(keyjson, "object");
- mj_append_field(keyjson, "header", "string", header, -1);
- mj_append_field(keyjson, "key bits", "integer", (int64_t) numkeybits(pubkey));
- mj_append_field(keyjson, "pka", "string", pgp_show_pka(pubkey->alg), -1);
- mj_append_field(keyjson, "key id", "string", strhexdump(keyid, key->sigid, PGP_KEY_ID_SIZE, ""), -1);
- mj_append_field(keyjson, "fingerprint", "string",
- strhexdump(fp, key->sigfingerprint.fingerprint, key->sigfingerprint.length, " "), -1);
- mj_append_field(keyjson, "birthtime", "integer", pubkey->birthtime);
- mj_append_field(keyjson, "duration", "integer", pubkey->duration);
- for (i = 0; i < key->uidc; i++) {
- if ((r = isrevoked(key, i)) >= 0 &&
- key->revokes[r].code == PGP_REVOCATION_COMPROMISED) {
- continue;
- }
- (void) memset(&sub_obj, 0x0, sizeof(sub_obj));
- mj_create(&sub_obj, "array");
- mj_append(&sub_obj, "string", key->uids[i], -1);
- mj_append(&sub_obj, "string", (r >= 0) ? "[REVOKED]" : "", -1);
- mj_append_field(keyjson, "uid", "array", &sub_obj);
- mj_delete(&sub_obj);
- for (j = 0 ; j < key->subsigc ; j++) {
- if (psigs) {
- if (key->subsigs[j].uid != i) {
- continue;
- }
- } else {
- if (!(key->subsigs[j].sig.info.version == 4 &&
- key->subsigs[j].sig.info.type == PGP_SIG_SUBKEY &&
- i == key->uidc - 1)) {
- continue;
- }
- }
- (void) memset(&sub_obj, 0x0, sizeof(sub_obj));
- mj_create(&sub_obj, "array");
- if (key->subsigs[j].sig.info.version == 4 &&
- key->subsigs[j].sig.info.type == PGP_SIG_SUBKEY) {
- mj_append(&sub_obj, "integer", (int64_t)numkeybits(&key->enckey));
- mj_append(&sub_obj, "string",
- (const char *)pgp_show_pka(key->enckey.alg), -1);
- mj_append(&sub_obj, "string",
- strhexdump(keyid, key->encid, PGP_KEY_ID_SIZE, ""), -1);
- mj_append(&sub_obj, "integer", (int64_t)key->enckey.birthtime);
- mj_append_field(keyjson, "encryption", "array", &sub_obj);
- mj_delete(&sub_obj);
- } else {
- mj_append(&sub_obj, "string",
- strhexdump(keyid, key->subsigs[j].sig.info.signer_id, PGP_KEY_ID_SIZE, ""), -1);
- mj_append(&sub_obj, "integer",
- (int64_t)(key->subsigs[j].sig.info.birthtime));
- from = 0;
- trustkey = pgp_getkeybyid(io, keyring, key->subsigs[j].sig.info.signer_id, &from, NULL);
- mj_append(&sub_obj, "string",
- (trustkey) ? (char *)trustkey->uids[trustkey->uid0] : "[unknown]", -1);
- mj_append_field(keyjson, "sig", "array", &sub_obj);
- mj_delete(&sub_obj);
- }
- }
- }
- if (pgp_get_debug_level(__FILE__)) {
- char *buf;
-
- mj_asprint(&buf, keyjson, 1);
- (void) fprintf(stderr, "pgp_sprint_mj: '%s'\n", buf);
- free(buf);
- }
- return 1;
-}
-
-int
-pgp_hkp_sprint_keydata(pgp_io_t *io, const pgp_keyring_t *keyring,
- const pgp_key_t *key, char **buf,
- const pgp_pubkey_t *pubkey, const int psigs)
-{
- const pgp_key_t *trustkey;
- unsigned from;
- unsigned i;
- unsigned j;
- char keyid[PGP_KEY_ID_SIZE * 3];
- char uidbuf[KB(128)];
- char fp[(PGP_FINGERPRINT_SIZE * 3) + 1];
- int n;
-
- if (key->revoked) {
- return -1;
- }
- for (i = 0, n = 0; i < key->uidc; i++) {
- n += snprintf(&uidbuf[n], sizeof(uidbuf) - n,
- "uid:%lld:%lld:%s\n",
- (long long)pubkey->birthtime,
- (long long)pubkey->duration,
- key->uids[i]);
- for (j = 0 ; j < key->subsigc ; j++) {
- if (psigs) {
- if (key->subsigs[j].uid != i) {
- continue;
- }
- } else {
- if (!(key->subsigs[j].sig.info.version == 4 &&
- key->subsigs[j].sig.info.type == PGP_SIG_SUBKEY &&
- i == key->uidc - 1)) {
- continue;
- }
- }
- from = 0;
- trustkey = pgp_getkeybyid(io, keyring, key->subsigs[j].sig.info.signer_id, &from, NULL);
- if (key->subsigs[j].sig.info.version == 4 &&
- key->subsigs[j].sig.info.type == PGP_SIG_SUBKEY) {
- n += snprintf(&uidbuf[n], sizeof(uidbuf) - n, "sub:%d:%d:%s:%lld:%lld\n",
- numkeybits(pubkey),
- key->subsigs[j].sig.info.key_alg,
- strhexdump(keyid, key->subsigs[j].sig.info.signer_id, PGP_KEY_ID_SIZE, ""),
- (long long)(key->subsigs[j].sig.info.birthtime),
- (long long)pubkey->duration);
- } else {
- n += snprintf(&uidbuf[n], sizeof(uidbuf) - n,
- "sig:%s:%lld:%s\n",
- strhexdump(keyid, key->subsigs[j].sig.info.signer_id, PGP_KEY_ID_SIZE, ""),
- (long long)key->subsigs[j].sig.info.birthtime,
- (trustkey) ? (char *)trustkey->uids[trustkey->uid0] : "");
- }
- }
- }
- return pgp_asprintf(buf, "pub:%s:%d:%d:%lld:%lld\n%s",
- strhexdump(fp, key->sigfingerprint.fingerprint, PGP_FINGERPRINT_SIZE, ""),
- pubkey->alg,
- numkeybits(pubkey),
- (long long)pubkey->birthtime,
- (long long)pubkey->duration,
- uidbuf);
-}
-
-/* print the key data for a pub or sec key */
-void
-pgp_print_keydata(pgp_io_t *io, const pgp_keyring_t *keyring,
- const pgp_key_t *key, const char *header,
- const pgp_pubkey_t *pubkey, const int psigs)
-{
- char *cp;
-
- if (pgp_sprint_keydata(io, keyring, key, &cp, header, pubkey, psigs) >= 0) {
- (void) fprintf(io->res, "%s", cp);
- free(cp);
- }
-}
-
-/**
-\ingroup Core_Print
-\param pubkey
-*/
-void
-pgp_print_pubkey(const pgp_pubkey_t *pubkey)
-{
- printf("------- PUBLIC KEY ------\n");
- print_uint(0, "Version", (unsigned)pubkey->version);
- print_time(0, "Creation Time", pubkey->birthtime);
- if (pubkey->version == PGP_V3) {
- print_uint(0, "Days Valid", pubkey->days_valid);
- }
- print_string_and_value(0, "Algorithm", pgp_show_pka(pubkey->alg),
- pubkey->alg);
- switch (pubkey->alg) {
- case PGP_PKA_DSA:
- print_bn(0, "p", pubkey->key.dsa.p);
- print_bn(0, "q", pubkey->key.dsa.q);
- print_bn(0, "g", pubkey->key.dsa.g);
- print_bn(0, "y", pubkey->key.dsa.y);
- break;
-
- case PGP_PKA_RSA:
- case PGP_PKA_RSA_ENCRYPT_ONLY:
- case PGP_PKA_RSA_SIGN_ONLY:
- print_bn(0, "n", pubkey->key.rsa.n);
- print_bn(0, "e", pubkey->key.rsa.e);
- break;
-
- case PGP_PKA_ELGAMAL:
- case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
- print_bn(0, "p", pubkey->key.elgamal.p);
- print_bn(0, "g", pubkey->key.elgamal.g);
- print_bn(0, "y", pubkey->key.elgamal.y);
- break;
-
- default:
- (void) fprintf(stderr,
- "pgp_print_pubkey: Unusual algorithm\n");
- }
-
- printf("------- end of PUBLIC KEY ------\n");
-}
-
-int
-pgp_sprint_pubkey(const pgp_key_t *key, char *out, size_t outsize)
-{
- char fp[(PGP_FINGERPRINT_SIZE * 3) + 1];
- int cc;
-
- cc = snprintf(out, outsize, "key=%s\nname=%s\ncreation=%lld\nexpiry=%lld\nversion=%d\nalg=%d\n",
- strhexdump(fp, key->sigfingerprint.fingerprint, PGP_FINGERPRINT_SIZE, ""),
- key->uids[key->uid0],
- (long long)key->key.pubkey.birthtime,
- (long long)key->key.pubkey.days_valid,
- key->key.pubkey.version,
- key->key.pubkey.alg);
- switch (key->key.pubkey.alg) {
- case PGP_PKA_DSA:
- cc += snprintf(&out[cc], outsize - cc,
- "p=%s\nq=%s\ng=%s\ny=%s\n",
- BN_bn2hex(key->key.pubkey.key.dsa.p),
- BN_bn2hex(key->key.pubkey.key.dsa.q),
- BN_bn2hex(key->key.pubkey.key.dsa.g),
- BN_bn2hex(key->key.pubkey.key.dsa.y));
- break;
- case PGP_PKA_RSA:
- case PGP_PKA_RSA_ENCRYPT_ONLY:
- case PGP_PKA_RSA_SIGN_ONLY:
- cc += snprintf(&out[cc], outsize - cc,
- "n=%s\ne=%s\n",
- BN_bn2hex(key->key.pubkey.key.rsa.n),
- BN_bn2hex(key->key.pubkey.key.rsa.e));
- break;
- case PGP_PKA_ELGAMAL:
- case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
- cc += snprintf(&out[cc], outsize - cc,
- "p=%s\ng=%s\ny=%s\n",
- BN_bn2hex(key->key.pubkey.key.elgamal.p),
- BN_bn2hex(key->key.pubkey.key.elgamal.g),
- BN_bn2hex(key->key.pubkey.key.elgamal.y));
- break;
- default:
- (void) fprintf(stderr,
- "pgp_print_pubkey: Unusual algorithm\n");
- }
- return cc;
-}
-
-/**
-\ingroup Core_Print
-\param type
-\param seckey
-*/
-static void
-print_seckey_verbose(const pgp_content_enum type,
- const pgp_seckey_t *seckey)
-{
- printf("------- SECRET KEY or ENCRYPTED SECRET KEY ------\n");
- print_tagname(0, (type == PGP_PTAG_CT_SECRET_KEY) ?
- "SECRET_KEY" :
- "ENCRYPTED_SECRET_KEY");
- /* pgp_print_pubkey(key); */
- printf("S2K Usage: %d\n", seckey->s2k_usage);
- if (seckey->s2k_usage != PGP_S2KU_NONE) {
- printf("S2K Specifier: %d\n", seckey->s2k_specifier);
- printf("Symmetric algorithm: %d (%s)\n", seckey->alg,
- pgp_show_symm_alg(seckey->alg));
- printf("Hash algorithm: %d (%s)\n", seckey->hash_alg,
- pgp_show_hash_alg((uint8_t)seckey->hash_alg));
- if (seckey->s2k_specifier != PGP_S2KS_SIMPLE) {
- print_hexdump(0, "Salt", seckey->salt,
- (unsigned)sizeof(seckey->salt));
- }
- if (seckey->s2k_specifier == PGP_S2KS_ITERATED_AND_SALTED) {
- printf("Octet count: %u\n", seckey->octetc);
- }
- print_hexdump(0, "IV", seckey->iv, pgp_block_size(seckey->alg));
- }
- /* no more set if encrypted */
- if (type == PGP_PTAG_CT_ENCRYPTED_SECRET_KEY) {
- return;
- }
- switch (seckey->pubkey.alg) {
- case PGP_PKA_RSA:
- print_bn(0, "d", seckey->key.rsa.d);
- print_bn(0, "p", seckey->key.rsa.p);
- print_bn(0, "q", seckey->key.rsa.q);
- print_bn(0, "u", seckey->key.rsa.u);
- break;
-
- case PGP_PKA_DSA:
- print_bn(0, "x", seckey->key.dsa.x);
- break;
-
- default:
- (void) fprintf(stderr,
- "print_seckey_verbose: unusual algorithm\n");
- }
- if (seckey->s2k_usage == PGP_S2KU_ENCRYPTED_AND_HASHED) {
- print_hexdump(0, "Checkhash", seckey->checkhash,
- PGP_CHECKHASH_SIZE);
- } else {
- printf("Checksum: %04x\n", seckey->checksum);
- }
- printf("------- end of SECRET KEY or ENCRYPTED SECRET KEY ------\n");
-}
-
-
-/**
-\ingroup Core_Print
-\param tag
-\param key
-*/
-static void
-print_pk_sesskey(pgp_content_enum tag,
- const pgp_pk_sesskey_t * key)
-{
- print_tagname(0, (tag == PGP_PTAG_CT_PK_SESSION_KEY) ?
- "PUBLIC KEY SESSION KEY" :
- "ENCRYPTED PUBLIC KEY SESSION KEY");
- printf("Version: %d\n", key->version);
- print_hexdump(0, "Key ID", key->key_id, (unsigned)sizeof(key->key_id));
- printf("Algorithm: %d (%s)\n", key->alg,
- pgp_show_pka(key->alg));
- switch (key->alg) {
- case PGP_PKA_RSA:
- print_bn(0, "encrypted_m", key->params.rsa.encrypted_m);
- break;
-
- case PGP_PKA_ELGAMAL:
- print_bn(0, "g_to_k", key->params.elgamal.g_to_k);
- print_bn(0, "encrypted_m", key->params.elgamal.encrypted_m);
- break;
-
- default:
- (void) fprintf(stderr,
- "print_pk_sesskey: unusual algorithm\n");
- }
- if (tag == PGP_PTAG_CT_PK_SESSION_KEY) {
- printf("Symmetric algorithm: %d (%s)\n", key->symm_alg,
- pgp_show_symm_alg(key->symm_alg));
- print_hexdump(0, "Key", key->key, pgp_key_size(key->symm_alg));
- printf("Checksum: %04x\n", key->checksum);
- }
-}
-
-static void
-start_subpacket(int *indent, int type)
-{
- *indent += 1;
- print_indent(*indent);
- printf("-- %s (type 0x%02x)\n",
- pgp_show_ss_type((pgp_content_enum)type),
- type - PGP_PTAG_SIG_SUBPKT_BASE);
-}
-
-static void
-end_subpacket(int *indent)
-{
- *indent -= 1;
-}
-
-/**
-\ingroup Core_Print
-\param contents
-*/
-int
-pgp_print_packet(pgp_printstate_t *print, const pgp_packet_t *pkt)
-{
- const pgp_contents_t *content = &pkt->u;
- pgp_text_t *text;
- const char *str;
-
- if (print->unarmoured && pkt->tag != PGP_PTAG_CT_UNARMOURED_TEXT) {
- print->unarmoured = 0;
- puts("UNARMOURED TEXT ends");
- }
- if (pkt->tag == PGP_PARSER_PTAG) {
- printf("=> PGP_PARSER_PTAG: %s\n",
- pgp_show_packet_tag((pgp_content_enum)content->ptag.type));
- } else {
- printf("=> %s\n", pgp_show_packet_tag(pkt->tag));
- }
-
- switch (pkt->tag) {
- case PGP_PARSER_ERROR:
- printf("parse error: %s\n", content->error);
- break;
-
- case PGP_PARSER_ERRCODE:
- printf("parse error: %s\n",
- pgp_errcode(content->errcode.errcode));
- break;
-
- case PGP_PARSER_PACKET_END:
- print_packet_hex(&content->packet);
- break;
-
- case PGP_PARSER_PTAG:
- if (content->ptag.type == PGP_PTAG_CT_PUBLIC_KEY) {
- print->indent = 0;
- printf("\n*** NEXT KEY ***\n");
- }
- printf("\n");
- print_indent(print->indent);
- printf("==== ptag new_format=%u type=%u length_type=%d"
- " length=0x%x (%u) position=0x%x (%u)\n",
- content->ptag.new_format,
- content->ptag.type, content->ptag.length_type,
- content->ptag.length, content->ptag.length,
- content->ptag.position, content->ptag.position);
- print_tagname(print->indent, pgp_show_packet_tag((pgp_content_enum)content->ptag.type));
- break;
-
- case PGP_PTAG_CT_SE_DATA_HEADER:
- print_tagname(print->indent, "SYMMETRIC ENCRYPTED DATA");
- break;
-
- case PGP_PTAG_CT_SE_IP_DATA_HEADER:
- print_tagname(print->indent,
- "SYMMETRIC ENCRYPTED INTEGRITY PROTECTED DATA HEADER");
- printf("Version: %d\n", content->se_ip_data_header);
- break;
-
- case PGP_PTAG_CT_SE_IP_DATA_BODY:
- print_tagname(print->indent,
- "SYMMETRIC ENCRYPTED INTEGRITY PROTECTED DATA BODY");
- hexdump(stdout, "data", content->se_data_body.data,
- content->se_data_body.length);
- break;
-
- case PGP_PTAG_CT_PUBLIC_KEY:
- case PGP_PTAG_CT_PUBLIC_SUBKEY:
- print_tagname(print->indent, (pkt->tag == PGP_PTAG_CT_PUBLIC_KEY) ?
- "PUBLIC KEY" :
- "PUBLIC SUBKEY");
- pgp_print_pubkey(&content->pubkey);
- break;
-
- case PGP_PTAG_CT_TRUST:
- print_tagname(print->indent, "TRUST");
- print_data(print->indent, "Trust", &content->trust);
- break;
-
- case PGP_PTAG_CT_USER_ID:
- print_tagname(print->indent, "USER ID");
- print_utf8_string(print->indent, "userid", content->userid);
- break;
-
- case PGP_PTAG_CT_SIGNATURE:
- print_tagname(print->indent, "SIGNATURE");
- print_indent(print->indent);
- print_uint(print->indent, "Signature Version",
- (unsigned)content->sig.info.version);
- if (content->sig.info.birthtime_set) {
- print_time(print->indent, "Signature Creation Time",
- content->sig.info.birthtime);
- }
- if (content->sig.info.duration_set) {
- print_uint(print->indent, "Signature Duration",
- (unsigned)content->sig.info.duration);
- }
-
- print_string_and_value(print->indent, "Signature Type",
- pgp_show_sig_type(content->sig.info.type),
- content->sig.info.type);
-
- if (content->sig.info.signer_id_set) {
- hexdump_data(print->indent, "Signer ID",
- content->sig.info.signer_id,
- (unsigned)sizeof(content->sig.info.signer_id));
- }
-
- print_string_and_value(print->indent, "Public Key Algorithm",
- pgp_show_pka(content->sig.info.key_alg),
- content->sig.info.key_alg);
- print_string_and_value(print->indent, "Hash Algorithm",
- pgp_show_hash_alg((uint8_t)
- content->sig.info.hash_alg),
- (uint8_t)content->sig.info.hash_alg);
- print_uint(print->indent, "Hashed data len",
- (unsigned)content->sig.info.v4_hashlen);
- print_indent(print->indent);
- hexdump_data(print->indent, "hash2", &content->sig.hash2[0], 2);
- switch (content->sig.info.key_alg) {
- case PGP_PKA_RSA:
- case PGP_PKA_RSA_SIGN_ONLY:
- print_bn(print->indent, "sig", content->sig.info.sig.rsa.sig);
- break;
-
- case PGP_PKA_DSA:
- print_bn(print->indent, "r", content->sig.info.sig.dsa.r);
- print_bn(print->indent, "s", content->sig.info.sig.dsa.s);
- break;
-
- case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
- print_bn(print->indent, "r", content->sig.info.sig.elgamal.r);
- print_bn(print->indent, "s", content->sig.info.sig.elgamal.s);
- break;
-
- default:
- (void) fprintf(stderr,
- "pgp_print_packet: Unusual algorithm\n");
- return 0;
- }
-
- if (content->sig.hash)
- printf("data hash is set\n");
-
- break;
-
- case PGP_PTAG_CT_COMPRESSED:
- print_tagname(print->indent, "COMPRESSED");
- print_uint(print->indent, "Compressed Data Type",
- (unsigned)content->compressed);
- break;
-
- case PGP_PTAG_CT_1_PASS_SIG:
- print_tagname(print->indent, "ONE PASS SIGNATURE");
-
- print_uint(print->indent, "Version", (unsigned)content->one_pass_sig.version);
- print_string_and_value(print->indent, "Signature Type",
- pgp_show_sig_type(content->one_pass_sig.sig_type),
- content->one_pass_sig.sig_type);
- print_string_and_value(print->indent, "Hash Algorithm",
- pgp_show_hash_alg((uint8_t)content->one_pass_sig.hash_alg),
- (uint8_t)content->one_pass_sig.hash_alg);
- print_string_and_value(print->indent, "Public Key Algorithm",
- pgp_show_pka(content->one_pass_sig.key_alg),
- content->one_pass_sig.key_alg);
- hexdump_data(print->indent, "Signer ID",
- content->one_pass_sig.keyid,
- (unsigned)sizeof(content->one_pass_sig.keyid));
- print_uint(print->indent, "Nested", content->one_pass_sig.nested);
- break;
-
- case PGP_PTAG_CT_USER_ATTR:
- print_tagname(print->indent, "USER ATTRIBUTE");
- print_hexdump(print->indent, "User Attribute",
- content->userattr.contents,
- (unsigned)content->userattr.len);
- break;
-
- case PGP_PTAG_RAW_SS:
- if (pkt->critical) {
- (void) fprintf(stderr, "contents are critical\n");
- return 0;
- }
- start_subpacket(&print->indent, pkt->tag);
- print_uint(print->indent, "Raw Signature Subpacket: tag",
- (unsigned)(content->ss_raw.tag -
- (unsigned)PGP_PTAG_SIG_SUBPKT_BASE));
- print_hexdump(print->indent, "Raw Data",
- content->ss_raw.raw,
- (unsigned)content->ss_raw.length);
- break;
-
- case PGP_PTAG_SS_CREATION_TIME:
- start_subpacket(&print->indent, pkt->tag);
- print_time(print->indent, "Signature Creation Time", content->ss_time);
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_SS_EXPIRATION_TIME:
- start_subpacket(&print->indent, pkt->tag);
- print_duration(print->indent, "Signature Expiration Time",
- content->ss_time);
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_SS_KEY_EXPIRY:
- start_subpacket(&print->indent, pkt->tag);
- print_duration(print->indent, "Key Expiration Time", content->ss_time);
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_SS_TRUST:
- start_subpacket(&print->indent, pkt->tag);
- print_string(print->indent, "Trust Signature", "");
- print_uint(print->indent, "Level", (unsigned)content->ss_trust.level);
- print_uint(print->indent, "Amount", (unsigned)content->ss_trust.amount);
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_SS_REVOCABLE:
- start_subpacket(&print->indent, pkt->tag);
- print_boolean(print->indent, "Revocable", content->ss_revocable);
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_SS_REVOCATION_KEY:
- start_subpacket(&print->indent, pkt->tag);
- /* not yet tested */
- printf(" revocation key: class=0x%x",
- content->ss_revocation_key.class);
- if (content->ss_revocation_key.class & 0x40) {
- printf(" (sensitive)");
- }
- printf(", algid=0x%x", content->ss_revocation_key.algid);
- hexdump(stdout, "fingerprint", content->ss_revocation_key.fingerprint,
- PGP_FINGERPRINT_SIZE);
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_SS_ISSUER_KEY_ID:
- start_subpacket(&print->indent, pkt->tag);
- print_hexdump(print->indent, "Issuer Key Id",
- content->ss_issuer, (unsigned)sizeof(content->ss_issuer));
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_SS_PREFERRED_SKA:
- start_subpacket(&print->indent, pkt->tag);
- print_data(print->indent, "Preferred Symmetric Algorithms",
- &content->ss_skapref);
- text = pgp_showall_ss_skapref(&content->ss_skapref);
- print_text_breakdown(print->indent, text);
- pgp_text_free(text);
-
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_SS_PRIMARY_USER_ID:
- start_subpacket(&print->indent, pkt->tag);
- print_boolean(print->indent, "Primary User ID",
- content->ss_primary_userid);
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_SS_PREFERRED_HASH:
- start_subpacket(&print->indent, pkt->tag);
- print_data(print->indent, "Preferred Hash Algorithms",
- &content->ss_hashpref);
- text = pgp_showall_ss_hashpref(&content->ss_hashpref);
- print_text_breakdown(print->indent, text);
- pgp_text_free(text);
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_SS_PREF_COMPRESS:
- start_subpacket(&print->indent, pkt->tag);
- print_data(print->indent, "Preferred Compression Algorithms",
- &content->ss_zpref);
- text = pgp_showall_ss_zpref(&content->ss_zpref);
- print_text_breakdown(print->indent, text);
- pgp_text_free(text);
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_SS_KEY_FLAGS:
- start_subpacket(&print->indent, pkt->tag);
- print_data(print->indent, "Key Flags", &content->ss_key_flags);
-
- text = pgp_showall_ss_key_flags(&content->ss_key_flags);
- print_text_breakdown(print->indent, text);
- pgp_text_free(text);
-
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_SS_KEYSERV_PREFS:
- start_subpacket(&print->indent, pkt->tag);
- print_data(print->indent, "Key Server Preferences",
- &content->ss_key_server_prefs);
- text = pgp_show_keyserv_prefs(&content->ss_key_server_prefs);
- print_text_breakdown(print->indent, text);
- pgp_text_free(text);
-
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_SS_FEATURES:
- start_subpacket(&print->indent, pkt->tag);
- print_data(print->indent, "Features", &content->ss_features);
- text = pgp_showall_ss_features(content->ss_features);
- print_text_breakdown(print->indent, text);
- pgp_text_free(text);
-
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_SS_NOTATION_DATA:
- start_subpacket(&print->indent, pkt->tag);
- print_indent(print->indent);
- printf("Notation Data:\n");
-
- print->indent++;
- print_data(print->indent, "Flags", &content->ss_notation.flags);
- text = pgp_showall_notation(content->ss_notation);
- print_text_breakdown(print->indent, text);
- pgp_text_free(text);
-
- print_data(print->indent, "Name", &content->ss_notation.name);
-
- print_data(print->indent, "Value", &content->ss_notation.value);
-
- print->indent--;
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_SS_REGEXP:
- start_subpacket(&print->indent, pkt->tag);
- print_hexdump(print->indent, "Regular Expression",
- (uint8_t *) content->ss_regexp,
- (unsigned)strlen(content->ss_regexp));
- print_string(print->indent, NULL, content->ss_regexp);
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_SS_POLICY_URI:
- start_subpacket(&print->indent, pkt->tag);
- print_string(print->indent, "Policy URL", content->ss_policy);
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_SS_SIGNERS_USER_ID:
- start_subpacket(&print->indent, pkt->tag);
- print_utf8_string(print->indent, "Signer's User ID", content->ss_signer);
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_SS_PREF_KEYSERV:
- start_subpacket(&print->indent, pkt->tag);
- print_string(print->indent, "Preferred Key Server", content->ss_keyserv);
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_SS_EMBEDDED_SIGNATURE:
- start_subpacket(&print->indent, pkt->tag);
- end_subpacket(&print->indent);/* \todo print out contents? */
- break;
-
- case PGP_PTAG_SS_USERDEFINED00:
- case PGP_PTAG_SS_USERDEFINED01:
- case PGP_PTAG_SS_USERDEFINED02:
- case PGP_PTAG_SS_USERDEFINED03:
- case PGP_PTAG_SS_USERDEFINED04:
- case PGP_PTAG_SS_USERDEFINED05:
- case PGP_PTAG_SS_USERDEFINED06:
- case PGP_PTAG_SS_USERDEFINED07:
- case PGP_PTAG_SS_USERDEFINED08:
- case PGP_PTAG_SS_USERDEFINED09:
- case PGP_PTAG_SS_USERDEFINED10:
- start_subpacket(&print->indent, pkt->tag);
- print_hexdump(print->indent, "Internal or user-defined",
- content->ss_userdef.contents,
- (unsigned)content->ss_userdef.len);
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_SS_RESERVED:
- start_subpacket(&print->indent, pkt->tag);
- print_hexdump(print->indent, "Reserved",
- content->ss_userdef.contents,
- (unsigned)content->ss_userdef.len);
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_SS_REVOCATION_REASON:
- start_subpacket(&print->indent, pkt->tag);
- print_hexdump(print->indent, "Revocation Reason",
- &content->ss_revocation.code,
- 1);
- str = pgp_show_ss_rr_code(content->ss_revocation.code);
- print_string(print->indent, NULL, str);
- end_subpacket(&print->indent);
- break;
-
- case PGP_PTAG_CT_LITDATA_HEADER:
- print_tagname(print->indent, "LITERAL DATA HEADER");
- printf(" literal data header format=%c filename='%s'\n",
- content->litdata_header.format,
- content->litdata_header.filename);
- showtime(" modification time",
- content->litdata_header.mtime);
- printf("\n");
- break;
-
- case PGP_PTAG_CT_LITDATA_BODY:
- print_tagname(print->indent, "LITERAL DATA BODY");
- printf(" literal data body length=%u\n",
- content->litdata_body.length);
- printf(" data=");
- print_escaped(content->litdata_body.data,
- content->litdata_body.length);
- printf("\n");
- break;
-
- case PGP_PTAG_CT_SIGNATURE_HEADER:
- print_tagname(print->indent, "SIGNATURE");
- print_indent(print->indent);
- print_uint(print->indent, "Signature Version",
- (unsigned)content->sig.info.version);
- if (content->sig.info.birthtime_set) {
- print_time(print->indent, "Signature Creation Time",
- content->sig.info.birthtime);
- }
- if (content->sig.info.duration_set) {
- print_uint(print->indent, "Signature Duration",
- (unsigned)content->sig.info.duration);
- }
- print_string_and_value(print->indent, "Signature Type",
- pgp_show_sig_type(content->sig.info.type),
- content->sig.info.type);
- if (content->sig.info.signer_id_set) {
- hexdump_data(print->indent, "Signer ID",
- content->sig.info.signer_id,
- (unsigned)sizeof(content->sig.info.signer_id));
- }
- print_string_and_value(print->indent, "Public Key Algorithm",
- pgp_show_pka(content->sig.info.key_alg),
- content->sig.info.key_alg);
- print_string_and_value(print->indent, "Hash Algorithm",
- pgp_show_hash_alg((uint8_t)content->sig.info.hash_alg),
- (uint8_t)content->sig.info.hash_alg);
- print_uint(print->indent, "Hashed data len",
- (unsigned)content->sig.info.v4_hashlen);
-
- break;
-
- case PGP_PTAG_CT_SIGNATURE_FOOTER:
- print_indent(print->indent);
- hexdump_data(print->indent, "hash2", &content->sig.hash2[0], 2);
-
- switch (content->sig.info.key_alg) {
- case PGP_PKA_RSA:
- print_bn(print->indent, "sig", content->sig.info.sig.rsa.sig);
- break;
-
- case PGP_PKA_DSA:
- print_bn(print->indent, "r", content->sig.info.sig.dsa.r);
- print_bn(print->indent, "s", content->sig.info.sig.dsa.s);
- break;
-
- case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
- print_bn(print->indent, "r", content->sig.info.sig.elgamal.r);
- print_bn(print->indent, "s", content->sig.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:
- print_data(print->indent, "Private/Experimental",
- &content->sig.info.sig.unknown);
- break;
-
- default:
- (void) fprintf(stderr,
- "pgp_print_packet: Unusual key algorithm\n");
- return 0;
- }
- break;
-
- case PGP_GET_PASSPHRASE:
- print_tagname(print->indent, "PGP_GET_PASSPHRASE");
- break;
-
- case PGP_PTAG_CT_SECRET_KEY:
- print_tagname(print->indent, "PGP_PTAG_CT_SECRET_KEY");
- print_seckey_verbose(pkt->tag, &content->seckey);
- break;
-
- case PGP_PTAG_CT_ENCRYPTED_SECRET_KEY:
- print_tagname(print->indent, "PGP_PTAG_CT_ENCRYPTED_SECRET_KEY");
- print_seckey_verbose(pkt->tag, &content->seckey);
- break;
-
- case PGP_PTAG_CT_ARMOUR_HEADER:
- print_tagname(print->indent, "ARMOUR HEADER");
- print_string(print->indent, "type", content->armour_header.type);
- break;
-
- case PGP_PTAG_CT_SIGNED_CLEARTEXT_HEADER:
- print_tagname(print->indent, "SIGNED CLEARTEXT HEADER");
- print_headers(&content->cleartext_head);
- break;
-
- case PGP_PTAG_CT_SIGNED_CLEARTEXT_BODY:
- print_tagname(print->indent, "SIGNED CLEARTEXT BODY");
- print_block(print->indent, "signed cleartext", content->cleartext_body.data,
- content->cleartext_body.length);
- break;
-
- case PGP_PTAG_CT_SIGNED_CLEARTEXT_TRAILER:
- print_tagname(print->indent, "SIGNED CLEARTEXT TRAILER");
- printf("hash algorithm: %d\n",
- content->cleartext_trailer->alg);
- printf("\n");
- break;
-
- case PGP_PTAG_CT_UNARMOURED_TEXT:
- if (!print->unarmoured) {
- print_tagname(print->indent, "UNARMOURED TEXT");
- print->unarmoured = 1;
- }
- putchar('[');
- print_escaped(content->unarmoured_text.data,
- content->unarmoured_text.length);
- putchar(']');
- break;
-
- case PGP_PTAG_CT_ARMOUR_TRAILER:
- print_tagname(print->indent, "ARMOUR TRAILER");
- print_string(print->indent, "type", content->armour_header.type);
- break;
-
- case PGP_PTAG_CT_PK_SESSION_KEY:
- case PGP_PTAG_CT_ENCRYPTED_PK_SESSION_KEY:
- print_pk_sesskey(pkt->tag, &content->pk_sesskey);
- break;
-
- case PGP_GET_SECKEY:
- print_pk_sesskey(PGP_PTAG_CT_ENCRYPTED_PK_SESSION_KEY,
- content->get_seckey.pk_sesskey);
- break;
-
- default:
- print_tagname(print->indent, "UNKNOWN PACKET TYPE");
- fprintf(stderr, "pgp_print_packet: unknown tag=%d (0x%x)\n",
- pkt->tag, pkt->tag);
- return 0;
- }
- return 1;
-}
-
-static pgp_cb_ret_t
-cb_list_packets(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
-{
- pgp_print_packet(&cbinfo->printstate, pkt);
- return PGP_RELEASE_MEMORY;
-}
-
-/**
-\ingroup Core_Print
-\param filename
-\param armour
-\param keyring
-\param cb_get_passphrase
-*/
-int
-pgp_list_packets(pgp_io_t *io,
- char *filename,
- unsigned armour,
- pgp_keyring_t *secring,
- pgp_keyring_t *pubring,
- void *passfp,
- pgp_cbfunc_t *cb_get_passphrase)
-{
- pgp_stream_t *stream = NULL;
- const unsigned accumulate = 1;
- const int printerrors = 1;
- int fd;
-
- fd = pgp_setup_file_read(io, &stream, filename, NULL, cb_list_packets,
- accumulate);
- pgp_parse_options(stream, PGP_PTAG_SS_ALL, PGP_PARSE_PARSED);
- stream->cryptinfo.secring = secring;
- stream->cryptinfo.pubring = pubring;
- stream->cbinfo.passfp = passfp;
- stream->cryptinfo.getpassphrase = cb_get_passphrase;
- if (armour) {
- pgp_reader_push_dearmour(stream);
- }
- pgp_parse(stream, printerrors);
- pgp_teardown_file_read(stream, fd);
- return 1;
-}
diff --git a/libs/netpgp/compress.c b/libs/netpgp/src/compress.c
similarity index 97%
rename from libs/netpgp/compress.c
rename to libs/netpgp/src/compress.c
index 1460e0dc..3186a019 100644
--- a/libs/netpgp/compress.c
+++ b/libs/netpgp/src/compress.c
@@ -49,7 +49,7 @@
/** \file
*/
-#include "config-netpgp.h"
+#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include
@@ -57,7 +57,7 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: compress.c,v 1.23 2012/03/05 02:20:18 christos Exp $");
+__RCSID("$NetBSD$");
#endif
#ifdef HAVE_ZLIB_H
@@ -70,12 +70,12 @@ __RCSID("$NetBSD: compress.c,v 1.23 2012/03/05 02:20:18 christos Exp $");
#include
-#include "packet-parse.h"
-#include "errors-netpgp.h"
-#include "netpgpdefs.h"
-#include "crypto-netpgp.h"
-#include "memory-netpgp.h"
-#include "writer-netpgp.h"
+#include "netpgp/packet-parse.h"
+#include "netpgp/errors.h"
+#include "netpgp/netpgpdefs.h"
+#include "netpgp/crypto.h"
+#include "netpgp/memory.h"
+#include "netpgp/writer.h"
#define DECOMPRESS_BUFFER 1024
@@ -108,7 +108,7 @@ typedef struct {
} compress_t;
/*
- * \todo remove code duplication between this and
+ * \todo re move code duplication between this and
* bzip2_compressed_data_reader
*/
static int
@@ -188,8 +188,9 @@ zlib_compressed_data_reader(pgp_stream_t *stream, void *dest, size_t length,
return 0;
}
len = (size_t)(z->zstream.next_out - &z->out[z->offset]);
- if (len > length) {
- len = length;
+ size_t left_in_cdest = length - cc;
+ if (len > left_in_cdest) {
+ len = left_in_cdest;
}
(void) memcpy(&cdest[cc], &z->out[z->offset], len);
z->offset += len;
diff --git a/libs/netpgp/create.c b/libs/netpgp/src/create.c
similarity index 71%
rename from libs/netpgp/create.c
rename to libs/netpgp/src/create.c
index 41487da5..2c80856e 100644
--- a/libs/netpgp/create.c
+++ b/libs/netpgp/src/create.c
@@ -49,7 +49,7 @@
/** \file
*/
-#include "config-netpgp.h"
+#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include
@@ -57,7 +57,7 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: create.c,v 1.38 2010/11/15 08:03:39 agc Exp $");
+__RCSID("$NetBSD$");
#endif
#include
@@ -78,15 +78,15 @@ __RCSID("$NetBSD: create.c,v 1.38 2010/11/15 08:03:39 agc Exp $");
#include
#endif
-#include "create-netpgp.h"
-#include "keyring-netpgp.h"
-#include "packet-netpgp.h"
-#include "signature-netpgp.h"
-#include "writer-netpgp.h"
-#include "readerwriter-netpgp.h"
-#include "memory-netpgp.h"
-#include "netpgpdefs.h"
-#include "netpgpdigest.h"
+#include "netpgp/create.h"
+#include "netpgp/keyring.h"
+#include "netpgp/packet.h"
+#include "netpgp/signature.h"
+#include "netpgp/writer.h"
+#include "netpgp/readerwriter.h"
+#include "netpgp/memory.h"
+#include "netpgp/netpgpdefs.h"
+#include "netpgp/netpgpdigest.h"
/**
* \ingroup Core_Create
@@ -98,10 +98,10 @@ __RCSID("$NetBSD: create.c,v 1.38 2010/11/15 08:03:39 agc Exp $");
unsigned
pgp_write_ss_header(pgp_output_t *output,
- unsigned length,
+ size_t length,
pgp_content_enum type)
{
- return pgp_write_length(output, length) &&
+ return pgp_write_length(output, (unsigned int)length) &&
pgp_write_scalar(output, (unsigned)(type -
(unsigned)PGP_PTAG_SIG_SUBPKT_BASE), 1);
}
@@ -176,6 +176,11 @@ pubkey_length(const pgp_pubkey_t *key)
case PGP_PKA_RSA:
return mpi_length(key->key.rsa.n) + mpi_length(key->key.rsa.e);
+ case PGP_PKA_ELGAMAL:
+ return mpi_length(key->key.elgamal.p) +
+ mpi_length(key->key.elgamal.g) +
+ mpi_length(key->key.elgamal.y);
+
default:
(void) fprintf(stderr,
"pubkey_length: unknown key algorithm\n");
@@ -188,7 +193,6 @@ seckey_length(const pgp_seckey_t *key)
{
int len;
- len = 0;
switch (key->pubkey.alg) {
case PGP_PKA_DSA:
return (unsigned)(mpi_length(key->key.dsa.x) + pubkey_length(&key->pubkey));
@@ -197,6 +201,11 @@ seckey_length(const pgp_seckey_t *key)
mpi_length(key->key.rsa.q) + mpi_length(key->key.rsa.u);
return (unsigned)(len + pubkey_length(&key->pubkey));
+
+ case PGP_PKA_ELGAMAL:
+ return (unsigned)(
+ mpi_length(key->key.dsa.x) + pubkey_length(&key->pubkey));
+
default:
(void) fprintf(stderr,
"seckey_length: unknown key algorithm\n");
@@ -273,7 +282,7 @@ write_pubkey_body(const pgp_pubkey_t *key, pgp_output_t *output)
* Note that we support v3 keys here because they're needed for
* verification.
*/
-unsigned
+static unsigned
write_seckey_body(const pgp_seckey_t *key,
const uint8_t *passphrase,
const size_t pplen,
@@ -285,160 +294,166 @@ write_seckey_body(const pgp_seckey_t *key,
pgp_hash_t hash;
unsigned done = 0;
unsigned i = 0;
- uint8_t *hashed;
uint8_t sesskey[CAST_KEY_LENGTH];
if (!write_pubkey_body(&key->pubkey, output)) {
return 0;
}
- if (key->s2k_usage != PGP_S2KU_ENCRYPTED_AND_HASHED) {
- (void) fprintf(stderr, "write_seckey_body: s2k usage\n");
- return 0;
- }
- if (!pgp_write_scalar(output, (unsigned)key->s2k_usage, 1)) {
- return 0;
- }
+ if (!pgp_write_scalar(output, (unsigned)key->s2k_usage, 1)) {
+ return 0;
+ }
+ 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;
+ }
- if (key->alg != PGP_SA_CAST5) {
- (void) fprintf(stderr, "write_seckey_body: algorithm\n");
- return 0;
- }
- if (!pgp_write_scalar(output, (unsigned)key->alg, 1)) {
- return 0;
- }
+ if (key->alg != PGP_SA_CAST5) {
+ (void) fprintf(stderr, "write_seckey_body: algorithm\n");
+ return 0;
+ }
+ if (!pgp_write_scalar(output, (unsigned)key->alg, 1)) {
+ return 0;
+ }
- if (key->s2k_specifier != PGP_S2KS_SIMPLE &&
- key->s2k_specifier != PGP_S2KS_SALTED) {
- /* = 1 \todo could also be iterated-and-salted */
- (void) fprintf(stderr, "write_seckey_body: s2k spec\n");
- return 0;
- }
- if (!pgp_write_scalar(output, (unsigned)key->s2k_specifier, 1)) {
- return 0;
- }
- if (!pgp_write_scalar(output, (unsigned)key->hash_alg, 1)) {
- return 0;
- }
+ if (key->s2k_specifier != PGP_S2KS_SIMPLE &&
+ key->s2k_specifier != PGP_S2KS_SALTED) {
+ /* = 1 \todo could also be iterated-and-salted */
+ (void) fprintf(stderr, "write_seckey_body: s2k spec\n");
+ return 0;
+ }
+ if (!pgp_write_scalar(output, (unsigned)key->s2k_specifier, 1)) {
+ return 0;
+ }
+ if (!pgp_write_scalar(output, (unsigned)key->hash_alg, 1)) {
+ return 0;
+ }
- switch (key->s2k_specifier) {
- case PGP_S2KS_SIMPLE:
- /* nothing more to do */
- break;
+ switch (key->s2k_specifier) {
+ case PGP_S2KS_SIMPLE:
+ /* nothing more to do */
+ break;
- case PGP_S2KS_SALTED:
- /* 8-octet salt value */
- pgp_random(__UNCONST(&key->salt[0]), PGP_SALT_SIZE);
- if (!pgp_write(output, key->salt, PGP_SALT_SIZE)) {
- return 0;
- }
- break;
+ case PGP_S2KS_SALTED:
+ /* 8-octet salt value */
+ pgp_random(__UNCONST(&key->salt[0]), PGP_SALT_SIZE);
+ if (!pgp_write(output, key->salt, PGP_SALT_SIZE)) {
+ return 0;
+ }
+ break;
- /*
- * \todo case PGP_S2KS_ITERATED_AND_SALTED: // 8-octet salt
- * value // 1-octet count break;
- */
+ /*
+ * \todo case PGP_S2KS_ITERATED_AND_SALTED: // 8-octet salt
+ * value // 1-octet count break;
+ */
- default:
- (void) fprintf(stderr,
- "invalid/unsupported s2k specifier %d\n",
- key->s2k_specifier);
- return 0;
- }
+ default:
+ (void) fprintf(stderr,
+ "invalid/unsupported s2k specifier %d\n",
+ key->s2k_specifier);
+ return 0;
+ }
- if (!pgp_write(output, &key->iv[0], pgp_block_size(key->alg))) {
- return 0;
- }
+ if (!pgp_write(output, &key->iv[0], pgp_block_size(key->alg))) {
+ return 0;
+ }
- /*
- * create the session key for encrypting the algorithm-specific
- * fields
- */
+ /*
+ * create the session key for encrypting the algorithm-specific
+ * fields
+ */
- switch (key->s2k_specifier) {
- case PGP_S2KS_SIMPLE:
- case PGP_S2KS_SALTED:
- /* RFC4880: section 3.7.1.1 and 3.7.1.2 */
+ switch (key->s2k_specifier) {
+ case PGP_S2KS_SIMPLE:
+ case PGP_S2KS_SALTED:
+ /* RFC4880: section 3.7.1.1 and 3.7.1.2 */
- for (done = 0, i = 0; done < CAST_KEY_LENGTH; i++) {
- unsigned hashsize;
- unsigned j;
- unsigned needed;
- unsigned size;
- uint8_t zero = 0;
+ for (done = 0, i = 0; done < CAST_KEY_LENGTH; i++) {
+ unsigned hashsize;
+ unsigned j;
+ unsigned needed;
+ unsigned size;
+ uint8_t zero = 0;
+ uint8_t *hashed;
- /* Hard-coded SHA1 for session key */
- pgp_hash_any(&hash, PGP_HASH_SHA1);
- hashsize = pgp_hash_size(key->hash_alg);
- needed = CAST_KEY_LENGTH - done;
- size = MIN(needed, hashsize);
- if ((hashed = calloc(1, hashsize)) == NULL) {
- (void) fprintf(stderr, "write_seckey_body: bad alloc\n");
- return 0;
- }
- if (!hash.init(&hash)) {
- (void) fprintf(stderr, "write_seckey_body: bad alloc\n");
- return 0;
- }
+ /* Hard-coded SHA1 for session key */
+ pgp_hash_any(&hash, PGP_HASH_SHA1);
+ hashsize = pgp_hash_size(key->hash_alg);
+ needed = CAST_KEY_LENGTH - done;
+ size = MIN(needed, hashsize);
+ if ((hashed = calloc(1, hashsize)) == NULL) {
+ (void) fprintf(stderr, "write_seckey_body: bad alloc\n");
+ return 0;
+ }
+ if (!hash.init(&hash)) {
+ (void) fprintf(stderr, "write_seckey_body: bad alloc\n");
+ free(hashed);
+ return 0;
+ }
- /* preload if iterating */
- for (j = 0; j < i; j++) {
- /*
- * Coverity shows a DEADCODE error on this
- * line. This is expected since the hardcoded
- * use of SHA1 and CAST5 means that it will
- * not used. This will change however when
- * other algorithms are supported.
- */
- hash.add(&hash, &zero, 1);
- }
+ /* preload if iterating */
+ for (j = 0; j < i; j++) {
+ /*
+ * Coverity shows a DEADCODE error on this
+ * line. This is expected since the hardcoded
+ * use of SHA1 and CAST5 means that it will
+ * not used. This will change however when
+ * other algorithms are supported.
+ */
+ hash.add(&hash, &zero, 1);
+ }
- if (key->s2k_specifier == PGP_S2KS_SALTED) {
- hash.add(&hash, key->salt, PGP_SALT_SIZE);
- }
- hash.add(&hash, passphrase, (unsigned)pplen);
- hash.finish(&hash, hashed);
+ if (key->s2k_specifier == PGP_S2KS_SALTED) {
+ hash.add(&hash, key->salt, PGP_SALT_SIZE);
+ }
+ hash.add(&hash, passphrase, (unsigned)pplen);
+ hash.finish(&hash, hashed);
- /*
- * if more in hash than is needed by session key, use
- * the leftmost octets
- */
- (void) memcpy(&sesskey[i * hashsize],
- hashed, (unsigned)size);
- done += (unsigned)size;
- if (done > CAST_KEY_LENGTH) {
- (void) fprintf(stderr,
- "write_seckey_body: short add\n");
- return 0;
- }
- }
+ /*
+ * if more in hash than is needed by session key, use
+ * the leftmost octets
+ */
+ (void) memcpy(&sesskey[i * hashsize],
+ hashed, (unsigned)size);
+ done += (unsigned)size;
+ free(hashed);
+ if (done > CAST_KEY_LENGTH) {
+ (void) fprintf(stderr,
+ "write_seckey_body: short add\n");
+ return 0;
+ }
+ }
- break;
+ break;
- /*
- * \todo case PGP_S2KS_ITERATED_AND_SALTED: * 8-octet salt
- * value * 1-octet count break;
- */
+ /*
+ * \todo case PGP_S2KS_ITERATED_AND_SALTED: * 8-octet salt
+ * value * 1-octet count break;
+ */
- default:
- (void) fprintf(stderr,
- "invalid/unsupported s2k specifier %d\n",
- key->s2k_specifier);
- return 0;
- }
+ default:
+ (void) fprintf(stderr,
+ "invalid/unsupported s2k specifier %d\n",
+ key->s2k_specifier);
+ return 0;
+ }
- /* use this session key to encrypt */
+ /* use this session key to encrypt */
- pgp_crypt_any(&crypted, key->alg);
- crypted.set_iv(&crypted, key->iv);
- crypted.set_crypt_key(&crypted, sesskey);
- pgp_encrypt_init(&crypted);
+ pgp_crypt_any(&crypted, key->alg);
+ crypted.set_iv(&crypted, key->iv);
+ crypted.set_crypt_key(&crypted, sesskey);
+ pgp_encrypt_init(&crypted);
- if (pgp_get_debug_level(__FILE__)) {
- hexdump(stderr, "writing: iv=", key->iv, pgp_block_size(key->alg));
- hexdump(stderr, "key= ", sesskey, CAST_KEY_LENGTH);
- (void) fprintf(stderr, "\nturning encryption on...\n");
- }
- pgp_push_enc_crypt(output, &crypted);
+ if (pgp_get_debug_level(__FILE__)) {
+ hexdump(stderr, "writing: iv=", key->iv, pgp_block_size(key->alg));
+ hexdump(stderr, "key= ", sesskey, CAST_KEY_LENGTH);
+ (void) fprintf(stderr, "\nturning encryption on...\n");
+ }
+ pgp_push_enc_crypt(output, &crypted);
+ }else{
+ pgp_push_sum16_writer(output);
+ }
switch (key->pubkey.alg) {
case PGP_PKA_RSA:
@@ -463,11 +478,19 @@ write_seckey_body(const pgp_seckey_t *key,
return 0;
}
- if (!pgp_write(output, key->checkhash, PGP_CHECKHASH_SIZE)) {
- return 0;
- }
- pgp_writer_pop(output);
+ if (key->s2k_usage != PGP_S2KU_NONE) {
+
+ if (!pgp_write(output, key->checkhash, PGP_CHECKHASH_SIZE)) {
+ return 0;
+ }
+ pgp_writer_pop(output);
+ }else{
+ uint16_t checksum = pgp_pop_sum16_writer(output);
+ if (!pgp_write_scalar(output, checksum, 2)) {
+ return 0;
+ }
+ }
return 1;
}
@@ -480,13 +503,20 @@ write_seckey_body(const pgp_seckey_t *key,
* \return 1 if OK, otherwise 0
*/
unsigned
-write_struct_pubkey(pgp_output_t *output, const pgp_pubkey_t *key)
+pgp_write_struct_pubkey_ptag(
+ pgp_output_t *output,
+ const pgp_pubkey_t *key,
+ pgp_content_enum ptag)
{
- return pgp_write_ptag(output, PGP_PTAG_CT_PUBLIC_KEY) &&
+ return pgp_write_ptag(output, ptag) &&
pgp_write_length(output, 1 + 4 + 1 + pubkey_length(key)) &&
write_pubkey_body(key, output);
}
-
+unsigned
+pgp_write_struct_pubkey(pgp_output_t *output, const pgp_pubkey_t *key)
+{
+ return pgp_write_struct_pubkey_ptag(output, key, PGP_PTAG_CT_PUBLIC_KEY);
+}
/**
\ingroup HighLevel_KeyWrite
@@ -500,46 +530,110 @@ write_struct_pubkey(pgp_output_t *output, const pgp_pubkey_t *key)
*/
unsigned
-pgp_write_xfer_pubkey(pgp_output_t *output,
- const pgp_key_t *key,
- const unsigned armoured)
+pgp_write_xfer_key(pgp_output_t *output,
+ const pgp_key_t *key,
+ const unsigned armoured)
{
- unsigned i, j;
+ unsigned directsigidx = 0;
+ pgp_directsig_t *directsigp;
+ unsigned uididx = 0;
+ unsigned uidsigidx = 0;
+ uint8_t **uidp;
+ pgp_uidsig_t *uidsigp;
+ pgp_subkey_t *subkeyp;
+ unsigned subkeyidx = 0;
+ unsigned subkeysigidx = 0;
+ pgp_subkeysig_t *subkeysigp;
- if (armoured) {
- pgp_writer_push_armoured(output, PGP_PGP_PUBLIC_KEY_BLOCK);
- }
- /* public key */
- if (!write_struct_pubkey(output, &key->key.pubkey)) {
- return 0;
- }
+ if (armoured) {
+ pgp_writer_push_armoured(output, PGP_PGP_PUBLIC_KEY_BLOCK);
+ }
- /* TODO: revocation signatures go here */
+ /* primary key */
+ if (key->type == PGP_PTAG_CT_PUBLIC_KEY) {
+ if (!pgp_write_struct_pubkey(output, &key->key.pubkey)) {
+ return 0;
+ }
+ }else{
+ if (!pgp_write_struct_seckey(&key->key.seckey, (const uint8_t *)"", 0, output)) {
+ return 0;
+ }
+ }
- /* 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;
- }
- }
- }
+ directsigp = key->directsigs;
+ for (directsigidx = 0 ; directsigidx < key->directsigc;
+ directsigidx++, directsigp++)
+ {
+ if (!pgp_write(output, directsigp->packet.raw,
+ (unsigned)directsigp->packet.length)) {
+ return 0;
+ }
+ }
- /* TODO: user attributes and corresponding signatures */
+ /* 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;
+ }
+ }
+ }
+ }
- /*
- * subkey packets and corresponding signatures and optional
- * revocation
- */
+ /* TODO attibutes */
- if (armoured) {
- pgp_writer_info_finalise(&output->errors, &output->writer);
- pgp_writer_pop(output);
- }
- return 1;
+ /* Loop over key's subkeys */
+ subkeyp = key->subkeys;
+ for (subkeyidx = 0 ; subkeyidx < key->subkeyc; subkeyidx++, subkeyp++)
+ {
+ if (key->type == PGP_PTAG_CT_PUBLIC_KEY) {
+ if (!pgp_write_struct_pubkey_ptag(
+ output, &subkeyp->key.pubkey,
+ PGP_PTAG_CT_PUBLIC_SUBKEY)) {
+ return 0;
+ }
+ }else{
+ if (!pgp_write_struct_seckey_ptag(
+ /* TODO support passphrase again */
+ &subkeyp->key.seckey, (const uint8_t *)"", 0, output,
+ PGP_PTAG_CT_SECRET_SUBKEY)) {
+ return 0;
+ }
+ }
+
+ /* Loop over key's subkeys sigs */
+ subkeysigp = key->subkeysigs;
+ for (subkeysigidx = 0 ; subkeysigidx < key->subkeysigc;
+ subkeysigidx++, subkeysigp++)
+ {
+ /* matching selected subkey */
+ if(subkeysigp->subkey == subkeyidx)
+ {
+ if (!pgp_write(output, subkeysigp->packet.raw,
+ (unsigned)subkeysigp->packet.length)) {
+ return 0;
+ }
+ }
+ }
+ }
+
+ if (armoured) {
+ pgp_writer_info_finalise(&output->errors, &output->writer);
+ pgp_writer_pop(output);
+ }
+ return 1;
}
/**
@@ -554,52 +648,14 @@ pgp_write_xfer_pubkey(pgp_output_t *output,
\param output Output stream
*/
-
+/* TODO have encrypted key export again
unsigned
pgp_write_xfer_seckey(pgp_output_t *output,
const pgp_key_t *key,
const uint8_t *passphrase,
const size_t pplen,
unsigned armoured)
-{
- unsigned i, j;
-
- if (armoured) {
- pgp_writer_push_armoured(output, PGP_PGP_PRIVATE_KEY_BLOCK);
- }
- /* public key */
- if (!pgp_write_struct_seckey(&key->key.seckey, passphrase,
- pplen, output)) {
- return 0;
- }
-
- /* TODO: revocation signatures go here */
-
- /* user ids and corresponding signatures */
- for (i = 0; i < key->uidc; i++) {
- if (!pgp_write_struct_userid(output, key->uids[i])) {
- return 0;
- }
- for (j = 0; j < key->packetc; j++) {
- if (!pgp_write(output, key->packets[j].raw, (unsigned)key->packets[j].length)) {
- return 0;
- }
- }
- }
-
- /* TODO: user attributes and corresponding signatures */
-
- /*
- * subkey packets and corresponding signatures and optional
- * revocation
- */
-
- if (armoured) {
- pgp_writer_info_finalise(&output->errors, &output->writer);
- pgp_writer_pop(output);
- }
- return 1;
-}
+*/
/**
* \ingroup Core_WritePackets
@@ -620,7 +676,7 @@ pgp_write_rsa_pubkey(time_t t, const BIGNUM *n,
pgp_pubkey_t key;
pgp_fast_create_rsa_pubkey(&key, t, __UNCONST(n), __UNCONST(e));
- return write_struct_pubkey(output, &key);
+ return pgp_write_struct_pubkey(output, &key);
}
/**
@@ -693,10 +749,11 @@ pgp_fast_create_rsa_seckey(pgp_seckey_t *key, time_t t,
* \return 1 if OK; else 0
*/
unsigned
-pgp_write_struct_seckey(const pgp_seckey_t *key,
+pgp_write_struct_seckey_ptag(const pgp_seckey_t *key,
const uint8_t *passphrase,
const size_t pplen,
- pgp_output_t *output)
+ pgp_output_t *output,
+ pgp_content_enum ptag)
{
int length = 0;
@@ -709,7 +766,7 @@ pgp_write_struct_seckey(const pgp_seckey_t *key,
/* Ref: RFC4880 Section 5.5.3 */
/* pubkey, excluding MPIs */
- length += 1 + 4 + 1 + 1;
+ length += 1 + 4 + 1;
/* s2k usage */
length += 1;
@@ -776,12 +833,21 @@ pgp_write_struct_seckey(const pgp_seckey_t *key,
/* secret key and public key MPIs */
length += (unsigned)seckey_length(key);
- return pgp_write_ptag(output, PGP_PTAG_CT_SECRET_KEY) &&
+ return pgp_write_ptag(output, ptag) &&
/* pgp_write_length(output,1+4+1+1+seckey_length(key)+2) && */
pgp_write_length(output, (unsigned)length) &&
write_seckey_body(key, passphrase, pplen, output);
}
+unsigned
+pgp_write_struct_seckey(const pgp_seckey_t *key,
+ const uint8_t *passphrase,
+ const size_t pplen,
+ pgp_output_t *output)
+{
+ return pgp_write_struct_seckey_ptag(
+ key, passphrase, pplen, output, PGP_PTAG_CT_SECRET_KEY);
+}
/**
* \ingroup Core_Create
*
@@ -932,7 +998,7 @@ encode_m_buf(const uint8_t *M, size_t mLen, const pgp_pubkey_t * pubkey,
\note Currently hard-coded to use RSA
*/
pgp_pk_sesskey_t *
-pgp_create_pk_sesskey(const pgp_key_t *key, const char *ciphername)
+pgp_create_pk_sesskey(pgp_key_t *key, const char *ciphername, pgp_pk_sesskey_t *initial_sesskey)
{
/*
* Creates a random session key and encrypts it for the given key
@@ -941,7 +1007,7 @@ pgp_create_pk_sesskey(const pgp_key_t *key, const char *ciphername)
* can be any, we're hardcoding RSA for now
*/
- const pgp_pubkey_t *pubkey;
+ pgp_pubkey_t *pubkey;
pgp_pk_sesskey_t *sesskey;
pgp_symm_alg_t cipher;
const uint8_t *id;
@@ -950,13 +1016,8 @@ pgp_create_pk_sesskey(const pgp_key_t *key, const char *ciphername)
uint8_t *encoded_m_buf;
size_t sz_encoded_m_buf;
- if (memcmp(key->encid, "\0\0\0\0\0\0\0\0", 8) == 0) {
- pubkey = pgp_get_pubkey(key);
- id = key->sigid;
- } else {
- pubkey = &key->enckey;
- id = key->encid;
- }
+ pubkey = pgp_key_get_enckey(key, &id);
+
/* allocate unencoded_m_buf here */
(void) memset(&cipherinfo, 0x0, sizeof(cipherinfo));
pgp_crypt_any(&cipherinfo,
@@ -1022,7 +1083,14 @@ pgp_create_pk_sesskey(const pgp_key_t *key, const char *ciphername)
sesskey->alg = pubkey->alg;
sesskey->symm_alg = cipher;
- pgp_random(sesskey->key, cipherinfo.keysize);
+ if(initial_sesskey){
+ if(initial_sesskey->symm_alg != cipher){
+ return NULL;
+ }
+ memcpy(sesskey->key, initial_sesskey->key, cipherinfo.keysize);
+ }else{
+ pgp_random(sesskey->key, cipherinfo.keysize);
+ }
if (pgp_get_debug_level(__FILE__)) {
hexdump(stderr, "sesskey created", sesskey->key,
diff --git a/libs/netpgp/crypto.c b/libs/netpgp/src/crypto.c
similarity index 77%
rename from libs/netpgp/crypto.c
rename to libs/netpgp/src/crypto.c
index 2fdc4651..7e5319d4 100644
--- a/libs/netpgp/crypto.c
+++ b/libs/netpgp/src/crypto.c
@@ -46,7 +46,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "config-netpgp.h"
+#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include
@@ -54,7 +54,7 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: crypto.c,v 1.36 2014/02/17 07:39:19 agc Exp $");
+__RCSID("$NetBSD$");
#endif
#include
@@ -66,12 +66,14 @@ __RCSID("$NetBSD: crypto.c,v 1.36 2014/02/17 07:39:19 agc Exp $");
#include
-#include "types-netpgp.h"
-#include "crypto-netpgp.h"
-#include "readerwriter-netpgp.h"
-#include "memory-netpgp.h"
-#include "netpgpdefs.h"
-#include "signature-netpgp.h"
+#include "netpgp/types.h"
+#include "netpgp/crypto.h"
+#include "netpgp/readerwriter.h"
+#include "netpgp/memory.h"
+#include "netpgp/netpgpdefs.h"
+#include "netpgp/signature.h"
+#include "netpgp/netpgpsdk.h"
+#include "netpgp/validate.h"
/**
\ingroup Core_MPI
@@ -273,7 +275,7 @@ write_parsed_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
if (pgp_get_debug_level(__FILE__)) {
printf("write_parsed_cb: ");
- pgp_print_packet(&cbinfo->printstate, pkt);
+ //pgp_print_packet(&cbinfo->printstate, pkt);
}
if (pkt->tag != PGP_PTAG_CT_UNARMOURED_TEXT && cbinfo->printstate.skipping) {
puts("...end of skip");
@@ -304,7 +306,10 @@ write_parsed_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
return pgp_get_seckey_cb(pkt, cbinfo);
case PGP_GET_PASSPHRASE:
- return cbinfo->cryptinfo.getpassphrase(pkt, cbinfo);
+ if (cbinfo->cryptinfo.getpassphrase) {
+ return cbinfo->cryptinfo.getpassphrase(pkt, cbinfo);
+ }
+ break;
case PGP_PTAG_CT_LITDATA_BODY:
return pgp_litdata_cb(pkt, cbinfo);
@@ -356,6 +361,7 @@ pgp_encrypt_file(pgp_io_t *io,
{
pgp_output_t *output;
pgp_memory_t *inmem;
+ pgp_keyring_t *rcpts;
int fd_out;
__PGP_USED(io);
@@ -374,11 +380,23 @@ pgp_encrypt_file(pgp_io_t *io,
pgp_writer_push_armor_msg(output);
}
+ if ((rcpts = calloc(1, sizeof(*rcpts))) == NULL) {
+ (void) fprintf(io->errs,
+ "netpgp_encrypt_buf: out of memory to create recipients list\n");
+ return 0;
+ }
+ pgp_keyring_add(rcpts, key);
+ if(rcpts->keys == NULL){
+ (void) fprintf(io->errs,
+ "netpgp_encrypt_buf: out of memory to add recipient\n");
+ return 0;
+ }
/* Push the encrypted writer */
- if (!pgp_push_enc_se_ip(output, key, cipher)) {
+ if (!pgp_push_enc_se_ip(output, rcpts, cipher, 0)) {
pgp_memory_free(inmem);
return 0;
}
+ pgp_keyring_free(rcpts);
/* This does the writing */
pgp_write(output, pgp_mem_data(inmem), (unsigned)pgp_mem_len(inmem));
@@ -395,9 +413,10 @@ pgp_memory_t *
pgp_encrypt_buf(pgp_io_t *io,
const void *input,
const size_t insize,
- const pgp_key_t *pubkey,
+ const pgp_keyring_t *pubkeys,
const unsigned use_armour,
- const char *cipher)
+ const char *cipher,
+ unsigned raw)
{
pgp_output_t *output;
pgp_memory_t *outmem;
@@ -417,7 +436,7 @@ pgp_encrypt_buf(pgp_io_t *io,
}
/* Push the encrypted writer */
- pgp_push_enc_se_ip(output, pubkey, cipher);
+ pgp_push_enc_se_ip(output, pubkeys, cipher, raw);
/* This does the writing */
pgp_write(output, input, (unsigned)insize);
@@ -610,3 +629,132 @@ pgp_decrypt_buf(pgp_io_t *io,
/* if we didn't get the passphrase, return NULL */
return (parse->cbinfo.gotpass) ? outmem : NULL;
}
+
+/* Special callback for decrypt and validate */
+static pgp_cb_ret_t
+pgp_decrypt_and_validate_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
+{
+ pgp_cb_ret_t ret_write_cb = PGP_RELEASE_MEMORY;
+ pgp_cb_ret_t ret_validate_cb = PGP_RELEASE_MEMORY;
+
+ ret_write_cb = write_parsed_cb(pkt, cbinfo);
+
+ /* Filter pkt sent to validate callback */
+ switch (pkt->tag) {
+ case PGP_PTAG_CT_LITDATA_BODY:
+ case PGP_PTAG_CT_SIGNED_CLEARTEXT_BODY:
+ case PGP_PTAG_CT_SIGNATURE: /* V3 sigs */
+ case PGP_PTAG_CT_SIGNATURE_FOOTER: /* V4 sigs */
+ ret_validate_cb = validate_data_cb(pkt, cbinfo);
+ break;
+ default:
+ break;
+ }
+
+ /* Only validate_data_cb takes some arguments.
+ * Otherwise, stacked callbacks would have been necessary
+ */
+ return (ret_write_cb == PGP_KEEP_MEMORY ||
+ ret_validate_cb == PGP_KEEP_MEMORY) ?
+ PGP_KEEP_MEMORY : PGP_RELEASE_MEMORY;
+}
+
+/* decrypt and validate an area of memory */
+pgp_memory_t *
+pgp_decrypt_and_validate_buf(pgp_io_t *io,
+ pgp_validation_t *result,
+ const void *input,
+ const size_t insize,
+ pgp_keyring_t *secring,
+ pgp_keyring_t *pubring,
+ const unsigned use_armour,
+ key_id_t **recipients_key_ids,
+ unsigned *recipients_count)
+{
+ // historical code bloat...
+ const unsigned sshkeys = 0;
+ void *passfp = NULL;
+ int numtries = -1;
+ pgp_cbfunc_t *getpassfunc = NULL;
+
+ validate_data_cb_t validation;
+ pgp_stream_t *stream = NULL;
+ pgp_memory_t *outmem;
+ pgp_memory_t *inmem;
+ const int printerrors = 1;
+
+ if (input == NULL) {
+ (void) fprintf(io->errs,
+ "pgp_encrypt_buf: null memory\n");
+ return 0;
+ }
+
+ inmem = pgp_memory_new();
+ pgp_memory_add(inmem, input, insize);
+
+ /* set up to read from memory */
+ pgp_setup_memory_read(io, &stream, inmem,
+ &validation,
+ pgp_decrypt_and_validate_cb,
+ 1);
+
+ /* Set verification reader and handling options */
+ (void) memset(&validation, 0x0, sizeof(validation));
+ validation.result = result;
+ validation.keyring = pubring;
+ validation.mem = pgp_memory_new();
+ pgp_memory_init(validation.mem, 128);
+
+ /* setup for writing decrypted contents */
+ pgp_setup_memory_write(&stream->cbinfo.output, &outmem, insize);
+
+ /* setup keyring and passphrase callback */
+ stream->cbinfo.cryptinfo.secring = secring;
+ stream->cbinfo.cryptinfo.pubring = pubring;
+ stream->cbinfo.passfp = passfp;
+ stream->cbinfo.cryptinfo.getpassphrase = getpassfunc;
+ stream->cbinfo.sshseckey = (sshkeys) ? &secring->keys[0].key.seckey : NULL;
+ stream->cbinfo.numtries = numtries;
+
+ /* Set up armour */
+ if (use_armour) {
+ pgp_reader_push_dearmour(stream);
+ }
+
+ /* Do it */
+ pgp_parse(stream, printerrors);
+
+ /* Unsetup */
+ if (use_armour) {
+ pgp_reader_pop_dearmour(stream);
+ }
+
+ *recipients_count = stream->cbinfo.cryptinfo.recipients_key_idsc;
+ if (*recipients_count == 0) {
+ *recipients_key_ids = NULL;
+ } else {
+ *recipients_key_ids = calloc(sizeof(key_id_t),*recipients_count);
+ if( *recipients_key_ids != NULL)
+ {
+ memcpy(*recipients_key_ids,
+ stream->cbinfo.cryptinfo.recipients_key_idss,
+ sizeof(key_id_t) * *recipients_count);
+ }
+ }
+
+ if( *recipients_key_ids == NULL)
+ {
+ pgp_memory_free(outmem);
+ *recipients_count = 0;
+ outmem = NULL;
+ }
+
+ /* tidy up */
+ pgp_writer_close(stream->cbinfo.output);
+ pgp_output_delete(stream->cbinfo.output);
+
+ pgp_teardown_memory_read(stream, inmem);
+ pgp_memory_free(validation.mem);
+
+ return outmem;
+}
diff --git a/libs/netpgp/src/keyring.c b/libs/netpgp/src/keyring.c
new file mode 100644
index 00000000..35a53e8a
--- /dev/null
+++ b/libs/netpgp/src/keyring.c
@@ -0,0 +1,1644 @@
+/*-
+ * 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
+ */
+#include "netpgp/config-netpgp.h"
+
+#ifdef HAVE_SYS_CDEFS_H
+#include
+#endif
+
+#if defined(__NetBSD__)
+__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
+__RCSID("$NetBSD$");
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include
+#endif
+
+#include
+#include
+#include
+
+#ifdef HAVE_TERMIOS_H
+#include
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include
+#endif
+
+#include "netpgp/types.h"
+#include "netpgp/keyring.h"
+#include "netpgp/packet-parse.h"
+#include "netpgp/signature.h"
+#include "netpgp/netpgpsdk.h"
+#include "netpgp/readerwriter.h"
+#include "netpgp/netpgpdefs.h"
+#include "netpgp/packet.h"
+#include "netpgp/crypto.h"
+#include "netpgp/validate.h"
+#include "netpgp/netpgpdefs.h"
+#include "netpgp/netpgpdigest.h"
+
+
+
+/**
+ \ingroup HighLevel_Keyring
+
+ \brief Creates a new pgp_key_t struct
+
+ \return A new pgp_key_t struct, initialised to zero.
+
+ \note The returned pgp_key_t struct must be freed after use with pgp_keydata_free.
+*/
+
+pgp_key_t *
+pgp_keydata_new(void)
+{
+ return calloc(1, sizeof(pgp_key_t));
+}
+
+
+/**
+ \ingroup HighLevel_Keyring
+
+ \brief Frees key's allocated memory
+
+ \param keydata Key to be freed.
+
+ \note This does not free the keydata itself, but any other memory alloc-ed by it.
+*/
+void
+pgp_key_free(pgp_key_t *key)
+{
+ unsigned n;
+
+ if (key->type == PGP_PTAG_CT_PUBLIC_KEY) {
+ pgp_pubkey_free(&key->key.pubkey);
+ } else {
+ pgp_seckey_free(&key->key.seckey);
+ }
+
+ for (n = 0; n < key->directsigc; ++n) {
+ pgp_free_sig_info(&key->directsigs[n].siginfo);
+ pgp_subpacket_free(&key->directsigs[n].packet);
+ }
+ FREE_ARRAY(key, directsig);
+
+ for (n = 0; n < key->uidc; ++n) {
+ pgp_userid_free(&key->uids[n]);
+ }
+ FREE_ARRAY(key, uid);
+
+ for (n = 0; n < key->uidsigc; ++n) {
+ pgp_free_sig_info(&key->uidsigs[n].siginfo);
+ pgp_subpacket_free(&key->uidsigs[n].packet);
+ }
+ FREE_ARRAY(key, uidsig);
+
+ for (n = 0; n < key->subkeyc; ++n) {
+ if (key->type == PGP_PTAG_CT_PUBLIC_KEY) {
+ pgp_pubkey_free(&key->subkeys[n].key.pubkey);
+ } else {
+ pgp_seckey_free(&key->subkeys[n].key.seckey);
+ }
+ }
+ FREE_ARRAY(key, subkey);
+
+ for (n = 0; n < key->subkeysigc; ++n) {
+ pgp_free_sig_info(&key->subkeysigs[n].siginfo);
+ pgp_subpacket_free(&key->subkeysigs[n].packet);
+ }
+ FREE_ARRAY(key, subkeysig);
+}
+
+/**
+ \ingroup HighLevel_Keyring
+
+ \brief Frees keydata and its memory
+
+ \param keydata Key to be freed.
+
+ \note This frees the keydata itself, as well as any other memory alloc-ed by it.
+*/
+void
+pgp_keydata_free(pgp_key_t *keydata)
+{
+ pgp_key_free(keydata);
+ free(keydata);
+}
+
+static unsigned siginfo_in_time(pgp_sig_info_t *siginfo){
+ time_t now;
+ now = time(NULL);
+ /* in sig validity time frame */
+ return now >= siginfo->birthtime && (
+ siginfo->key_expiry == 0 ||
+ now < siginfo->birthtime +
+ siginfo->key_expiry);
+}
+
+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)
+{
+ unsigned uididx = 0;
+ unsigned uidsigidx = 0;
+ int32_t res = -1; /* Not found */
+ int32_t lastgood;
+ uint8_t **uidp;
+ pgp_uidsig_t *uidsigp;
+ time_t yngst = 0;
+
+ /* If not maximum age given, take default */
+ if(!youngest)
+ youngest = &yngst;
+
+ /* Loop over key's user ids*/
+ uidp = key->uids;
+ for (uididx = 0 ; uididx < key->uidc; uididx++, uidp++)
+ {
+ if(uidcond && !uidcond(*uidp, uidcondarg)) continue;
+
+ lastgood = res;
+ /* 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 uid is revoked */
+ /* revoke on secret keys has no effect*/
+ if(uidsigp->siginfo.type == PGP_SIG_REV_CERT)
+ {
+ /* ignore revocation if secret */
+ if(!checkrevoke)
+ continue;
+
+ /* revert to last good candidate */
+ res = lastgood;
+ break; /* jump to next uid */
+ }
+
+ /* in sig validity time frame */
+ if(!checkexpiry || siginfo_in_time(&uidsigp->siginfo))
+ {
+ /* sig cond is ok ? */
+ if(!sigcond || sigcond(&uidsigp->siginfo, sigcondarg))
+ {
+ /* youngest signature is deciding */
+ if(uidsigp->siginfo.birthtime > *youngest)
+ {
+ *youngest = uidsigp->siginfo.birthtime;
+ res = uididx;
+ }
+ }
+ }
+ }
+ }
+ }
+ return res;
+}
+
+/*
+ * Returns :
+ * -2 not found
+ * -1 match is priamary key
+ * >=0 index of matching valid subkey
+ * */
+const int32_t
+pgp_key_find_key_conds(
+ pgp_key_t *key,
+ unsigned(*keycond) ( const pgp_pubkey_t *, const uint8_t *, void*),
+ void *keycondarg,
+ unsigned(*sigcond) ( const pgp_sig_info_t *, void*),
+ void *sigcondarg,
+ unsigned checkrevoke,
+ unsigned checkexpiry)
+{
+ unsigned subkeyidx = 0;
+ unsigned subkeysigidx = 0;
+ unsigned directsigidx = 0;
+ int32_t res = -2; /* Not found */
+ int32_t lastgood;
+ pgp_subkey_t *subkeyp;
+ pgp_subkeysig_t *subkeysigp;
+ pgp_directsig_t *directsigp;
+ time_t youngest;
+
+ youngest = 0;
+
+ /* check pubkey first */
+ if(!keycond || keycond(pgp_key_get_pubkey(key),
+ key->pubkeyid, keycondarg)){
+
+ int32_t uidres;
+
+ /* Loop over key's direct sigs */
+ directsigp = key->directsigs;
+
+ for (directsigidx = 0 ; directsigidx < key->directsigc;
+ directsigidx++, directsigp++)
+ {
+ /* if direct is revoked */
+ if(directsigp->siginfo.type == PGP_SIG_REV_KEY)
+ {
+ /* ignore revocation if secret */
+ if(!checkrevoke)
+ continue;
+
+ return -2; /* Key is globally revoked, no result */
+ }
+
+ /* in sig validity time frame */
+ if(!checkexpiry || siginfo_in_time(&directsigp->siginfo))
+ {
+ /* condition on sig is ok */
+ if(!sigcond || sigcond(&directsigp->siginfo, sigcondarg))
+ {
+ /* youngest signature is deciding */
+ if(directsigp->siginfo.birthtime > youngest)
+ {
+ youngest = directsigp->siginfo.birthtime;
+ res = -1; /* Primary key is a candidate */
+ }
+ }
+ }
+ }
+
+ uidres = pgp_key_find_uid_cond(
+ key, NULL, NULL, sigcond, sigcondarg, &youngest,
+ checkrevoke, checkexpiry);
+
+ /* if matching uid sig, then primary is matching key */
+ if(uidres != -1){
+ res = -1;
+ }
+ }
+
+ /* Loop over key's subkeys */
+ subkeyp = key->subkeys;
+ for (subkeyidx = 0 ; subkeyidx < key->subkeyc; subkeyidx++, subkeyp++)
+ {
+ lastgood = res;
+
+ subkeysigp = key->subkeysigs;
+
+ /* Skip this subkey if key condition not met */
+ if(keycond && !keycond(&subkeyp->key.pubkey, subkeyp->id, keycondarg))
+ continue;
+
+ /* Loop over key's subkeys sigs */
+ for (subkeysigidx = 0 ; subkeysigidx < key->subkeysigc;
+ subkeysigidx++, subkeysigp++)
+ {
+ /* matching selected subkey */
+ if(subkeysigp->subkey == subkeyidx)
+ {
+ /* if subkey is revoked */
+ if(subkeysigp->siginfo.type == PGP_SIG_REV_SUBKEY)
+ {
+ /* ignore revocation if secret */
+ if(!checkrevoke)
+ continue;
+
+ /* revert to last good candidate */
+ res = lastgood;
+ break; /* jump to next subkey */
+ }
+
+ /* in sig validity time frame */
+ if(!checkexpiry || siginfo_in_time(&subkeysigp->siginfo))
+ {
+ /* subkey sig condition is ok */
+ if(!sigcond || sigcond(&subkeysigp->siginfo, sigcondarg))
+ {
+ /* youngest signature is deciding */
+ if(subkeysigp->siginfo.birthtime > youngest)
+ {
+ youngest = subkeysigp->siginfo.birthtime;
+ res = subkeyidx;
+ }
+ }
+ }
+ }
+ }
+ }
+ return res;
+}
+
+/**
+ \ingroup HighLevel_KeyGeneral
+
+ \brief Returns the public key in the given keydata.
+ \param keydata
+
+ \return Pointer to public key
+
+ \note This is not a copy, do not free it after use.
+*/
+
+pgp_pubkey_t *
+pgp_key_get_pubkey(pgp_key_t *keydata)
+{
+ return (keydata->type == PGP_PTAG_CT_PUBLIC_KEY) ?
+ &keydata->key.pubkey :
+ &keydata->key.seckey.pubkey;
+}
+
+pgp_pubkey_t *
+pgp_key_get_subpubkey(pgp_key_t *key, int32_t subkeyidx)
+{
+ return (key->type == PGP_PTAG_CT_PUBLIC_KEY) ?
+ &key->subkeys[subkeyidx].key.pubkey :
+ &key->subkeys[subkeyidx].key.seckey.pubkey;
+}
+
+pgp_seckey_t *
+pgp_key_get_subseckey(pgp_key_t *key, int32_t subkeyidx)
+{
+ return (key->type == PGP_PTAG_CT_SECRET_KEY) ?
+ &key->subkeys[subkeyidx].key.seckey :
+ NULL;
+}
+static pgp_pubkey_t *
+key_get_pubkey_from_subidx(
+ pgp_key_t *key,
+ const uint8_t **id,
+ int32_t subkeyidx)
+{
+ if(subkeyidx == -2){
+ return NULL;
+ }
+
+ if(subkeyidx != -1)
+ {
+ if(id)
+ *id = key->subkeys[subkeyidx].id;
+
+ return pgp_key_get_subpubkey(key, subkeyidx);
+
+ }
+
+ if(id)
+ *id = key->pubkeyid;
+
+ return pgp_key_get_pubkey(key);
+}
+
+static pgp_seckey_t *
+key_get_seckey_from_subidx(
+ pgp_key_t *key,
+ const uint8_t **id,
+ int32_t subkeyidx)
+{
+ if(subkeyidx == -2){
+ return NULL;
+ }
+
+ if(subkeyidx != -1)
+ {
+ if(id)
+ *id = key->subkeys[subkeyidx].id;
+
+ return pgp_key_get_subseckey(key, subkeyidx);
+
+ }
+
+ if(id)
+ *id = key->pubkeyid;
+
+ return pgp_get_seckey(key);
+}
+
+static unsigned is_signing_role(const pgp_sig_info_t *siginfo, void *arg)
+{
+ return siginfo->key_flags & PGP_KEYFLAG_SIGN_DATA;
+}
+
+/* Get a pub key to check signature */
+pgp_pubkey_t *
+pgp_key_get_sigkey(pgp_key_t *key)
+{
+ int32_t subkeyidx =
+ pgp_key_find_key_conds(key, NULL, NULL, &is_signing_role, NULL, 0, 0);
+ return key_get_pubkey_from_subidx(key, NULL, subkeyidx);
+}
+
+/* Get a sec key to write a signature */
+pgp_seckey_t *
+pgp_key_get_certkey(pgp_key_t *key)
+{
+ int32_t subkeyidx =
+ pgp_key_find_key_conds(key, NULL, NULL, &is_signing_role, NULL, 1, 0);
+ return key_get_seckey_from_subidx(key, NULL, subkeyidx);
+}
+
+static unsigned is_encryption_role(const pgp_sig_info_t *siginfo, void *arg)
+{
+ return siginfo->key_flags & PGP_KEYFLAG_ENC_COMM;
+}
+
+pgp_pubkey_t *
+pgp_key_get_enckey(pgp_key_t *key, const uint8_t **id)
+{
+ int32_t subkeyidx =
+ pgp_key_find_key_conds(key, NULL, NULL, &is_encryption_role, NULL, 1, 0);
+
+ return key_get_pubkey_from_subidx(key, id, subkeyidx);
+}
+
+pgp_seckey_t *
+pgp_key_get_deckey(pgp_key_t *key, const uint8_t **id)
+{
+ int32_t subkeyidx =
+ pgp_key_find_key_conds(key, NULL, NULL, &is_encryption_role, NULL, 0, 0);
+
+ return key_get_seckey_from_subidx(key, id, subkeyidx);
+}
+
+static unsigned primary_uid_sigcond(const pgp_sig_info_t *siginfo, void *arg)
+{
+ return siginfo->primary_userid;
+}
+
+const int32_t pgp_key_get_uid0(pgp_key_t *key)
+{
+ int32_t res =
+ pgp_key_find_uid_cond(key, NULL, NULL, &primary_uid_sigcond, NULL, NULL, 1, 0);
+
+ /* arbitrarily use youngest uid if no primary is found */
+ return res == -1 ?
+ pgp_key_find_uid_cond(key, NULL, NULL, NULL, NULL, NULL, 1, 0):
+ res;
+}
+
+const uint8_t *pgp_key_get_primary_userid(pgp_key_t *key)
+{
+ const int32_t uid0 = pgp_key_get_uid0(key);
+ if( uid0 >= 0 && key->uids && key->uidc > uid0)
+ {
+ return key->uids[uid0];
+ }
+ return NULL;
+}
+
+unsigned key_bit_len(const pgp_pubkey_t *key)
+{
+ switch (key->alg) {
+ case PGP_PKA_DSA:
+ return BN_num_bits(key->key.dsa.p);
+
+ case PGP_PKA_RSA:
+ return BN_num_bits(key->key.rsa.n);
+
+ case PGP_PKA_ELGAMAL:
+ return BN_num_bits(key->key.elgamal.p);
+
+ default:
+ return 0;
+ }
+}
+
+unsigned key_is_weak(
+ const pgp_pubkey_t *key,
+ const uint8_t *keyid,
+ void *arg)
+{
+ unsigned kbl;
+ pgp_key_rating_t *res;
+
+ res = (pgp_key_rating_t*)arg;
+ kbl = key_bit_len(key);
+
+ if(kbl == 0)
+ {
+ *res = PGP_INVALID;
+ }
+ else if(kbl < 1024)
+ {
+ *res = PGP_TOOSHORT;
+ }
+ else if(kbl == 1024 && key->alg == PGP_PKA_RSA)
+ {
+ *res = PGP_WEAK;
+ }
+
+ return 0;
+}
+
+const pgp_key_rating_t pgp_key_get_rating(pgp_key_t *key)
+{
+ /* keys exist in rings only if valid */
+ pgp_key_rating_t res = PGP_VALID;
+
+ pgp_key_find_key_conds(key, &key_is_weak, (void*)&res, NULL, NULL, 0, 0);
+
+ if(res == PGP_VALID)
+ {
+ if(pgp_key_find_key_conds(
+ key, NULL, NULL, NULL, NULL, 1, 0) == -2)
+ {
+ return PGP_REVOKED;
+ }
+ if(pgp_key_find_key_conds(
+ key, NULL, NULL, NULL, NULL, 0, 1) == -2)
+ {
+ return PGP_EXPIRED;
+ }
+ }
+
+ return res;
+}
+/**
+\ingroup HighLevel_KeyGeneral
+
+\brief Check whether this is a secret key or not.
+*/
+
+unsigned
+pgp_is_key_secret(pgp_key_t *data)
+{
+ return data->type != PGP_PTAG_CT_PUBLIC_KEY;
+}
+
+/**
+ \ingroup HighLevel_KeyGeneral
+
+ \brief Returns the secret key in the given keydata.
+
+ \note This is not a copy, do not free it after use.
+
+ \note This returns a const. If you need to be able to write to this
+ pointer, use pgp_get_writable_seckey
+*/
+
+pgp_seckey_t *
+pgp_get_seckey(pgp_key_t *data)
+{
+ return (data->type == PGP_PTAG_CT_SECRET_KEY) ?
+ &data->key.seckey : NULL;
+}
+
+/**
+ \ingroup HighLevel_KeyGeneral
+
+ \brief Returns the secret key in the given keydata.
+
+ \note This is not a copy, do not free it after use.
+
+ \note If you do not need to be able to modify this key, there is an
+ equivalent read-only function pgp_get_seckey.
+*/
+
+pgp_seckey_t *
+pgp_get_writable_seckey(pgp_key_t *data)
+{
+ return (data->type == PGP_PTAG_CT_SECRET_KEY) ?
+ &data->key.seckey : NULL;
+}
+
+/* utility function to zero out memory */
+void
+pgp_forget(void *vp, unsigned size)
+{
+ (void) memset(vp, 0x0, size);
+}
+
+typedef struct {
+ FILE *passfp;
+ const pgp_key_t *key;
+ char *passphrase;
+ pgp_seckey_t *seckey;
+} decrypt_t;
+
+// FIXME : support encrypted seckeys again
+// static pgp_cb_ret_t
+// decrypt_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
+// {
+// const pgp_contents_t *content = &pkt->u;
+// decrypt_t *decrypt;
+// char pass[MAX_PASSPHRASE_LENGTH];
+//
+// decrypt = pgp_callback_arg(cbinfo);
+// switch (pkt->tag) {
+// case PGP_PARSER_PTAG:
+// case PGP_PTAG_CT_USER_ID:
+// case PGP_PTAG_CT_SIGNATURE:
+// case PGP_PTAG_CT_SIGNATURE_HEADER:
+// case PGP_PTAG_CT_SIGNATURE_FOOTER:
+// case PGP_PTAG_CT_TRUST:
+// break;
+//
+// case PGP_GET_PASSPHRASE:
+// (void) pgp_getpassphrase(decrypt->passfp, pass, sizeof(pass));
+// *content->skey_passphrase.passphrase = netpgp_strdup(pass);
+// pgp_forget(pass, (unsigned)sizeof(pass));
+// return PGP_KEEP_MEMORY;
+//
+// case PGP_PARSER_ERRCODE:
+// switch (content->errcode.errcode) {
+// case PGP_E_P_MPI_FORMAT_ERROR:
+// /* Generally this means a bad passphrase */
+// fprintf(stderr, "Bad passphrase!\n");
+// return PGP_RELEASE_MEMORY;
+//
+// case PGP_E_P_PACKET_CONSUMED:
+// /* And this is because of an error we've accepted */
+// return PGP_RELEASE_MEMORY;
+// default:
+// break;
+// }
+// (void) fprintf(stderr, "parse error: %s\n",
+// pgp_errcode(content->errcode.errcode));
+// return PGP_FINISHED;
+//
+// case PGP_PARSER_ERROR:
+// fprintf(stderr, "parse error: %s\n", content->error);
+// return PGP_FINISHED;
+//
+// case PGP_PTAG_CT_SECRET_KEY:
+// if ((decrypt->seckey = calloc(1, sizeof(*decrypt->seckey))) == NULL) {
+// (void) fprintf(stderr, "decrypt_cb: bad alloc\n");
+// return PGP_FINISHED;
+// }
+// decrypt->seckey->checkhash = calloc(1, PGP_CHECKHASH_SIZE);
+// *decrypt->seckey = content->seckey; /* XXX WTF ? */
+// return PGP_KEEP_MEMORY;
+//
+// case PGP_PARSER_PACKET_END:
+// /* nothing to do */
+// break;
+//
+// default:
+// fprintf(stderr, "Unexpected tag %d (0x%x)\n", pkt->tag,
+// pkt->tag);
+// return PGP_FINISHED;
+// }
+//
+// return PGP_RELEASE_MEMORY;
+// }
+
+// FIXME : support encrypted seckeys again
+// /**
+// \ingroup Core_Keys
+// \brief Decrypts secret key from given keydata with given passphrase
+// \param key Key from which to get secret key
+// \param passphrase Passphrase to use to decrypt secret key
+// \return secret key
+// */
+// pgp_seckey_t *
+// pgp_decrypt_seckey(const pgp_key_t *key, void *passfp)
+// {
+// pgp_stream_t *stream;
+// const int printerrors = 1;
+// decrypt_t decrypt;
+//
+// (void) memset(&decrypt, 0x0, sizeof(decrypt));
+// decrypt.key = key;
+// decrypt.passfp = passfp;
+// stream = pgp_new(sizeof(*stream));
+// pgp_keydata_reader_set(stream, key);
+// pgp_set_callback(stream, decrypt_cb, &decrypt);
+// stream->readinfo.accumulate = 1;
+// pgp_parse(stream, !printerrors);
+// return decrypt.seckey;
+// }
+
+/* \todo check where userid pointers are copied */
+/**
+\ingroup Core_Keys
+\brief Copy user id, including contents
+\param dst Destination User ID
+\param src Source User ID
+\note If dst already has a userid, it will be freed.
+*/
+uint8_t *
+pgp_copy_userid(uint8_t **dst, const uint8_t *src)
+{
+ size_t len;
+
+ len = strlen((const char *) src);
+ if (*dst) {
+ free(*dst);
+ }
+ if ((*dst = calloc(1, len + 1)) == NULL) {
+ (void) fprintf(stderr, "pgp_copy_userid: bad alloc\n");
+ } else {
+ (void) memcpy(*dst, src, len);
+ }
+ return *dst;
+}
+
+/* \todo check where pkt pointers are copied */
+/**
+\ingroup Core_Keys
+\brief Copy packet, including contents
+\param dst Destination packet
+\param src Source packet
+\note If dst already has a packet, it will be freed.
+*/
+pgp_subpacket_t *
+pgp_copy_packet(pgp_subpacket_t *dst, const pgp_subpacket_t *src)
+{
+ if (dst->raw) {
+ free(dst->raw);
+ }
+ if ((dst->raw = calloc(1, src->length)) == NULL) {
+ (void) fprintf(stderr, "pgp_copy_packet: bad alloc\n");
+ } else {
+ dst->length = src->length;
+ (void) memcpy(dst->raw, src->raw, src->length);
+ }
+
+ return dst;
+}
+
+#if 0
+/**
+\ingroup Core_Keys
+\brief Add User ID to key
+\param key Key to which to add User ID
+\param userid User ID to add
+\return Pointer to new User ID
+*/
+uint8_t *
+pgp_add_userid(pgp_key_t *key, const uint8_t *userid)
+{
+ uint8_t **uidp;
+
+ EXPAND_ARRAY(key, uid);
+ /* initialise new entry in array */
+ uidp = &key->uids[key->uidc++];
+ *uidp = NULL;
+ /* now copy it */
+ return pgp_copy_userid(uidp, userid);
+}
+#endif
+
+void print_packet_hex(const pgp_subpacket_t *pkt);
+
+/**
+\ingroup Core_Keys
+\brief Add selfsigned User ID to key
+\param keydata Key to which to add user ID
+\param userid Self-signed User ID to add
+\return 1 if OK; else 0
+*/
+unsigned
+pgp_add_selfsigned_userid(pgp_key_t *skey, pgp_key_t *pkey, const uint8_t *userid, time_t key_expiry)
+{
+ pgp_create_sig_t *sig;
+ pgp_subpacket_t sigpacket;
+ pgp_memory_t *mem_sig = NULL;
+ pgp_output_t *sigoutput = NULL;
+
+ /*
+ * create signature packet for this userid
+ */
+
+ /* create sig for this pkt */
+ sig = pgp_create_sig_new();
+ pgp_sig_start_key_sig(sig, &skey->key.seckey.pubkey, userid, PGP_CERT_POSITIVE);
+
+ pgp_add_creation_time(sig, time(NULL));
+ pgp_add_key_expiration_time(sig, key_expiry);
+ pgp_add_issuer_keyid(sig, skey->pubkeyid);
+ pgp_add_primary_userid(sig, 1);
+ pgp_add_key_flags(sig, PGP_KEYFLAG_SIGN_DATA|PGP_KEYFLAG_ENC_COMM);
+ pgp_add_key_prefs(sig);
+ pgp_add_key_features(sig);
+
+ pgp_end_hashed_subpkts(sig);
+
+ pgp_setup_memory_write(&sigoutput, &mem_sig, 128);
+ pgp_write_sig(sigoutput, sig, &skey->key.seckey.pubkey, &skey->key.seckey);
+
+ /* add this packet to key */
+ sigpacket.length = pgp_mem_len(mem_sig);
+ sigpacket.raw = pgp_mem_data(mem_sig);
+
+ /* add user id and signature to key */
+ pgp_update_userid(skey, userid, &sigpacket, &sig->sig.info);
+ if(pkey)
+ pgp_update_userid(pkey, userid, &sigpacket, &sig->sig.info);
+
+ /* cleanup */
+ pgp_create_sig_delete(sig);
+ pgp_output_delete(sigoutput);
+ pgp_memory_free(mem_sig);
+
+ return 1;
+}
+
+unsigned
+pgp_key_revoke(pgp_key_t *skey, pgp_key_t *pkey, uint8_t code, const char *reason)
+{
+ pgp_create_sig_t *sig;
+ pgp_subpacket_t sigpacket;
+ pgp_memory_t *mem_sig = NULL;
+ pgp_output_t *sigoutput = NULL;
+
+ sig = pgp_create_sig_new();
+ pgp_sig_start_key_rev(
+ sig, &skey->key.seckey.pubkey,
+ PGP_SIG_REV_KEY);
+
+ pgp_add_creation_time(sig, time(NULL));
+ pgp_add_issuer_keyid(sig, skey->pubkeyid);
+ pgp_add_revocation_reason(sig, code, reason);
+ pgp_end_hashed_subpkts(sig);
+
+ pgp_setup_memory_write(&sigoutput, &mem_sig, 128);
+ pgp_write_sig(sigoutput, sig, &skey->key.seckey.pubkey, &skey->key.seckey);
+
+ sigpacket.length = pgp_mem_len(mem_sig);
+ sigpacket.raw = pgp_mem_data(mem_sig);
+
+ pgp_add_directsig(skey, &sigpacket, &sig->sig.info);
+ pgp_add_directsig(pkey, &sigpacket, &sig->sig.info);
+
+ /* cleanup */
+ pgp_create_sig_delete(sig);
+ pgp_output_delete(sigoutput);
+ pgp_memory_free(mem_sig);
+
+ return 1;
+}
+
+/**
+\ingroup Core_Keys
+\brief Initialise pgp_key_t
+\param keydata Keydata to initialise
+\param type PGP_PTAG_CT_PUBLIC_KEY or PGP_PTAG_CT_SECRET_KEY
+*/
+void
+pgp_keydata_init(pgp_key_t *keydata, const pgp_content_enum type)
+{
+ if (keydata->type != PGP_PTAG_CT_RESERVED) {
+ (void) fprintf(stderr,
+ "pgp_keydata_init: wrong keydata type\n");
+ } else if (type != PGP_PTAG_CT_PUBLIC_KEY &&
+ type != PGP_PTAG_CT_SECRET_KEY) {
+ (void) fprintf(stderr, "pgp_keydata_init: wrong type\n");
+ } else {
+ keydata->type = type;
+ }
+}
+
+/**
+ \ingroup HighLevel_KeyringRead
+
+ \brief Reads a keyring from a file
+
+ \param keyring Pointer to an existing pgp_keyring_t struct
+ \param armour 1 if file is armoured; else 0
+ \param filename Filename of keyring to be read
+
+ \return pgp 1 if OK; 0 on error
+
+ \note Keyring struct must already exist.
+
+ \note Can be used with either a public or secret keyring.
+
+ \note You must call pgp_keyring_free() after usage to free alloc-ed memory.
+
+ \note If you call this twice on the same keyring struct, without calling
+ pgp_keyring_free() between these calls, you will introduce a memory leak.
+
+ \sa pgp_keyring_read_from_mem()
+ \sa pgp_keyring_free()
+
+*/
+
+unsigned
+pgp_keyring_fileread(pgp_io_t *io,
+ pgp_keyring_t *pubring,
+ pgp_keyring_t *secring,
+ const unsigned armour,
+ const char *filename)
+{
+ return pgp_filter_keys_fileread(
+ io,
+ pubring,
+ secring,
+ NULL /*certring -> self cert */,
+ armour,
+ filename);
+}
+
+/**
+ \ingroup HighLevel_KeyringRead
+
+ \brief Reads a keyring from memory
+
+ \param keyring Pointer to existing pgp_keyring_t struct
+ \param armour 1 if file is armoured; else 0
+ \param mem Pointer to a pgp_memory_t struct containing keyring to be read
+
+ \return pgp 1 if OK; 0 on error
+
+ \note Keyring struct must already exist.
+
+ \note Can be used with either a public or secret keyring.
+
+ \note You must call pgp_keyring_free() after usage to free alloc-ed memory.
+
+ \note If you call this twice on the same keyring struct, without calling
+ pgp_keyring_free() between these calls, you will introduce a memory leak.
+
+ \sa pgp_keyring_fileread
+ \sa pgp_keyring_free
+*/
+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)
+{
+ return pgp_filter_keys_from_mem(io,
+ pubring,
+ secring,
+ NULL /* certring -> self certification */,
+ armour,
+ mem);
+}
+
+/**
+ \ingroup HighLevel_KeyringRead
+
+ \brief Frees keyring's contents (but not keyring itself)
+
+ \param keyring Keyring whose data is to be freed
+
+ \note This does not free keyring itself, just the memory alloc-ed in it.
+ */
+void
+pgp_keyring_free(pgp_keyring_t *keyring)
+{
+ (void)free(keyring->keys);
+ keyring->keys = NULL;
+ keyring->keyc = keyring->keyvsize = 0;
+}
+
+void
+pgp_keyring_purge(pgp_keyring_t *keyring)
+{
+ pgp_key_t *keyp;
+ unsigned c = 0;
+ for (keyp = keyring->keys; c < keyring->keyc; c++, keyp++) {
+ pgp_key_free(keyp);
+ }
+ pgp_keyring_free(keyring);
+}
+
+static unsigned
+deletekey( pgp_keyring_t *keyring, pgp_key_t *key, unsigned from)
+{
+ /* 'from' is index of key to delete */
+
+ /* free key internals */
+ pgp_key_free(key);
+
+ /* decrement key count, vsize stays the same so no realloc needed */
+ keyring->keyc--;
+
+ /* Move following keys to fill the gap */
+ for ( ; keyring && from < keyring->keyc; from += 1) {
+ memcpy(&keyring->keys[from], &keyring->keys[from+1],
+ sizeof(pgp_key_t));
+ }
+
+ return 1;
+}
+
+unsigned key_id_match(const pgp_pubkey_t *key, const uint8_t *keyid, void *refidarg)
+{
+ uint8_t *refid = refidarg;
+ return (memcmp(keyid, refid, PGP_KEY_ID_SIZE) == 0);
+}
+/**
+ \ingroup HighLevel_KeyringFind
+
+ \brief Finds key in keyring from its Key ID
+
+ \param keyring Keyring to be searched
+ \param keyid ID of required key
+
+ \return Pointer to key, if found; NULL, if not found
+
+ \note This returns a pointer to the key inside the given keyring,
+ not a copy. Do not free it after use.
+
+*/
+pgp_key_t *
+pgp_getkeybyid(pgp_io_t *io, const pgp_keyring_t *keyring,
+ const uint8_t *keyid, unsigned *from,
+ pgp_pubkey_t **pubkey,
+ pgp_seckey_t **seckey,
+ unsigned checkrevoke,
+ unsigned checkexpiry)
+{
+ uint8_t nullid[PGP_KEY_ID_SIZE];
+
+ (void) memset(nullid, 0x0, sizeof(nullid));
+ for ( ; keyring && *from < keyring->keyc; *from += 1) {
+ pgp_key_t *key = &keyring->keys[*from];
+ int32_t subkeyidx;
+ if (pgp_get_debug_level(__FILE__)) {
+ hexdump(io->errs, "keyring keyid", key->pubkeyid, PGP_KEY_ID_SIZE);
+ hexdump(io->errs, "keyid", keyid, PGP_KEY_ID_SIZE);
+ }
+
+ subkeyidx = pgp_key_find_key_conds(key, &key_id_match,
+ (void*)keyid, NULL, NULL,
+ checkrevoke, checkexpiry);
+
+ if (subkeyidx != -2) {
+ if (pubkey) {
+ *pubkey = key_get_pubkey_from_subidx(key, NULL, subkeyidx);
+ }
+ if (seckey) {
+ *seckey = key_get_seckey_from_subidx(key, NULL, subkeyidx);
+ }
+ return key;
+ }
+ }
+ return NULL;
+}
+
+unsigned
+pgp_deletekeybyid(pgp_io_t *io, pgp_keyring_t *keyring,
+ const uint8_t *keyid)
+{
+ unsigned from = 0;
+ pgp_key_t *key;
+
+ if ((key = (pgp_key_t *)pgp_getkeybyid(io, keyring, keyid,
+ &from, NULL, NULL, 0, 0)) == NULL) {
+ return 0;
+ }
+ /* 'from' is now index of key to delete */
+
+ deletekey(keyring, key, from);
+
+ return 1;
+}
+
+/**
+ \ingroup HighLevel_KeyringFind
+
+ \brief Finds key in keyring from its Key Fingerprint
+
+ \param keyring Keyring to be searched
+ \param fpr fingerprint of required key
+ \param fpr length of required key
+
+ \return Pointer to key, if found; NULL, if not found
+
+ \note This returns a pointer to the key inside the given keyring,
+ not a copy. Do not free it after use.
+
+*/
+
+pgp_key_t *
+pgp_getkeybyfpr(pgp_io_t *io, const pgp_keyring_t *keyring,
+ const uint8_t *fpr, size_t length,
+ unsigned *from,
+ pgp_pubkey_t **pubkey,
+ unsigned checkrevoke,
+ unsigned checkexpiry)
+{
+
+ for ( ; keyring && *from < keyring->keyc; *from += 1) {
+ pgp_key_t *key = &keyring->keys[*from];
+
+ pgp_fingerprint_t *kfp = &key->pubkeyfpr;
+
+ if (kfp->length == length &&
+ memcmp(kfp->fingerprint, fpr, length) == 0) {
+
+ if(checkrevoke || checkexpiry){
+ int32_t subkeyidx;
+
+ subkeyidx = pgp_key_find_key_conds(key,
+ NULL, NULL,
+ NULL, NULL,
+ checkrevoke, checkexpiry);
+
+ if (subkeyidx == -2) return NULL;
+ }
+ if (pubkey) {
+ *pubkey = &key->key.pubkey;
+ }
+ return key;
+ }
+ }
+ return NULL;
+}
+
+unsigned
+pgp_deletekeybyfpr(pgp_io_t *io, pgp_keyring_t *keyring,
+ const uint8_t *fpr, size_t length)
+{
+ unsigned from = 0;
+ pgp_key_t *key;
+
+ if ((key = (pgp_key_t *)pgp_getkeybyfpr(io, keyring, fpr, length,
+ &from, NULL,0,0)) == NULL) {
+ return 0;
+ }
+ /* 'from' is now index of key to delete */
+
+ deletekey(keyring, key, from);
+
+ return 1;
+}
+
+#if 0
+/* convert a string keyid into a binary keyid */
+static void
+str2keyid(const char *userid, uint8_t *keyid, size_t len)
+{
+ static const char *uppers = "0123456789ABCDEF";
+ static const char *lowers = "0123456789abcdef";
+ const char *hi;
+ const char *lo;
+ uint8_t hichar;
+ uint8_t lochar;
+ size_t j;
+ int i;
+
+ for (i = 0, j = 0 ; j < len && userid[i] && userid[i + 1] ; i += 2, j++) {
+ if ((hi = strchr(uppers, userid[i])) == NULL) {
+ if ((hi = strchr(lowers, userid[i])) == NULL) {
+ break;
+ }
+ hichar = (uint8_t)(hi - lowers);
+ } else {
+ hichar = (uint8_t)(hi - uppers);
+ }
+ if ((lo = strchr(uppers, userid[i + 1])) == NULL) {
+ if ((lo = strchr(lowers, userid[i + 1])) == NULL) {
+ break;
+ }
+ lochar = (uint8_t)(lo - lowers);
+ } else {
+ lochar = (uint8_t)(lo - uppers);
+ }
+ keyid[j] = (hichar << 4) | (lochar);
+ }
+ keyid[j] = 0x0;
+}
+#endif
+
+/* return the next key which matches, starting searching at *from */
+#if 0 //////
+static const pgp_key_t *
+getkeybyname(pgp_io_t *io,
+ const pgp_keyring_t *keyring,
+ const char *name,
+ unsigned *from)
+{
+ //const pgp_key_t *kp;
+ uint8_t **uidp;
+ unsigned i = 0;
+ pgp_key_t *keyp;
+ // unsigned savedstart;
+ regex_t r;
+ //uint8_t keyid[PGP_KEY_ID_SIZE + 1];
+ size_t len;
+
+ if (!keyring || !name || !from) {
+ return NULL;
+ }
+ len = strlen(name);
+ if (pgp_get_debug_level(__FILE__)) {
+ (void) fprintf(io->outs, "[%u] name '%s', len %zu\n",
+ *from, name, len);
+ }
+
+ /* first try name as a keyid */
+ // (void) memset(keyid, 0x0, sizeof(keyid));
+ // str2keyid(name, keyid, sizeof(keyid));
+ // if (pgp_get_debug_level(__FILE__)) {
+ // hexdump(io->outs, "keyid", keyid, 4);
+ // }
+ // savedstart = *from;
+ // if ((kp = pgp_getkeybyid(io, keyring, keyid, from,
+ // NULL, NULL, 0, 0)) != NULL) {
+ // return kp;
+ // }
+ // *from = savedstart;
+
+ if (pgp_get_debug_level(__FILE__) && name != NULL) {
+ (void) fprintf(io->outs, "regex match '%s' from %u\n",
+ name, *from);
+ }
+ /* match on full name or email address as a
+ - NOSUB only success/failure, no match content
+ - LITERAL ignore special chars in given string
+ - ICASE ignore case
+ */
+ if (name != NULL) {
+ (void) regcomp(&r, name, REG_NOSUB | REG_LITERAL | REG_ICASE);
+ }
+ if(keyring->keys != NULL)
+ for (keyp = &keyring->keys[*from]; *from < keyring->keyc; *from += 1, keyp++) {
+ uidp = keyp->uids;
+ if (name == NULL) {
+ return keyp;
+ } else {
+ for (i = 0 ; i < keyp->uidc; i++, uidp++) {
+ if (regexec(&r, (char *)*uidp, 0, NULL, 0) == 0) {
+ if (pgp_get_debug_level(__FILE__)) {
+ (void) fprintf(io->outs,
+ "MATCHED keyid \"%s\" len %" PRIsize "u\n",
+ (char *) *uidp, len);
+ }
+ regfree(&r);
+ return keyp;
+ }
+ }
+ }
+ }
+ regfree(&r);
+ return NULL;
+}
+#endif //////
+
+/**
+ \ingroup HighLevel_KeyringFind
+
+ \brief Finds key from its User ID
+
+ \param keyring Keyring to be searched
+ \param userid User ID of required key
+
+ \return Pointer to Key, if found; NULL, if not found
+
+ \note This returns a pointer to the key inside the keyring, not a
+ copy. Do not free it.
+
+*/
+#if 0 //////
+const pgp_key_t *
+pgp_getkeybyname(pgp_io_t *io,
+ const pgp_keyring_t *keyring,
+ const char *name)
+{
+ unsigned from;
+
+ from = 0;
+ return getkeybyname(io, keyring, name, &from);
+}
+#endif //////
+
+#if 0 //////
+const pgp_key_t *
+pgp_getnextkeybyname(pgp_io_t *io,
+ const pgp_keyring_t *keyring,
+ const char *name,
+ unsigned *n)
+{
+ return getkeybyname(io, keyring, name, n);
+}
+#endif //////
+
+/* this interface isn't right - hook into callback for getting passphrase */
+#if 0 //////
+char *
+pgp_export_key(pgp_io_t *io, const pgp_key_t *keydata, uint8_t *passphrase)
+{
+ pgp_output_t *output;
+ pgp_memory_t *mem;
+ char *cp;
+
+ __PGP_USED(io);
+ pgp_setup_memory_write(&output, &mem, 128);
+ pgp_write_xfer_key(output, keydata, 1);
+
+ /* TODO deal with passphrase again
+ pgp_write_xfer_seckey(output, keydata, passphrase,
+ strlen((char *)passphrase), 1);
+ */
+ cp = netpgp_strdup(pgp_mem_data(mem));
+ pgp_teardown_memory_write(output, mem);
+ return cp;
+}
+#endif //////
+
+/* lowlevel add to keyring */
+int
+pgp_keyring_add(pgp_keyring_t *dst, const pgp_key_t *src)
+{
+ pgp_key_t *key;
+
+ EXPAND_ARRAY(dst, key);
+ key = &dst->keys[dst->keyc++];
+ memcpy(key, src, sizeof(*key));
+ return 1;
+}
+
+pgp_key_t *pgp_ensure_pubkey(
+ pgp_keyring_t *keyring,
+ pgp_pubkey_t *pubkey,
+ uint8_t *pubkeyid)
+{
+ pgp_key_t *key;
+ unsigned c;
+
+ if(keyring == NULL) return NULL;
+
+ /* try to find key in keyring */
+ for (c = 0; c < keyring->keyc; c += 1) {
+ if (memcmp(keyring->keys[c].pubkeyid,
+ pubkeyid, PGP_KEY_ID_SIZE) == 0) {
+ return &keyring->keys[c];
+ }
+ }
+
+ /* if key doesn't already exist in keyring, create it */
+ EXPAND_ARRAY(keyring, key);
+ key = &keyring->keys[keyring->keyc++];
+ (void) memset(key, 0x0, sizeof(*key));
+
+ /* fill in what we already know */
+ key->type = PGP_PTAG_CT_PUBLIC_KEY;
+ pgp_pubkey_dup(&key->key.pubkey, pubkey);
+ (void) memcpy(&key->pubkeyid, pubkeyid, PGP_KEY_ID_SIZE);
+ pgp_fingerprint(&key->pubkeyfpr, pubkey, keyring->hashtype);
+
+ return key;
+}
+
+pgp_key_t *pgp_ensure_seckey(
+ pgp_keyring_t *keyring,
+ pgp_seckey_t *seckey,
+ uint8_t *pubkeyid)
+{
+ pgp_key_t *key;
+ unsigned c;
+
+ if (keyring == NULL) return NULL;
+
+ /* try to find key in keyring */
+ for (c = 0; c < keyring->keyc; c += 1) {
+ if (memcmp(keyring->keys[c].pubkeyid,
+ pubkeyid, PGP_KEY_ID_SIZE) == 0) {
+ return &keyring->keys[c];
+ }
+ }
+
+ /* if key doesn't already exist in keyring, create it */
+ EXPAND_ARRAY(keyring, key);
+ key = &keyring->keys[keyring->keyc++];
+ (void) memset(key, 0x0, sizeof(*key));
+
+ /* fill in what we already know */
+ key->type = PGP_PTAG_CT_SECRET_KEY;
+ pgp_seckey_dup(&key->key.seckey, seckey);
+ (void) memcpy(&key->pubkeyid, pubkeyid, PGP_KEY_ID_SIZE);
+ pgp_fingerprint(&key->pubkeyfpr, &seckey->pubkey, keyring->hashtype);
+
+ return key;
+}
+
+unsigned pgp_add_directsig(
+ pgp_key_t *key,
+ const pgp_subpacket_t *sigpkt,
+ pgp_sig_info_t *siginfo)
+{
+ pgp_directsig_t *directsigp;
+ unsigned directsigidx;
+
+ /* Detect duplicate direct sig */
+ directsigp = key->directsigs;
+ for (directsigidx = 0 ; directsigidx < key->directsigc;
+ directsigidx++, directsigp++)
+ {
+ if( directsigp->packet.length == sigpkt->length &&
+ memcmp(directsigp->packet.raw, sigpkt->raw, sigpkt->length) == 0)
+ {
+ /* signature already exist */
+ return 1;
+ }
+ }
+
+
+ EXPAND_ARRAY(key, directsig);
+ directsigp = &key->directsigs[key->directsigc++];
+
+ copy_sig_info(&directsigp->siginfo,
+ siginfo);
+ pgp_copy_packet(&directsigp->packet, sigpkt);
+
+ return 0;
+}
+
+unsigned pgp_update_userid(
+ pgp_key_t *key,
+ const uint8_t *userid,
+ const pgp_subpacket_t *sigpkt,
+ pgp_sig_info_t *siginfo)
+{
+ unsigned uididx = 0;
+ unsigned uidsigidx = 0;
+ uint8_t **uidp;
+ pgp_uidsig_t *uidsigp;
+
+ /* Try to find identical userID */
+ uidp = key->uids;
+ for (uididx = 0 ; uididx < key->uidc; uididx++, uidp++)
+ {
+ if (strcmp((char *)*uidp, (char *)userid) == 0)
+ {
+ /* Found one. check for duplicate uidsig */
+ uidsigp = key->uidsigs;
+ for (uidsigidx = 0 ; uidsigidx < key->uidsigc;
+ uidsigidx++, uidsigp++)
+ {
+ if(uidsigp->uid == uididx &&
+ uidsigp->packet.length == sigpkt->length &&
+ memcmp(uidsigp->packet.raw, sigpkt->raw,
+ sigpkt->length) == 0)
+ {
+ /* signature already exists */
+ return 1;
+ }
+ }
+ break;
+ }
+ }
+
+ /* Add a new one if none found */
+ if(uididx==key->uidc){
+ EXPAND_ARRAY(key, uid);
+ uidp = &key->uids[key->uidc++];
+ *uidp = NULL;
+ pgp_copy_userid(uidp, userid);
+ }
+
+ /* Add uid sig info, pointing to that uid */
+ EXPAND_ARRAY(key, uidsig);
+ uidsigp = &key->uidsigs[key->uidsigc++];
+ uidsigp->uid = uididx;
+
+ /* store sig info and packet */
+ copy_sig_info(&uidsigp->siginfo, siginfo);
+ pgp_copy_packet(&uidsigp->packet, sigpkt);
+
+ return 0;
+}
+
+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)
+{
+ unsigned subkeyidx = 0;
+ unsigned subkeysigidx = 0;
+ pgp_subkey_t *subkeyp;
+ pgp_subkeysig_t *subkeysigp;
+ uint8_t subkeyid[PGP_KEY_ID_SIZE];
+
+ pgp_keyid(subkeyid, PGP_KEY_ID_SIZE,
+ (subkeytype == PGP_PTAG_CT_PUBLIC_KEY) ?
+ &subkey->pubkey:
+ &subkey->seckey.pubkey, PGP_HASH_SHA1);
+
+ /* Try to find identical subkey ID */
+ subkeyp = key->subkeys;
+ for (subkeyidx = 0 ; subkeyidx < key->subkeyc; subkeyidx++, subkeyp++)
+ {
+ if(memcmp(subkeyid, subkeyp->id, PGP_KEY_ID_SIZE) == 0 )
+ {
+ /* Found same subkey. Detect duplicate sig */
+ subkeysigp = key->subkeysigs;
+ for (subkeysigidx = 0 ; subkeysigidx < key->subkeysigc;
+ subkeysigidx++, subkeysigp++)
+ {
+ if(subkeysigp->subkey == subkeyidx &&
+ subkeysigp->packet.length == sigpkt->length &&
+ memcmp(subkeysigp->packet.raw, sigpkt->raw,
+ sigpkt->length) == 0)
+ {
+ /* signature already exists */
+ return 1;
+ }
+ }
+
+ break;
+ }
+ }
+ /* Add a new one if none found */
+ if(subkeyidx==key->subkeyc){
+ if(subkeytype == PGP_PTAG_CT_PUBLIC_KEY &&
+ key->type != PGP_PTAG_CT_PUBLIC_KEY){
+ /* cannot create secret subkey from public */
+ /* and may not insert public subkey in seckey */
+ return 1;
+ }
+
+ EXPAND_ARRAY(key, subkey);
+ subkeyp = &key->subkeys[key->subkeyc++];
+ /* copy subkey material */
+ if(key->type == PGP_PTAG_CT_PUBLIC_KEY) {
+ pgp_pubkey_dup(&subkeyp->key.pubkey,
+ (subkeytype == PGP_PTAG_CT_PUBLIC_KEY) ?
+ &subkey->pubkey:
+ &subkey->seckey.pubkey);
+ } else {
+ pgp_seckey_dup(&subkeyp->key.seckey, &subkey->seckey);
+ }
+ /* copy subkeyID */
+ memcpy(subkeyp->id, subkeyid, PGP_KEY_ID_SIZE);
+ }
+
+ /* Add subkey sig info, pointing to that subkey */
+ EXPAND_ARRAY(key, subkeysig);
+ subkeysigp = &key->subkeysigs[key->subkeysigc++];
+ subkeysigp->subkey = subkeyidx;
+
+ /* store sig info and packet */
+ copy_sig_info(&subkeysigp->siginfo,
+ siginfo);
+ pgp_copy_packet(&subkeysigp->packet, sigpkt);
+
+ return 0;
+}
+
+/* append one keyring to another */
+int
+pgp_append_keyring(pgp_keyring_t *keyring, pgp_keyring_t *newring)
+{
+ unsigned i;
+
+ for (i = 0 ; i < newring->keyc ; i++) {
+ EXPAND_ARRAY(keyring, key);
+ (void) memcpy(&keyring->keys[keyring->keyc], &newring->keys[i],
+ sizeof(newring->keys[i]));
+ keyring->keyc += 1;
+ }
+ return 1;
+}
diff --git a/libs/netpgp/misc.c b/libs/netpgp/src/misc.c
similarity index 90%
rename from libs/netpgp/misc.c
rename to libs/netpgp/src/misc.c
index a610681f..256d1c33 100644
--- a/libs/netpgp/misc.c
+++ b/libs/netpgp/src/misc.c
@@ -49,7 +49,7 @@
/** \file
*/
-#include "config-netpgp.h"
+#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include
@@ -57,7 +57,7 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: misc.c,v 1.41 2012/03/05 02:20:18 christos Exp $");
+__RCSID("$NetBSD$");
#endif
#include
@@ -78,123 +78,24 @@ __RCSID("$NetBSD: misc.c,v 1.41 2012/03/05 02:20:18 christos Exp $");
#include
#endif
-#include "errors-netpgp.h"
-#include "packet-netpgp.h"
-#include "crypto-netpgp.h"
-#include "create-netpgp.h"
-#include "packet-parse.h"
-#include "packet-show.h"
-#include "signature-netpgp.h"
-#include "netpgpsdk.h"
-#include "netpgpdefs.h"
-#include "memory-netpgp.h"
-#include "readerwriter-netpgp.h"
-#include "version-netpgp.h"
-#include "netpgpdigest.h"
+#include "netpgp/errors.h"
+#include "netpgp/packet.h"
+#include "netpgp/crypto.h"
+#include "netpgp/create.h"
+#include "netpgp/packet-parse.h"
+#include "netpgp/packet-show.h"
+#include "netpgp/signature.h"
+#include "netpgp/netpgpsdk.h"
+#include "netpgp/netpgpdefs.h"
+#include "netpgp/memory.h"
+#include "netpgp/readerwriter.h"
+#include "netpgp/version.h"
+#include "netpgp/netpgpdigest.h"
#ifdef WIN32
#define vsnprintf _vsnprintf
#endif
-
-typedef struct {
- pgp_keyring_t *keyring;
-} accumulate_t;
-
-/**
- * \ingroup Core_Callbacks
- */
-static pgp_cb_ret_t
-accumulate_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
-{
- const pgp_contents_t *content = &pkt->u;
- pgp_keyring_t *keyring;
- accumulate_t *accumulate;
-
- if (pgp_get_debug_level(__FILE__)) {
- (void) fprintf(stderr, "accumulate callback: packet tag %u\n", pkt->tag);
- }
- accumulate = pgp_callback_arg(cbinfo);
- keyring = accumulate->keyring;
- switch (pkt->tag) {
- case PGP_PTAG_CT_PUBLIC_KEY:
- case PGP_PTAG_CT_PUBLIC_SUBKEY:
- pgp_add_to_pubring(keyring, &content->pubkey, pkt->tag);
- return PGP_KEEP_MEMORY;
- case PGP_PTAG_CT_SECRET_KEY:
- case PGP_PTAG_CT_ENCRYPTED_SECRET_KEY:
- pgp_add_to_secring(keyring, &content->seckey);
- return PGP_KEEP_MEMORY;
- case PGP_PTAG_CT_USER_ID:
- if (pgp_get_debug_level(__FILE__)) {
- (void) fprintf(stderr, "User ID: %s for key %d\n",
- content->userid,
- keyring->keyc - 1);
- }
- if (keyring->keyc == 0) {
- PGP_ERROR_1(cbinfo->errors, PGP_E_P_NO_USERID, "%s",
- "No userid found");
- } else {
- pgp_add_userid(&keyring->keys[keyring->keyc - 1], content->userid);
- }
- return PGP_KEEP_MEMORY;
- case PGP_PARSER_PACKET_END:
- if (keyring->keyc > 0) {
- pgp_add_subpacket(&keyring->keys[keyring->keyc - 1],
- &content->packet);
- return PGP_KEEP_MEMORY;
- }
- return PGP_RELEASE_MEMORY;
- case PGP_PARSER_ERROR:
- (void) fprintf(stderr, "Error: %s\n", content->error);
- return PGP_FINISHED;
- case PGP_PARSER_ERRCODE:
- (void) fprintf(stderr, "parse error: %s\n",
- pgp_errcode(content->errcode.errcode));
- break;
- default:
- break;
- }
- /* XXX: we now exclude so many things, we should either drop this or */
- /* do something to pass on copies of the stuff we keep */
- return pgp_stacked_callback(pkt, cbinfo);
-}
-
-/**
- * \ingroup Core_Parse
- *
- * Parse packets from an input stream until EOF or error.
- *
- * Key data found in the parsed data is added to #keyring.
- *
- * \param keyring Pointer to an existing keyring
- * \param parse Options to use when parsing
-*/
-int
-pgp_parse_and_accumulate(pgp_keyring_t *keyring, pgp_stream_t *parse)
-{
- accumulate_t accumulate;
- const int printerrors = 1;
- int ret;
-
- if (parse->readinfo.accumulate) {
- (void) fprintf(stderr,
- "pgp_parse_and_accumulate: already init\n");
- return 0;
- }
-
- (void) memset(&accumulate, 0x0, sizeof(accumulate));
-
- accumulate.keyring = keyring;
-
- pgp_callback_push(parse, accumulate_cb, &accumulate);
- parse->readinfo.accumulate = 1;
- ret = pgp_parse(parse, !printerrors);
-
- return ret;
-}
-
-
/** \file
* \brief Error Handling
*/
@@ -597,7 +498,7 @@ pgp_hash_add_int(pgp_hash_t *hash, unsigned n, unsigned length)
\param hash Hash to set up
\param alg Hash algorithm to use
*/
-void
+unsigned
pgp_hash_any(pgp_hash_t *hash, pgp_hash_alg_t alg)
{
switch (alg) {
@@ -627,7 +528,9 @@ pgp_hash_any(pgp_hash_t *hash, pgp_hash_alg_t alg)
default:
(void) fprintf(stderr, "pgp_hash_any: bad algorithm\n");
+ return 0;
}
+ return 1;
}
/**
diff --git a/libs/netpgp/src/netpgp.c b/libs/netpgp/src/netpgp.c
new file mode 100644
index 00000000..5e68e60b
--- /dev/null
+++ b/libs/netpgp/src/netpgp.c
@@ -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
+#endif
+
+#if defined(__NetBSD__)
+__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
+__RCSID("$NetBSD$");
+#endif
+
+#include
+#include
+#include
+#include
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef HAVE_UNISTD_H
+#include
+#endif
+
+#include
+
+#ifdef HAVE_LIMITS_H
+#include
+#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, "") == 0) {
+ io->outs = stderr;
+ }
+ io->errs = stderr;
+ if ((stream = netpgp_getvar(netpgp, "errs")) != NULL &&
+ strcmp(stream, "") == 0) {
+ io->errs = stdout;
+ }
+ if ((results = netpgp_getvar(netpgp, "res")) == NULL) {
+ io->res = io->errs;
+ } else if (strcmp(results, "") == 0) {
+ io->res = stdout;
+ } else if (strcmp(results, "") == 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;
+}
diff --git a/libs/netpgp/openssl_crypto.c b/libs/netpgp/src/openssl_crypto.c
similarity index 82%
rename from libs/netpgp/openssl_crypto.c
rename to libs/netpgp/src/openssl_crypto.c
index 8c75eb26..6df937bb 100644
--- a/libs/netpgp/openssl_crypto.c
+++ b/libs/netpgp/src/openssl_crypto.c
@@ -49,7 +49,7 @@
/** \file
*/
-#include "config-netpgp.h"
+#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include
@@ -57,7 +57,7 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: openssl_crypto.c,v 1.33 2010/11/07 08:39:59 agc Exp $");
+__RCSID("$NetBSD$");
#endif
#ifdef HAVE_OPENSSL_DSA_H
@@ -82,25 +82,28 @@ __RCSID("$NetBSD: openssl_crypto.c,v 1.33 2010/11/07 08:39:59 agc Exp $");
#include
#endif
-#include "crypto-netpgp.h"
-#include "keyring-netpgp.h"
-#include "readerwriter-netpgp.h"
-#include "netpgpdefs.h"
-#include "netpgpdigest.h"
-#include "packet-netpgp.h"
+#include "netpgp/crypto.h"
+#include "netpgp/keyring.h"
+#include "netpgp/readerwriter.h"
+#include "netpgp/netpgpdefs.h"
+#include "netpgp/netpgpdigest.h"
+#include "netpgp/packet.h"
+#include "netpgp/openssl11stub.h"
static void
test_seckey(const pgp_seckey_t *seckey)
{
- RSA *test = RSA_new();
+ RSA *test = RSA_new();
- test->n = BN_dup(seckey->pubkey.key.rsa.n);
- test->e = BN_dup(seckey->pubkey.key.rsa.e);
+ RSA_set0_key(test,
+ BN_dup(seckey->pubkey.key.rsa.n),
+ BN_dup(seckey->pubkey.key.rsa.e),
+ BN_dup(seckey->key.rsa.d));
- test->d = BN_dup(seckey->key.rsa.d);
- test->p = BN_dup(seckey->key.rsa.p);
- test->q = BN_dup(seckey->key.rsa.q);
+ RSA_set0_factors(test,
+ BN_dup(seckey->key.rsa.p),
+ BN_dup(seckey->key.rsa.q));
if (RSA_check_key(test) != 1) {
(void) fprintf(stderr,
@@ -440,20 +443,25 @@ pgp_dsa_verify(const uint8_t *hash, size_t hash_length,
int ret;
osig = DSA_SIG_new();
- osig->r = sig->r;
- osig->s = sig->s;
+ DSA_SIG_set0(osig,
+ BN_dup(sig->r),
+ BN_dup(sig->s));
odsa = DSA_new();
- odsa->p = dsa->p;
- odsa->q = dsa->q;
- odsa->g = dsa->g;
- odsa->pub_key = dsa->y;
+ DSA_set0_pqg(odsa,
+ BN_dup(dsa->p),
+ BN_dup(dsa->q),
+ BN_dup(dsa->g));
+
+ DSA_set0_key(odsa,
+ BN_dup(dsa->y),
+ NULL);
if (pgp_get_debug_level(__FILE__)) {
hexdump(stderr, "input hash", hash, hash_length);
- (void) fprintf(stderr, "Q=%d\n", BN_num_bytes(odsa->q));
+ (void) fprintf(stderr, "Q=%d\n", BN_num_bytes(dsa->q));
}
- if ((qlen = (unsigned)BN_num_bytes(odsa->q)) < hash_length) {
+ if ((qlen = (unsigned)BN_num_bytes(dsa->q)) < hash_length) {
hash_length = qlen;
}
ret = DSA_do_verify(hash, (int)hash_length, osig, odsa);
@@ -465,10 +473,8 @@ pgp_dsa_verify(const uint8_t *hash, size_t hash_length,
return 0;
}
- odsa->p = odsa->q = odsa->g = odsa->pub_key = NULL;
DSA_free(odsa);
- osig->r = osig->s = NULL;
DSA_SIG_free(osig);
return (unsigned)ret;
@@ -493,12 +499,14 @@ pgp_rsa_public_decrypt(uint8_t *out,
int n;
orsa = RSA_new();
- orsa->n = pubkey->n;
- orsa->e = pubkey->e;
+ RSA_set0_key(orsa,
+ BN_dup(pubkey->n),
+ BN_dup(pubkey->e),
+ NULL);
+
n = RSA_public_decrypt((int)length, in, out, orsa, RSA_NO_PADDING);
- orsa->n = orsa->e = NULL;
RSA_free(orsa);
return n;
@@ -525,20 +533,19 @@ pgp_rsa_private_encrypt(uint8_t *out,
int n;
orsa = RSA_new();
- orsa->n = BN_dup(pubkey->n);
- orsa->d = seckey->d;
- orsa->p = seckey->q; /* p and q are round the other way in openssl */
- orsa->q = seckey->p;
+
+ RSA_set0_key(orsa,
+ BN_dup(pubkey->n),
+ BN_dup(pubkey->e),
+ BN_dup(seckey->d));
+
+ /* p and q are round the other way in openssl */
+ RSA_set0_factors(orsa,
+ /* q */ BN_dup(seckey->p),
+ /* p */ BN_dup(seckey->q));
+
/* debug */
- orsa->e = BN_dup(pubkey->e);
- /* If this isn't set, it's very likely that the programmer hasn't */
- /* decrypted the secret key. RSA_check_key segfaults in that case. */
- /* Use pgp_decrypt_seckey() to do that. */
- if (orsa->d == NULL) {
- (void) fprintf(stderr, "orsa is not set\n");
- return 0;
- }
if (RSA_check_key(orsa) != 1) {
(void) fprintf(stderr, "RSA_check_key is not set\n");
return 0;
@@ -547,7 +554,6 @@ pgp_rsa_private_encrypt(uint8_t *out,
n = RSA_private_encrypt((int)length, in, out, orsa, RSA_NO_PADDING);
- orsa->n = orsa->d = orsa->p = orsa->q = NULL;
RSA_free(orsa);
return n;
@@ -575,13 +581,16 @@ pgp_rsa_private_decrypt(uint8_t *out,
char errbuf[1024];
keypair = RSA_new();
- keypair->n = pubkey->n; /* XXX: do we need n? */
- keypair->d = seckey->d;
- keypair->p = seckey->q;
- keypair->q = seckey->p;
+ RSA_set0_key(keypair,
+ BN_dup(pubkey->n),
+ BN_dup(pubkey->e),
+ BN_dup(seckey->d));
+
+ RSA_set0_factors(keypair,
+ BN_dup(seckey->p),
+ BN_dup(seckey->q));
/* debug */
- keypair->e = pubkey->e;
if (RSA_check_key(keypair) != 1) {
(void) fprintf(stderr, "RSA_check_key is not set\n");
return 0;
@@ -601,7 +610,6 @@ pgp_rsa_private_decrypt(uint8_t *out,
ERR_error_string(err, &errbuf[0]);
(void) fprintf(stderr, "openssl error : %s\n", errbuf);
}
- keypair->n = keypair->d = keypair->p = keypair->q = NULL;
RSA_free(keypair);
return n;
@@ -627,8 +635,10 @@ pgp_rsa_public_encrypt(uint8_t *out,
/* printf("pgp_rsa_public_encrypt: length=%ld\n", length); */
orsa = RSA_new();
- orsa->n = pubkey->n;
- orsa->e = pubkey->e;
+ RSA_set0_key(orsa,
+ BN_dup(pubkey->n),
+ BN_dup(pubkey->e),
+ NULL);
/* printf("len: %ld\n", length); */
/* pgp_print_bn("n: ", orsa->n); */
@@ -641,7 +651,6 @@ pgp_rsa_public_encrypt(uint8_t *out,
fd_out = BIO_new_fd(fileno(stderr), BIO_NOCLOSE);
ERR_print_errors(fd_out);
}
- orsa->n = orsa->e = NULL;
RSA_free(orsa);
return n;
@@ -656,8 +665,8 @@ pgp_rsa_public_encrypt(uint8_t *out,
void
pgp_crypto_finish(void)
{
- CRYPTO_cleanup_all_ex_data();
- ERR_remove_state((unsigned long)0);
+ // No cleanup since OpenSSL 1.1.0
+ // CRYPTO_cleanup_all_ex_data();
}
/**
@@ -682,17 +691,25 @@ pgp_text_from_hash(pgp_hash_t *hash)
\note It is the caller's responsibility to call pgp_keydata_free(keydata)
*/
unsigned
-rsa_generate_keypair(pgp_key_t *keydata,
+pgp_rsa_generate_keypair(pgp_key_t *keydata,
const int numbits,
const unsigned long e__,
const char *hashalg,
- const char *cipher)
+ const char *cipher,
+ const uint8_t *passphrase,
+ const size_t pplen)
{
pgp_seckey_t *seckey;
- RSA *rsa = RSA_new();
+ RSA *rsa;
BN_CTX *ctx;
pgp_output_t *output;
pgp_memory_t *mem;
+ int res;
+ const BIGNUM *_n = NULL;
+ const BIGNUM *_e = NULL;
+ const BIGNUM *_d = NULL;
+ const BIGNUM *_p = NULL;
+ const BIGNUM *_q = NULL;
ctx = BN_CTX_new();
pgp_keydata_init(keydata, PGP_PTAG_CT_SECRET_KEY);
@@ -700,14 +717,29 @@ rsa_generate_keypair(pgp_key_t *keydata,
/* generate the key pair */
- //rsa = RSA_generate_key(numbits, e, NULL, NULL);
- /* generate key */
- BIGNUM* e = BN_new();
- BN_set_word(e, e__);
- if( RSA_generate_key_ex(rsa, numbits, e, 0) != 1 ) {
+ BIGNUM *exp = BN_new();
+ BN_set_word(exp, e__);
+ /*
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ exp = BN_bin2bn((const unsigned char *)&e, sizeof(e), NULL);
+#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ exp = BN_lebin2bn((const unsigned char *)&e, sizeof(e), NULL);
+#else
+#error Unsupported endian
+#endif
+ if (!exp)
+ return 0;
+ */
+
+ rsa = RSA_new();
+ res = RSA_generate_key_ex(rsa, numbits, exp, NULL);
+
+ BN_free(exp);
+
+ if (!res){
+ RSA_free(rsa);
return 0;
- }
- BN_free(e);
+ };
/* populate pgp key from ssl key */
@@ -716,11 +748,14 @@ rsa_generate_keypair(pgp_key_t *keydata,
seckey->pubkey.days_valid = 0;
seckey->pubkey.alg = PGP_PKA_RSA;
- seckey->pubkey.key.rsa.n = BN_dup(rsa->n);
- seckey->pubkey.key.rsa.e = BN_dup(rsa->e);
+ RSA_get0_key(rsa, &_n, &_e, &_d);
- seckey->s2k_usage = PGP_S2KU_ENCRYPTED_AND_HASHED;
- seckey->s2k_specifier = PGP_S2KS_SALTED;
+ seckey->pubkey.key.rsa.n = BN_dup(_n);
+ seckey->pubkey.key.rsa.e = BN_dup(_e);
+
+ /* seckey->s2k_usage = PGP_S2KU_ENCRYPTED_AND_HASHED; */
+ seckey->s2k_usage = PGP_S2KU_NONE;
+ /* seckey->s2k_specifier = PGP_S2KS_SALTED;*/
/* seckey->s2k_specifier=PGP_S2KS_SIMPLE; */
if ((seckey->hash_alg = pgp_str_to_hash_alg(hashalg)) == PGP_HASH_UNKNOWN) {
seckey->hash_alg = PGP_HASH_SHA1;
@@ -729,20 +764,22 @@ rsa_generate_keypair(pgp_key_t *keydata,
seckey->octetc = 0;
seckey->checksum = 0;
- seckey->key.rsa.d = BN_dup(rsa->d);
- seckey->key.rsa.p = BN_dup(rsa->p);
- seckey->key.rsa.q = BN_dup(rsa->q);
- seckey->key.rsa.u = BN_mod_inverse(NULL, rsa->p, rsa->q, ctx);
+ RSA_get0_factors(rsa, &_p, &_q);
+ seckey->key.rsa.d = BN_dup(_d);
+ seckey->key.rsa.p = BN_dup(_p);
+ seckey->key.rsa.q = BN_dup(_q);
+ seckey->key.rsa.u = BN_mod_inverse(NULL, _p, _q, ctx);
if (seckey->key.rsa.u == NULL) {
- //(void) fprintf(stderr, "seckey->key.rsa.u is NULL\n");
+ RSA_free(rsa);
+ (void) fprintf(stderr, "seckey->key.rsa.u is NULL\n");
return 0;
}
BN_CTX_free(ctx);
RSA_free(rsa);
- pgp_keyid(keydata->sigid, PGP_KEY_ID_SIZE, &keydata->key.seckey.pubkey, seckey->hash_alg);
- pgp_fingerprint(&keydata->sigfingerprint, &keydata->key.seckey.pubkey, seckey->hash_alg);
+ pgp_keyid(keydata->pubkeyid, PGP_KEY_ID_SIZE, &keydata->key.seckey.pubkey, seckey->hash_alg);
+ pgp_fingerprint(&keydata->pubkeyfpr, &keydata->key.seckey.pubkey, seckey->hash_alg);
/* Generate checksum */
@@ -797,7 +834,7 @@ rsa_generate_keypair(pgp_key_t *keydata,
\return The new keypair or NULL
\note It is the caller's responsibility to call pgp_keydata_free(keydata)
- \sa rsa_generate_keypair()
+ \sa pgp_rsa_generate_keypair()
\sa pgp_keydata_free()
*/
pgp_key_t *
@@ -810,15 +847,16 @@ pgp_rsa_new_selfsign_key(const int numbits,
pgp_key_t *keydata;
keydata = pgp_keydata_new();
- if (!rsa_generate_keypair(keydata, numbits, e, hashalg, cipher) ||
- !pgp_add_selfsigned_userid(keydata, userid)) {
+ if (!pgp_rsa_generate_keypair(keydata, numbits, e, hashalg, cipher,
+ (const uint8_t *) "", (const size_t) 0) ||
+ !pgp_add_selfsigned_userid(keydata, NULL, userid, 0 /*never expire*/)) {
pgp_keydata_free(keydata);
return NULL;
}
return keydata;
}
-DSA_SIG *
+pgp_dsa_sig_t *
pgp_dsa_sign(uint8_t *hashbuf,
unsigned hashsize,
const pgp_dsa_seckey_t *secdsa,
@@ -826,64 +864,37 @@ pgp_dsa_sign(uint8_t *hashbuf,
{
DSA_SIG *dsasig;
DSA *odsa;
+ pgp_dsa_sig_t *pgpdsasig;
+ const BIGNUM *pr = NULL;
+ const BIGNUM *ps = NULL;
odsa = DSA_new();
- odsa->p = pubdsa->p;
- odsa->q = pubdsa->q;
- odsa->g = pubdsa->g;
- odsa->pub_key = pubdsa->y;
- odsa->priv_key = secdsa->x;
+ DSA_set0_pqg(odsa,
+ BN_dup(pubdsa->p),
+ BN_dup(pubdsa->q),
+ BN_dup(pubdsa->g));
+
+ DSA_set0_key(odsa,
+ BN_dup(pubdsa->y),
+ BN_dup(secdsa->x));
dsasig = DSA_do_sign(hashbuf, (int)hashsize, odsa);
- odsa->p = odsa->q = odsa->g = odsa->pub_key = odsa->priv_key = NULL;
DSA_free(odsa);
- return dsasig;
+
+ DSA_SIG_get0(dsasig, &pr, &ps);
+
+ pgpdsasig = calloc(1,sizeof(pgp_dsa_sig_t));
+ if(pgpdsasig != NULL){
+ pgpdsasig->r = BN_dup(pr);
+ pgpdsasig->s = BN_dup(ps);
+ }
+
+ DSA_SIG_free(dsasig);
+ return pgpdsasig;
}
-int
-openssl_read_pem_seckey(const char *f, pgp_key_t *key, const char *type, int verbose)
-{
- FILE *fp;
- char prompt[BUFSIZ];
- char *pass;
- DSA *dsa;
- RSA *rsa;
- int ok;
-
- OpenSSL_add_all_algorithms();
- if ((fp = fopen(f, "r")) == NULL) {
- if (verbose) {
- (void) fprintf(stderr, "can't open '%s'\n", f);
- }
- return 0;
- }
- ok = 1;
- if (strcmp(type, "ssh-rsa") == 0) {
- if ((rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) {
- (void) snprintf(prompt, sizeof(prompt), "netpgp PEM %s passphrase: ", f);
- do {
- pass = getpass(prompt);
- rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, pass);
- } while (rsa == NULL);
- }
- key->key.seckey.key.rsa.d = rsa->d;
- key->key.seckey.key.rsa.p = rsa->p;
- key->key.seckey.key.rsa.q = rsa->q;
- key->key.seckey.key.rsa.d = rsa->d;
- } else if (strcmp(type, "ssh-dss") == 0) {
- if ((dsa = PEM_read_DSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) {
- ok = 0;
- } else {
- key->key.seckey.key.dsa.x = dsa->priv_key;
- }
- } else {
- ok = 0;
- }
- (void) fclose(fp);
- return ok;
-}
/*
* Decide the number of bits in the random componont k
diff --git a/libs/netpgp/packet-parse.c b/libs/netpgp/src/packet-parse.c
similarity index 91%
rename from libs/netpgp/packet-parse.c
rename to libs/netpgp/src/packet-parse.c
index 754d67a7..dbf24506 100644
--- a/libs/netpgp/packet-parse.c
+++ b/libs/netpgp/src/packet-parse.c
@@ -50,7 +50,7 @@
/** \file
* \brief Parser for OpenPGP packets
*/
-#include "config-netpgp.h"
+#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include
@@ -58,7 +58,7 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: packet-parse.c,v 1.51 2012/03/05 02:20:18 christos Exp $");
+__RCSID("$NetBSD$");
#endif
#include
@@ -80,16 +80,16 @@ __RCSID("$NetBSD: packet-parse.c,v 1.51 2012/03/05 02:20:18 christos Exp $");
#include
#endif
-#include "packet-netpgp.h"
-#include "packet-parse.h"
-#include "keyring-netpgp.h"
-#include "errors-netpgp.h"
-#include "packet-show.h"
-#include "create-netpgp.h"
-#include "readerwriter-netpgp.h"
-#include "netpgpdefs.h"
-#include "crypto-netpgp.h"
-#include "netpgpdigest.h"
+#include "netpgp/packet.h"
+#include "netpgp/packet-parse.h"
+#include "netpgp/keyring.h"
+#include "netpgp/errors.h"
+#include "netpgp/packet-show.h"
+#include "netpgp/create.h"
+#include "netpgp/readerwriter.h"
+#include "netpgp/netpgpdefs.h"
+#include "netpgp/crypto.h"
+#include "netpgp/netpgpdigest.h"
#define ERRP(cbinfo, cont, err) do { \
cont.u.error = err; \
@@ -189,6 +189,30 @@ pgp_init_subregion(pgp_region_t *subregion, pgp_region_t *region)
* XXX: replace pgp_ptag_t with something more appropriate for limiting reads
*/
+/* data from partial blocks is queued up in virtual block in stream */
+static int
+read_partial_data(pgp_stream_t *stream,
+ pgp_reader_t *readinfo,
+ void *dest, size_t length)
+{
+ unsigned n;
+
+ if (pgp_get_debug_level(__FILE__)) {
+ (void) fprintf(stderr, "fd_reader: coalesced data, off %d\n",
+ readinfo->virtualoff);
+ }
+ n = MIN(readinfo->virtualc - readinfo->virtualoff, (unsigned)length);
+ (void) memcpy(dest, &readinfo->virtualpkt[readinfo->virtualoff], n);
+ readinfo->virtualoff += n;
+ if (readinfo->virtualoff == readinfo->virtualc) {
+ free(readinfo->virtualpkt);
+ readinfo->virtualpkt = NULL;
+ readinfo->virtualc = readinfo->virtualoff = 0;
+ }
+ return (int)n;
+}
+
+
/**
* low-level function to read data from reader function
*
@@ -231,8 +255,13 @@ sub_base_read(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **err
for (n = 0; n < length;) {
int r;
- r = readinfo->reader(stream, (char *) dest + n, length - n, errors,
- readinfo, cbinfo);
+ if (!readinfo->coalescing && readinfo->virtualc && readinfo->virtualoff < readinfo->virtualc) {
+ r = read_partial_data(stream, readinfo, (char*) dest + n, length - n);
+ }else{
+ r = readinfo->reader(stream, (char *) dest + n,
+ length - n, errors,
+ readinfo, cbinfo);
+ }
if (r > (int)(length - n)) {
(void) fprintf(stderr, "sub_base_read: bad read\n");
return 0;
@@ -454,6 +483,7 @@ limread(uint8_t *dest, unsigned length,
&info->readinfo, &info->cbinfo);
}
+#if 0
static unsigned
exact_limread(uint8_t *dest, unsigned len,
pgp_region_t *region,
@@ -466,6 +496,7 @@ exact_limread(uint8_t *dest, unsigned len,
stream->exact_read = 0;
return ret;
}
+#endif
/** Skip over length bytes of this packet.
*
@@ -655,10 +686,10 @@ limread_mpi(BIGNUM **pbn, pgp_region_t *region, pgp_stream_t *stream)
unsigned nonzero;
unsigned ret;
- stream->reading_mpi_len = 1;
+ //stream->reading_mpi_len = 1;
ret = (unsigned)limread_scalar(&length, 2, region, stream);
- stream->reading_mpi_len = 0;
+ //stream->reading_mpi_len = 0;
if (!ret)
return 0;
@@ -704,11 +735,12 @@ static void
streamread(pgp_stream_t *stream, unsigned c)
{
int cc;
+ pgp_reader_t *readinfo = &stream->readinfo;
- stream->virtualpkt = realloc(stream->virtualpkt, stream->virtualc + c);
- cc = stream->readinfo.reader(stream, &stream->virtualpkt[stream->virtualc],
- c, &stream->errors, &stream->readinfo, &stream->cbinfo);
- stream->virtualc += cc;
+ readinfo->virtualpkt = realloc(readinfo->virtualpkt, readinfo->virtualc + c);
+ cc = readinfo->reader(stream, &readinfo->virtualpkt[readinfo->virtualc],
+ c, &stream->errors, readinfo, &stream->cbinfo);
+ readinfo->virtualc += cc;
}
/* coalesce all the partial blocks together */
@@ -716,17 +748,20 @@ static int
coalesce_blocks(pgp_stream_t *stream, unsigned length)
{
unsigned c;
+ unsigned r;
+
+ pgp_reader_t *readinfo = &stream->readinfo;
+ readinfo->coalescing = 1;
- stream->coalescing = 1;
/* already read a partial block length - prime the array */
streamread(stream, length);
- while (read_new_length(&c, stream) && stream->partial_read) {
+ while ((r = read_new_length(&c, stream)) && readinfo->partial_read) {
/* length we read is partial - add to end of array */
streamread(stream, c);
}
/* not partial - add the last extent to the end of the array */
- streamread(stream, c);
- stream->coalescing = 0;
+ if(r > 0) streamread(stream, c);
+ readinfo->coalescing = 0;
return 1;
}
@@ -744,8 +779,9 @@ static unsigned
read_new_length(unsigned *length, pgp_stream_t *stream)
{
uint8_t c;
+ pgp_reader_t *readinfo = &stream->readinfo;
- stream->partial_read = 0;
+ readinfo->partial_read = 0;
if (base_read(&c, 1, stream) != 1) {
return 0;
}
@@ -766,13 +802,13 @@ read_new_length(unsigned *length, pgp_stream_t *stream)
}
if (c < 255) {
/* 3. Partial Body Length */
- stream->partial_read = 1;
+ readinfo->partial_read = 1;
*length = 1 << (c & 0x1f);
- if (!stream->coalescing) {
+ if (!readinfo->coalescing) {
/* we have been called from coalesce_blocks -
* just return with the partial length */
coalesce_blocks(stream, *length);
- *length = stream->virtualc;
+ *length = readinfo->virtualc;
}
return 1;
}
@@ -802,6 +838,7 @@ limited_read_new_length(unsigned *length, pgp_region_t *region,
pgp_stream_t *stream)
{
uint8_t c = 0x0;
+ pgp_reader_t *readinfo = &stream->readinfo;
if (!limread(&c, 1, region, stream)) {
return 0;
@@ -820,13 +857,13 @@ limited_read_new_length(unsigned *length, pgp_region_t *region,
return 1;
}
if (c < 255) {
- stream->partial_read = 1;
+ readinfo->partial_read = 1;
*length = 1 << (c & 0x1f);
- if (!stream->coalescing) {
+ if (!readinfo->coalescing) {
/* we have been called from coalesce_blocks -
* just return with the partial length */
coalesce_blocks(stream, *length);
- *length = stream->virtualc;
+ *length = readinfo->virtualc;
}
return 1;
}
@@ -845,6 +882,14 @@ pgp_data_free(pgp_data_t *data)
data->len = 0;
}
+void
+pgp_data_dup(pgp_data_t *dst, const pgp_data_t *src)
+{
+ dst->contents = calloc(1, src->len);
+ memcpy(dst->contents, src->contents, src->len);
+ dst->len = src->len;
+}
+
/**
\ingroup Core_Create
\brief Free allocated memory
@@ -920,28 +965,37 @@ free_BN(BIGNUM **pp)
*pp = NULL;
}
-/**
- * \ingroup Core_Create
- * \brief Free the memory used when parsing a signature
- * \param sig
- */
static void
-sig_free(pgp_sig_t *sig)
+dup_BN(BIGNUM **dst, const BIGNUM *src)
{
- switch (sig->info.key_alg) {
+ *dst = BN_dup(src);
+}
+
+void
+copy_sig_info(pgp_sig_info_t *dst, const pgp_sig_info_t *src)
+{
+ (void) memcpy(dst, src, sizeof(*src));
+
+ if ((dst->v4_hashed = calloc(1, src->v4_hashlen)) == NULL) {
+ (void) fprintf(stderr, "copy_sig_info: bad alloc\n");
+ } else {
+ (void) memcpy(dst->v4_hashed, src->v4_hashed, src->v4_hashlen);
+ }
+
+ switch (src->key_alg) {
case PGP_PKA_RSA:
case PGP_PKA_RSA_SIGN_ONLY:
- free_BN(&sig->info.sig.rsa.sig);
+ dup_BN(&dst->sig.rsa.sig, src->sig.rsa.sig);
break;
case PGP_PKA_DSA:
- free_BN(&sig->info.sig.dsa.r);
- free_BN(&sig->info.sig.dsa.s);
+ dup_BN(&dst->sig.dsa.r, src->sig.dsa.r);
+ dup_BN(&dst->sig.dsa.s, src->sig.dsa.s);
break;
case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
- free_BN(&sig->info.sig.elgamal.r);
- free_BN(&sig->info.sig.elgamal.s);
+ dup_BN(&dst->sig.elgamal.r, src->sig.elgamal.r);
+ dup_BN(&dst->sig.elgamal.s, src->sig.elgamal.s);
break;
case PGP_PKA_PRIVATE00:
@@ -955,13 +1009,65 @@ sig_free(pgp_sig_t *sig)
case PGP_PKA_PRIVATE08:
case PGP_PKA_PRIVATE09:
case PGP_PKA_PRIVATE10:
- pgp_data_free(&sig->info.sig.unknown);
+ pgp_data_dup(&dst->sig.unknown, &src->sig.unknown);
break;
default:
- (void) fprintf(stderr, "sig_free: bad sig type\n");
+ (void) fprintf(stderr, "sig_dup: bad sig type\n");
}
}
+/**
+ * \ingroup Core_Create
+ * \brief Free the memory used when parsing a signature
+ * \param sig
+ */
+void
+pgp_free_sig_info(pgp_sig_info_t *info)
+{
+ free(info->v4_hashed);
+
+ switch (info->key_alg) {
+ case PGP_PKA_RSA:
+ case PGP_PKA_RSA_SIGN_ONLY:
+ free_BN(&info->sig.rsa.sig);
+ break;
+
+ case PGP_PKA_DSA:
+ free_BN(&info->sig.dsa.r);
+ free_BN(&info->sig.dsa.s);
+ break;
+
+ case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
+ free_BN(&info->sig.elgamal.r);
+ free_BN(&info->sig.elgamal.s);
+ break;
+
+ case PGP_PKA_PRIVATE00:
+ case PGP_PKA_PRIVATE01:
+ case PGP_PKA_PRIVATE02:
+ case PGP_PKA_PRIVATE03:
+ case PGP_PKA_PRIVATE04:
+ case PGP_PKA_PRIVATE05:
+ case PGP_PKA_PRIVATE06:
+ case PGP_PKA_PRIVATE07:
+ case PGP_PKA_PRIVATE08:
+ case PGP_PKA_PRIVATE09:
+ case PGP_PKA_PRIVATE10:
+ pgp_data_free(&info->sig.unknown);
+ break;
+
+ default:
+ (void) fprintf(stderr, "info-free: bad info-type\n");
+ }
+ memset(info, 0, sizeof(pgp_sig_info_t));
+}
+
+static void
+sig_free(pgp_sig_t *sig)
+{
+ pgp_free_sig_info(&sig->info);
+}
+
/**
\ingroup Core_Create
@@ -1188,8 +1294,48 @@ pgp_pubkey_free(pgp_pubkey_t *p)
default:
(void) fprintf(stderr, "pgp_pubkey_free: bad alg\n");
}
+ memset(p, 0, sizeof(*p));
}
+int
+pgp_pubkey_dup(pgp_pubkey_t *dst, pgp_pubkey_t *src)
+{
+ memcpy(dst, src, sizeof(*src));
+
+ switch (src->alg) {
+ case PGP_PKA_RSA:
+ case PGP_PKA_RSA_ENCRYPT_ONLY:
+ case PGP_PKA_RSA_SIGN_ONLY:
+ dup_BN(&dst->key.rsa.n, src->key.rsa.n);
+ dup_BN(&dst->key.rsa.e, src->key.rsa.e);
+ break;
+
+ case PGP_PKA_DSA:
+ dup_BN(&dst->key.dsa.p, src->key.dsa.p);
+ dup_BN(&dst->key.dsa.q, src->key.dsa.q);
+ dup_BN(&dst->key.dsa.g, src->key.dsa.g);
+ dup_BN(&dst->key.dsa.y, src->key.dsa.y);
+ break;
+
+ case PGP_PKA_ELGAMAL:
+ case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
+ dup_BN(&dst->key.elgamal.p, src->key.elgamal.p);
+ dup_BN(&dst->key.elgamal.g, src->key.elgamal.g);
+ dup_BN(&dst->key.elgamal.y, src->key.elgamal.y);
+ break;
+
+ case PGP_PKA_NOTHING:
+ /* nothing to dup */
+ break;
+
+ default:
+ (void) fprintf(stderr, "pgp_pubkey_dup: bad alg\n");
+ return 0;
+ }
+
+ /*TODO alloc error handling */
+ return 1;
+}
/**
\ingroup Core_ReadPackets
*/
@@ -1606,6 +1752,10 @@ parse_one_sig_subpacket(pgp_sig_t *sig,
sig->info.duration = pkt.u.ss_time;
sig->info.duration_set = 1;
}
+ if (pkt.tag == PGP_PTAG_SS_KEY_EXPIRY) {
+ sig->info.key_expiry = pkt.u.ss_time;
+ sig->info.key_expiry_set = 1;
+ }
break;
case PGP_PTAG_SS_TRUST:
@@ -1653,12 +1803,18 @@ parse_one_sig_subpacket(pgp_sig_t *sig,
return 0;
}
pkt.u.ss_primary_userid = !!bools;
+ sig->info.primary_userid = pkt.u.ss_primary_userid;
break;
case PGP_PTAG_SS_KEY_FLAGS:
if (!read_data(&pkt.u.ss_key_flags, &subregion, stream)) {
return 0;
}
+ if(pkt.u.ss_key_flags.len > 0){
+ /* Only one byte is defined in rfc4880 for now */
+ sig->info.key_flags = pkt.u.ss_key_flags.contents[0];
+ sig->info.key_flags_set = 1;
+ }
break;
case PGP_PTAG_SS_KEYSERV_PREFS:
@@ -1817,6 +1973,7 @@ parse_one_sig_subpacket(pgp_sig_t *sig,
PGP_ERROR_1(&stream->errors, PGP_E_R_UNCONSUMED_DATA,
"Unconsumed data (%d)",
subregion.length - subregion.readc);
+ pgp_parser_content_free(&pkt);
return 0;
}
CALLBACK(pkt.tag, &stream->cbinfo, &pkt);
@@ -1968,24 +2125,24 @@ parse_v4_sig(pgp_region_t *region, pgp_stream_t *stream)
if (!stream->readinfo.accumulate) {
/* We must accumulate, else we can't check the signature */
fprintf(stderr, "*** ERROR: must set accumulate to 1\n");
- return 0;
+ goto error_unalloc_v4_hashed;
}
(void) memcpy(pkt.u.sig.info.v4_hashed,
stream->readinfo.accumulated + pkt.u.sig.v4_hashstart,
pkt.u.sig.info.v4_hashlen);
if (!parse_sig_subpkts(&pkt.u.sig, region, stream)) {
- return 0;
+ goto error_unalloc_v4_hashed;
}
if (!limread(pkt.u.sig.hash2, 2, region, stream)) {
- return 0;
+ goto error_unalloc_v4_hashed;
}
switch (pkt.u.sig.info.key_alg) {
case PGP_PKA_RSA:
if (!limread_mpi(&pkt.u.sig.info.sig.rsa.sig, region, stream)) {
- return 0;
+ goto error_unalloc_v4_hashed;
}
if (pgp_get_debug_level(__FILE__)) {
(void) fprintf(stderr, "parse_v4_sig: RSA: sig is\n");
@@ -2004,7 +2161,7 @@ parse_v4_sig(pgp_region_t *region, pgp_stream_t *stream)
(void) fprintf(stderr,
"Error reading DSA r field in signature");
}
- return 0;
+ goto error_unalloc_v4_hashed;
}
if (!limread_mpi(&pkt.u.sig.info.sig.dsa.s, region, stream)) {
ERRP(&stream->cbinfo, pkt,
@@ -2017,7 +2174,7 @@ parse_v4_sig(pgp_region_t *region, pgp_stream_t *stream)
stream) ||
!limread_mpi(&pkt.u.sig.info.sig.elgamal.s, region,
stream)) {
- return 0;
+ goto error_unalloc_v4_hashed;
}
break;
@@ -2033,7 +2190,7 @@ parse_v4_sig(pgp_region_t *region, pgp_stream_t *stream)
case PGP_PKA_PRIVATE09:
case PGP_PKA_PRIVATE10:
if (!read_data(&pkt.u.sig.info.sig.unknown, region, stream)) {
- return 0;
+ goto error_unalloc_v4_hashed;
}
break;
@@ -2041,16 +2198,21 @@ parse_v4_sig(pgp_region_t *region, pgp_stream_t *stream)
PGP_ERROR_1(&stream->errors, PGP_E_ALG_UNSUPPORTED_SIGNATURE_ALG,
"Bad v4 signature key algorithm (%s)",
pgp_show_pka(pkt.u.sig.info.key_alg));
- return 0;
+ goto error_unalloc_v4_hashed;
}
if (region->readc != region->length) {
PGP_ERROR_1(&stream->errors, PGP_E_R_UNCONSUMED_DATA,
"Unconsumed data (%d)",
region->length - region->readc);
- return 0;
+ goto error_unalloc_v4_hashed;
}
CALLBACK(PGP_PTAG_CT_SIGNATURE_FOOTER, &stream->cbinfo, &pkt);
return 1;
+
+error_unalloc_v4_hashed:
+ free(pkt.u.sig.info.v4_hashed);
+ return 0;
+
}
/**
@@ -2306,6 +2468,50 @@ pgp_seckey_free(pgp_seckey_t *key)
pgp_show_pka(key->pubkey.alg));
}
free(key->checkhash);
+ pgp_pubkey_free(&key->pubkey);
+ memset(key, 0, sizeof(*key));
+}
+
+int
+pgp_seckey_dup(pgp_seckey_t *dst, pgp_seckey_t *src)
+{
+ memcpy(dst, src, sizeof(*src));
+
+ switch (src->pubkey.alg) {
+ case PGP_PKA_RSA:
+ case PGP_PKA_RSA_ENCRYPT_ONLY:
+ case PGP_PKA_RSA_SIGN_ONLY:
+ dup_BN(&dst->key.rsa.d, src->key.rsa.d);
+ dup_BN(&dst->key.rsa.p, src->key.rsa.p);
+ dup_BN(&dst->key.rsa.q, src->key.rsa.q);
+ dup_BN(&dst->key.rsa.u, src->key.rsa.u);
+ break;
+
+ case PGP_PKA_DSA:
+ dup_BN(&dst->key.dsa.x, src->key.dsa.x);
+ break;
+
+ default:
+ (void) fprintf(stderr,
+ "pgp_seckey_dup: Unknown algorithm: %d (%s)\n",
+ src->pubkey.alg,
+ pgp_show_pka(src->pubkey.alg));
+ return 0;
+ }
+
+ if(src->checkhash) {
+ if ((dst->checkhash = calloc(1, PGP_CHECKHASH_SIZE)) == NULL) {
+ (void) fprintf(stderr, "pgp_seckey_dup: bad alloc\n");
+ return 0;
+ }else{
+ memcpy(dst->checkhash, src->checkhash, PGP_CHECKHASH_SIZE);
+ }
+ }
+
+ pgp_pubkey_dup(&dst->pubkey, &src->pubkey);
+
+ /*TODO alloc error handling */
+ return 1;
}
static int
@@ -2339,7 +2545,7 @@ consume_packet(pgp_region_t *region, pgp_stream_t *stream, unsigned warn)
* \brief Parse a secret key
*/
static int
-parse_seckey(pgp_region_t *region, pgp_stream_t *stream)
+parse_seckey(pgp_content_enum tag, pgp_region_t *region, pgp_stream_t *stream)
{
pgp_packet_t pkt;
pgp_region_t encregion;
@@ -2364,9 +2570,14 @@ parse_seckey(pgp_region_t *region, pgp_stream_t *stream)
}
if (pgp_get_debug_level(__FILE__)) {
fprintf(stderr, "parse_seckey: public key parsed\n");
- pgp_print_pubkey(&pkt.u.seckey.pubkey);
+ //pgp_print_pubkey(&pkt.u.seckey.pubkey);
}
- stream->reading_v3_secret = (pkt.u.seckey.pubkey.version != PGP_V4);
+ //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;
+ }
if (!limread(&c, 1, region, stream)) {
return 0;
@@ -2576,9 +2787,10 @@ parse_seckey(pgp_region_t *region, pgp_stream_t *stream)
if (pgp_get_debug_level(__FILE__)) {
fprintf(stderr, "parse_seckey: end of crypted passphrase\n");
}
+
+ /* XXX - Hard-coded SHA1 here ?? Check */
if (pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED_AND_HASHED) {
- /* XXX - Hard-coded SHA1 here ?? Check */
- 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) {
(void) fprintf(stderr, "parse_seckey: bad alloc\n");
return 0;
@@ -2627,7 +2839,7 @@ parse_seckey(pgp_region_t *region, pgp_stream_t *stream)
if (pgp_get_debug_level(__FILE__)) {
(void) fprintf(stderr, "4 MPIs read\n");
}
- stream->reading_v3_secret = 0;
+ //stream->reading_v3_secret = 0;
if (pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED_AND_HASHED) {
uint8_t hash[PGP_CHECKHASH_SIZE];
@@ -2687,7 +2899,7 @@ parse_seckey(pgp_region_t *region, pgp_stream_t *stream)
if (!ret) {
return 0;
}
- CALLBACK(PGP_PTAG_CT_SECRET_KEY, &stream->cbinfo, &pkt);
+ CALLBACK(tag, &stream->cbinfo, &pkt);
if (pgp_get_debug_level(__FILE__)) {
(void) fprintf(stderr, "--- end of parse_seckey\n\n");
}
@@ -2869,6 +3081,7 @@ parse_pk_sesskey(pgp_region_t *region,
return 1;
}
+#if 0
static int
decrypt_se_data(pgp_content_enum tag, pgp_region_t *region,
pgp_stream_t *stream)
@@ -2928,6 +3141,7 @@ decrypt_se_data(pgp_content_enum tag, pgp_region_t *region,
return r;
}
+#endif
static int
decrypt_se_ip_data(pgp_content_enum tag, pgp_region_t *region,
@@ -2977,6 +3191,7 @@ decrypt_se_ip_data(pgp_content_enum tag, pgp_region_t *region,
return r;
}
+#if 0
/**
\ingroup Core_ReadPackets
\brief Read a Symmetrically Encrypted packet
@@ -2995,6 +3210,7 @@ parse_se_data(pgp_region_t *region, pgp_stream_t *stream)
*/
return decrypt_se_data(PGP_PTAG_CT_SE_DATA_BODY, region, stream);
}
+#endif
/**
\ingroup Core_ReadPackets
@@ -3021,7 +3237,7 @@ parse_se_ip_data(pgp_region_t *region, pgp_stream_t *stream)
if (pgp_get_debug_level(__FILE__)) {
(void) fprintf(stderr, "parse_se_ip_data: region %d,%d\n",
region->readc, region->length);
- hexdump(stderr, "compressed region", stream->virtualpkt, stream->virtualc);
+ hexdump(stderr, "compressed region", stream->readinfo.virtualpkt, stream->readinfo.virtualc);
}
/*
* The content of an encrypted data packet is more OpenPGP packets
@@ -3104,7 +3320,6 @@ parse_packet(pgp_stream_t *stream, uint32_t *pktlen)
} else {
unsigned rb;
- rb = 0;
pkt.u.ptag.type = ((unsigned)ptag &
PGP_PTAG_OF_CONTENT_TAG_MASK)
>> PGP_PTAG_OF_CONTENT_TAG_SHIFT;
@@ -3177,11 +3392,8 @@ parse_packet(pgp_stream_t *stream, uint32_t *pktlen)
break;
case PGP_PTAG_CT_SECRET_KEY:
- ret = parse_seckey(®ion, stream);
- break;
-
case PGP_PTAG_CT_SECRET_SUBKEY:
- ret = parse_seckey(®ion, stream);
+ ret = parse_seckey((pgp_content_enum)pkt.u.ptag.type, ®ion, stream);
break;
case PGP_PTAG_CT_PK_SESSION_KEY:
@@ -3189,7 +3401,9 @@ parse_packet(pgp_stream_t *stream, uint32_t *pktlen)
break;
case PGP_PTAG_CT_SE_DATA:
- ret = parse_se_data(®ion, stream);
+ // SE_DATA CURRENTLY BROKEN
+ ret = 0;
+ //ret = parse_se_data(®ion, stream);
break;
case PGP_PTAG_CT_SE_IP_DATA:
@@ -3347,11 +3561,15 @@ pgp_stream_delete(pgp_stream_t *stream)
{
pgp_cbdata_t *cbinfo;
pgp_cbdata_t *next;
+ pgp_cryptinfo_t *cryptinfo = &stream->cbinfo.cryptinfo;
for (cbinfo = stream->cbinfo.next; cbinfo; cbinfo = next) {
next = cbinfo->next;
free(cbinfo);
}
+
+ FREE_ARRAY(cryptinfo, recipients_key_ids);
+
if (stream->readinfo.destroyer) {
stream->readinfo.destroyer(&stream->readinfo);
}
diff --git a/libs/netpgp/packet-show.c b/libs/netpgp/src/packet-show.c
similarity index 59%
rename from libs/netpgp/packet-show.c
rename to libs/netpgp/src/packet-show.c
index 1efcf061..fdc4909c 100644
--- a/libs/netpgp/packet-show.c
+++ b/libs/netpgp/src/packet-show.c
@@ -52,7 +52,7 @@
* Creates printable text strings from packet contents
*
*/
-#include "config-netpgp.h"
+#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include
@@ -60,16 +60,16 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: packet-show.c,v 1.21 2011/08/14 11:19:51 christos Exp $");
+__RCSID("$NetBSD$");
#endif
#include
#include
-#include "packet-show.h"
+#include "netpgp/packet-show.h"
-#include "netpgpsdk.h"
-#include "netpgpdefs.h"
+#include "netpgp/netpgpsdk.h"
+#include "netpgp/netpgpdefs.h"
/*
@@ -271,50 +271,11 @@ static pgp_map_t compression_alg_map[] =
{0x00, NULL}, /* this is the end-of-array marker */
};
-static pgp_bit_map_t ss_notation_map_byte0[] =
-{
- {0x80, "Human-readable"},
- {0x00, NULL},
-};
-
-static pgp_bit_map_t *ss_notation_map[] =
-{
- ss_notation_map_byte0,
-};
-
-static pgp_bit_map_t ss_feature_map_byte0[] =
-{
- {0x01, "Modification Detection"},
- {0x00, NULL},
-};
-
-static pgp_bit_map_t *ss_feature_map[] =
-{
- ss_feature_map_byte0,
-};
-
-static pgp_bit_map_t ss_key_flags_map[] =
-{
- {0x01, "May be used to certify other keys"},
- {0x02, "May be used to sign data"},
- {0x04, "May be used to encrypt communications"},
- {0x08, "May be used to encrypt storage"},
- {0x10, "Private component may have been split by a secret-sharing mechanism"},
- {0x80, "Private component may be in possession of more than one person"},
- {0x00, NULL},
-};
-
-static pgp_bit_map_t ss_key_server_prefs_map[] =
-{
- {0x80, "Key holder requests that this key only be modified or updated by the key holder or an administrator of the key server"},
- {0x00, NULL},
-};
-
/*
* Private functions
*/
-static void
+static void
list_init(pgp_list_t *list)
{
list->size = 0;
@@ -322,7 +283,7 @@ list_init(pgp_list_t *list)
list->strings = NULL;
}
-static void
+static void
list_free_strings(pgp_list_t *list)
{
unsigned i;
@@ -333,7 +294,7 @@ list_free_strings(pgp_list_t *list)
}
}
-static void
+static void
list_free(pgp_list_t *list)
{
if (list->strings)
@@ -341,37 +302,6 @@ list_free(pgp_list_t *list)
list_init(list);
}
-static unsigned
-list_resize(pgp_list_t *list)
-{
- /*
- * We only resize in one direction - upwards. Algorithm used : double
- * the current size then add 1
- */
- char **newstrings;
- int newsize;
-
- newsize = (list->size * 2) + 1;
- newstrings = realloc(list->strings, newsize * sizeof(char *));
- if (newstrings) {
- list->strings = newstrings;
- list->size = newsize;
- return 1;
- }
- (void) fprintf(stderr, "list_resize - bad alloc\n");
- return 0;
-}
-
-static unsigned
-add_str(pgp_list_t *list, const char *str)
-{
- if (list->size == list->used && !list_resize(list)) {
- return 0;
- }
- list->strings[list->used++] = __UNCONST(str);
- return 1;
-}
-
/* find a bitfield in a map - serial search */
static const char *
find_bitfield(pgp_bit_map_t *map, uint8_t octet)
@@ -384,7 +314,7 @@ find_bitfield(pgp_bit_map_t *map, uint8_t octet)
}
/* ! generic function to initialise pgp_text_t structure */
-void
+void
pgp_text_init(pgp_text_t *text)
{
list_init(&text->known);
@@ -398,7 +328,7 @@ pgp_text_init(pgp_text_t *text)
*
* \param text Pointer to a previously allocated structure. This structure and its contents will be freed.
*/
-void
+void
pgp_text_free(pgp_text_t *text)
{
/* Strings in "known" array will be constants, so don't free them */
@@ -414,161 +344,6 @@ pgp_text_free(pgp_text_t *text)
free(text);
}
-/* XXX: should this (and many others) be unsigned? */
-/* ! generic function which adds text derived from single octet map to text */
-static unsigned
-add_str_from_octet_map(pgp_text_t *map, char *str, uint8_t octet)
-{
- if (str && !add_str(&map->known, str)) {
- /*
- * value recognised, but there was a problem adding it to the
- * list
- */
- /* XXX - should print out error msg here, Ben? - rachel */
- return 0;
- } else if (!str) {
- /*
- * value not recognised and there was a problem adding it to
- * the unknown list
- */
- unsigned len = 2 + 2 + 1; /* 2 for "0x", 2 for
- * single octet in hex
- * format, 1 for NUL */
- if ((str = calloc(1, len)) == NULL) {
- (void) fprintf(stderr, "add_str_from_octet_map: bad alloc\n");
- return 0;
- }
- (void) snprintf(str, len, "0x%x", octet);
- if (!add_str(&map->unknown, str)) {
- return 0;
- }
- free(str);
- }
- return 1;
-}
-
-/* ! generic function which adds text derived from single bit map to text */
-static unsigned
-add_bitmap_entry(pgp_text_t *map, const char *str, uint8_t bit)
-{
-
- if (str && !add_str(&map->known, str)) {
- /*
- * value recognised, but there was a problem adding it to the
- * list
- */
- /* XXX - should print out error msg here, Ben? - rachel */
- return 0;
- } else if (!str) {
- /*
- * value not recognised and there was a problem adding it to
- * the unknown list
- * 2 chars of the string are the format definition, this will
- * be replaced in the output by 2 chars of hex, so the length
- * will be correct
- */
- char *newstr;
- if (pgp_asprintf(&newstr, "Unknown bit(0x%x)", bit) == -1) {
- (void) fprintf(stderr, "add_bitmap_entry: bad alloc\n");
- return 0;
- }
- if (!add_str(&map->unknown, newstr)) {
- return 0;
- }
- free(newstr);
- }
- return 1;
-}
-
-/**
- * Produce a structure containing human-readable textstrings
- * representing the recognised and unrecognised contents
- * of this byte array. text_fn() will be called on each octet in turn.
- * Each octet will generate one string representing the whole byte.
- *
- */
-
-static pgp_text_t *
-text_from_bytemapped_octets(const pgp_data_t *data,
- const char *(*text_fn)(uint8_t octet))
-{
- pgp_text_t *text;
- const char *str;
- unsigned i;
-
- /*
- * ! allocate and initialise pgp_text_t structure to store derived
- * strings
- */
- if ((text = calloc(1, sizeof(*text))) == NULL) {
- return NULL;
- }
-
- pgp_text_init(text);
-
- /* ! for each octet in field ... */
- for (i = 0; i < data->len; i++) {
- /* ! derive string from octet */
- str = (*text_fn) (data->contents[i]);
-
- /* ! and add to text */
- if (!add_str_from_octet_map(text, netpgp_strdup(str),
- data->contents[i])) {
- pgp_text_free(text);
- return NULL;
- }
- }
- /*
- * ! All values have been added to either the known or the unknown
- * list
- */
- return text;
-}
-
-/**
- * Produce a structure containing human-readable textstrings
- * representing the recognised and unrecognised contents
- * of this byte array, derived from each bit of each octet.
- *
- */
-static pgp_text_t *
-showall_octets_bits(pgp_data_t *data, pgp_bit_map_t **map, size_t nmap)
-{
- pgp_text_t *text;
- const char *str;
- unsigned i;
- uint8_t mask, bit;
- int j = 0;
-
- /*
- * ! allocate and initialise pgp_text_t structure to store derived
- * strings
- */
- if ((text = calloc(1, sizeof(pgp_text_t))) == NULL) {
- return NULL;
- }
-
- pgp_text_init(text);
-
- /* ! for each octet in field ... */
- for (i = 0; i < data->len; i++) {
- /* ! for each bit in octet ... */
- mask = 0x80;
- for (j = 0; j < 8; j++, mask = (unsigned)mask >> 1) {
- bit = data->contents[i] & mask;
- if (bit) {
- str = (i >= nmap) ? "Unknown" :
- find_bitfield(map[i], bit);
- if (!add_bitmap_entry(text, str, bit)) {
- pgp_text_free(text);
- return NULL;
- }
- }
- }
- }
- return text;
-}
-
/*
* Public Functions
*/
@@ -655,22 +430,6 @@ pgp_show_ss_zpref(uint8_t octet)
return pgp_str_from_map(octet, compression_alg_map);
}
-/**
- * \ingroup Core_Print
- *
- * returns set of descriptions of the given Preferred Compression Algorithms
- * \param ss_zpref Array of Preferred Compression Algorithms
- * \return NULL if cannot allocate memory or other error
- * \return pointer to structure, if no error
- */
-pgp_text_t *
-pgp_showall_ss_zpref(const pgp_data_t *ss_zpref)
-{
- return text_from_bytemapped_octets(ss_zpref,
- &pgp_show_ss_zpref);
-}
-
-
/**
* \ingroup Core_Print
*
@@ -684,21 +443,6 @@ pgp_show_hash_alg(uint8_t hash)
return pgp_str_from_map(hash, hash_alg_map);
}
-/**
- * \ingroup Core_Print
- *
- * returns set of descriptions of the given Preferred Hash Algorithms
- * \param ss_hashpref Array of Preferred Hash Algorithms
- * \return NULL if cannot allocate memory or other error
- * \return pointer to structure, if no error
- */
-pgp_text_t *
-pgp_showall_ss_hashpref(const pgp_data_t *ss_hashpref)
-{
- return text_from_bytemapped_octets(ss_hashpref,
- &pgp_show_hash_alg);
-}
-
const char *
pgp_show_symm_alg(uint8_t hash)
{
@@ -717,76 +461,6 @@ pgp_show_ss_skapref(uint8_t octet)
return pgp_str_from_map(octet, symm_alg_map);
}
-/**
- * \ingroup Core_Print
- *
- * returns set of descriptions of the given Preferred Symmetric Key Algorithms
- * \param ss_skapref Array of Preferred Symmetric Key Algorithms
- * \return NULL if cannot allocate memory or other error
- * \return pointer to structure, if no error
- */
-pgp_text_t *
-pgp_showall_ss_skapref(const pgp_data_t *ss_skapref)
-{
- return text_from_bytemapped_octets(ss_skapref,
- &pgp_show_ss_skapref);
-}
-
-/**
- * \ingroup Core_Print
- * returns description of one SS Feature
- * \param octet
- * \return string or "Unknown"
-*/
-static const char *
-show_ss_feature(uint8_t octet, unsigned offset)
-{
- if (offset >= PGP_ARRAY_SIZE(ss_feature_map)) {
- return "Unknown";
- }
- return find_bitfield(ss_feature_map[offset], octet);
-}
-
-/**
- * \ingroup Core_Print
- *
- * returns set of descriptions of the given SS Features
- * \param ss_features Signature Sub-Packet Features
- * \return NULL if cannot allocate memory or other error
- * \return pointer to structure, if no error
- */
-/* XXX: shouldn't this use show_all_octets_bits? */
-pgp_text_t *
-pgp_showall_ss_features(pgp_data_t ss_features)
-{
- pgp_text_t *text;
- const char *str;
- unsigned i;
- uint8_t mask, bit;
- int j;
-
- if ((text = calloc(1, sizeof(*text))) == NULL) {
- return NULL;
- }
-
- pgp_text_init(text);
-
- for (i = 0; i < ss_features.len; i++) {
- mask = 0x80;
- for (j = 0; j < 8; j++, mask = (unsigned)mask >> 1) {
- bit = ss_features.contents[i] & mask;
- if (bit) {
- str = show_ss_feature(bit, i);
- if (!add_bitmap_entry(text, str, bit)) {
- pgp_text_free(text);
- return NULL;
- }
- }
- }
- }
- return text;
-}
-
/**
* \ingroup Core_Print
* returns description of SS Key Flag
@@ -800,46 +474,6 @@ pgp_show_ss_key_flag(uint8_t octet, pgp_bit_map_t *map)
return find_bitfield(map, octet);
}
-/**
- * \ingroup Core_Print
- *
- * returns set of descriptions of the given Preferred Key Flags
- * \param ss_key_flags Array of Key Flags
- * \return NULL if cannot allocate memory or other error
- * \return pointer to structure, if no error
- */
-pgp_text_t *
-pgp_showall_ss_key_flags(const pgp_data_t *ss_key_flags)
-{
- pgp_text_t *text;
- const char *str;
- uint8_t mask, bit;
- int i;
-
- if ((text = calloc(1, sizeof(*text))) == NULL) {
- return NULL;
- }
-
- pgp_text_init(text);
-
- /* xxx - TBD: extend to handle multiple octets of bits - rachel */
- for (i = 0, mask = 0x80; i < 8; i++, mask = (unsigned)mask >> 1) {
- bit = ss_key_flags->contents[0] & mask;
- if (bit) {
- str = pgp_show_ss_key_flag(bit, ss_key_flags_map);
- if (!add_bitmap_entry(text, netpgp_strdup(str), bit)) {
- pgp_text_free(text);
- return NULL;
- }
- }
- }
- /*
- * xxx - must add error text if more than one octet. Only one
- * currently specified -- rachel
- */
- return text;
-}
-
/**
* \ingroup Core_Print
*
@@ -855,60 +489,3 @@ pgp_show_keyserv_pref(uint8_t prefs, pgp_bit_map_t *map)
return find_bitfield(map, prefs);
}
-/**
- * \ingroup Core_Print
- * returns set of descriptions of given Key Server Preferences
- * \param ss_key_server_prefs
- * \return NULL if cannot allocate memory or other error
- * \return pointer to structure, if no error
- *
-*/
-pgp_text_t *
-pgp_show_keyserv_prefs(const pgp_data_t *prefs)
-{
- pgp_text_t *text;
- const char *str;
- uint8_t mask, bit;
- int i = 0;
-
- if ((text = calloc(1, sizeof(*text))) == NULL) {
- return NULL;
- }
-
- pgp_text_init(text);
-
- /* xxx - TBD: extend to handle multiple octets of bits - rachel */
-
- for (i = 0, mask = 0x80; i < 8; i++, mask = (unsigned)mask >> 1) {
- bit = prefs->contents[0] & mask;
- if (bit) {
- str = pgp_show_keyserv_pref(bit,
- ss_key_server_prefs_map);
- if (!add_bitmap_entry(text, netpgp_strdup(str), bit)) {
- pgp_text_free(text);
- return NULL;
- }
- }
- }
- /*
- * xxx - must add error text if more than one octet. Only one
- * currently specified -- rachel
- */
- return text;
-}
-
-/**
- * \ingroup Core_Print
- *
- * returns set of descriptions of the given SS Notation Data Flags
- * \param ss_notation Signature Sub-Packet Notation Data
- * \return NULL if cannot allocate memory or other error
- * \return pointer to structure, if no error
- */
-pgp_text_t *
-pgp_showall_notation(pgp_ss_notation_t ss_notation)
-{
- return showall_octets_bits(&ss_notation.flags,
- ss_notation_map,
- PGP_ARRAY_SIZE(ss_notation_map));
-}
diff --git a/libs/netpgp/reader.c b/libs/netpgp/src/reader.c
similarity index 92%
rename from libs/netpgp/reader.c
rename to libs/netpgp/src/reader.c
index d0afc748..68bc1a4d 100644
--- a/libs/netpgp/reader.c
+++ b/libs/netpgp/src/reader.c
@@ -46,7 +46,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "config-netpgp.h"
+#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include
@@ -54,7 +54,7 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: reader.c,v 1.49 2012/03/05 02:20:18 christos Exp $");
+__RCSID("$NetBSD$");
#endif
#include
@@ -120,39 +120,20 @@ __RCSID("$NetBSD: reader.c,v 1.49 2012/03/05 02:20:18 christos Exp $");
#include
#endif
-#include "errors-netpgp.h"
-#include "crypto-netpgp.h"
-#include "create-netpgp.h"
-#include "signature-netpgp.h"
-#include "packet-netpgp.h"
-#include "packet-parse.h"
-#include "packet-show.h"
-#include "keyring-netpgp.h"
-#include "readerwriter-netpgp.h"
-#include "netpgpsdk.h"
-#include "netpgpdefs.h"
-#include "netpgpdigest.h"
+#include "netpgp/errors.h"
+#include "netpgp/crypto.h"
+#include "netpgp/create.h"
+#include "netpgp/signature.h"
+#include "netpgp/packet.h"
+#include "netpgp/packet-parse.h"
+#include "netpgp/packet-show.h"
+#include "netpgp/packet.h"
+#include "netpgp/keyring.h"
+#include "netpgp/readerwriter.h"
+#include "netpgp/netpgpsdk.h"
+#include "netpgp/netpgpdefs.h"
+#include "netpgp/netpgpdigest.h"
-/* data from partial blocks is queued up in virtual block in stream */
-static int
-read_partial_data(pgp_stream_t *stream, void *dest, size_t length)
-{
- unsigned n;
-
- if (pgp_get_debug_level(__FILE__)) {
- (void) fprintf(stderr, "fd_reader: coalesced data, off %d\n",
- stream->virtualoff);
- }
- n = MIN(stream->virtualc - stream->virtualoff, (unsigned)length);
- (void) memcpy(dest, &stream->virtualpkt[stream->virtualoff], n);
- stream->virtualoff += n;
- if (stream->virtualoff == stream->virtualc) {
- free(stream->virtualpkt);
- stream->virtualpkt = NULL;
- stream->virtualc = stream->virtualoff = 0;
- }
- return (int)n;
-}
/* get a pass phrase from the user */
int
@@ -233,6 +214,10 @@ pgp_reader_pop(pgp_stream_t *stream)
{
pgp_reader_t *next = stream->readinfo.next;
+ if (stream->readinfo.accumulate && stream->readinfo.asize > 0) {
+ free(stream->readinfo.accumulated);
+ }
+
stream->readinfo = *next;
free(next);
}
@@ -448,6 +433,9 @@ read_char(pgp_stream_t *stream, dearmour_t *dearmour,
do {
if (dearmour->pushbackc) {
+ if (!dearmour->pushback) {
+ return -1;
+ }
c = dearmour->pushback[--dearmour->pushbackc];
if (dearmour->pushbackc == 0) {
free(dearmour->pushback);
@@ -844,8 +832,8 @@ read4(pgp_stream_t *stream, dearmour_t *dearmour, pgp_error_t **errors,
pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo,
int *pc, unsigned *pn, uint32_t *pl)
{
- int n, c;
- uint32_t l = 0;
+ int n = 0, c = 0;
+ uint32_t l = 0;
for (n = 0; n < 4; ++n) {
c = read_char(stream, dearmour, errors, readinfo, cbinfo, 1);
@@ -1398,7 +1386,7 @@ typedef struct {
size_t off;
pgp_crypt_t *decrypt;
pgp_region_t *region;
- unsigned prevplain:1;
+ // unsigned prevplain:1;
} encrypted_t;
static int
@@ -1414,6 +1402,8 @@ encrypted_data_reader(pgp_stream_t *stream, void *dest,
encrypted = pgp_reader_get_arg(readinfo);
saved = (int)length;
+
+#if 0
/*
* V3 MPIs have the count plain and the cipher is reset after each
* count
@@ -1430,13 +1420,15 @@ encrypted_data_reader(pgp_stream_t *stream, void *dest,
readinfo->parent->reading_mpi_len) {
encrypted->prevplain = 1;
}
+#endif
+
while (length > 0) {
if (encrypted->c) {
unsigned n;
/*
* if we are reading v3 we should never read
- * more than we're asked for */
+ * more than we're asked for
if (length < encrypted->c &&
(readinfo->parent->reading_v3_secret ||
readinfo->parent->exact_read)) {
@@ -1444,6 +1436,7 @@ encrypted_data_reader(pgp_stream_t *stream, void *dest,
"encrypted_data_reader: bad v3 read\n");
return 0;
}
+ */
n = (int)MIN(length, encrypted->c);
(void) memcpy(dest,
encrypted->decrypted + encrypted->off, n);
@@ -1475,18 +1468,19 @@ encrypted_data_reader(pgp_stream_t *stream, void *dest,
/*
* we can only read as much as we're asked for
* in v3 keys because they're partially
- * unencrypted! */
+ * unencrypted!
if ((readinfo->parent->reading_v3_secret ||
readinfo->parent->exact_read) && n > length) {
n = (unsigned)length;
}
+ */
if (!pgp_stacked_limited_read(stream, buffer, n,
encrypted->region, errors, readinfo, cbinfo)) {
return -1;
}
- if (!readinfo->parent->reading_v3_secret ||
- !readinfo->parent->reading_mpi_len) {
+ //if (!readinfo->parent->reading_v3_secret ||
+ // !readinfo->parent->reading_mpi_len) {
encrypted->c =
pgp_decrypt_se_ip(encrypted->decrypt,
encrypted->decrypted, buffer, n);
@@ -1495,11 +1489,11 @@ encrypted_data_reader(pgp_stream_t *stream, void *dest,
hexdump(stderr, "encrypted", buffer, 16);
hexdump(stderr, "decrypted", encrypted->decrypted, 16);
}
- } else {
- (void) memcpy(
- &encrypted->decrypted[encrypted->off], buffer, n);
- encrypted->c = n;
- }
+ //} else {
+ // (void) memcpy(
+ //&encrypted->decrypted[encrypted->off], buffer, n);
+ //encrypted->c = n;
+ //}
if (encrypted->c == 0) {
(void) fprintf(stderr,
@@ -1780,11 +1774,9 @@ fd_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
__PGP_USED(cbinfo);
reader = pgp_reader_get_arg(readinfo);
- if (!stream->coalescing && stream->virtualc && stream->virtualoff < stream->virtualc) {
- n = read_partial_data(stream, dest, length);
- } else {
- n = (int)read(reader->fd, dest, length);
- }
+
+ n = (int)read(reader->fd, dest, length);
+
if (n == 0) {
return 0;
}
@@ -1837,20 +1829,18 @@ mem_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors
__PGP_USED(cbinfo);
__PGP_USED(errors);
- if (!stream->coalescing && stream->virtualc && stream->virtualoff < stream->virtualc) {
- n = read_partial_data(stream, dest, length);
- } else {
- if (reader->offset + length > reader->length) {
- n = (unsigned)(reader->length - reader->offset);
- } else {
- n = (unsigned)length;
- }
- if (n == (unsigned)0) {
- return 0;
- }
- memcpy(dest, reader->buffer + reader->offset, n);
- reader->offset += n;
- }
+
+ if (reader->offset + length > reader->length) {
+ n = (unsigned)(reader->length - reader->offset);
+ } else {
+ n = (unsigned)length;
+ }
+ if (n == (unsigned)0) {
+ return 0;
+ }
+ memcpy(dest, reader->buffer + reader->offset, n);
+ reader->offset += n;
+
return n;
}
@@ -2124,7 +2114,7 @@ pgp_litdata_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
if (pgp_get_debug_level(__FILE__)) {
printf("pgp_litdata_cb: ");
- pgp_print_packet(&cbinfo->printstate, pkt);
+ //pgp_print_packet(&cbinfo->printstate, pkt);
}
/* Read data from packet into static buffer */
switch (pkt->tag) {
@@ -2161,7 +2151,7 @@ pgp_pk_sesskey_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
io = cbinfo->io;
if (pgp_get_debug_level(__FILE__)) {
- pgp_print_packet(&cbinfo->printstate, pkt);
+ //pgp_print_packet(&cbinfo->printstate, pkt);
}
/* Read data from packet into static buffer */
switch (pkt->tag) {
@@ -2177,7 +2167,8 @@ pgp_pk_sesskey_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
from = 0;
cbinfo->cryptinfo.keydata =
pgp_getkeybyid(io, cbinfo->cryptinfo.secring,
- content->pk_sesskey.key_id, &from, NULL);
+ content->pk_sesskey.key_id, &from, NULL, NULL,
+ 0, 0); /* accepts revoked and expired */
if (!cbinfo->cryptinfo.keydata) {
break;
}
@@ -2208,55 +2199,67 @@ pgp_cb_ret_t
pgp_get_seckey_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
{
const pgp_contents_t *content = &pkt->u;
- const pgp_seckey_t *secret;
- const pgp_key_t *pubkey;
- const pgp_key_t *keypair;
+ pgp_seckey_t *secret;
+ // const pgp_key_t *pubkey;
+ //const pgp_key_t *keypair;
unsigned from;
pgp_io_t *io;
- int i;
+ //int i;
+
+ pgp_cryptinfo_t *cryptinfo = &cbinfo->cryptinfo;
+ key_id_t *key_id;
io = cbinfo->io;
if (pgp_get_debug_level(__FILE__)) {
- pgp_print_packet(&cbinfo->printstate, pkt);
+ //pgp_print_packet(&cbinfo->printstate, pkt);
}
switch (pkt->tag) {
case PGP_GET_SECKEY:
/* print key from pubring */
- from = 0;
- pubkey = pgp_getkeybyid(io, cbinfo->cryptinfo.pubring,
- content->get_seckey.pk_sesskey->key_id,
- &from, NULL);
- /* validate key from secring */
+ // from = 0;
+ // pubkey = pgp_getkeybyid(io, cbinfo->cryptinfo.pubring,
+ // content->get_seckey.pk_sesskey->key_id,
+ // &from, NULL);
+ // /* validate key from secring */
+
+ EXPAND_ARRAY(cryptinfo, recipients_key_ids);
+ key_id = &cryptinfo->recipients_key_idss[cryptinfo->recipients_key_idsc++];
+ memcpy(key_id, content->get_seckey.pk_sesskey->key_id, sizeof(key_id_t));
+
from = 0;
cbinfo->cryptinfo.keydata =
pgp_getkeybyid(io, cbinfo->cryptinfo.secring,
content->get_seckey.pk_sesskey->key_id,
- &from, NULL);
+ &from, NULL, &secret, 0, 0);
if (!cbinfo->cryptinfo.keydata ||
+ !secret ||
!pgp_is_key_secret(cbinfo->cryptinfo.keydata)) {
return (pgp_cb_ret_t)0;
}
- keypair = cbinfo->cryptinfo.keydata;
- if (pubkey == NULL) {
- pubkey = keypair;
- }
- secret = NULL;
- cbinfo->gotpass = 0;
- for (i = 0 ; cbinfo->numtries == -1 || i < cbinfo->numtries ; i++) {
- /* print out the user id */
- pgp_print_keydata(io, cbinfo->cryptinfo.pubring, pubkey,
- "signature ", &pubkey->key.pubkey, 0);
- /* now decrypt key */
- secret = pgp_decrypt_seckey(keypair, cbinfo->passfp);
- if (secret != NULL) {
- break;
- }
- (void) fprintf(io->errs, "Bad passphrase\n");
- }
- if (secret == NULL) {
- (void) fprintf(io->errs, "Exhausted passphrase attempts\n");
- return (pgp_cb_ret_t)PGP_RELEASE_MEMORY;
- }
+
+ // FIXME : support encrypted seckeys again
+ // keypair = cbinfo->cryptinfo.keydata;
+ // if (pubkey == NULL) {
+ // pubkey = keypair;
+ // }
+ // secret = NULL;
+ // cbinfo->gotpass = 0;
+ // for (i = 0 ; cbinfo->numtries == -1 || i < cbinfo->numtries ; i++) {
+ // /* print out the user id */
+ // pgp_print_keydata(io, cbinfo->cryptinfo.pubring, pubkey,
+ // "signature ", &pubkey->key.pubkey, 0);
+ // /* now decrypt key */
+ // pgp_decrypt_seckey(keypair, cbinfo->passfp);
+ // if (secret != NULL) {
+ // break;
+ // }
+ // (void) fprintf(io->errs, "Bad passphrase\n");
+ // }
+ // if (secret == NULL) {
+ // (void) fprintf(io->errs, "Exhausted passphrase attempts\n");
+ // return (pgp_cb_ret_t)PGP_RELEASE_MEMORY;
+ // }
+
cbinfo->gotpass = 1;
*content->get_seckey.seckey = secret;
break;
@@ -2268,39 +2271,6 @@ pgp_get_seckey_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
return PGP_RELEASE_MEMORY;
}
-/**
- \ingroup HighLevel_Callbacks
- \brief Callback to use when you need to prompt user for passphrase
- \param contents
- \param cbinfo
-*/
-pgp_cb_ret_t
-get_passphrase_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
-{
- const pgp_contents_t *content = &pkt->u;
- pgp_io_t *io;
-
- io = cbinfo->io;
- if (pgp_get_debug_level(__FILE__)) {
- pgp_print_packet(&cbinfo->printstate, pkt);
- }
- if (cbinfo->cryptinfo.keydata == NULL) {
- (void) fprintf(io->errs, "get_passphrase_cb: NULL keydata\n");
- } else {
- pgp_print_keydata(io, cbinfo->cryptinfo.pubring, cbinfo->cryptinfo.keydata, "signature ",
- &cbinfo->cryptinfo.keydata->key.pubkey, 0);
- }
- switch (pkt->tag) {
- case PGP_GET_PASSPHRASE:
- *(content->skey_passphrase.passphrase) =
- netpgp_strdup(getpass("netpgp passphrase: "));
- return PGP_KEEP_MEMORY;
- default:
- break;
- }
- return PGP_RELEASE_MEMORY;
-}
-
unsigned
pgp_reader_set_accumulate(pgp_stream_t *stream, unsigned state)
{
@@ -2363,15 +2333,12 @@ mmap_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **error
__PGP_USED(errors);
__PGP_USED(cbinfo);
- if (!stream->coalescing && stream->virtualc && stream->virtualoff < stream->virtualc) {
- n = read_partial_data(stream, dest, length);
- } else {
- n = (unsigned)MIN(length, (unsigned)(mem->size - mem->offset));
- if (n > 0) {
- (void) memcpy(dest, &cmem[(int)mem->offset], (unsigned)n);
- mem->offset += n;
- }
- }
+
+ n = (unsigned)MIN(length, (unsigned)(mem->size - mem->offset));
+ if (n > 0) {
+ (void) memcpy(dest, &cmem[(int)mem->offset], (unsigned)n);
+ mem->offset += n;
+ }
return (int)n;
}
diff --git a/libs/netpgp/signature.c b/libs/netpgp/src/signature.c
similarity index 84%
rename from libs/netpgp/signature.c
rename to libs/netpgp/src/signature.c
index e9887582..94a4366c 100644
--- a/libs/netpgp/signature.c
+++ b/libs/netpgp/src/signature.c
@@ -49,7 +49,7 @@
/** \file
*/
-#include "config-netpgp.h"
+#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include
@@ -57,7 +57,7 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: signature.c,v 1.34 2012/03/05 02:20:18 christos Exp $");
+__RCSID("$NetBSD$");
#endif
#include
@@ -77,29 +77,16 @@ __RCSID("$NetBSD: signature.c,v 1.34 2012/03/05 02:20:18 christos Exp $");
#include
#endif
-#include "signature-netpgp.h"
-#include "crypto-netpgp.h"
-#include "create-netpgp.h"
-#include "netpgpsdk.h"
-#include "readerwriter-netpgp.h"
-#include "validate-netpgp.h"
-#include "netpgpdefs.h"
-#include "netpgpdigest.h"
+#include "netpgp/signature.h"
+#include "netpgp/crypto.h"
+#include "netpgp/create.h"
+#include "netpgp/netpgpsdk.h"
+#include "netpgp/readerwriter.h"
+#include "netpgp/validate.h"
+#include "netpgp/netpgpdefs.h"
+#include "netpgp/netpgpdigest.h"
-/** \ingroup Core_Create
- * needed for signature creation
- */
-struct pgp_create_sig_t {
- pgp_hash_t hash;
- pgp_sig_t sig;
- pgp_memory_t *mem;
- pgp_output_t *output; /* how to do the writing */
- unsigned hashoff; /* hashed count offset */
- unsigned hashlen;
- unsigned unhashoff;
-};
-
/**
\ingroup Core_Signature
Creates new pgp_create_sig_t
@@ -149,6 +136,11 @@ static uint8_t prefix_sha256[] = {
0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
};
+static uint8_t prefix_sha512[] = {
+ 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+ 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
+ 0x00, 0x04, 0x40
+};
/* XXX: both this and verify would be clearer if the signature were */
/* treated as an MPI. */
@@ -174,11 +166,16 @@ rsa_sign(pgp_hash_t *hash,
prefix = prefix_sha1;
prefixsize = sizeof(prefix_sha1);
expected = PGP_SHA1_HASH_SIZE;
- } else {
+ } else if (strcmp(hash->name, "SHA256") == 0) {
hashsize = PGP_SHA256_HASH_SIZE + sizeof(prefix_sha256);
prefix = prefix_sha256;
prefixsize = sizeof(prefix_sha256);
expected = PGP_SHA256_HASH_SIZE;
+ } else {
+ hashsize = PGP_SHA512_HASH_SIZE + sizeof(prefix_sha512);
+ prefix = prefix_sha512;
+ prefixsize = sizeof(prefix_sha512);
+ expected = PGP_SHA512_HASH_SIZE;
}
keysize = (BN_num_bits(pubrsa->n) + 7) / 8;
if (keysize > sizeof(hashbuf)) {
@@ -231,7 +228,7 @@ dsa_sign(pgp_hash_t *hash,
unsigned hashsize;
unsigned t;
uint8_t hashbuf[NETPGP_BUFSIZ];
- DSA_SIG *dsasig;
+ pgp_dsa_sig_t *pgpdsasig;
/* hashsize must be "equal in size to the number of bits of q, */
/* the group generated by the DSA key's generator value */
@@ -249,12 +246,18 @@ dsa_sign(pgp_hash_t *hash,
pgp_write(output, &hashbuf[0], 2);
/* write signature to buf */
- dsasig = pgp_dsa_sign(hashbuf, hashsize, sdsa, dsa);
+ pgpdsasig = pgp_dsa_sign(hashbuf, hashsize, sdsa, dsa);
+
+ if(pgpdsasig == NULL)
+ return 0;
/* convert and write the sig out to memory */
- pgp_write_mpi(output, dsasig->r);
- pgp_write_mpi(output, dsasig->s);
- DSA_SIG_free(dsasig);
+ pgp_write_mpi(output, pgpdsasig->r);
+ pgp_write_mpi(output, pgpdsasig->s);
+
+ BN_free(pgpdsasig->r);
+ BN_free(pgpdsasig->s);
+ free(pgpdsasig);
return 1;
}
@@ -273,8 +276,6 @@ rsa_verify(pgp_hash_alg_t type,
uint8_t sigbuf[NETPGP_BUFSIZ];
uint8_t hashbuf_from_sig[NETPGP_BUFSIZ];
- plen = 0;
- prefix = (const uint8_t *) "";
keysize = BN_num_bytes(pubrsa->n);
/* RSA key can't be bigger than 65535 bits, so... */
if (keysize > sizeof(hashbuf_from_sig)) {
@@ -315,6 +316,10 @@ rsa_verify(pgp_hash_alg_t type,
prefix = prefix_sha256;
plen = sizeof(prefix_sha256);
break;
+ case PGP_HASH_SHA512:
+ prefix = prefix_sha512;
+ plen = sizeof(prefix_sha512);
+ break;
default:
(void) fprintf(stderr, "Unknown hash algorithm: %d\n", type);
return 0;
@@ -356,6 +361,7 @@ hash_add_key(pgp_hash_t *hash, const pgp_pubkey_t *key)
pgp_hash_add_int(hash, 0x99, 1);
pgp_hash_add_int(hash, (unsigned)len, 2);
hash->add(hash, pgp_mem_data(mem), (unsigned)len);
+
pgp_memory_free(mem);
}
@@ -380,12 +386,11 @@ init_key_sig(pgp_hash_t *hash, const pgp_sig_t *sig,
}
static void
-hash_add_trailer(pgp_hash_t *hash, const pgp_sig_t *sig,
- const uint8_t *raw_packet)
+hash_add_trailer(pgp_hash_t *hash, const pgp_sig_t *sig)
{
if (sig->info.version == PGP_V4) {
- if (raw_packet) {
- hash->add(hash, raw_packet + sig->v4_hashstart,
+ if (sig->info.v4_hashlen) {
+ hash->add(hash, sig->info.v4_hashed,
(unsigned)sig->info.v4_hashlen);
}
pgp_hash_add_int(hash, (unsigned)sig->info.version, 1);
@@ -416,8 +421,8 @@ pgp_check_sig(const uint8_t *hash, unsigned length,
if (pgp_get_debug_level(__FILE__)) {
hexdump(stdout, "hash", hash, length);
}
- ret = 0;
- switch (sig->info.key_alg) {
+
+ switch (sig->info.key_alg) {
case PGP_PKA_DSA:
ret = pgp_dsa_verify(hash, length, &sig->info.sig.dsa,
&signer->key.dsa);
@@ -452,10 +457,9 @@ hash_and_check_sig(pgp_hash_t *hash,
static unsigned
finalise_sig(pgp_hash_t *hash,
const pgp_sig_t *sig,
- const pgp_pubkey_t *signer,
- const uint8_t *raw_packet)
+ const pgp_pubkey_t *signer)
{
- hash_add_trailer(hash, sig, raw_packet);
+ hash_add_trailer(hash, sig);
return hash_and_check_sig(hash, sig, signer);
}
@@ -475,8 +479,7 @@ unsigned
pgp_check_useridcert_sig(const pgp_pubkey_t *key,
const uint8_t *id,
const pgp_sig_t *sig,
- const pgp_pubkey_t *signer,
- const uint8_t *raw_packet)
+ const pgp_pubkey_t *signer)
{
pgp_hash_t hash;
size_t userid_len;
@@ -488,7 +491,7 @@ pgp_check_useridcert_sig(const pgp_pubkey_t *key,
pgp_hash_add_int(&hash, (unsigned)userid_len, 4);
}
hash.add(&hash, id, (unsigned)userid_len);
- return finalise_sig(&hash, sig, signer, raw_packet);
+ return finalise_sig(&hash, sig, signer);
}
/**
@@ -507,8 +510,7 @@ unsigned
pgp_check_userattrcert_sig(const pgp_pubkey_t *key,
const pgp_data_t *attribute,
const pgp_sig_t *sig,
- const pgp_pubkey_t *signer,
- const uint8_t *raw_packet)
+ const pgp_pubkey_t *signer)
{
pgp_hash_t hash;
@@ -518,7 +520,7 @@ pgp_check_userattrcert_sig(const pgp_pubkey_t *key,
pgp_hash_add_int(&hash, (unsigned)attribute->len, 4);
}
hash.add(&hash, attribute->contents, (unsigned)attribute->len);
- return finalise_sig(&hash, sig, signer, raw_packet);
+ return finalise_sig(&hash, sig, signer);
}
/**
@@ -537,15 +539,14 @@ unsigned
pgp_check_subkey_sig(const pgp_pubkey_t *key,
const pgp_pubkey_t *subkey,
const pgp_sig_t *sig,
- const pgp_pubkey_t *signer,
- const uint8_t *raw_packet)
+ const pgp_pubkey_t *signer)
{
pgp_hash_t hash;
unsigned ret;
init_key_sig(&hash, sig, key);
hash_add_key(&hash, subkey);
- ret = finalise_sig(&hash, sig, signer, raw_packet);
+ ret = finalise_sig(&hash, sig, signer);
return ret;
}
@@ -563,14 +564,13 @@ pgp_check_subkey_sig(const pgp_pubkey_t *key,
unsigned
pgp_check_direct_sig(const pgp_pubkey_t *key,
const pgp_sig_t *sig,
- const pgp_pubkey_t *signer,
- const uint8_t *raw_packet)
+ const pgp_pubkey_t *signer)
{
pgp_hash_t hash;
unsigned ret;
init_key_sig(&hash, sig, key);
- ret = finalise_sig(&hash, sig, signer, raw_packet);
+ ret = finalise_sig(&hash, sig, signer);
return ret;
}
@@ -592,7 +592,7 @@ pgp_check_hash_sig(pgp_hash_t *hash,
const pgp_pubkey_t *signer)
{
return (sig->info.hash_alg == hash->alg) ?
- finalise_sig(hash, sig, signer, NULL) :
+ finalise_sig(hash, sig, signer) :
0;
}
@@ -649,6 +649,22 @@ pgp_sig_start_key_sig(pgp_create_sig_t *sig,
start_sig_in_mem(sig);
}
+void
+pgp_sig_start_key_rev(pgp_create_sig_t *sig,
+ const pgp_pubkey_t *key,
+ pgp_sig_type_t type)
+{
+ sig->output = pgp_output_new();
+
+ sig->sig.info.version = PGP_V4;
+ sig->sig.info.hash_alg = PGP_HASH_SHA1;
+ sig->sig.info.key_alg = key->alg;
+ sig->sig.info.type = type;
+ sig->hashlen = (unsigned)-1;
+ init_key_sig(&sig->hash, &sig->sig, key);
+ start_sig_in_mem(sig);
+}
+
/**
* \ingroup Core_Signature
*
@@ -831,17 +847,100 @@ pgp_write_sig(pgp_output_t *output,
return ret;
}
-/* add a time stamp to the output */
unsigned
-pgp_add_time(pgp_create_sig_t *sig, int64_t when, const char *type)
+pgp_add_creation_time(pgp_create_sig_t *sig, time_t when)
{
pgp_content_enum tag;
- tag = (strcmp(type, "birth") == 0) ?
- PGP_PTAG_SS_CREATION_TIME : PGP_PTAG_SS_EXPIRATION_TIME;
- /* just do 32-bit timestamps for just now - it's in the protocol */
+ tag = PGP_PTAG_SS_CREATION_TIME;
+
+ sig->sig.info.birthtime = when;
+ sig->sig.info.birthtime_set = 1;
+
+ return pgp_write_ss_header(sig->output, 5, tag) &&
+ pgp_write_scalar(sig->output, (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, (uint32_t)when, (unsigned)sizeof(uint32_t));
+ pgp_write_scalar(sig->output, (unsigned int)duration, 4);
+}
+
+unsigned
+pgp_add_key_flags(pgp_create_sig_t *sig, uint8_t flags)
+{
+ pgp_content_enum tag;
+
+ tag = PGP_PTAG_SS_KEY_FLAGS;
+
+ sig->sig.info.key_flags = flags;
+ sig->sig.info.key_flags_set = 1;
+
+ return pgp_write_ss_header(sig->output, 2, tag) &&
+ pgp_write_scalar(sig->output, (unsigned int)flags, 1);
+}
+
+unsigned
+pgp_add_key_prefs(pgp_create_sig_t *sig)
+{
+
+ /* Mimic of GPG default settings, limited to supported algos */
+
+ return
+ /* Symmetric algo prefs */
+ pgp_write_ss_header(sig->output, 6, PGP_PTAG_SS_PREFERRED_SKA) &&
+ pgp_write_scalar(sig->output, PGP_SA_AES_256, 1) &&
+ pgp_write_scalar(sig->output, PGP_SA_AES_128, 1) &&
+ pgp_write_scalar(sig->output, PGP_SA_CAST5, 1) &&
+ pgp_write_scalar(sig->output, PGP_SA_TRIPLEDES, 1) &&
+ pgp_write_scalar(sig->output, PGP_SA_IDEA, 1) &&
+
+ /* Hash algo prefs */
+ pgp_write_ss_header(sig->output, 6, PGP_PTAG_SS_PREFERRED_HASH) &&
+ pgp_write_scalar(sig->output, PGP_HASH_SHA256, 1) &&
+ pgp_write_scalar(sig->output, PGP_HASH_SHA1, 1) &&
+ pgp_write_scalar(sig->output, PGP_HASH_SHA384, 1) &&
+ pgp_write_scalar(sig->output, PGP_HASH_SHA512, 1) &&
+ pgp_write_scalar(sig->output, PGP_HASH_SHA224, 1) &&
+
+ /* Compression algo prefs */
+ pgp_write_ss_header(sig->output, 3, PGP_PTAG_SS_PREF_COMPRESS) &&
+ pgp_write_scalar(sig->output, PGP_C_ZLIB, 1) &&
+ pgp_write_scalar(sig->output, PGP_C_BZIP2, 1);
+}
+
+unsigned
+pgp_add_key_features(pgp_create_sig_t *sig)
+{
+ pgp_content_enum tag;
+
+ tag = PGP_PTAG_SS_FEATURES;
+
+ return pgp_write_ss_header(sig->output, 2, tag) &&
+ pgp_write_scalar(sig->output, 0x01, 1);
}
/**
@@ -877,6 +976,19 @@ pgp_add_primary_userid(pgp_create_sig_t *sig, unsigned primary)
pgp_write_scalar(sig->output, primary, 1);
}
+unsigned
+pgp_add_revocation_reason(
+ pgp_create_sig_t *sig,
+ uint8_t code, const char *reason)
+{
+ size_t rlen = reason ? strlen(reason) : 0;
+ return pgp_write_ss_header(
+ sig->output, rlen + 1,
+ PGP_PTAG_SS_REVOCATION_REASON) &&
+ pgp_write_scalar(sig->output, code, 1) &&
+ pgp_write(sig->output, reason, (unsigned int)rlen);
+}
+
/**
* \ingroup Core_Signature
*
@@ -937,8 +1049,8 @@ pgp_sign_file(pgp_io_t *io,
const char *outname,
const pgp_seckey_t *seckey,
const char *hashname,
- const int64_t from,
- const uint64_t duration,
+ const time_t from,
+ const time_t duration,
const unsigned armored,
const unsigned cleartext,
const unsigned overwrite)
@@ -958,7 +1070,6 @@ pgp_sign_file(pgp_io_t *io,
infile = NULL;
output = NULL;
hash = NULL;
- fd_out = 0;
/* find the hash algorithm */
hash_alg = pgp_str_to_hash_alg(hashname);
@@ -1006,8 +1117,8 @@ pgp_sign_file(pgp_io_t *io,
/* - creation time */
/* - key id */
ret = pgp_writer_use_armored_sig(output) &&
- pgp_add_time(sig, (int64_t)from, "birth") &&
- pgp_add_time(sig, (int64_t)duration, "expiration");
+ pgp_add_creation_time(sig, from) &&
+ pgp_add_sig_expiration_time(sig, duration);
if (ret == 0) {
pgp_teardown_file_write(output, fd_out);
return 0;
@@ -1053,8 +1164,8 @@ pgp_sign_file(pgp_io_t *io,
#endif
/* add creation time to signature */
- pgp_add_time(sig, (int64_t)from, "birth");
- pgp_add_time(sig, (int64_t)duration, "expiration");
+ pgp_add_creation_time(sig, from);
+ pgp_add_sig_expiration_time(sig, duration);
/* add key id to signature */
pgp_keyid(keyid, PGP_KEY_ID_SIZE, &seckey->pubkey, hash_alg);
pgp_add_issuer_keyid(sig, keyid);
@@ -1090,8 +1201,8 @@ pgp_sign_buf(pgp_io_t *io,
const void *input,
const size_t insize,
const pgp_seckey_t *seckey,
- const int64_t from,
- const uint64_t duration,
+ const time_t from,
+ const time_t duration,
const char *hashname,
const unsigned armored,
const unsigned cleartext)
@@ -1111,7 +1222,6 @@ pgp_sign_buf(pgp_io_t *io,
output = NULL;
mem = pgp_memory_new();
hash = NULL;
- ret = 0;
hash_alg = pgp_str_to_hash_alg(hashname);
if (hash_alg == PGP_HASH_UNKNOWN) {
@@ -1147,8 +1257,8 @@ pgp_sign_buf(pgp_io_t *io,
ret = pgp_writer_push_clearsigned(output, sig) &&
pgp_write(output, input, (unsigned)insize) &&
pgp_writer_use_armored_sig(output) &&
- pgp_add_time(sig, from, "birth") &&
- pgp_add_time(sig, (int64_t)duration, "expiration");
+ pgp_add_creation_time(sig, from) &&
+ pgp_add_sig_expiration_time(sig, duration);
if (ret == 0) {
return NULL;
}
@@ -1178,8 +1288,8 @@ pgp_sign_buf(pgp_io_t *io,
}
/* add creation time to signature */
- pgp_add_time(sig, from, "birth");
- pgp_add_time(sig, (int64_t)duration, "expiration");
+ pgp_add_creation_time(sig, from);
+ pgp_add_sig_expiration_time(sig, duration);
/* add key id to signature */
pgp_keyid(keyid, PGP_KEY_ID_SIZE, &seckey->pubkey, hash_alg);
pgp_add_issuer_keyid(sig, keyid);
@@ -1200,10 +1310,10 @@ int
pgp_sign_detached(pgp_io_t *io,
const char *f,
char *sigfile,
- pgp_seckey_t *seckey,
+ const pgp_seckey_t *seckey,
const char *hash,
- const int64_t from,
- const uint64_t duration,
+ const time_t from,
+ const time_t duration,
const unsigned armored, const unsigned overwrite)
{
pgp_create_sig_t *sig;
@@ -1246,14 +1356,13 @@ pgp_sign_detached(pgp_io_t *io,
pgp_memory_free(mem);
/* calculate the signature */
- pgp_add_time(sig, from, "birth");
- pgp_add_time(sig, (int64_t)duration, "expiration");
+ pgp_add_creation_time(sig, from);
+ pgp_add_sig_expiration_time(sig, duration);
pgp_keyid(keyid, sizeof(keyid), &seckey->pubkey, hash_alg);
pgp_add_issuer_keyid(sig, keyid);
pgp_end_hashed_subpkts(sig);
pgp_write_sig(output, sig, &seckey->pubkey, seckey);
pgp_teardown_file_write(output, fd);
- pgp_seckey_free(seckey);
return 1;
}
diff --git a/libs/netpgp/symmetric.c b/libs/netpgp/src/symmetric.c
similarity index 98%
rename from libs/netpgp/symmetric.c
rename to libs/netpgp/src/symmetric.c
index bacdc4c9..033d1d04 100644
--- a/libs/netpgp/symmetric.c
+++ b/libs/netpgp/src/symmetric.c
@@ -46,7 +46,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "config-netpgp.h"
+#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include
@@ -54,11 +54,11 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: symmetric.c,v 1.18 2010/11/07 08:39:59 agc Exp $");
+__RCSID("$NetBSD$");
#endif
-#include "crypto-netpgp.h"
-#include "packet-show.h"
+#include "netpgp/crypto.h"
+#include "netpgp/packet-show.h"
#include
@@ -82,8 +82,8 @@ __RCSID("$NetBSD: symmetric.c,v 1.18 2010/11/07 08:39:59 agc Exp $");
#include
#endif
-#include "crypto-netpgp.h"
-#include "netpgpdefs.h"
+#include "netpgp/crypto.h"
+#include "netpgp/netpgpdefs.h"
static void
diff --git a/libs/netpgp/validate.c b/libs/netpgp/src/validate.c
similarity index 54%
rename from libs/netpgp/validate.c
rename to libs/netpgp/src/validate.c
index 3f07a882..084a96c6 100644
--- a/libs/netpgp/validate.c
+++ b/libs/netpgp/src/validate.c
@@ -46,7 +46,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "config-netpgp.h"
+#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include
@@ -54,7 +54,7 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: validate.c,v 1.44 2012/03/05 02:20:18 christos Exp $");
+__RCSID("$NetBSD$");
#endif
#include
@@ -72,76 +72,67 @@ __RCSID("$NetBSD: validate.c,v 1.44 2012/03/05 02:20:18 christos Exp $");
#include
#endif
-#include "packet-parse.h"
-#include "packet-show.h"
-#include "keyring-netpgp.h"
-#include "signature-netpgp.h"
-#include "netpgpsdk.h"
-#include "readerwriter-netpgp.h"
-#include "netpgpdefs.h"
-#include "memory-netpgp.h"
-#include "packet-netpgp.h"
-#include "crypto-netpgp.h"
-#include "validate-netpgp.h"
+#include "netpgp/packet-parse.h"
+#include "netpgp/packet-show.h"
+#include "netpgp/keyring.h"
+#include "netpgp/signature.h"
+#include "netpgp/netpgpsdk.h"
+#include "netpgp/readerwriter.h"
+#include "netpgp/netpgpdefs.h"
+#include "netpgp/memory.h"
+#include "netpgp/packet.h"
+#include "netpgp/crypto.h"
+#include "netpgp/validate.h"
#ifdef HAVE_FCNTL_H
#include
#endif
-
-static int
-keydata_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
- pgp_reader_t *readinfo,
- pgp_cbdata_t *cbinfo)
-{
- validate_reader_t *reader = pgp_reader_get_arg(readinfo);
-
- __PGP_USED(stream);
- __PGP_USED(errors);
- __PGP_USED(cbinfo);
- if (reader->offset == reader->key->packets[reader->packet].length) {
- reader->packet += 1;
- reader->offset = 0;
- }
- if (reader->packet == reader->key->packetc) {
- return 0;
- }
-
- /*
- * we should never be asked to cross a packet boundary in a single
- * read
- */
- if (reader->key->packets[reader->packet].length <
- reader->offset + length) {
- (void) fprintf(stderr, "keydata_reader: weird length\n");
- return 0;
- }
-
- (void) memcpy(dest,
- &reader->key->packets[reader->packet].raw[reader->offset],
- length);
- reader->offset += (unsigned)length;
-
- return (int)length;
-}
+// FIXME to support seckey decryption again.
+//
+// static int
+// keydata_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
+// pgp_reader_t *readinfo,
+// pgp_cbdata_t *cbinfo)
+// {
+// validate_reader_t *reader = pgp_reader_get_arg(readinfo);
+//
+// __PGP_USED(stream);
+// __PGP_USED(errors);
+// __PGP_USED(cbinfo);
+// if (reader->offset == reader->key->packets[reader->packet].length) {
+// reader->packet += 1;
+// reader->offset = 0;
+// }
+// if (reader->packet == reader->key->packetc) {
+// return 0;
+// }
+//
+// /*
+// * we should never be asked to cross a packet boundary in a single
+// * read
+// */
+// if (reader->key->packets[reader->packet].length <
+// reader->offset + length) {
+// (void) fprintf(stderr, "keydata_reader: weird length\n");
+// return 0;
+// }
+//
+// (void) memcpy(dest,
+// &reader->key->packets[reader->packet].raw[reader->offset],
+// length);
+// reader->offset += (unsigned)length;
+//
+// return (int)length;
+// }
static void
free_sig_info(pgp_sig_info_t *sig)
{
- free(sig->v4_hashed);
+ pgp_free_sig_info(sig);
free(sig);
}
-static void
-copy_sig_info(pgp_sig_info_t *dst, const pgp_sig_info_t *src)
-{
- (void) memcpy(dst, src, sizeof(*src));
- if ((dst->v4_hashed = calloc(1, src->v4_hashlen)) == NULL) {
- (void) fprintf(stderr, "copy_sig_info: bad alloc\n");
- } else {
- (void) memcpy(dst->v4_hashed, src->v4_hashed, src->v4_hashlen);
- }
-}
static int
add_sig_to_list(const pgp_sig_info_t *sig, pgp_sig_info_t **sigs,
@@ -232,16 +223,36 @@ check_binary_sig(const uint8_t *data,
return pgp_check_sig(hashout, n, sig, signer);
}
+static void validate_key_cb_free (validate_key_cb_t *vdata){
+
+ /* Free according to previous allocated type */
+ if (vdata->type == PGP_PTAG_CT_PUBLIC_KEY) {
+ pgp_pubkey_free(&vdata->key.pubkey);
+ pgp_pubkey_free(&vdata->subkey.pubkey);
+ } else if (vdata->type == PGP_PTAG_CT_SECRET_KEY) {
+ pgp_seckey_free(&vdata->key.seckey);
+ if(vdata->subkey.seckey.pubkey.alg)
+ pgp_seckey_free(&vdata->subkey.seckey);
+ }
+ memset(&vdata->key, 0, sizeof(vdata->key));
+ memset(&vdata->subkey, 0, sizeof(vdata->subkey));
+ vdata->type = PGP_PTAG_CT_RESERVED; /* 0 */
+
+ pgp_userid_free(&vdata->userid);
+ pgp_data_free(&vdata->userattr);
+
+ if(vdata->valid_sig_info.key_alg) {
+ pgp_free_sig_info(&vdata->valid_sig_info);
+ }
+}
+
pgp_cb_ret_t
pgp_validate_key_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
{
const pgp_contents_t *content = &pkt->u;
- const pgp_key_t *signer;
- validate_key_cb_t *key;
- pgp_pubkey_t *sigkey;
+ validate_key_cb_t *vdata;
pgp_error_t **errors;
pgp_io_t *io;
- unsigned from;
unsigned valid = 0;
io = cbinfo->io;
@@ -249,175 +260,270 @@ pgp_validate_key_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
(void) fprintf(io->errs, "%s\n",
pgp_show_packet_tag(pkt->tag));
}
- key = pgp_callback_arg(cbinfo);
+ vdata = pgp_callback_arg(cbinfo);
errors = pgp_callback_errors(cbinfo);
+
+ vdata->sig_is_valid &= pkt->tag == PGP_PARSER_PACKET_END;
+
switch (pkt->tag) {
case PGP_PTAG_CT_PUBLIC_KEY:
- if (key->pubkey.version != 0) {
- (void) fprintf(io->errs,
- "pgp_validate_key_cb: version bad\n");
- return PGP_FINISHED;
- }
- key->pubkey = content->pubkey;
- return PGP_KEEP_MEMORY;
+ validate_key_cb_free(vdata);
+ vdata->key.pubkey = content->pubkey;
+ pgp_keyid(vdata->pubkeyid, PGP_KEY_ID_SIZE,
+ &vdata->key.pubkey, PGP_HASH_SHA1); /* TODO v3*/
- case PGP_PTAG_CT_PUBLIC_SUBKEY:
- if (key->subkey.version) {
- pgp_pubkey_free(&key->subkey);
- }
- key->subkey = content->pubkey;
+ vdata->last_seen = LS_PRIMARY;
+ vdata->type = PGP_PTAG_CT_PUBLIC_KEY;
+ vdata->not_commited = 1;
return PGP_KEEP_MEMORY;
case PGP_PTAG_CT_SECRET_KEY:
- key->seckey = content->seckey;
- key->pubkey = key->seckey.pubkey;
+ /* TODO
+ * check pubkey seckey consistency */
+ validate_key_cb_free(vdata);
+ vdata->key.seckey = content->seckey;
+ pgp_keyid(vdata->pubkeyid, PGP_KEY_ID_SIZE,
+ &vdata->key.seckey.pubkey, PGP_HASH_SHA1); /* TODO v3*/
+ vdata->last_seen = LS_PRIMARY;
+ vdata->type = PGP_PTAG_CT_SECRET_KEY;
+ vdata->not_commited = 1;
return PGP_KEEP_MEMORY;
+ case PGP_PTAG_CT_PUBLIC_SUBKEY:
+ if(vdata->type == PGP_PTAG_CT_PUBLIC_KEY && (
+ vdata->last_seen == LS_ID ||
+ vdata->last_seen == LS_ATTRIBUTE)){
+ pgp_pubkey_free(&vdata->subkey.pubkey);
+ vdata->subkey.pubkey = content->pubkey;
+ vdata->last_seen = LS_SUBKEY;
+ return PGP_KEEP_MEMORY;
+ }else{
+ (void) fprintf(io->errs,
+ "pgp_validate_key_cb: unexpected public subkey packet");
+ vdata->last_seen = LS_UNKNOWN;
+ return PGP_RELEASE_MEMORY;
+ }
+
+ case PGP_PTAG_CT_SECRET_SUBKEY:
+ /* TODO
+ * check pubkey seckey consistency */
+ if(vdata->type == PGP_PTAG_CT_SECRET_KEY && (
+ vdata->last_seen == LS_ID ||
+ vdata->last_seen == LS_ATTRIBUTE)){
+ if(vdata->subkey.seckey.pubkey.alg)
+ pgp_seckey_free(&vdata->subkey.seckey);
+ vdata->subkey.seckey = content->seckey;
+ vdata->last_seen = LS_SUBKEY;
+ return PGP_KEEP_MEMORY;
+ }else{
+ (void) fprintf(io->errs,
+ "pgp_validate_key_cb: unexpected secret subkey packet");
+ vdata->last_seen = LS_UNKNOWN;
+ return PGP_RELEASE_MEMORY;
+ }
+
case PGP_PTAG_CT_USER_ID:
- if (key->userid) {
- pgp_userid_free(&key->userid);
- }
- key->userid = content->userid;
- key->last_seen = ID;
- return PGP_KEEP_MEMORY;
+ if(vdata->last_seen == LS_PRIMARY ||
+ vdata->last_seen == LS_ATTRIBUTE ||
+ vdata->last_seen == LS_ID){
+ if (vdata->userid) {
+ pgp_userid_free(&vdata->userid);
+ }
+ vdata->userid = content->userid;
+ vdata->last_seen = LS_ID;
+ return PGP_KEEP_MEMORY;
+ }else{
+ (void) fprintf(io->errs,
+ "pgp_validate_key_cb: unexpected userID packet");
+ vdata->last_seen = LS_UNKNOWN;
+ return PGP_RELEASE_MEMORY;
+ }
case PGP_PTAG_CT_USER_ATTR:
- if (content->userattr.len == 0) {
+ if(vdata->last_seen == LS_PRIMARY ||
+ vdata->last_seen == LS_ATTRIBUTE ||
+ vdata->last_seen == LS_ID){
+ if (content->userattr.len == 0) {
+ (void) fprintf(io->errs,
+ "pgp_validate_key_cb: user attribute length 0");
+ vdata->last_seen = LS_UNKNOWN;
+ return PGP_RELEASE_MEMORY;
+ }
+ (void) fprintf(io->outs, "user attribute, length=%d\n",
+ (int) content->userattr.len);
+ if (vdata->userattr.len) {
+ pgp_data_free(&vdata->userattr);
+ }
+ vdata->userattr = content->userattr;
+ vdata->last_seen = LS_ATTRIBUTE;
+ return PGP_KEEP_MEMORY;
+ }else{
(void) fprintf(io->errs,
- "pgp_validate_key_cb: user attribute length 0");
- return PGP_FINISHED;
- }
- (void) fprintf(io->outs, "user attribute, length=%d\n",
- (int) content->userattr.len);
- if (key->userattr.len) {
- pgp_data_free(&key->userattr);
- }
- key->userattr = content->userattr;
- key->last_seen = ATTRIBUTE;
- return PGP_KEEP_MEMORY;
-
+ "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 */
- 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,
- "pgp_validate_key_cb: user attribute length 0");
- return PGP_FINISHED;
- }
- break;
- }
- if (sigkey == &signer->enckey) {
- (void) fprintf(io->errs,
- "WARNING: signature made with encryption key\n");
- }
+ case PGP_PTAG_CT_SIGNATURE_FOOTER:{ /* V4 sigs */
+ pgp_pubkey_t *sigkey = NULL;
+ pgp_pubkey_t *primary_pubkey;
+
+ if(vdata->last_seen == LS_UNKNOWN)
+ break;
+
+ primary_pubkey =
+ (vdata->type == PGP_PTAG_CT_PUBLIC_KEY) ?
+ &vdata->key.pubkey:
+ &vdata->key.seckey.pubkey;
+
+ if(vdata->keyring){
+ unsigned from;
+ from = 0;
+ /* Returned key ignored, care about ID-targeted pubkey only */
+ pgp_getkeybyid(io, vdata->keyring,
+ content->sig.info.signer_id,
+ &from, &sigkey, NULL,
+ 1, 0); /* reject revoked, accept expired */
+ } else {
+ /* If no keyring is given to check against
+ * then this is a self certification check.
+ * First ensure signature issuer ID is pubkey's ID*/
+ if(memcmp(vdata->pubkeyid,
+ content->sig.info.signer_id,
+ PGP_KEY_ID_SIZE) == 0){
+ sigkey = primary_pubkey;
+ }
+ }
+ if (!sigkey) {
+ if (vdata->result && !add_sig_to_list(&content->sig.info,
+ &vdata->result->unknown_sigs,
+ &vdata->result->unknownc)) {
+ (void) fprintf(io->errs,
+ "pgp_validate_key_cb: out of memory");
+ return PGP_FINISHED;
+ }
+ break;
+ }
switch (content->sig.info.type) {
case PGP_CERT_GENERIC:
case PGP_CERT_PERSONA:
case PGP_CERT_CASUAL:
case PGP_CERT_POSITIVE:
case PGP_SIG_REV_CERT:
- valid = (key->last_seen == ID) ?
- pgp_check_useridcert_sig(&key->pubkey,
- key->userid,
+ if(vdata->last_seen == LS_ID){
+ valid = pgp_check_useridcert_sig(
+ primary_pubkey,
+ vdata->userid,
&content->sig,
- pgp_get_pubkey(signer),
- key->reader->key->packets[
- key->reader->packet].raw) :
- pgp_check_userattrcert_sig(&key->pubkey,
- &key->userattr,
+ sigkey);
+ } else if(vdata->last_seen == LS_ATTRIBUTE) {
+ valid = pgp_check_userattrcert_sig(
+ primary_pubkey,
+ &vdata->userattr,
&content->sig,
- pgp_get_pubkey(signer),
- key->reader->key->packets[
- key->reader->packet].raw);
+ sigkey);
+ }
break;
+ case PGP_SIG_REV_SUBKEY:
case PGP_SIG_SUBKEY:
/*
- * XXX: we should also check that the signer is the
- * key we are validating, I think.
+ * we ensure that the signing key is the
+ * primary key we are validating, "vdata->pubkey".
*/
- valid = pgp_check_subkey_sig(&key->pubkey,
- &key->subkey,
- &content->sig,
- pgp_get_pubkey(signer),
- key->reader->key->packets[
- key->reader->packet].raw);
+ if(vdata->last_seen == LS_SUBKEY &&
+ memcmp(vdata->pubkeyid,
+ content->sig.info.signer_id,
+ PGP_KEY_ID_SIZE) == 0 )
+ {
+ valid = pgp_check_subkey_sig(
+ primary_pubkey,
+ (vdata->type == PGP_PTAG_CT_PUBLIC_KEY) ?
+ &vdata->subkey.pubkey:
+ &vdata->subkey.seckey.pubkey,
+ &content->sig,
+ primary_pubkey);
+ }
break;
+ case PGP_SIG_REV_KEY:
case PGP_SIG_DIRECT:
- valid = pgp_check_direct_sig(&key->pubkey,
- &content->sig,
- pgp_get_pubkey(signer),
- key->reader->key->packets[
- key->reader->packet].raw);
+ if(vdata->last_seen == LS_PRIMARY){
+ valid = pgp_check_direct_sig(
+ primary_pubkey,
+ &content->sig,
+ sigkey);
+ }
break;
case PGP_SIG_STANDALONE:
case PGP_SIG_PRIMARY:
- case PGP_SIG_REV_KEY:
- case PGP_SIG_REV_SUBKEY:
case PGP_SIG_TIMESTAMP:
case PGP_SIG_3RD_PARTY:
- PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED,
- "Sig Verification type 0x%02x not done yet\n",
- content->sig.info.type);
- break;
+ if (vdata->result){
+ PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED,
+ "Sig Verification type 0x%02x not done yet\n",
+ content->sig.info.type);
+ break;
+ }
default:
- PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED,
- "Unexpected signature type 0x%02x\n",
- content->sig.info.type);
+ if (vdata->result){
+ PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED,
+ "Unexpected signature type 0x%02x\n",
+ content->sig.info.type);
+ }
}
if (valid) {
- if (!add_sig_to_list(&content->sig.info,
- &key->result->valid_sigs,
- &key->result->validc)) {
+ if (vdata->result && !add_sig_to_list(&content->sig.info,
+ &vdata->result->valid_sigs,
+ &vdata->result->validc)) {
PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED, "%s",
- "Can't add good sig to list\n");
+ "Can't add valid sig to list\n");
}
- } else {
+ vdata->sig_is_valid = 1;
+ copy_sig_info(&vdata->valid_sig_info,
+ &content->sig.info);
+ } else if (vdata->result){
PGP_ERROR_1(errors, PGP_E_V_BAD_SIGNATURE, "%s",
"Bad Sig");
if (!add_sig_to_list(&content->sig.info,
- &key->result->invalid_sigs,
- &key->result->invalidc)) {
+ &vdata->result->invalid_sigs,
+ &vdata->result->invalidc)) {
PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED, "%s",
- "Can't add good sig to list\n");
+ "Can't add invalid sig to list\n");
}
}
break;
+ }
+ case PGP_PARSER_PACKET_END:
+ if(vdata->sig_is_valid){
+ pgp_cb_ret_t ret = PGP_RELEASE_MEMORY;
+ if(vdata->on_valid){
+ ret = vdata->on_valid(vdata, &content->packet);
+ }
+ vdata->sig_is_valid = 0;
+ vdata->not_commited = 0;
+ return ret;
+ }
+ return PGP_RELEASE_MEMORY;
- /* ignore these */
+ /* ignore these */
case PGP_PARSER_PTAG:
case PGP_PTAG_CT_SIGNATURE_HEADER:
- case PGP_PARSER_PACKET_END:
- break;
-
- case PGP_GET_PASSPHRASE:
- if (key->getpassphrase) {
- return key->getpassphrase(pkt, cbinfo);
- }
- break;
-
case PGP_PTAG_CT_TRUST:
- /* 1 byte for level (depth), 1 byte for trust amount */
- printf("trust dump\n");
- printf("Got trust\n");
- //hexdump(stdout, (const uint8_t *)content->trust.data, 10, " ");
- //hexdump(stdout, (const uint8_t *)&content->ss_trust, 2, " ");
- //printf("Trust level %d, amount %d\n", key->trust.level, key->trust.amount);
break;
+ // case PGP_GET_PASSPHRASE:
+ // if (vdata->getpassphrase) {
+ // return vdata->getpassphrase(pkt, cbinfo);
+ // }
+ // break;
+
default:
- (void) fprintf(stderr, "unexpected tag=0x%x\n", pkt->tag);
- return PGP_FINISHED;
+ // (void) fprintf(stderr, "unexpected tag=0x%x\n", pkt->tag);
+ return PGP_RELEASE_MEMORY;
}
return PGP_RELEASE_MEMORY;
}
@@ -426,7 +532,7 @@ pgp_cb_ret_t
validate_data_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
{
const pgp_contents_t *content = &pkt->u;
- const pgp_key_t *signer;
+ pgp_key_t *signer;
validate_data_cb_t *data;
pgp_pubkey_t *sigkey;
pgp_error_t **errors;
@@ -480,9 +586,11 @@ validate_data_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
sizeof(content->sig.info.signer_id));
}
from = 0;
+ sigkey = NULL;
signer = pgp_getkeybyid(io, data->keyring,
- content->sig.info.signer_id, &from, &sigkey);
- if (!signer) {
+ content->sig.info.signer_id, &from, &sigkey, NULL,
+ 0, 0); /* check neither revocation nor expiry */
+ if (!signer || !sigkey) {
PGP_ERROR_1(errors, PGP_E_V_UNKNOWN_SIGNER,
"%s", "Unknown Signer");
if (!add_sig_to_list(&content->sig.info,
@@ -493,10 +601,6 @@ validate_data_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
}
break;
}
- if (sigkey == &signer->enckey) {
- (void) fprintf(io->errs,
- "WARNING: signature made with encryption key\n");
- }
if (content->sig.info.birthtime_set) {
data->result->birthtime = content->sig.info.birthtime;
}
@@ -506,8 +610,8 @@ validate_data_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
switch (content->sig.info.type) {
case PGP_SIG_BINARY:
case PGP_SIG_TEXT:
- if (pgp_mem_len(data->mem) == 0 &&
- data->detachname) {
+ if (pgp_mem_len(data->mem) == 0){
+ if(data->detachname) {
/* check we have seen some data */
/* if not, need to read from detached name */
(void) fprintf(io->errs,
@@ -515,7 +619,8 @@ validate_data_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
data->detachname);
data->mem = pgp_memory_new();
pgp_mem_readfile(data->mem, data->detachname);
- }
+ }
+ }
if (pgp_get_debug_level(__FILE__)) {
hexdump(stderr, "sig dump", (const uint8_t *)(const void *)&content->sig,
sizeof(content->sig));
@@ -523,7 +628,7 @@ validate_data_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
valid = check_binary_sig(pgp_mem_data(data->mem),
(const unsigned)pgp_mem_len(data->mem),
&content->sig,
- pgp_get_pubkey(signer));
+ sigkey);
break;
default:
@@ -571,27 +676,6 @@ validate_data_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
return PGP_RELEASE_MEMORY;
}
-static void
-keydata_destroyer(pgp_reader_t *readinfo)
-{
- free(pgp_reader_get_arg(readinfo));
-}
-
-void
-pgp_keydata_reader_set(pgp_stream_t *stream, const pgp_key_t *key)
-{
- validate_reader_t *data;
-
- if ((data = calloc(1, sizeof(*data))) == NULL) {
- (void) fprintf(stderr, "pgp_keydata_reader_set: bad alloc\n");
- } else {
- data->key = key;
- data->packet = 0;
- data->offset = 0;
- pgp_reader_set(stream, keydata_reader, keydata_destroyer, data);
- }
-}
-
static char *
fmtsecs(int64_t n, char *buf, size_t size)
{
@@ -669,81 +753,195 @@ validate_result_status(FILE *errs, const char *f, pgp_validation_t *val)
return val->validc && !val->invalidc && !val->unknownc;
}
-/**
- * \ingroup HighLevel_Verify
- * \brief Validate all signatures on a single key against the given keyring
- * \param result Where to put the result
- * \param key Key to validate
- * \param keyring Keyring to use for validation
- * \param cb_get_passphrase Callback to use to get passphrase
- * \return 1 if all signatures OK; else 0
- * \note It is the caller's responsiblity to free result after use.
- * \sa pgp_validate_result_free()
- */
+typedef struct key_filter_cb_t{
+ pgp_keyring_t *destpubring;
+ pgp_keyring_t *destsecring;
+ pgp_key_t *pubkey;
+ pgp_key_t *seckey;
+} key_filter_cb_t;
+
+static pgp_cb_ret_t key_filter_cb (
+ validate_key_cb_t *vdata,
+ const pgp_subpacket_t *sigpkt)
+{
+ pgp_key_t *pubkey;
+ pgp_key_t *seckey = NULL;
+ key_filter_cb_t *filter = vdata->on_valid_args;
+
+ if(vdata->not_commited){
+
+ if((filter->pubkey = pgp_ensure_pubkey(filter->destpubring,
+ (vdata->type == PGP_PTAG_CT_PUBLIC_KEY) ?
+ &vdata->key.pubkey :
+ &vdata->key.seckey.pubkey,
+ vdata->pubkeyid))==NULL){
+ return PGP_RELEASE_MEMORY;
+ }
+
+ filter->seckey = NULL;
+ if (vdata->type == PGP_PTAG_CT_SECRET_KEY && filter->destsecring) {
+ if((filter->seckey = pgp_ensure_seckey(
+ filter->destsecring,
+ &vdata->key.seckey,
+ vdata->pubkeyid))==NULL){
+ return PGP_RELEASE_MEMORY;
+ }
+ }
+ /* TODO get seckey by ID id even if given key is public
+ * in order to update uids an attributes from pubkey */
+ }
+
+ pubkey = filter->pubkey;
+ if(pubkey == NULL)
+ return PGP_RELEASE_MEMORY;
+
+ if (vdata->type == PGP_PTAG_CT_SECRET_KEY) {
+ seckey = filter->seckey;
+ }
+
+ switch(vdata->last_seen){
+ case LS_PRIMARY:
+
+ pgp_add_directsig(pubkey, sigpkt, &vdata->valid_sig_info);
+
+ if (seckey) {
+ pgp_add_directsig(seckey, sigpkt, &vdata->valid_sig_info);
+ }
+ break;
+ case LS_ID:
+
+ pgp_update_userid(pubkey, vdata->userid, sigpkt, &vdata->valid_sig_info);
+ if (seckey) {
+ pgp_update_userid(seckey, vdata->userid, sigpkt, &vdata->valid_sig_info);
+ }
+
+ break;
+ case LS_ATTRIBUTE:
+ /* TODO */
+ break;
+ case LS_SUBKEY:
+ pgp_update_subkey(pubkey,
+ vdata->type, &vdata->subkey,
+ sigpkt, &vdata->valid_sig_info);
+ if (seckey) {
+ pgp_update_subkey(seckey,
+ vdata->type, &vdata->subkey,
+ sigpkt, &vdata->valid_sig_info);
+ }
+
+ break;
+ default:
+ break;
+ }
+ return PGP_RELEASE_MEMORY;
+}
+
unsigned
-pgp_validate_key_sigs(pgp_validation_t *result,
- const pgp_key_t *key,
- const pgp_keyring_t *keyring,
- pgp_cb_ret_t cb_get_passphrase(const pgp_packet_t *,
- pgp_cbdata_t *))
+pgp_filter_keys_fileread(
+ pgp_io_t *io,
+ pgp_keyring_t *destpubring,
+ pgp_keyring_t *destsecring,
+ pgp_keyring_t *certring,
+ const unsigned armour,
+ const char *filename)
{
pgp_stream_t *stream;
- validate_key_cb_t keysigs;
- const int printerrors = 1;
+ validate_key_cb_t vdata;
+ key_filter_cb_t filter;
+ unsigned res = 1;
+ int fd;
- (void) memset(&keysigs, 0x0, sizeof(keysigs));
- keysigs.result = result;
- keysigs.getpassphrase = cb_get_passphrase;
+ (void) memset(&vdata, 0x0, sizeof(vdata));
+ vdata.result = NULL;
+ vdata.getpassphrase = NULL;
- stream = pgp_new(sizeof(*stream));
- /* pgp_parse_options(&opt,PGP_PTAG_CT_SIGNATURE,PGP_PARSE_PARSED); */
+ (void) memset(&filter, 0x0, sizeof(filter));
+ filter.destpubring = destpubring;
+ filter.destsecring = destsecring;
- keysigs.keyring = keyring;
+ fd = pgp_setup_file_read(io,
+ &stream,filename,
+ &vdata,
+ pgp_validate_key_cb,
+ 1);
- pgp_set_callback(stream, pgp_validate_key_cb, &keysigs);
- stream->readinfo.accumulate = 1;
- pgp_keydata_reader_set(stream, key);
-
- /* Note: Coverity incorrectly reports an error that keysigs.reader */
- /* is never used. */
- keysigs.reader = stream->readinfo.arg;
-
- pgp_parse(stream, !printerrors);
-
- pgp_pubkey_free(&keysigs.pubkey);
- if (keysigs.subkey.version) {
- pgp_pubkey_free(&keysigs.subkey);
+ if (fd < 0) {
+ perror(filename);
+ return 0;
}
- pgp_userid_free(&keysigs.userid);
- pgp_data_free(&keysigs.userattr);
+
+ pgp_parse_options(stream, PGP_PTAG_SS_ALL, PGP_PARSE_PARSED);
+
+ if (armour) {
+ pgp_reader_push_dearmour(stream);
+ }
+
+ vdata.keyring = certring;
+
+ vdata.on_valid = &key_filter_cb;
+ vdata.on_valid_args = &filter;
+
+ res = pgp_parse(stream, 0);
+
+ validate_key_cb_free(&vdata);
+
+ if (armour) {
+ pgp_reader_pop_dearmour(stream);
+ }
+
+ (void)close(fd);
pgp_stream_delete(stream);
- return (!result->invalidc && !result->unknownc && result->validc);
+ return res;
}
-/**
- \ingroup HighLevel_Verify
- \param result Where to put the result
- \param ring Keyring to use
- \param cb_get_passphrase Callback to use to get passphrase
- \note It is the caller's responsibility to free result after use.
- \sa pgp_validate_result_free()
-*/
unsigned
-pgp_validate_all_sigs(pgp_validation_t *result,
- const pgp_keyring_t *ring,
- pgp_cb_ret_t cb_get_passphrase(const pgp_packet_t *,
- pgp_cbdata_t *))
+pgp_filter_keys_from_mem(
+ pgp_io_t *io,
+ pgp_keyring_t *destpubring,
+ pgp_keyring_t *destsecring,
+ pgp_keyring_t *certring,
+ const unsigned armour,
+ pgp_memory_t *mem)
{
- unsigned n;
+ pgp_stream_t *stream;
+ validate_key_cb_t vdata;
+ key_filter_cb_t filter;
+ unsigned res;
- (void) memset(result, 0x0, sizeof(*result));
- for (n = 0; n < ring->keyc; ++n) {
- pgp_validate_key_sigs(result, &ring->keys[n], ring,
- cb_get_passphrase);
+ (void) memset(&vdata, 0x0, sizeof(vdata));
+ vdata.result = NULL;
+ vdata.getpassphrase = NULL;
+
+ (void) memset(&filter, 0x0, sizeof(filter));
+ filter.destpubring = destpubring;
+ filter.destsecring = destsecring;
+
+ stream = pgp_new(sizeof(*stream));
+ pgp_parse_options(stream, PGP_PTAG_SS_ALL, PGP_PARSE_PARSED);
+ pgp_setup_memory_read(io, &stream, mem, &vdata, pgp_validate_key_cb, 1);
+
+ if (armour) {
+ pgp_reader_push_dearmour(stream);
}
- return validate_result_status(stderr, "keyring", result);
+
+ vdata.keyring = certring;
+
+ vdata.on_valid = &key_filter_cb;
+ vdata.on_valid_args = &filter;
+
+ res = pgp_parse(stream, 0);
+
+ validate_key_cb_free(&vdata);
+
+ if (armour) {
+ pgp_reader_pop_dearmour(stream);
+ }
+
+ /* don't call teardown_memory_read because memory was passed in */
+ pgp_stream_delete(stream);
+ return res;
}
/**
@@ -846,9 +1044,6 @@ pgp_validate_file(pgp_io_t *io,
validation.keyring = keyring;
validation.mem = pgp_memory_new();
pgp_memory_init(validation.mem, 128);
- /* Note: Coverity incorrectly reports an error that validation.reader */
- /* is never used. */
- validation.reader = parse->readinfo.arg;
if (realarmour) {
pgp_reader_push_dearmour(parse);
@@ -910,20 +1105,21 @@ pgp_validate_file(pgp_io_t *io,
\param mem Memory to be validated
\param user_says_armoured Treat data as armoured, if set
\param keyring Keyring to use
+ \param detachmem detached memory (free done in this call if provided)
\return 1 if signature validates successfully; 0 if not
\note After verification, result holds the details of all keys which
have passed, failed and not been recognised.
\note It is the caller's responsiblity to call
pgp_validate_result_free(result) after use.
*/
-
-unsigned
-pgp_validate_mem(pgp_io_t *io,
+static inline unsigned
+_pgp_validate_mem(pgp_io_t *io,
pgp_validation_t *result,
pgp_memory_t *mem,
pgp_memory_t **cat,
const int user_says_armoured,
- const pgp_keyring_t *keyring)
+ const pgp_keyring_t *keyring,
+ pgp_memory_t *detachmem)
{
validate_data_cb_t validation;
pgp_stream_t *stream = NULL;
@@ -931,15 +1127,17 @@ pgp_validate_mem(pgp_io_t *io,
int realarmour;
pgp_setup_memory_read(io, &stream, mem, &validation, validate_data_cb, 1);
+
/* Set verification reader and handling options */
(void) memset(&validation, 0x0, sizeof(validation));
validation.result = result;
validation.keyring = keyring;
- validation.mem = pgp_memory_new();
- pgp_memory_init(validation.mem, 128);
- /* Note: Coverity incorrectly reports an error that validation.reader */
- /* is never used. */
- validation.reader = stream->readinfo.arg;
+ if (detachmem) {
+ validation.mem = detachmem;
+ }else{
+ validation.mem = pgp_memory_new();
+ pgp_memory_init(validation.mem, 128);
+ }
if ((realarmour = user_says_armoured) != 0 ||
strncmp(pgp_mem_data(mem),
@@ -964,8 +1162,44 @@ pgp_validate_mem(pgp_io_t *io,
/* need to send validated output somewhere */
*cat = validation.mem;
} else {
- pgp_memory_free(validation.mem);
+ pgp_memory_free(validation.mem);
}
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);
+}
+
diff --git a/libs/netpgp/writer.c b/libs/netpgp/src/writer.c
similarity index 92%
rename from libs/netpgp/writer.c
rename to libs/netpgp/src/writer.c
index e9f3a83d..83b4c79b 100644
--- a/libs/netpgp/writer.c
+++ b/libs/netpgp/src/writer.c
@@ -50,7 +50,7 @@
/** \file
* This file contains the base functions used by the writers.
*/
-#include "config-netpgp.h"
+#include "netpgp/config-netpgp.h"
#ifdef HAVE_SYS_CDEFS_H
#include
@@ -58,7 +58,7 @@
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: writer.c,v 1.33 2012/03/05 02:20:18 christos Exp $");
+__RCSID("$NetBSD$");
#endif
#include
@@ -74,17 +74,17 @@ __RCSID("$NetBSD: writer.c,v 1.33 2012/03/05 02:20:18 christos Exp $");
#include
#endif
-#include "create-netpgp.h"
-#include "writer-netpgp.h"
-#include "keyring-netpgp.h"
-#include "signature-netpgp.h"
-#include "packet-netpgp.h"
-#include "packet-parse.h"
-#include "readerwriter-netpgp.h"
-#include "memory-netpgp.h"
-#include "netpgpdefs.h"
-#include "version-netpgp.h"
-#include "netpgpdigest.h"
+#include "netpgp/create.h"
+#include "netpgp/writer.h"
+#include "netpgp/keyring.h"
+#include "netpgp/signature.h"
+#include "netpgp/packet.h"
+#include "netpgp/packet-parse.h"
+#include "netpgp/readerwriter.h"
+#include "netpgp/memory.h"
+#include "netpgp/netpgpdefs.h"
+#include "netpgp/version.h"
+#include "netpgp/netpgpdigest.h"
/*
@@ -285,11 +285,13 @@ pgp_writer_push(pgp_output_t *output,
{
pgp_writer_t *copy;
- if ((copy = calloc(1, sizeof(*copy))) == NULL) {
- (void) fprintf(stderr, "pgp_writer_push: bad alloc\n");
- } else if (output->writer.writer == NULL) {
+ if (output->writer.writer == NULL) {
(void) fprintf(stderr, "pgp_writer_push: no orig writer\n");
} else {
+ if ((copy = calloc(1, sizeof(*copy))) == NULL) {
+ (void) fprintf(stderr, "pgp_writer_push: bad alloc\n");
+ return; /* TODO return error */
+ }
*copy = output->writer;
output->writer.next = copy;
@@ -910,6 +912,7 @@ pgp_writer_push_armoured(pgp_output_t *output, pgp_armor_type_t type)
if ((base64 = calloc(1, sizeof(*base64))) == NULL) {
(void) fprintf(stderr,
"pgp_writer_push_armoured: bad alloc\n");
+ free(linebreak);
return;
}
base64->checksum = CRC24_INIT;
@@ -1011,6 +1014,7 @@ pgp_push_enc_crypt(pgp_output_t *output, pgp_crypt_t *pgp_crypt)
typedef struct {
pgp_crypt_t *crypt;
+ unsigned raw;
} encrypt_se_ip_t;
static unsigned encrypt_se_ip_writer(const uint8_t *,
@@ -1026,24 +1030,46 @@ static void encrypt_se_ip_destroyer(pgp_writer_t *);
\brief Push Encrypted SE IP Writer onto stack
*/
int
-pgp_push_enc_se_ip(pgp_output_t *output, const pgp_key_t *pubkey, const char *cipher)
+pgp_push_enc_se_ip(pgp_output_t *output, const pgp_keyring_t *pubkeys, const char *cipher, unsigned raw)
{
+ pgp_pk_sesskey_t *initial_sesskey = NULL;
pgp_pk_sesskey_t *encrypted_pk_sesskey;
encrypt_se_ip_t *se_ip;
pgp_crypt_t *encrypted;
uint8_t *iv;
+ unsigned n;
if ((se_ip = calloc(1, sizeof(*se_ip))) == NULL) {
(void) fprintf(stderr, "pgp_push_enc_se_ip: bad alloc\n");
return 0;
}
- /* Create and write encrypted PK session key */
- if ((encrypted_pk_sesskey = pgp_create_pk_sesskey(pubkey, cipher)) == NULL) {
- (void) fprintf(stderr, "pgp_push_enc_se_ip: null pk sesskey\n");
- return 0;
- }
- pgp_write_pk_sesskey(output, encrypted_pk_sesskey);
+ for (n = 0; n < pubkeys->keyc; ++n) {
+ /* Create and write encrypted PK session key */
+ if ((encrypted_pk_sesskey =
+ pgp_create_pk_sesskey(&pubkeys->keys[n],
+ cipher, initial_sesskey)) == NULL) {
+ (void) fprintf(stderr, "pgp_push_enc_se_ip: null pk sesskey\n");
+ free(se_ip);
+ return 0;
+ }
+
+ if (initial_sesskey == NULL) {
+ initial_sesskey = encrypted_pk_sesskey;
+ }
+
+ pgp_write_pk_sesskey(output, encrypted_pk_sesskey);
+
+ if(encrypted_pk_sesskey != initial_sesskey){
+ free(encrypted_pk_sesskey);
+ }
+ }
+
+ if (initial_sesskey == NULL) {
+ (void) fprintf(stderr, "pgp_push_enc_se_ip: no sesskey\n");
+ free(se_ip);
+ return 0;
+ }
/* Setup the se_ip */
if ((encrypted = calloc(1, sizeof(*encrypted))) == NULL) {
@@ -1051,7 +1077,7 @@ pgp_push_enc_se_ip(pgp_output_t *output, const pgp_key_t *pubkey, const char *ci
(void) fprintf(stderr, "pgp_push_enc_se_ip: bad alloc\n");
return 0;
}
- pgp_crypt_any(encrypted, encrypted_pk_sesskey->symm_alg);
+ pgp_crypt_any(encrypted, initial_sesskey->symm_alg);
if ((iv = calloc(1, encrypted->blocksize)) == NULL) {
free(se_ip);
free(encrypted);
@@ -1059,16 +1085,17 @@ pgp_push_enc_se_ip(pgp_output_t *output, const pgp_key_t *pubkey, const char *ci
return 0;
}
encrypted->set_iv(encrypted, iv);
- encrypted->set_crypt_key(encrypted, &encrypted_pk_sesskey->key[0]);
+ encrypted->set_crypt_key(encrypted, &initial_sesskey->key[0]);
pgp_encrypt_init(encrypted);
se_ip->crypt = encrypted;
+ se_ip->raw = raw;
/* And push writer on stack */
pgp_writer_push(output, encrypt_se_ip_writer, NULL,
encrypt_se_ip_destroyer, se_ip);
/* tidy up */
- free(encrypted_pk_sesskey);
+ free(initial_sesskey);
free(iv);
return 1;
}
@@ -1089,19 +1116,29 @@ encrypt_se_ip_writer(const uint8_t *src,
pgp_memory_t *localmem;
unsigned ret = 1;
+ const uint8_t *zsrc;
+ unsigned zsrclen;
+
pgp_setup_memory_write(&litoutput, &litmem, bufsz);
pgp_setup_memory_write(&zoutput, &zmem, bufsz);
pgp_setup_memory_write(&output, &localmem, bufsz);
- /* create literal data packet from source data */
- pgp_write_litdata(litoutput, src, (const int)len, PGP_LDT_BINARY);
- if (pgp_mem_len(litmem) <= len) {
- (void) fprintf(stderr, "encrypt_se_ip_writer: bad len\n");
- return 0;
- }
+ if (!se_ip->raw) {
+ /* create literal data packet from source data */
+ pgp_write_litdata(litoutput, src, (const int)len, PGP_LDT_BINARY);
+ if (pgp_mem_len(litmem) <= len) {
+ (void) fprintf(stderr, "encrypt_se_ip_writer: bad len\n");
+ return 0;
+ }
+ zsrc = pgp_mem_data(litmem);
+ zsrclen = (unsigned)pgp_mem_len(litmem);
+ }else{
+ zsrc = src;
+ zsrclen = len;
+ }
/* create compressed packet from literal data packet */
- pgp_writez(zoutput, pgp_mem_data(litmem), (unsigned)pgp_mem_len(litmem));
+ pgp_writez(zoutput, zsrc, zsrclen);
/* create SE IP packet set from this compressed literal data */
pgp_write_se_ip_pktset(output, pgp_mem_data(zmem),
@@ -1379,6 +1416,60 @@ pgp_push_checksum_writer(pgp_output_t *output, pgp_seckey_t *seckey)
/**************************************************************************/
+typedef struct {
+ uint16_t sum;
+} sum16_t;
+
+static unsigned
+sum16_writer(const uint8_t *src,
+ const unsigned len,
+ pgp_error_t **errors,
+ pgp_writer_t *writer)
+{
+ sum16_t *arg;
+ unsigned ret = 1;
+ int n;
+
+ arg = pgp_writer_get_arg(writer);
+
+ for (n = 0; n < len; ++n) {
+ arg->sum = (arg->sum + src[n]) & 0xffff;
+ }
+
+ /* write to next stacked writer */
+ ret = stacked_write(writer, src, len, errors);
+ /* tidy up and return */
+ return ret;
+}
+
+void
+pgp_push_sum16_writer(pgp_output_t *output)
+{
+ sum16_t *sum;
+
+ if ((sum = calloc(1, sizeof(*sum))) == NULL) {
+ (void) fprintf(stderr,
+ "pgp_push_sum16_writer: bad alloc\n");
+ } else {
+ pgp_writer_push(output, sum16_writer,
+ NULL, NULL, sum);
+ }
+}
+
+uint16_t
+pgp_pop_sum16_writer(pgp_output_t *output)
+{
+ uint16_t sum;
+ sum16_t *arg;
+ arg = pgp_writer_get_arg(&output->writer);
+ sum = arg->sum;
+ pgp_writer_pop(output);
+ free(arg);
+ return sum;
+}
+
+/**************************************************************************/
+
#define MAX_PARTIAL_DATA_LENGTH 1073741824
typedef struct {
@@ -1412,7 +1503,7 @@ static void str_enc_se_ip_destroyer(pgp_writer_t *writer);
\param pubkey
*/
void
-pgp_push_stream_enc_se_ip(pgp_output_t *output, const pgp_key_t *pubkey, const char *cipher)
+pgp_push_stream_enc_se_ip(pgp_output_t *output, pgp_key_t *pubkey, const char *cipher)
{
pgp_pk_sesskey_t *encrypted_pk_sesskey;
str_enc_se_ip_t *se_ip;
@@ -1425,7 +1516,7 @@ pgp_push_stream_enc_se_ip(pgp_output_t *output, const pgp_key_t *pubkey, const c
"pgp_push_stream_enc_se_ip: bad alloc\n");
return;
}
- encrypted_pk_sesskey = pgp_create_pk_sesskey(pubkey, cipher);
+ encrypted_pk_sesskey = pgp_create_pk_sesskey(pubkey, cipher, NULL);
pgp_write_pk_sesskey(output, encrypted_pk_sesskey);
/* Setup the se_ip */
@@ -1701,7 +1792,6 @@ str_enc_se_ip_writer(const uint8_t *src,
size_t datalength;
se_ip = pgp_writer_get_arg(writer);
- ret = 1;
if (se_ip->litoutput == NULL) {
/* first literal data chunk is not yet written */
diff --git a/src/mre2ee_driver_openssl.c b/src/mre2ee_driver_openssl.c
index b54c6412..7170386d 100644
--- a/src/mre2ee_driver_openssl.c
+++ b/src/mre2ee_driver_openssl.c
@@ -119,9 +119,10 @@ int mre2ee_driver_create_keypair(mrmailbox_t* mailbox, const char* addr, mrkey_t
/* generate keypair */
keypair = pgp_rsa_new_selfsign_key(2048/*bits*/, 65537UL/*e*/, (const uint8_t*)user_id, NULL, NULL);
- /* get public key */
+ /* write public key */
+ keypair->type = PGP_PTAG_CT_PUBLIC_KEY; // TODO: this seems to me like a hack, PLUS: add a subkey
pgp_writer_set_memory(output1, mem1);
- if( !pgp_write_xfer_pubkey(output1, keypair, 0/*armoured*/) ) {
+ if( !pgp_write_xfer_key(output1, keypair, 0/*armoured*/) ) {
goto cleanup;
}
@@ -132,8 +133,9 @@ int mre2ee_driver_create_keypair(mrmailbox_t* mailbox, const char* addr, mrkey_t
mrkey_set_from_raw(ret_public_key, (const unsigned char*)mem1->buf, mem1->length, MR_PRIVATE);
/* write private key */
+ keypair->type = PGP_PTAG_CT_SECRET_KEY; // TODO: this seems to me like a hack
pgp_writer_set_memory(output2, mem2);
- if( !pgp_write_xfer_seckey(output2, keypair, NULL, 0, 0/*armoured*/) ) {
+ if( !pgp_write_xfer_key(output2, keypair, 0/*armoured*/) ) {
goto cleanup;
}