summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos <nmav@crystal.(none)>2008-01-13 15:21:24 +0200
committerNikos <nmav@crystal.(none)>2008-01-13 15:21:24 +0200
commita0b2d269d69a25b2611380c85377197d03092283 (patch)
tree0ae919209178f08a82a5b1818b6c71e9ff07598d
parenta3e4759117cee5d756475215437a440dc12fcc6c (diff)
downloadgnutls-a0b2d269d69a25b2611380c85377197d03092283.tar.gz
merged the openpgp branch to head\!
-rw-r--r--README2
-rw-r--r--configure.in66
-rw-r--r--includes/gnutls/gnutls.h.in2
-rw-r--r--includes/gnutls/openpgp.h51
-rw-r--r--lib/Makefile.am27
-rw-r--r--lib/auth_cert.c124
-rw-r--r--lib/auth_cert.h2
-rw-r--r--lib/gnutls_cert.c65
-rw-r--r--lib/gnutls_cert.h4
-rw-r--r--lib/gnutls_errors.c2
-rw-r--r--lib/gnutls_extra_hooks.c76
-rw-r--r--lib/gnutls_extra_hooks.h106
-rw-r--r--lib/gnutls_openpgp.c (renamed from libextra/gnutls_openpgp.c)430
-rw-r--r--lib/gnutls_state.c4
-rw-r--r--lib/opencdk/Makefile.am (renamed from libextra/opencdk/Makefile.am)6
-rw-r--r--lib/opencdk/README (renamed from libextra/opencdk/README)0
-rw-r--r--lib/opencdk/armor.c (renamed from libextra/opencdk/armor.c)23
-rw-r--r--lib/opencdk/context.h (renamed from libextra/opencdk/context.h)0
-rw-r--r--lib/opencdk/dummy.c (renamed from libextra/opencdk/dummy.c)0
-rw-r--r--lib/opencdk/filters.h (renamed from libextra/opencdk/filters.h)0
-rw-r--r--lib/opencdk/hash.c81
-rw-r--r--lib/opencdk/kbnode.c (renamed from libextra/opencdk/kbnode.c)84
-rw-r--r--lib/opencdk/keydb.c (renamed from libextra/opencdk/keydb.c)37
-rw-r--r--lib/opencdk/literal.c (renamed from libextra/opencdk/literal.c)21
-rw-r--r--lib/opencdk/main.c (renamed from libextra/opencdk/main.c)23
-rw-r--r--lib/opencdk/main.h (renamed from libextra/opencdk/main.h)0
-rw-r--r--lib/opencdk/misc.c324
-rw-r--r--lib/opencdk/new-packet.c (renamed from libextra/opencdk/new-packet.c)23
-rw-r--r--lib/opencdk/opencdk.h (renamed from libextra/opencdk/opencdk.h)13
-rw-r--r--lib/opencdk/packet.h (renamed from libextra/opencdk/packet.h)0
-rw-r--r--lib/opencdk/pubkey.c (renamed from libextra/opencdk/pubkey.c)27
-rw-r--r--lib/opencdk/read-packet.c (renamed from libextra/opencdk/read-packet.c)58
-rw-r--r--lib/opencdk/seskey.c (renamed from libextra/opencdk/seskey.c)23
-rw-r--r--lib/opencdk/sig-check.c (renamed from libextra/opencdk/sig-check.c)23
-rw-r--r--lib/opencdk/stream.c (renamed from libextra/opencdk/stream.c)97
-rw-r--r--lib/opencdk/stream.h (renamed from libextra/opencdk/stream.h)0
-rw-r--r--lib/opencdk/types.h (renamed from libextra/opencdk/types.h)0
-rw-r--r--lib/opencdk/verify.c (renamed from libextra/opencdk/verify.c)23
-rw-r--r--lib/opencdk/write-packet.c (renamed from libextra/opencdk/write-packet.c)23
-rw-r--r--lib/openpgp/Makefile.am50
-rw-r--r--lib/openpgp/compat.c247
-rw-r--r--lib/openpgp/extras.c172
-rw-r--r--lib/openpgp/gnutls_openpgp.h99
-rw-r--r--lib/openpgp/openpgp.h107
-rw-r--r--lib/openpgp/output.c402
-rw-r--r--lib/openpgp/pgp.c1079
-rw-r--r--lib/openpgp/pgpverify.c144
-rw-r--r--lib/openpgp/privkey.c575
-rw-r--r--libextra/Makefile.am19
-rw-r--r--libextra/gnutls_extra.c18
-rw-r--r--libextra/opencdk/cipher.c529
-rw-r--r--libextra/opencdk/compress.c239
-rw-r--r--libextra/opencdk/misc.c564
-rw-r--r--src/Makefile.am12
-rw-r--r--src/certtool-gaa.c127
-rw-r--r--src/certtool-gaa.h28
-rw-r--r--src/certtool.c51
-rw-r--r--src/certtool.gaa2
-rw-r--r--src/cli.c8
-rw-r--r--src/serv.c6
-rw-r--r--src/tls_test.c6
61 files changed, 4107 insertions, 2247 deletions
diff --git a/README b/README
index a9658ff6e0..8e3ef9836c 100644
--- a/README
+++ b/README
@@ -67,7 +67,7 @@ see http://www.gnu.org/philosophy/why-not-lgpl.html.
The GNU Lesser GPL license applies to the main gnutls library, while the
gnutls-extra library is under the GPL. The gnutls-extra library contains
-the code for the "OpenPGP key" support and the OpenSSL compatibility layer.
+the code for "GnuTLS Inner Application" support and the OpenSSL compatibility layer.
The gnutls library is located in the lib/ directory, while the gnutls-extra
library is at libextra/.
diff --git a/configure.in b/configure.in
index d5bb2679b0..a201c829c6 100644
--- a/configure.in
+++ b/configure.in
@@ -198,7 +198,6 @@ AC_HEADER_STDC
AC_CHECK_HEADERS(strings.h alloca.h)
AC_CHECK_HEADERS(errno.h)
AC_CHECK_HEADERS(math.h limits.h float.h stdarg.h ctype.h)
-dnl opencdk
AC_CHECK_HEADERS(netdb.h)
AC_CHECK_FUNCS(umask vasprintf isascii fork,,)
AC_FUNC_ALLOCA
@@ -488,35 +487,38 @@ AM_CONDITIONAL(ENABLE_OPENPGP, test "$ac_enable_openpgp" = "yes")
dnl Test whether to use the included opencdk library
dnl
-if test x$ac_enable_openpgp = xyes; then
- AC_ARG_WITH(included-opencdk,
- AS_HELP_STRING([--with-included-opencdk], [use the included opencdk]),
- ac_enable_included_opencdk=$withval,
- ac_enable_included_opencdk=no)
- if test x$ac_enable_included_opencdk = xno;then
- AC_LIB_HAVE_LINKFLAGS(opencdk,, [
-#include <opencdk.h>], [
-#if OPENCDK_VERSION_MINOR < 6 || OPENCDK_VERSION_PATCH < 5
-# error "OpenCDK 0.6.5 is required"
-#else
-cdk_check_version( NULL);
-#endif
-])
- if test "$ac_cv_libopencdk" != yes; then
- ac_enable_included_opencdk=yes
- AC_MSG_WARN([[
-***
-*** libopencdk was not found. You may want to get it from
-*** ftp://ftp.gnutls.org/pub/gnutls/opencdk/
-***
-*** Will use the included opencdk.
-***
-]])
- fi
- AC_MSG_CHECKING([whether to use the included opencdk])
- AC_MSG_RESULT($ac_enable_included_opencdk)
- fi
-fi
+dnl We no longer test for it. We use the LGPL parts of this library internally
+dnl if test x$ac_enable_openpgp = xyes; then
+dnl AC_ARG_WITH(included-opencdk,
+dnl AS_HELP_STRING([--with-included-opencdk], [use the included opencdk]),
+dnl ac_enable_included_opencdk=$withval,
+dnl ac_enable_included_opencdk=no)
+dnl if test x$ac_enable_included_opencdk = xno;then
+dnl AC_LIB_HAVE_LINKFLAGS(opencdk,, [
+dnl #include <opencdk.h>], [
+dnl #if OPENCDK_VERSION_MINOR < 6 || OPENCDK_VERSION_PATCH < 5
+dnl # error "OpenCDK 0.6.5 is required"
+dnl #else
+dnl cdk_check_version( NULL);
+dnl #endif
+dnl ])
+dnl if test "$ac_cv_libopencdk" != yes; then
+dnl ac_enable_included_opencdk=yes
+dnl AC_MSG_WARN([[
+dnl ***
+dnl *** libopencdk was not found. You may want to get it from
+dnl *** ftp://ftp.gnutls.org/pub/gnutls/opencdk/
+dnl ***
+dnl *** Will use the included opencdk.
+dnl ***
+dnl ]])
+dnl fi
+dnl AC_MSG_CHECKING([whether to use the included opencdk])
+dnl AC_MSG_RESULT($ac_enable_included_opencdk)
+dnl fi
+dnl fi
+
+ac_enable_included_opencdk=yes
AM_CONDITIONAL(ENABLE_INCLUDED_OPENCDK, test "$ac_enable_included_opencdk" = "yes")
@@ -717,8 +719,8 @@ AC_CONFIG_FILES([Makefile po/Makefile.in \
tests/hostname-check/Makefile \
includes/Makefile includes/gnutls/gnutls.h \
lib/Makefile lib/minitasn1/Makefile lib/x509/Makefile \
- libextra/Makefile libextra/openpgp/Makefile libextra/opencdk/Makefile \
- tests/openpgp/Makefile \
+ libextra/Makefile lib/openpgp/Makefile lib/opencdk/Makefile \
+ libextra/minilzo/Makefile tests/openpgp/Makefile \
src/Makefile \
src/cfg/Makefile src/cfg/platon/Makefile src/cfg/platon/str/Makefile \
lib/libgnutls-config libextra/libgnutls-extra-config \
diff --git a/includes/gnutls/gnutls.h.in b/includes/gnutls/gnutls.h.in
index c043c6fd94..11d1526ea2 100644
--- a/includes/gnutls/gnutls.h.in
+++ b/includes/gnutls/gnutls.h.in
@@ -1275,6 +1275,8 @@ extern "C"
#define GNUTLS_E_RANDOM_FAILED -206
#define GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR -207
+#define GNUTLS_E_OPENPGP_SUBKEY_ERROR -208
+
#define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250
diff --git a/includes/gnutls/openpgp.h b/includes/gnutls/openpgp.h
index fae404c8a8..850dfa08c5 100644
--- a/includes/gnutls/openpgp.h
+++ b/includes/gnutls/openpgp.h
@@ -37,6 +37,11 @@ extern "C"
#include <gnutls/gnutls.h>
#include <gnutls/extra.h>
+ typedef struct
+ {
+ unsigned char keyid[8];
+ } gnutls_openpgp_keyid_t;
+
/* gnutls_openpgp_cert_t should be defined in gnutls.h
*/
@@ -53,6 +58,10 @@ extern "C"
void *output_data,
size_t * output_data_size);
+ int gnutls_openpgp_crt_print (gnutls_openpgp_crt_t cert,
+ gnutls_certificate_print_formats_t format,
+ gnutls_datum_t *out);
+
/* The key_usage flags are defined in gnutls.h. They are
* the GNUTLS_KEY_* definitions.
*/
@@ -74,11 +83,24 @@ extern "C"
time_t gnutls_openpgp_crt_get_expiration_time (gnutls_openpgp_crt_t key);
int gnutls_openpgp_crt_get_id (gnutls_openpgp_crt_t key,
- unsigned char keyid[8]);
+ gnutls_openpgp_keyid_t* keyid);
int gnutls_openpgp_crt_check_hostname (gnutls_openpgp_crt_t key,
const char *hostname);
+ int gnutls_openpgp_crt_get_revoked_status (gnutls_openpgp_crt_t key);
+
+ int gnutls_openpgp_crt_get_subkey_count (gnutls_openpgp_crt_t key);
+ int gnutls_openpgp_crt_get_subkey_idx (gnutls_openpgp_crt_t key, gnutls_openpgp_keyid_t keyid);
+ int gnutls_openpgp_crt_get_subkey_revoked_status (gnutls_openpgp_crt_t key, unsigned int idx);
+ gnutls_pk_algorithm_t gnutls_openpgp_crt_get_subkey_pk_algorithm (gnutls_openpgp_crt_t key,
+ unsigned int idx, unsigned int *bits);
+ time_t gnutls_openpgp_crt_get_subkey_creation_time (gnutls_openpgp_crt_t key, unsigned int idx);
+ time_t gnutls_openpgp_crt_get_subkey_expiration_time (gnutls_openpgp_crt_t key, unsigned int idx);
+ int gnutls_openpgp_crt_get_subkey_id (gnutls_openpgp_crt_t key, unsigned int idx, gnutls_openpgp_keyid_t* keyid);
+ int gnutls_openpgp_crt_get_subkey_usage (gnutls_openpgp_crt_t key, unsigned int idx,
+ unsigned int *key_usage);
+
/* privkey stuff.
*/
int gnutls_openpgp_privkey_init (gnutls_openpgp_privkey_t * key);
@@ -91,14 +113,33 @@ extern "C"
gnutls_openpgp_crt_fmt_t format,
const char *pass, unsigned int flags);
int gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key,
- const gnutls_datum_t * hash,
- gnutls_datum_t * signature);
+ gnutls_openpgp_keyid_t subkeyid,
+ const gnutls_datum_t * hash,
+ gnutls_datum_t * signature);
+ int gnutls_openpgp_privkey_get_fingerprint (gnutls_openpgp_privkey_t key,
+ void *fpr, size_t * fprlen);
+ int gnutls_openpgp_privkey_get_key_id (gnutls_openpgp_privkey_t key, gnutls_openpgp_keyid_t* keyid);
+ int gnutls_openpgp_privkey_get_subkey_count (gnutls_openpgp_privkey_t key);
+ int gnutls_openpgp_privkey_get_subkey_idx (gnutls_openpgp_privkey_t key, gnutls_openpgp_keyid_t keyid);
+
+ int gnutls_openpgp_privkey_get_subkey_revoked_status (gnutls_openpgp_privkey_t key, unsigned int idx);
+
+ int gnutls_openpgp_privkey_get_revoked_status (gnutls_openpgp_privkey_t key);
+
+ gnutls_pk_algorithm_t gnutls_openpgp_privkey_get_subkey_pk_algorithm (gnutls_openpgp_privkey_t key,
+ unsigned int idx, unsigned int *bits);
+
+ time_t gnutls_openpgp_privkey_get_subkey_expiration_time (gnutls_openpgp_privkey_t key, unsigned int idx);
+
+ int gnutls_openpgp_privkey_get_subkey_id (gnutls_openpgp_privkey_t key, unsigned int idx, gnutls_openpgp_keyid_t* keyid);
+
+ time_t gnutls_openpgp_privkey_get_subkey_creation_time (gnutls_openpgp_privkey_t key, unsigned int idx);
/* Keyring stuff.
*/
struct gnutls_openpgp_keyring_int; /* object to hold (parsed) openpgp keyrings */
typedef struct gnutls_openpgp_keyring_int *gnutls_openpgp_keyring_t;
-
+
int gnutls_openpgp_keyring_init (gnutls_openpgp_keyring_t * keyring);
void gnutls_openpgp_keyring_deinit (gnutls_openpgp_keyring_t keyring);
@@ -107,7 +148,7 @@ extern "C"
gnutls_openpgp_crt_fmt_t format);
int gnutls_openpgp_keyring_check_id (gnutls_openpgp_keyring_t ring,
- const unsigned char keyid[8],
+ gnutls_openpgp_keyid_t keyid,
unsigned int flags);
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 62351ecadb..28a3d3dd4d 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -25,16 +25,25 @@ if ENABLE_MINITASN1
SUBDIRS += minitasn1
endif
+
localedir = $(datadir)/locale
AM_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" \
-I$(top_srcdir)/lgl -I$(top_builddir)/lgl \
-I$(top_srcdir)/includes -I../includes \
-I$(srcdir)/x509 \
- -I$(top_srcdir)/libextra -I$(top_srcdir)/libextra/openpgp/ \
- -I$(top_srcdir)/libextra/opencdk \
+ -I$(top_srcdir)/libextra -I$(top_srcdir)/lib/openpgp/ \
+ -I$(top_srcdir)/lib/opencdk \
$(LIBOPENCDK_CFLAGS) $(LIBGCRYPT_CFLAGS)
+if ENABLE_OPENPGP
+if ENABLE_INCLUDED_OPENCDK
+SUBDIRS += opencdk
+AM_CPPFLAGS += -I$(srcdir)/opencdk
+endif
+SUBDIRS += openpgp
+endif
+
if ENABLE_MINITASN1
AM_CPPFLAGS += -I$(srcdir)/minitasn1
else
@@ -75,7 +84,7 @@ COBJECTS = gnutls_record.c gnutls_compress.c debug.c gnutls_cipher.c \
ext_max_record.c gnutls_alert.c gnutls_str.c gnutls_state.c \
gnutls_x509.c ext_cert_type.c gnutls_rsa_export.c \
auth_rsa_export.c ext_server_name.c auth_dh_common.c \
- gnutls_helper.c ext_inner_application.c gnutls_extra_hooks.c \
+ gnutls_helper.c ext_inner_application.c \
gnutls_supplemental.c
if ENABLE_OPRFI
@@ -96,7 +105,7 @@ HFILES = debug.h gnutls_compress.h defines.h gnutls_cipher.h \
gnutls_rsa_export.h ext_server_name.h auth_dh_common.h \
ext_srp.h gnutls_srp.h auth_srp.h auth_srp_passwd.h \
gnutls_helper.h auth_psk.h auth_psk_passwd.h \
- ext_inner_application.h gnutls_extra_hooks.h \
+ ext_inner_application.h \
gnutls_supplemental.h ext_oprfi.h
# Separate so we can create the documentation
@@ -110,6 +119,16 @@ libgnutls_la_LDFLAGS = -no-undefined \
libgnutls_la_LIBADD = ../lgl/liblgnu.la x509/libgnutls_x509.la \
@LTLIBZ@ $(LIBGCRYPT_LIBS) @LTLIBINTL@
+if ENABLE_OPENPGP
+libgnutls_la_SOURCES += gnutls_openpgp.c
+libgnutls_la_LIBADD += openpgp/libgnutls_openpgp.la
+if ENABLE_INCLUDED_OPENCDK
+libgnutls_la_LIBADD += opencdk/libminiopencdk.la
+else
+libgnutls_la_LDFLAGS += $(LTLIBOPENCDK)
+endif
+endif
+
if HAVE_LD_VERSION_SCRIPT
libgnutls_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libgnutls.vers
endif
diff --git a/lib/auth_cert.c b/lib/auth_cert.c
index c9cd8d4ff9..3f97b1e50f 100644
--- a/lib/auth_cert.c
+++ b/lib/auth_cert.c
@@ -43,15 +43,22 @@
#include <gnutls_state.h>
#include <gnutls_pk.h>
#include <gnutls_x509.h>
-#include <gnutls_extra_hooks.h>
#include "debug.h"
+#ifdef ENABLE_OPENPGP
+# include "openpgp/gnutls_openpgp.h"
+
+static gnutls_privkey *
+alloc_and_load_pgp_key (const gnutls_openpgp_privkey_t key, gnutls_openpgp_keyid_t keyid);
+static gnutls_cert *
+alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert, gnutls_openpgp_keyid_t* keyid);
+
+#endif
+
static gnutls_cert *alloc_and_load_x509_certs (gnutls_x509_crt_t * certs,
unsigned);
static gnutls_privkey *alloc_and_load_x509_key (gnutls_x509_privkey_t key);
-static gnutls_cert *alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert);
-static gnutls_privkey *alloc_and_load_pgp_key (const gnutls_openpgp_privkey_t
- key);
+
/* Copies data from a internal certificate struct (gnutls_cert) to
@@ -255,6 +262,7 @@ _find_x509_cert (const gnutls_certificate_credentials_t cred,
}
+#ifdef ENABLE_OPENPGP
/* Locates the most appropriate openpgp cert
*/
static int
@@ -289,6 +297,7 @@ _find_openpgp_cert (const gnutls_certificate_credentials_t cred,
return 0;
}
+#endif
/* Returns the number of issuers in the server's
* certificate request packet.
@@ -438,8 +447,16 @@ call_get_cert_callback (gnutls_session_t session,
if (type == GNUTLS_CRT_X509)
{
local_certs = alloc_and_load_x509_certs (st.cert.x509, st.ncerts);
- if (local_certs != NULL)
- local_key = alloc_and_load_x509_key (st.key.x509);
+ if (local_certs != NULL)
+ {
+ local_key = alloc_and_load_x509_key (st.key.x509);
+ if (local_key == NULL)
+ {
+ gnutls_assert();
+ ret = GNUTLS_E_INTERNAL_ERROR;
+ goto cleanup;
+ }
+ }
}
else
@@ -451,10 +468,23 @@ call_get_cert_callback (gnutls_session_t session,
goto cleanup;
}
- local_certs = alloc_and_load_pgp_certs (st.cert.pgp);
- if (local_certs != NULL)
- local_key = alloc_and_load_pgp_key (st.key.pgp);
-
+#ifdef ENABLE_OPENPGP
+ {
+ gnutls_openpgp_keyid_t selected_keyid;
+
+ local_certs = alloc_and_load_pgp_certs (st.cert.pgp, &selected_keyid);
+ if (local_certs != NULL)
+ {
+ local_key = alloc_and_load_pgp_key (st.key.pgp, selected_keyid);
+ if (local_key == NULL)
+ {
+ gnutls_assert();
+ ret = GNUTLS_E_INTERNAL_ERROR;
+ goto cleanup;
+ }
+ }
+ }
+#endif
}
_gnutls_selected_certs_set (session, local_certs,
@@ -479,18 +509,13 @@ cleanup:
}
else
{
+#ifdef ENABLE_OPENPGP
if (st.deinit_all)
{
- if (_E_gnutls_openpgp_crt_deinit == NULL ||
- _E_gnutls_openpgp_privkey_deinit == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_INIT_LIBEXTRA;
- }
-
- _E_gnutls_openpgp_crt_deinit (st.cert.pgp);
- _E_gnutls_openpgp_privkey_deinit (st.key.pgp);
+ gnutls_openpgp_crt_deinit (st.cert.pgp);
+ gnutls_openpgp_privkey_deinit (st.key.pgp);
}
+#endif
}
return ret;
@@ -578,9 +603,10 @@ _select_client_cert (gnutls_session_t session,
_find_x509_cert (cred, _data, _data_size,
pk_algos, pk_algos_length, &indx);
+#ifdef ENABLE_OPENPGP
if (session->security_parameters.cert_type == GNUTLS_CRT_OPENPGP)
result = _find_openpgp_cert (cred, pk_algos, pk_algos_length, &indx);
-
+#endif
if (result < 0)
{
@@ -670,6 +696,7 @@ _gnutls_gen_x509_crt (gnutls_session_t session, opaque ** data)
enum PGPKeyDescriptorType
{ PGP_KEY_FINGERPRINT, PGP_KEY };
+#ifdef ENABLE_OPENPGP
int
_gnutls_gen_openpgp_certificate (gnutls_session_t session, opaque ** data)
{
@@ -767,14 +794,8 @@ _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session, opaque ** data)
fpr_size = 20;
- if (_E_gnutls_openpgp_fingerprint == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_INIT_LIBEXTRA;
- }
-
if ((ret =
- _E_gnutls_openpgp_fingerprint (&apr_cert_list[0].raw, pdata,
+ _gnutls_openpgp_fingerprint (&apr_cert_list[0].raw, pdata,
&fpr_size)) < 0)
{
gnutls_assert ();
@@ -783,7 +804,7 @@ _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session, opaque ** data)
return packet_size;
}
-
+#endif
int
@@ -791,12 +812,13 @@ _gnutls_gen_cert_client_certificate (gnutls_session_t session, opaque ** data)
{
switch (session->security_parameters.cert_type)
{
+#ifdef ENABLE_OPENPGP
case GNUTLS_CRT_OPENPGP:
if (_gnutls_openpgp_send_fingerprint (session) == 0)
return _gnutls_gen_openpgp_certificate (session, data);
else
return _gnutls_gen_openpgp_certificate_fpr (session, data);
-
+#endif
case GNUTLS_CRT_X509:
return _gnutls_gen_x509_crt (session, data);
@@ -811,8 +833,10 @@ _gnutls_gen_cert_server_certificate (gnutls_session_t session, opaque ** data)
{
switch (session->security_parameters.cert_type)
{
+#ifdef ENABLE_OPENPGP
case GNUTLS_CRT_OPENPGP:
return _gnutls_gen_openpgp_certificate (session, data);
+#endif
case GNUTLS_CRT_X509:
return _gnutls_gen_x509_crt (session, data);
default:
@@ -967,6 +991,7 @@ cleanup:
}
#define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_gcert_deinit(&peer_certificate_list[x])
+#ifdef ENABLE_OPENPGP
int
_gnutls_proc_openpgp_server_certificate (gnutls_session_t session,
opaque * data, size_t data_size)
@@ -1038,13 +1063,8 @@ _gnutls_proc_openpgp_server_certificate (gnutls_session_t session,
/* request the actual key from our database, or
* a key server or anything.
*/
- if (_E_gnutls_openpgp_request_key == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_INIT_LIBEXTRA;
- }
if ((ret =
- _E_gnutls_openpgp_request_key (session, &akey, cred, p, 20)) < 0)
+ _gnutls_openpgp_request_key (session, &akey, cred, p, 20)) < 0)
{
gnutls_assert ();
return ret;
@@ -1103,15 +1123,8 @@ _gnutls_proc_openpgp_server_certificate (gnutls_session_t session,
memset (peer_certificate_list, 0, sizeof (gnutls_cert) *
peer_certificate_list_size);
- if (_E_gnutls_openpgp_raw_key_to_gcert == NULL)
- {
- gnutls_assert ();
- ret = GNUTLS_E_INIT_LIBEXTRA;
- goto cleanup;
- }
-
if ((ret =
- _E_gnutls_openpgp_raw_key_to_gcert (&peer_certificate_list[0],
+ _gnutls_openpgp_raw_crt_to_gcert (&peer_certificate_list[0],
&tmp)) < 0)
{
gnutls_assert ();
@@ -1145,6 +1158,7 @@ cleanup:
return ret;
}
+#endif
int
_gnutls_proc_cert_server_certificate (gnutls_session_t session,
@@ -1152,9 +1166,11 @@ _gnutls_proc_cert_server_certificate (gnutls_session_t session,
{
switch (session->security_parameters.cert_type)
{
+#ifdef ENABLE_OPENPGP
case GNUTLS_CRT_OPENPGP:
return _gnutls_proc_openpgp_server_certificate (session,
data, data_size);
+#endif
case GNUTLS_CRT_X509:
return _gnutls_proc_x509_server_certificate (session, data, data_size);
default:
@@ -1582,8 +1598,9 @@ alloc_and_load_x509_key (gnutls_x509_privkey_t key)
/* converts the given pgp certificate to gnutls_cert* and allocates
* space for them.
*/
+#ifdef ENABLE_OPENPGP
static gnutls_cert *
-alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert)
+alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert, gnutls_openpgp_keyid_t* keyid)
{
gnutls_cert *local_certs;
int ret = 0;
@@ -1598,13 +1615,14 @@ alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert)
return NULL;
}
- if (_E_gnutls_openpgp_crt_to_gcert == NULL)
+ ret = _gnutls_openpgp_find_valid_subkey( cert, keyid);
+ if (ret < 0)
{
- gnutls_assert ();
+ gnutls_assert();
return NULL;
}
- ret = _E_gnutls_openpgp_crt_to_gcert (local_certs, cert);
+ ret = _gnutls_openpgp_crt_to_gcert (local_certs, cert, *keyid);
if (ret < 0)
{
gnutls_assert ();
@@ -1626,7 +1644,7 @@ alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert)
* space for it.
*/
static gnutls_privkey *
-alloc_and_load_pgp_key (const gnutls_openpgp_privkey_t key)
+alloc_and_load_pgp_key (const gnutls_openpgp_privkey_t key, gnutls_openpgp_keyid_t keyid)
{
gnutls_privkey *local_key;
int ret = 0;
@@ -1641,13 +1659,7 @@ alloc_and_load_pgp_key (const gnutls_openpgp_privkey_t key)
return NULL;
}
- if (_E_gnutls_openpgp_privkey_to_gkey == NULL)
- {
- gnutls_assert ();
- return NULL;
- }
-
- ret = _E_gnutls_openpgp_privkey_to_gkey (local_key, key);
+ ret = _gnutls_openpgp_privkey_to_gkey (local_key, key, keyid);
if (ret < 0)
{
gnutls_assert ();
@@ -1656,7 +1668,7 @@ alloc_and_load_pgp_key (const gnutls_openpgp_privkey_t key)
return local_key;
}
-
+#endif
void
_gnutls_selected_certs_deinit (gnutls_session_t session)
diff --git a/lib/auth_cert.h b/lib/auth_cert.h
index e59e094b9d..d2db7ab158 100644
--- a/lib/auth_cert.h
+++ b/lib/auth_cert.h
@@ -28,7 +28,7 @@
# include "gnutls_auth.h"
# include "auth_dh_common.h"
# include "x509/x509.h"
-# include "../libextra/openpgp/openpgp.h"
+# include "openpgp/openpgp.h"
/* This structure may be complex, but it's the only way to
* support a server that has multiple certificates
diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c
index f33b538802..669deb33cc 100644
--- a/lib/gnutls_cert.c
+++ b/lib/gnutls_cert.c
@@ -40,9 +40,11 @@
#include <gnutls_state.h>
#include <gnutls_auth_int.h>
#include <gnutls_x509.h>
-#include <gnutls_extra_hooks.h>
#include "x509/x509.h"
#include "x509/mpi.h"
+#ifdef ENABLE_OPENPGP
+# include "openpgp/gnutls_openpgp.h"
+#endif
/**
* gnutls_certificate_free_keys - Used to free all the keys from a gnutls_certificate_credentials_t structure
@@ -191,12 +193,14 @@ gnutls_certificate_free_credentials (gnutls_certificate_credentials_t sc)
gnutls_certificate_free_crls (sc);
#endif
+#ifdef ENABLE_OPENPGP
#ifndef KEYRING_HACK
if (_E_gnutls_openpgp_keyring_deinit)
_E_gnutls_openpgp_keyring_deinit( sc->keyring);
#else
_gnutls_free_datum( &sc->keyring);
#endif
+#endif
gnutls_free (sc);
}
@@ -436,6 +440,7 @@ _gnutls_x509_get_raw_crt_expiration_time (const gnutls_datum_t * cert)
return result;
}
+#ifdef ENABLE_OPENPGP
/*-
* _gnutls_openpgp_crt_verify_peers - This function returns the peer's certificate status
* @session: is a gnutls session
@@ -485,13 +490,8 @@ _gnutls_openpgp_crt_verify_peers (gnutls_session_t session,
/* Verify certificate
*/
- if (_E_gnutls_openpgp_verify_key == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_INIT_LIBEXTRA;
- }
ret =
- _E_gnutls_openpgp_verify_key (cred, &info->raw_certificate_list[0],
+ _gnutls_openpgp_verify_key (cred, &info->raw_certificate_list[0],
peer_certificate_list_size, status);
if (ret < 0)
@@ -502,7 +502,7 @@ _gnutls_openpgp_crt_verify_peers (gnutls_session_t session,
return 0;
}
-
+#endif
/**
* gnutls_certificate_verify_peers2 - This function returns the peer's certificate verification status
@@ -551,8 +551,10 @@ gnutls_certificate_verify_peers2 (gnutls_session_t session,
{
case GNUTLS_CRT_X509:
return _gnutls_x509_cert_verify_peers (session, status);
+#ifdef ENABLE_OPENPGP
case GNUTLS_CRT_OPENPGP:
return _gnutls_openpgp_crt_verify_peers (session, status);
+#endif
default:
return GNUTLS_E_INVALID_REQUEST;
}
@@ -625,12 +627,12 @@ gnutls_certificate_expiration_time_peers (gnutls_session_t session)
return _gnutls_x509_get_raw_crt_expiration_time (&info->
raw_certificate_list
[0]);
+#ifdef ENABLE_OPENPGP
case GNUTLS_CRT_OPENPGP:
- if (_E_gnutls_openpgp_get_raw_key_expiration_time == NULL)
- return (time_t) - 1;
- return _E_gnutls_openpgp_get_raw_key_expiration_time (&info->
+ return _gnutls_openpgp_get_raw_key_expiration_time (&info->
raw_certificate_list
[0]);
+#endif
default:
return (time_t) - 1;
}
@@ -670,12 +672,12 @@ gnutls_certificate_activation_time_peers (gnutls_session_t session)
return _gnutls_x509_get_raw_crt_activation_time (&info->
raw_certificate_list
[0]);
+#ifdef ENABLE_OPENPGP
case GNUTLS_CRT_OPENPGP:
- if (_E_gnutls_openpgp_get_raw_key_creation_time == NULL)
- return (time_t) - 1;
- return _E_gnutls_openpgp_get_raw_key_creation_time (&info->
+ return _gnutls_openpgp_get_raw_key_creation_time (&info->
raw_certificate_list
[0]);
+#endif
default:
return (time_t) - 1;
}
@@ -691,45 +693,16 @@ _gnutls_raw_cert_to_gcert (gnutls_cert * gcert,
{
case GNUTLS_CRT_X509:
return _gnutls_x509_raw_cert_to_gcert (gcert, raw_cert, flags);
+#ifdef ENABLE_OPENPGP
case GNUTLS_CRT_OPENPGP:
- if (_E_gnutls_openpgp_raw_key_to_gcert == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_INIT_LIBEXTRA;
- }
- return _E_gnutls_openpgp_raw_key_to_gcert (gcert, raw_cert);
- default:
- gnutls_assert ();
- return GNUTLS_E_INTERNAL_ERROR;
- }
-}
-
-int
-_gnutls_raw_privkey_to_gkey (gnutls_privkey * key,
- gnutls_certificate_type_t type,
- const gnutls_datum_t * raw_key,
- int key_enc /* DER or PEM */ )
-{
- switch (type)
- {
- case GNUTLS_CRT_X509:
- return _gnutls_x509_raw_privkey_to_gkey (key, raw_key, key_enc);
- case GNUTLS_CRT_OPENPGP:
- if (_E_gnutls_openpgp_raw_privkey_to_gkey == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_INIT_LIBEXTRA;
- }
- return _E_gnutls_openpgp_raw_privkey_to_gkey (key, raw_key,
- (gnutls_openpgp_crt_fmt_t)
- key_enc);
+ return _gnutls_openpgp_raw_crt_to_gcert (gcert, raw_cert);
+#endif
default:
gnutls_assert ();
return GNUTLS_E_INTERNAL_ERROR;
}
}
-
/* This function will convert a der certificate to a format
* (structure) that gnutls can understand and use. Actually the
* important thing on this function is that it extracts the
diff --git a/lib/gnutls_cert.h b/lib/gnutls_cert.h
index 6ce0847368..3101e6825c 100644
--- a/lib/gnutls_cert.h
+++ b/lib/gnutls_cert.h
@@ -124,9 +124,5 @@ int _gnutls_raw_cert_to_gcert (gnutls_cert * gcert,
gnutls_certificate_type_t type,
const gnutls_datum_t * raw_cert,
int flags /* OR of ConvFlags */ );
-int _gnutls_raw_privkey_to_gkey (gnutls_privkey * key,
- gnutls_certificate_type_t type,
- const gnutls_datum_t * raw_key,
- int key_enc /* DER or PEM */ );
#endif
diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c
index d7635f198d..465806f8f0 100644
--- a/lib/gnutls_errors.c
+++ b/lib/gnutls_errors.c
@@ -208,6 +208,8 @@ static const gnutls_error_entry error_algorithms[] = {
GNUTLS_E_NO_CIPHER_SUITES, 1),
ERROR_ENTRY (N_("Could not get OpenPGP key."),
GNUTLS_E_OPENPGP_GETKEY_FAILED, 1),
+ ERROR_ENTRY (N_("Could not find OpenPGP subkey."),
+ GNUTLS_E_OPENPGP_SUBKEY_ERROR, 1),
ERROR_ENTRY (N_("The SRP username supplied is illegal."),
GNUTLS_E_ILLEGAL_SRP_USERNAME, 1),
diff --git a/lib/gnutls_extra_hooks.c b/lib/gnutls_extra_hooks.c
deleted file mode 100644
index eedf902860..0000000000
--- a/lib/gnutls_extra_hooks.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2007 Free Software Foundation
- *
- * Author: Simon Josefsson
- *
- * This file is part of GNUTLS.
- *
- * The GNUTLS library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA
- *
- */
-
-#include <gnutls_int.h>
-#include <gnutls_extra_hooks.h>
-
-/* Variables used by libgnutls, set by
- _gnutls_add_openpgp_functions(), typically invoked by
- libgnutls_extra. */
-_gnutls_openpgp_verify_key_func _E_gnutls_openpgp_verify_key = NULL;
-_gnutls_openpgp_crt_creation_time_func
-_E_gnutls_openpgp_get_raw_key_creation_time = NULL;
-_gnutls_openpgp_crt_expiration_time_func
-_E_gnutls_openpgp_get_raw_key_expiration_time = NULL;
-_gnutls_openpgp_fingerprint_func _E_gnutls_openpgp_fingerprint = NULL;
-_gnutls_openpgp_crt_request_func _E_gnutls_openpgp_request_key = NULL;
-_gnutls_openpgp_raw_key_to_gcert_func _E_gnutls_openpgp_raw_key_to_gcert = NULL;
-_gnutls_openpgp_raw_privkey_to_gkey_func _E_gnutls_openpgp_raw_privkey_to_gkey = NULL;
-_gnutls_openpgp_crt_to_gcert_func _E_gnutls_openpgp_crt_to_gcert = NULL;
-_gnutls_openpgp_privkey_to_gkey_func _E_gnutls_openpgp_privkey_to_gkey = NULL;
-_gnutls_openpgp_crt_deinit_func _E_gnutls_openpgp_crt_deinit = NULL;
-_gnutls_openpgp_keyring_deinit_func _E_gnutls_openpgp_keyring_deinit = NULL;
-_gnutls_openpgp_privkey_deinit_func _E_gnutls_openpgp_privkey_deinit = NULL;
-
-/* Called by libgnutls_extra to set the OpenPGP functions that are
- needed by GnuTLS. */
-extern void
-_gnutls_add_openpgp_functions
-(_gnutls_openpgp_verify_key_func verify_key,
- _gnutls_openpgp_crt_creation_time_func key_creation_time,
- _gnutls_openpgp_crt_expiration_time_func key_expiration_time,
- _gnutls_openpgp_fingerprint_func fingerprint,
- _gnutls_openpgp_crt_request_func request_key,
- _gnutls_openpgp_raw_key_to_gcert_func raw_key_to_gcert,
- _gnutls_openpgp_raw_privkey_to_gkey_func raw_privkey_to_gkey,
- _gnutls_openpgp_crt_to_gcert_func key_to_gcert,
- _gnutls_openpgp_privkey_to_gkey_func privkey_to_gkey,
- _gnutls_openpgp_crt_deinit_func key_deinit,
- _gnutls_openpgp_keyring_deinit_func keyring_deinit,
- _gnutls_openpgp_privkey_deinit_func privkey_deinit)
-{
- _E_gnutls_openpgp_verify_key = verify_key;
- _E_gnutls_openpgp_get_raw_key_creation_time = key_creation_time;
- _E_gnutls_openpgp_get_raw_key_expiration_time = key_expiration_time;
- _E_gnutls_openpgp_fingerprint = fingerprint;
- _E_gnutls_openpgp_request_key = request_key;
- _E_gnutls_openpgp_raw_key_to_gcert = raw_key_to_gcert;
- _E_gnutls_openpgp_raw_privkey_to_gkey = raw_privkey_to_gkey;
- _E_gnutls_openpgp_crt_to_gcert = key_to_gcert;
- _E_gnutls_openpgp_privkey_to_gkey = privkey_to_gkey;
- _E_gnutls_openpgp_crt_deinit = key_deinit;
- _E_gnutls_openpgp_keyring_deinit = keyring_deinit;
- _E_gnutls_openpgp_privkey_deinit = privkey_deinit;
-
-}
diff --git a/lib/gnutls_extra_hooks.h b/lib/gnutls_extra_hooks.h
deleted file mode 100644
index ac55d06a76..0000000000
--- a/lib/gnutls_extra_hooks.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2007 Free Software Foundation
- *
- * Author: Simon Josefsson
- *
- * This file is part of GNUTLS.
- *
- * The GNUTLS library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA
- *
- */
-
-/* This file is included by libgnutls-extra, and it will call the
- _gnutls_add_openpgp_functions() function to register its OpenPGP
- functions. */
-
-#include <auth_cert.h>
-
-typedef int (*_gnutls_openpgp_verify_key_func)
-(const gnutls_certificate_credentials_t,
- const gnutls_datum_t *, int,
- unsigned int *);
-
-typedef time_t (*_gnutls_openpgp_crt_creation_time_func)
-(const gnutls_datum_t *);
-
-typedef time_t (*_gnutls_openpgp_crt_expiration_time_func)
-(const gnutls_datum_t *);
-
-typedef int (*_gnutls_openpgp_crt_request_func)
-(gnutls_session_t, gnutls_datum_t *,
- const gnutls_certificate_credentials_t,
- opaque *, int);
-
-typedef int (*_gnutls_openpgp_fingerprint_func)
-(const gnutls_datum_t *,
- unsigned char *, size_t *);
-
-typedef int (*_gnutls_openpgp_raw_key_to_gcert_func)
-(gnutls_cert *,
- const gnutls_datum_t *);
-typedef int (*_gnutls_openpgp_raw_privkey_to_gkey_func)
-(gnutls_privkey *,
- const gnutls_datum_t *,
- gnutls_openpgp_crt_fmt_t);
-
-typedef int (*_gnutls_openpgp_crt_to_gcert_func)
-(gnutls_cert *, gnutls_openpgp_crt_t);
-
-typedef int (*_gnutls_openpgp_privkey_to_gkey_func)
-(gnutls_privkey *,
- gnutls_openpgp_privkey_t);
-
-typedef void (*_gnutls_openpgp_crt_deinit_func)
-(gnutls_openpgp_crt_t);
-
-typedef void (*_gnutls_openpgp_keyring_deinit_func)
-(gnutls_openpgp_keyring_t);
-
-typedef void (*_gnutls_openpgp_privkey_deinit_func)
-(gnutls_openpgp_privkey_t);
-
-/* These are defined in libgnutls, but not exported from libgnutls,
- and not intended to be used by libgnutls-extra or elsewhere. They
- are declared here, because this file is included by auth_cert.c and
- gnutls_cert.c too. */
-extern _gnutls_openpgp_verify_key_func _E_gnutls_openpgp_verify_key;
-extern _gnutls_openpgp_crt_creation_time_func
-_E_gnutls_openpgp_get_raw_key_creation_time;
-extern _gnutls_openpgp_crt_expiration_time_func
-_E_gnutls_openpgp_get_raw_key_expiration_time;
-extern _gnutls_openpgp_fingerprint_func _E_gnutls_openpgp_fingerprint;
-extern _gnutls_openpgp_crt_request_func _E_gnutls_openpgp_request_key;
-extern _gnutls_openpgp_raw_key_to_gcert_func _E_gnutls_openpgp_raw_key_to_gcert;
-extern _gnutls_openpgp_raw_privkey_to_gkey_func _E_gnutls_openpgp_raw_privkey_to_gkey;
-extern _gnutls_openpgp_crt_to_gcert_func _E_gnutls_openpgp_crt_to_gcert;
-extern _gnutls_openpgp_privkey_to_gkey_func _E_gnutls_openpgp_privkey_to_gkey;
-extern _gnutls_openpgp_crt_deinit_func _E_gnutls_openpgp_crt_deinit;
-extern _gnutls_openpgp_keyring_deinit_func _E_gnutls_openpgp_keyring_deinit;
-extern _gnutls_openpgp_privkey_deinit_func _E_gnutls_openpgp_privkey_deinit;
-
-extern void _gnutls_add_openpgp_functions
-(_gnutls_openpgp_verify_key_func verify_key,
- _gnutls_openpgp_crt_creation_time_func key_creation_time,
- _gnutls_openpgp_crt_expiration_time_func key_expiration_time,
- _gnutls_openpgp_fingerprint_func fingerprint,
- _gnutls_openpgp_crt_request_func request_key,
- _gnutls_openpgp_raw_key_to_gcert_func raw_key_to_gcert,
- _gnutls_openpgp_raw_privkey_to_gkey_func raw_privkey_to_gkey,
- _gnutls_openpgp_crt_to_gcert_func key_to_gcert,
- _gnutls_openpgp_privkey_to_gkey_func privkey_to_gkey,
- _gnutls_openpgp_crt_deinit_func key_deinit,
- _gnutls_openpgp_keyring_deinit_func keyring_deinit,
- _gnutls_openpgp_privkey_deinit_func privkey_deinit);
diff --git a/libextra/gnutls_openpgp.c b/lib/gnutls_openpgp.c
index 73f9aef08f..8e95b53806 100644
--- a/libextra/gnutls_openpgp.c
+++ b/lib/gnutls_openpgp.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
*
- * Author: Timo Schulz
+ * Author: Timo Schulz, Nikos Mavrogiannopoulos
*
* This file is part of GNUTLS-EXTRA.
*
@@ -22,6 +22,7 @@
#include "gnutls_int.h"
#include "gnutls_errors.h"
#include "gnutls_mpi.h"
+#include "gnutls_num.h"
#include "gnutls_cert.h"
#include "gnutls_datum.h"
#include "gnutls_global.h"
@@ -34,8 +35,6 @@
#include <time.h>
#include <sys/stat.h>
-#define OPENPGP_NAME_SIZE 256
-
#define datum_append(x, y, z) _gnutls_datum_append_m (x, y, z, gnutls_realloc)
@@ -82,183 +81,53 @@ _gnutls_map_cdk_rc (int rc)
}
}
-
-static unsigned long
-buftou32 (const uint8_t * buf)
-{
- unsigned a;
- a = buf[0] << 24;
- a |= buf[1] << 16;
- a |= buf[2] << 8;
- a |= buf[3];
- return a;
-}
-
-static int
-openpgp_pk_to_gnutls_cert (gnutls_cert * cert, cdk_pkt_pubkey_t pk)
+/* Finds a subkey to use for authentication
+ */
+int _gnutls_openpgp_find_valid_subkey( gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t* keyid)
{
- uint8_t buf[512+2];
- size_t nbytes;
- int algo, i;
- int rc = 0;
+ int ret, subkeys, i;
+ unsigned int usage;
- if (!cert || !pk)
+ subkeys = gnutls_openpgp_crt_get_subkey_count( crt);
+ if (subkeys <= 0)
{
- gnutls_assert ();
- return GNUTLS_E_INVALID_REQUEST;
- }
-
- /* GnuTLS OpenPGP does not support ELG keys */
- if (is_ELG (pk->pubkey_algo))
- return GNUTLS_E_UNWANTED_ALGORITHM;
-
- algo = is_DSA (pk->pubkey_algo) ? GNUTLS_PK_DSA : GNUTLS_PK_RSA;
- cert->subject_pk_algorithm = algo;
- cert->version = pk->version;
- cert->cert_type = GNUTLS_CRT_OPENPGP;
-
- cert->key_usage = 0;
- if (pk->pubkey_usage & CDK_KEY_USG_SIGN)
- cert->key_usage = KEY_DIGITAL_SIGNATURE;
- if (pk->pubkey_usage & CDK_KEY_USG_ENCR)
- cert->key_usage = KEY_KEY_ENCIPHERMENT;
- if (!cert->key_usage) /* Fallback code. */
- {
- if (pk->pubkey_algo == GCRY_PK_DSA || pk->pubkey_algo == GCRY_PK_RSA_S)
- cert->key_usage = KEY_DIGITAL_SIGNATURE;
- else if (pk->pubkey_algo == GCRY_PK_RSA_E)
- cert->key_usage = KEY_KEY_ENCIPHERMENT;
- else if (pk->pubkey_algo == GCRY_PK_RSA)
- cert->key_usage = KEY_DIGITAL_SIGNATURE | KEY_KEY_ENCIPHERMENT;
- }
-
- cert->params_size = cdk_pk_get_npkey (pk->pubkey_algo);
- for (i = 0; i < cert->params_size; i++)
- {
- nbytes = sizeof (buf) / sizeof (buf[0]);
- cdk_pk_get_mpi (pk, i, buf, nbytes, &nbytes, NULL);
- rc = _gnutls_mpi_scan_pgp (&cert->params[i], buf, &nbytes);
- if (rc)
- {
- rc = GNUTLS_E_MPI_SCAN_FAILED;
- break;
- }
+ gnutls_assert();
+ return GNUTLS_E_OPENPGP_SUBKEY_ERROR;
}
- if (rc)
- release_mpi_array (cert->params, i - 1);
- return rc;
-}
-
-/*-
- * _gnutls_openpgp_raw_privkey_to_gkey - Converts an OpenPGP secret key to GnuTLS
- * @pkey: the GnuTLS private key context to store the key.
- * @raw_key: the raw data which contains the whole key packets.
- * @format: the format of the key packets.
- *
- * The RFC2440 (OpenPGP Message Format) data is converted into the
- * GnuTLS specific data which is need to perform secret key operations.
- *
- * This function can read both BASE64 and RAW keys.
- -*/
-int
-_gnutls_openpgp_raw_privkey_to_gkey (gnutls_privkey * pkey,
- const gnutls_datum_t * raw_key,
- gnutls_openpgp_crt_fmt_t format)
-{
- cdk_kbnode_t snode = NULL;
- cdk_packet_t pkt;
- cdk_stream_t out;
- cdk_pkt_seckey_t sk = NULL;
- int pke_algo, i, j;
- size_t nbytes = 0;
- uint8_t buf[512];
- int rc = 0;
-
- if (!pkey || raw_key->size <= 0)
+ /* Try to find a subkey with the authentication flag set.
+ * if none exists use the last one found
+ */
+ for (i=0;i<subkeys;i++)
{
- gnutls_assert ();
- return GNUTLS_E_CERTIFICATE_ERROR;
- }
- rc = cdk_stream_tmp_new (&out);
- if (rc)
- return GNUTLS_E_CERTIFICATE_ERROR;
+ ret = gnutls_openpgp_crt_get_subkey_revoked_status(crt, i);
+ if (ret != 0) /* it is revoked. ignore it */
+ continue;
- if (format == GNUTLS_OPENPGP_FMT_BASE64)
- {
- rc = cdk_stream_set_armor_flag (out, 0);
- if (rc)
- {
- cdk_stream_close (out);
- rc = _gnutls_map_cdk_rc (rc);
- gnutls_assert ();
- goto leave;
- }
- }
+ ret = gnutls_openpgp_crt_get_subkey_id( crt, i, keyid);
+ if (ret < 0)
+ {
+ gnutls_assert();
+ return ret;
+ }
- cdk_stream_write (out, raw_key->data, raw_key->size);
- cdk_stream_seek (out, 0);
+ ret = gnutls_openpgp_crt_get_subkey_usage( crt, i, &usage);
+ if (ret < 0)
+ {
+ gnutls_assert();
+ return ret;
+ }
- rc = cdk_keydb_get_keyblock (out, &snode);
- cdk_stream_close (out);
- if (rc)
- {
- rc = GNUTLS_E_OPENPGP_GETKEY_FAILED;
- goto leave;
- }
-
- pkt = cdk_kbnode_find_packet (snode, CDK_PKT_SECRET_KEY);
- if (!pkt)
- {
- rc = GNUTLS_E_OPENPGP_GETKEY_FAILED;
- goto leave;
- }
- sk = pkt->pkt.secret_key;
- pke_algo = sk->pk->pubkey_algo;
- pkey->params_size = cdk_pk_get_npkey (pke_algo);
- for (i = 0; i < pkey->params_size; i++)
- {
- nbytes = sizeof (buf) / sizeof (buf[0]);
- cdk_pk_get_mpi (sk->pk, i, buf, nbytes, &nbytes, NULL);
- rc = _gnutls_mpi_scan_pgp (&pkey->params[i], buf, &nbytes);
- if (rc)
- {
- rc = GNUTLS_E_MPI_SCAN_FAILED;
- release_mpi_array (pkey->params, i - 1);
- goto leave;
- }
- }
-
- pkey->params_size += cdk_pk_get_nskey (pke_algo);
- for (j = 0; j < cdk_pk_get_nskey (pke_algo); j++, i++)
- {
- nbytes = sizeof (buf) / sizeof (buf[0]);
- cdk_sk_get_mpi (sk, j, buf, nbytes, &nbytes, NULL);
- rc = _gnutls_mpi_scan_pgp (&pkey->params[i], buf, &nbytes);
- if (rc)
- {
- rc = GNUTLS_E_MPI_SCAN_FAILED;
- release_mpi_array (pkey->params, i - 1);
- goto leave;
- }
+ if (usage & GNUTLS_KEY_KEY_AGREEMENT)
+ break;
}
- if (is_ELG (pke_algo))
- return GNUTLS_E_UNWANTED_ALGORITHM;
- else if (is_DSA (pke_algo))
- pkey->pk_algorithm = GNUTLS_PK_DSA;
- else if (is_RSA (pke_algo))
- pkey->pk_algorithm = GNUTLS_PK_RSA;
-
-leave:
- cdk_kbnode_release (snode);
- return rc;
+ return 0;
}
-
/*-
- * _gnutls_openpgp_raw_key_to_gcert - Converts raw OpenPGP data to GnuTLS certs
+ * _gnutls_openpgp_raw_crt_to_gcert - Converts raw OpenPGP data to GnuTLS certs
* @cert: the certificate to store the data.
* @raw: the buffer which contains the whole OpenPGP key packets.
*
@@ -266,36 +135,40 @@ leave:
* specific certificate.
-*/
int
-_gnutls_openpgp_raw_key_to_gcert (gnutls_cert * cert,
+_gnutls_openpgp_raw_crt_to_gcert (gnutls_cert * gcert,
const gnutls_datum_t * raw)
{
- cdk_kbnode_t knode = NULL;
- cdk_packet_t pkt = NULL;
- int rc;
+ int ret;
+ gnutls_openpgp_crt_t pcrt;
+ gnutls_openpgp_keyid_t keyid;
- if (!cert)
+ ret = gnutls_openpgp_crt_init (&pcrt);
+ if (ret < 0)
{
gnutls_assert ();
- return GNUTLS_E_INVALID_REQUEST;
+ return ret;
}
- memset (cert, 0, sizeof *cert);
-
- rc = cdk_kbnode_read_from_mem (&knode, raw->data, raw->size);
- if (!(rc = _gnutls_map_cdk_rc (rc)))
- pkt = cdk_kbnode_find_packet (knode, CDK_PKT_PUBLIC_KEY);
- if (!pkt)
+ ret = gnutls_openpgp_crt_import (pcrt, raw, GNUTLS_OPENPGP_FMT_RAW);
+ if (ret < 0)
{
gnutls_assert ();
- rc = _gnutls_map_cdk_rc (rc);
+ gnutls_openpgp_crt_deinit (pcrt);
+ return ret;
}
- if (!rc)
- rc = _gnutls_set_datum (&cert->raw, raw->data, raw->size);
- if (!rc)
- rc = openpgp_pk_to_gnutls_cert (cert, pkt->pkt.public_key);
- cdk_kbnode_release (knode);
- return rc;
+ ret = _gnutls_openpgp_find_valid_subkey( pcrt, &keyid);
+
+ if (ret < 0)
+ {
+ gnutls_assert();
+ return ret;
+ }
+
+ ret = _gnutls_openpgp_crt_to_gcert (gcert, pcrt, keyid);
+ gnutls_openpgp_crt_deinit (pcrt);
+
+ return ret;
}
/**
@@ -316,6 +189,15 @@ gnutls_certificate_set_openpgp_key (gnutls_certificate_credentials_t
gnutls_openpgp_privkey_t pkey)
{
int ret;
+ gnutls_openpgp_keyid_t keyid;
+
+ ret = _gnutls_openpgp_find_valid_subkey( crt, &keyid);
+
+ if (ret < 0)
+ {
+ gnutls_assert();
+ return ret;
+ }
/* this should be first */
@@ -328,7 +210,7 @@ gnutls_certificate_set_openpgp_key (gnutls_certificate_credentials_t
return GNUTLS_E_MEMORY_ERROR;
}
- ret = _gnutls_openpgp_privkey_to_gkey (&res->pkey[res->ncerts], pkey);
+ ret = _gnutls_openpgp_privkey_to_gkey (&res->pkey[res->ncerts], pkey, keyid);
if (ret < 0)
{
gnutls_assert ();
@@ -363,7 +245,7 @@ gnutls_certificate_set_openpgp_key (gnutls_certificate_credentials_t
res->cert_list_length[res->ncerts] = 1;
- ret = _gnutls_openpgp_crt_to_gcert (res->cert_list[res->ncerts], crt);
+ ret = _gnutls_openpgp_crt_to_gcert (res->cert_list[res->ncerts], crt, keyid);
if (ret < 0)
{
gnutls_assert ();
@@ -410,13 +292,13 @@ gnutls_openpgp_get_key (gnutls_datum_t * key,
if (by == KEY_ATTR_SHORT_KEYID)
{
- keyid[0] = buftou32 (pattern);
+ keyid[0] = _gnutls_read_uint32(pattern);
desc = keyid;
}
else if (by == KEY_ATTR_KEYID)
{
- keyid[0] = buftou32 (pattern);
- keyid[1] = buftou32 (pattern + 4);
+ keyid[0] = _gnutls_read_uint32(pattern);
+ keyid[1] = _gnutls_read_uint32(pattern + 4);
desc = keyid;
}
else
@@ -838,84 +720,123 @@ gnutls_openpgp_set_recv_key_function (gnutls_session_t session,
/* Copies a gnutls_openpgp_privkey_t to a gnutls_privkey structure. */
int
_gnutls_openpgp_privkey_to_gkey (gnutls_privkey * dest,
- gnutls_openpgp_privkey_t src)
+ gnutls_openpgp_privkey_t src, gnutls_openpgp_keyid_t keyid)
{
- int i, ret;
-
- memset (dest, 0, sizeof (gnutls_privkey));
-
- for (i = 0; i < src->pkey.params_size; i++)
+ int ret = 0, idx;
+ uint32_t kid32[2];
+
+ if (dest==NULL || src == NULL)
{
- dest->params[i] = _gnutls_mpi_copy (src->pkey.params[i]);
- if (dest->params[i] == NULL)
- {
- gnutls_assert ();
- ret = GNUTLS_E_MEMORY_ERROR;
- goto cleanup;
- }
+ gnutls_assert ();
+ return GNUTLS_E_CERTIFICATE_ERROR;
}
- dest->pk_algorithm = src->pkey.pk_algorithm;
- dest->params_size = src->pkey.params_size;
-
+ KEYID_IMPORT(kid32, keyid);
+
+ idx = gnutls_openpgp_privkey_get_subkey_idx( src, keyid);
+ if (idx < 0)
+ {
+ gnutls_assert();
+ return idx;
+ }
+
+ dest->pk_algorithm = gnutls_openpgp_privkey_get_subkey_pk_algorithm( src, idx, NULL);
+
+ dest->params_size = MAX_PRIV_PARAMS_SIZE;
+ ret = _gnutls_openpgp_privkey_get_mpis( src, kid32, dest->params, &dest->params_size);
+
+ if (ret < 0)
+ {
+ gnutls_assert();
+ return ret;
+ }
+
return 0;
-cleanup:
- for (i = 0; i < src->pkey.params_size; i++)
- _gnutls_mpi_release (&dest->params[i]);
- return ret;
}
/* Converts a parsed gnutls_openpgp_crt_t to a gnutls_cert structure.
*/
int
-_gnutls_openpgp_crt_to_gcert (gnutls_cert * gcert, gnutls_openpgp_crt_t cert)
+_gnutls_openpgp_crt_to_gcert (gnutls_cert * gcert, gnutls_openpgp_crt_t cert,
+ gnutls_openpgp_keyid_t keyid)
{
- opaque *der;
- size_t der_size = 0;
- gnutls_datum_t raw;
- int ret;
+ int ret, idx;
+ uint32_t kid32[2];
+
+ KEYID_IMPORT(kid32, keyid);
memset (gcert, 0, sizeof (gnutls_cert));
gcert->cert_type = GNUTLS_CRT_OPENPGP;
-
- ret = gnutls_openpgp_crt_export (cert, GNUTLS_OPENPGP_FMT_RAW,
- NULL, &der_size);
- if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
+ idx = gnutls_openpgp_crt_get_subkey_idx( cert, keyid);
+ if (idx < 0)
{
- gnutls_assert ();
- return ret;
+ gnutls_assert();
+ return idx;
}
- der = gnutls_malloc (der_size);
- if (der == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
+ gcert->subject_pk_algorithm = gnutls_openpgp_crt_get_subkey_pk_algorithm( cert, idx, NULL);
+ gcert->version = gnutls_openpgp_crt_get_version( cert);
+
+ gnutls_openpgp_crt_get_subkey_usage( cert, idx, &gcert->key_usage);
- ret = gnutls_openpgp_crt_export (cert, GNUTLS_OPENPGP_FMT_RAW,
- der, &der_size);
+ gcert->params_size = MAX_PUBLIC_PARAMS_SIZE;
+ ret = _gnutls_openpgp_crt_get_mpis( cert, kid32, gcert->params, &gcert->params_size);
+
if (ret < 0)
{
- gnutls_assert ();
- gnutls_free (der);
+ gnutls_assert();
return ret;
}
- raw.data = der;
- raw.size = der_size;
+ { /* copy the raw certificate */
+#define SMALL_RAW 512
+ opaque *raw;
+ size_t raw_size = SMALL_RAW;
- ret = _gnutls_openpgp_raw_key_to_gcert (gcert, &raw);
- if (ret < 0)
- {
- gnutls_assert ();
- gnutls_free (der);
- return ret;
- }
+ /* initially allocate a bogus size, just in case the certificate
+ * fits in it. That way we minimize the DER encodings performed.
+ */
+ raw = gnutls_malloc (raw_size);
+ if (raw == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
- gnutls_free (der);
+ ret =
+ gnutls_openpgp_crt_export (cert, GNUTLS_OPENPGP_FMT_RAW, raw, &raw_size);
+ if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
+ {
+ gnutls_assert ();
+ gnutls_free (raw);
+ return ret;
+ }
+
+ if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
+ {
+ raw = gnutls_realloc (raw, raw_size);
+ if (raw == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ ret =
+ gnutls_openpgp_crt_export (cert, GNUTLS_OPENPGP_FMT_RAW, raw,
+ &raw_size);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ gnutls_free (raw);
+ return ret;
+ }
+ }
+
+ gcert->raw.data = raw;
+ gcert->raw.size = raw_size;
+ }
return 0;
@@ -925,20 +846,28 @@ _gnutls_openpgp_crt_to_gcert (gnutls_cert * gcert, gnutls_openpgp_crt_t cert)
/**
* gnutls_openpgp_privkey_sign_hash - This function will sign the given data using the private key params
* @key: Holds the key
+ * @src_keyid: Holds the keyid to be used
* @hash: holds the data to be signed
* @signature: will contain newly allocated signature
*
* This function will sign the given hash using the private key.
+ * You should use gnutls_openpgp_privkey_set_subkey() before calling this function
+ * to set the subkey to use.
*
* Return value: In case of failure a negative value will be returned,
* and 0 on success.
**/
int
gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key,
+ gnutls_openpgp_keyid_t src_keyid,
const gnutls_datum_t * hash,
gnutls_datum_t * signature)
{
- int result;
+int result, i;
+uint32_t keyid[2];
+mpi_t params[MAX_PUBLIC_PARAMS_SIZE];
+int params_size = MAX_PUBLIC_PARAMS_SIZE;
+int pk_algorithm;
if (key == NULL)
{
@@ -946,8 +875,23 @@ gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key,
return GNUTLS_E_INVALID_REQUEST;
}
- result = _gnutls_sign (key->pkey.pk_algorithm, key->pkey.params,
- key->pkey.params_size, hash, signature);
+ KEYID_IMPORT( keyid, src_keyid);
+
+ result = _gnutls_openpgp_privkey_get_mpis( key, keyid, params, &params_size);
+ if (result < 0)
+ {
+ gnutls_assert ();
+ return result;
+ }
+
+ pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL);
+
+ result = _gnutls_sign (pk_algorithm, params,
+ params_size, hash, signature);
+
+ for (i=0;i<params_size;i++)
+ _gnutls_mpi_release( &params[i]);
+
if (result < 0)
{
gnutls_assert ();
diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c
index 4058dbcf9d..a8ad52ad55 100644
--- a/lib/gnutls_state.c
+++ b/lib/gnutls_state.c
@@ -624,6 +624,7 @@ _gnutls_dh_set_group (gnutls_session_t session, mpi_t gen, mpi_t prime)
return 0;
}
+#ifdef ENABLE_OPENPGP
/**
* gnutls_openpgp_send_cert - This function will order gnutls to send the openpgp fingerprint instead of the key
* @session: is a pointer to a #gnutls_session_t structure.
@@ -640,6 +641,7 @@ gnutls_openpgp_send_cert (gnutls_session_t session,
{
session->internals.pgp_fingerprint = status;
}
+#endif
/**
* gnutls_certificate_send_x509_rdn_sequence - This function will order gnutls to send or not the x.509 rdn sequence
@@ -662,11 +664,13 @@ gnutls_certificate_send_x509_rdn_sequence (gnutls_session_t session,
session->internals.ignore_rdn_sequence = status;
}
+#ifdef ENABLE_OPENPGP
int
_gnutls_openpgp_send_fingerprint (gnutls_session_t session)
{
return session->internals.pgp_fingerprint;
}
+#endif
/*-
* _gnutls_record_set_default_version - Used to set the default version for the first record packet
diff --git a/libextra/opencdk/Makefile.am b/lib/opencdk/Makefile.am
index 9f6a805f86..7e74320c0e 100644
--- a/libextra/opencdk/Makefile.am
+++ b/lib/opencdk/Makefile.am
@@ -25,9 +25,9 @@ INCLUDES = -I$(top_srcdir)/lib \
noinst_LTLIBRARIES = libminiopencdk.la
-libminiopencdk_la_SOURCES = armor.c filters.h main.c seskey.c types.h \
- cipher.c kbnode.c main.h packet.h dummy.c sig-check.c verify.c \
- compress.c keydb.c misc.c pubkey.c stream.c write-packet.c \
+libminiopencdk_la_SOURCES = armor.c filters.h main.c types.h \
+ kbnode.c main.h packet.h dummy.c sig-check.c verify.c hash.c \
+ keydb.c pubkey.c stream.c write-packet.c misc.c seskey.c \
context.h literal.c new-packet.c read-packet.c stream.h opencdk.h
EXTRA_DIST = README
diff --git a/libextra/opencdk/README b/lib/opencdk/README
index 2cf780e04c..2cf780e04c 100644
--- a/libextra/opencdk/README
+++ b/lib/opencdk/README
diff --git a/libextra/opencdk/armor.c b/lib/opencdk/armor.c
index 5195d41f72..4921995d1c 100644
--- a/libextra/opencdk/armor.c
+++ b/lib/opencdk/armor.c
@@ -4,15 +4,20 @@
*
* This file is part of OpenCDK.
*
- * OpenCDK is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * OpenCDK is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * The OpenCDK library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
*
* ChangeLog for basic BASE64 code (base64_encode, base64_decode):
* Original author: Eric S. Raymond (Fetchmail)
diff --git a/libextra/opencdk/context.h b/lib/opencdk/context.h
index e656952302..e656952302 100644
--- a/libextra/opencdk/context.h
+++ b/lib/opencdk/context.h
diff --git a/libextra/opencdk/dummy.c b/lib/opencdk/dummy.c
index e21e927d43..e21e927d43 100644
--- a/libextra/opencdk/dummy.c
+++ b/lib/opencdk/dummy.c
diff --git a/libextra/opencdk/filters.h b/lib/opencdk/filters.h
index a60881edb8..a60881edb8 100644
--- a/libextra/opencdk/filters.h
+++ b/lib/opencdk/filters.h
diff --git a/lib/opencdk/hash.c b/lib/opencdk/hash.c
new file mode 100644
index 0000000000..abfc101fca
--- /dev/null
+++ b/lib/opencdk/hash.c
@@ -0,0 +1,81 @@
+/* hash.c - Hash filters
+ * Copyright (C) 2002, 2003, 2007 Timo Schulz
+ *
+ * This file is part of OpenCDK.
+ *
+ * The OpenCDK library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
+ */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <assert.h>
+#include <sys/stat.h>
+
+#include "opencdk.h"
+#include "main.h"
+#include "filters.h"
+
+static cdk_error_t
+hash_encode (void *opaque, FILE *in, FILE *out)
+{
+ md_filter_t *mfx = opaque;
+ byte buf[BUFSIZE];
+ gcry_error_t err;
+ int nread;
+
+ if (!mfx)
+ return CDK_Inv_Value;
+
+ _cdk_log_debug ("hash filter: encode algo=%d\n", mfx->digest_algo);
+
+ if (!mfx->md)
+ {
+ err = gcry_md_open (&mfx->md, mfx->digest_algo, 0);
+ if (err)
+ return map_gcry_error (err);
+ }
+
+ while (!feof (in))
+ {
+ nread = fread (buf, 1, BUFSIZE, in);
+ if (!nread)
+ break;
+ gcry_md_write (mfx->md, buf, nread);
+ }
+
+ wipemem (buf, sizeof (buf));
+ return 0;
+}
+
+cdk_error_t
+_cdk_filter_hash (void *opaque, int ctl, FILE *in, FILE *out)
+{
+ if (ctl == STREAMCTL_READ)
+ return hash_encode (opaque, in, out);
+ else if (ctl == STREAMCTL_FREE)
+ {
+ md_filter_t *mfx = opaque;
+ if (mfx)
+ {
+ _cdk_log_debug ("free hash filter\n");
+ gcry_md_close (mfx->md);
+ mfx->md = NULL;
+ return 0;
+ }
+ }
+ return CDK_Inv_Mode;
+}
diff --git a/libextra/opencdk/kbnode.c b/lib/opencdk/kbnode.c
index 848a34214b..dd76fd74d5 100644
--- a/libextra/opencdk/kbnode.c
+++ b/lib/opencdk/kbnode.c
@@ -4,15 +4,20 @@
*
* This file is part of OpenCDK.
*
- * OpenCDK is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * The OpenCDK library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
*
- * OpenCDK is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
@@ -31,7 +36,7 @@
* cdk_kbnode_new:
* @pkt: the packet to add
*
- * Allocate a new key node and add the packet.
+ * Allocates a new key node and adds a packet.
**/
cdk_kbnode_t
cdk_kbnode_new (cdk_packet_t pkt)
@@ -60,7 +65,7 @@ _cdk_kbnode_clone (cdk_kbnode_t node)
* cdk_kbnode_release:
* @n: the key node
*
- * Release the memory of the node.
+ * Releases the memory of the node.
**/
void
cdk_kbnode_release (cdk_kbnode_t node)
@@ -82,7 +87,7 @@ cdk_kbnode_release (cdk_kbnode_t node)
* cdk_kbnode_delete:
* @node: the key node
*
- * Mark the given node as deleted.
+ * Marks the given node as deleted.
**/
void
cdk_kbnode_delete (cdk_kbnode_t node)
@@ -110,7 +115,7 @@ _cdk_kbnode_add (cdk_kbnode_t root, cdk_kbnode_t node)
* @node: the node to add
* @pkttype: packet type
*
- * Insert @node into the list after @root but before a packet which is not of
+ * Inserts @node into the list after @root but before a packet which is not of
* type @pkttype (only if @pkttype != 0).
**/
void
@@ -145,7 +150,7 @@ cdk_kbnode_insert (cdk_kbnode_t root, cdk_kbnode_t node, int pkttype)
* @node: the key node
* @pkttype: packet type
*
- * Find the previous node (if @pkttype = 0) or the previous node
+ * Finds the previous node (if @pkttype = 0) or the previous node
* with pkttype @pkttype in the list starting with @root of @node.
**/
cdk_kbnode_t
@@ -202,7 +207,7 @@ cdk_kbnode_find_next (cdk_kbnode_t node, int pkttype)
* @node: the key node
* @pkttype: packet type
*
- * Try to find the next node with the packettype @pkttype.
+ * Tries to find the next node with the packettype @pkttype.
**/
cdk_kbnode_t
cdk_kbnode_find (cdk_kbnode_t node, int pkttype)
@@ -233,28 +238,30 @@ cdk_kbnode_find_packet (cdk_kbnode_t node, int pkttype)
}
-/****************
- * Walk through a list of kbnodes. This function returns
+/**
+ * cdk_kbnode_walk:
+ *
+ * Walks through a list of kbnodes. This function returns
* the next kbnode for each call; before using the function the first
* time, the caller must set CONTEXT to NULL (This has simply the effect
* to start with ROOT).
*/
cdk_kbnode_t
-cdk_kbnode_walk (cdk_kbnode_t root, cdk_kbnode_t * context, int all)
+cdk_kbnode_walk (cdk_kbnode_t root, cdk_kbnode_t *ctx, int all)
{
cdk_kbnode_t n;
do
{
- if(! *context )
+ if (! *ctx)
{
- *context = root;
+ *ctx = root;
n = root;
}
else
{
- n = (*context)->next;
- *context = n;
+ n = (*ctx)->next;
+ *ctx = n;
}
}
while (!all && n && n->is_deleted);
@@ -266,13 +273,13 @@ cdk_kbnode_walk (cdk_kbnode_t root, cdk_kbnode_t * context, int all)
* cdk_kbnode_commit:
* @root: the nodes
*
- * Commit changes made to the kblist at ROOT. Note that ROOT my change,
+ * Commits changes made to the kblist at ROOT. Note that ROOT my change,
* and it is therefore passed by reference.
* The function has the effect of removing all nodes marked as deleted.
* returns true if any node has been changed
*/
int
-cdk_kbnode_commit (cdk_kbnode_t * root)
+cdk_kbnode_commit (cdk_kbnode_t *root)
{
cdk_kbnode_t n, nl;
int changed = 0;
@@ -302,7 +309,7 @@ cdk_kbnode_commit (cdk_kbnode_t * root)
* @root: the root node
* @node: the node to delete
*
- * Remove a node from the root node.
+ * Removes a node from the root node.
*/
void
cdk_kbnode_remove (cdk_kbnode_t *root, cdk_kbnode_t node)
@@ -334,7 +341,7 @@ cdk_kbnode_remove (cdk_kbnode_t *root, cdk_kbnode_t node)
* @node: the node to move
* @where: destination place where to move the node.
*
- * Move NODE behind right after WHERE or to the beginning if WHERE is NULL.
+ * Moves NODE behind right after WHERE or to the beginning if WHERE is NULL.
*/
void
cdk_kbnode_move (cdk_kbnode_t * root, cdk_kbnode_t node, cdk_kbnode_t where)
@@ -370,7 +377,7 @@ cdk_kbnode_move (cdk_kbnode_t * root, cdk_kbnode_t node, cdk_kbnode_t where)
* cdk_kbnode_get_packet:
* @node: the key node
*
- * Return the packet which is stored inside the node in @node.
+ * Returns the packet which is stored inside the node in @node.
**/
cdk_packet_t
cdk_kbnode_get_packet (cdk_kbnode_t node)
@@ -387,7 +394,7 @@ cdk_kbnode_get_packet (cdk_kbnode_t node)
* @buf: the buffer which stores the key sequence
* @buflen: the length of the buffer
*
- * Try to read a key node from the memory buffer @buf.
+ * Tries to read a key node from the memory buffer @buf.
**/
cdk_error_t
cdk_kbnode_read_from_mem (cdk_kbnode_t *ret_node,
@@ -396,10 +403,13 @@ cdk_kbnode_read_from_mem (cdk_kbnode_t *ret_node,
cdk_stream_t inp;
cdk_error_t rc;
- if (!buflen || !ret_node || !buf)
+ if (!ret_node || !buf)
return CDK_Inv_Value;
*ret_node = NULL;
+ if (!buflen)
+ return CDK_Too_Short;
+
rc = cdk_stream_tmp_from_mem (buf, buflen, &inp);
if (rc)
return rc;
@@ -408,6 +418,7 @@ cdk_kbnode_read_from_mem (cdk_kbnode_t *ret_node,
return rc;
}
+
/**
* cdk_kbnode_write_to_mem_alloc:
* @node: the key node
@@ -426,7 +437,7 @@ cdk_kbnode_write_to_mem_alloc (cdk_kbnode_t node,
cdk_error_t rc;
size_t len;
- if (!node)
+ if (!node || !r_buf || !r_buflen)
return CDK_Inv_Value;
*r_buf = NULL;
@@ -470,7 +481,7 @@ cdk_kbnode_write_to_mem_alloc (cdk_kbnode_t node,
* @buf: the buffer to store the node data
* @r_nbytes: the new length of the buffer.
*
- * Try to write the contents of the key node to the buffer @buf and
+ * Tries to write the contents of the key node to the buffer @buf and
* return the length of it in @r_nbytes. If buf is zero, only the
* length of the node is calculated and returned in @r_nbytes.
* Whenever it is possible, the cdk_kbnode_write_to_mem_alloc should be used.
@@ -479,11 +490,11 @@ cdk_error_t
cdk_kbnode_write_to_mem (cdk_kbnode_t node, byte *buf, size_t *r_nbytes)
{
cdk_kbnode_t n;
- cdk_stream_t s;
- size_t len;
+ cdk_stream_t s;
cdk_error_t rc;
+ size_t len;
- if (!node)
+ if (!node || !r_nbytes)
return CDK_Inv_Value;
rc = cdk_stream_tmp_new (&s);
@@ -518,7 +529,10 @@ cdk_kbnode_write_to_mem (cdk_kbnode_t node, byte *buf, size_t *r_nbytes)
return 0;
}
if (*r_nbytes < len)
- rc = CDK_Too_Short;
+ {
+ *r_nbytes = len;
+ rc = CDK_Too_Short;
+ }
if (!rc)
*r_nbytes = cdk_stream_read (s, buf, len);
cdk_stream_close (s);
@@ -534,7 +548,7 @@ cdk_kbnode_write_to_mem (cdk_kbnode_t node, byte *buf, size_t *r_nbytes)
* @pkttype: packet type to hash (if zero use the packet type from the node)
* @flags: flags which depend on the operation
*
- * Hash the key node contents. Two modes are supported. If the packet
+ * Hashes the key node contents. Two modes are supported. If the packet
* type is used (!= 0) then the function searches the first node with
* this type. Otherwise the node is seen as a single node and the type
* is extracted from it.
diff --git a/libextra/opencdk/keydb.c b/lib/opencdk/keydb.c
index 8b04d3f6ac..79b7b89c5a 100644
--- a/libextra/opencdk/keydb.c
+++ b/lib/opencdk/keydb.c
@@ -3,15 +3,20 @@
*
* This file is part of OpenCDK.
*
- * OpenCDK is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * The OpenCDK library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
*
- * OpenCDK is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
@@ -1499,12 +1504,20 @@ keydb_merge_selfsig (cdk_kbnode_t key, u32 *keyid)
s = cdk_subpkt_find (sig->hashed, CDK_SIGSUBPKT_KEY_FLAGS);
if (s)
{
- if (s->d[0] & 0x03) /* cert + sign data */
- key_usage |= CDK_KEY_USG_SIGN;
- if (s->d[0] & 0x0C) /* encrypt comm. + storage */
- key_usage |= CDK_KEY_USG_ENCR;
+ if (s->d[0] & 0x01) /* cert + sign data */
+ key_usage |= CDK_KEY_USG_CERT_SIGN;
+ if (s->d[0] & 0x02) /* cert + sign data */
+ key_usage |= CDK_KEY_USG_DATA_SIGN;
+ if (s->d[0] & 0x04) /* encrypt comm. + storage */
+ key_usage |= CDK_KEY_USG_COMM_ENCR;
+ if (s->d[0] & 0x08) /* encrypt comm. + storage */
+ key_usage |= CDK_KEY_USG_STORAGE_ENCR;
+ if (s->d[0] & 0x10) /* encrypt comm. + storage */
+ key_usage |= CDK_KEY_USG_SPLIT_KEY;
if (s->d[0] & 0x20)
key_usage |= CDK_KEY_USG_AUTH;
+ if (s->d[0] & 0x80) /* encrypt comm. + storage */
+ key_usage |= CDK_KEY_USG_SHARED_KEY;
}
s = cdk_subpkt_find (sig->hashed, CDK_SIGSUBPKT_PREFS_SYM);
if (s)
diff --git a/libextra/opencdk/literal.c b/lib/opencdk/literal.c
index e38e564bbf..438a0b6526 100644
--- a/libextra/opencdk/literal.c
+++ b/lib/opencdk/literal.c
@@ -3,15 +3,20 @@
*
* This file is part of OpenCDK.
*
- * OpenCDK is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * The OpenCDK library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
*
- * OpenCDK is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
diff --git a/libextra/opencdk/main.c b/lib/opencdk/main.c
index 2d3648ef3a..c0e67da149 100644
--- a/libextra/opencdk/main.c
+++ b/lib/opencdk/main.c
@@ -3,15 +3,20 @@
*
* This file is part of OpenCDK.
*
- * OpenCDK is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * OpenCDK is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * The OpenCDK library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
diff --git a/libextra/opencdk/main.h b/lib/opencdk/main.h
index 3e9a443d8f..3e9a443d8f 100644
--- a/libextra/opencdk/main.h
+++ b/lib/opencdk/main.h
diff --git a/lib/opencdk/misc.c b/lib/opencdk/misc.c
new file mode 100644
index 0000000000..35c8ad4482
--- /dev/null
+++ b/lib/opencdk/misc.c
@@ -0,0 +1,324 @@
+/* misc.c
+ * Copyright (C) 2002, 2003 Timo Schulz
+ * Copyright (C) 1998-2002, 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of OpenCDK.
+ *
+ * The OpenCDK library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
+ */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/stat.h>
+
+#include "opencdk.h"
+#include "main.h"
+
+
+u32
+_cdk_buftou32 (const byte *buf)
+{
+ u32 u;
+
+ if (!buf)
+ return 0;
+ u = buf[0] << 24;
+ u |= buf[1] << 16;
+ u |= buf[2] << 8;
+ u |= buf[3];
+ return u;
+}
+
+
+void
+_cdk_u32tobuf (u32 u, byte *buf)
+{
+ if (!buf)
+ return;
+ buf[0] = u >> 24;
+ buf[1] = u >> 16;
+ buf[2] = u >> 8;
+ buf[3] = u ;
+}
+
+
+static const char *
+parse_version_number (const char *s, int *number)
+{
+ int val = 0;
+
+ if (*s == '0' && isdigit (s[1]))
+ return NULL;
+ /* leading zeros are not allowed */
+ for (; isdigit(*s); s++)
+ {
+ val *= 10;
+ val += *s - '0';
+ }
+ *number = val;
+ return val < 0? NULL : s;
+}
+
+
+static const char *
+parse_version_string (const char * s, int * major, int * minor, int * micro)
+{
+ s = parse_version_number( s, major );
+ if( !s || *s != '.' )
+ return NULL;
+ s++;
+ s = parse_version_number (s, minor);
+ if (!s || *s != '.')
+ return NULL;
+ s++;
+ s = parse_version_number(s, micro);
+ if (!s)
+ return NULL;
+ return s; /* patchlevel */
+}
+
+
+/**
+ * cdk_check_version:
+ * @req_version: The requested version
+ *
+ * Check that the the version of the library is at minimum the requested
+ * one and return the version string; return NULL if the condition is
+ * not satisfied. If a NULL is passed to this function, no check is done,
+ *but the version string is simply returned.
+ **/
+const char *
+cdk_check_version (const char *req_version)
+{
+ const char *ver = VERSION;
+ int my_major, my_minor, my_micro;
+ int rq_major, rq_minor, rq_micro;
+ const char *my_plvl, *rq_plvl;
+
+ if (!req_version)
+ return ver;
+ my_plvl = parse_version_string (ver, &my_major, &my_minor, &my_micro);
+ if (!my_plvl)
+ return NULL;
+ /* very strange our own version is bogus */
+ rq_plvl = parse_version_string (req_version, &rq_major, &rq_minor,
+ &rq_micro);
+ if (!rq_plvl)
+ return NULL; /* req version string is invalid */
+ if (my_major > rq_major
+ || (my_major == rq_major && my_minor > rq_minor)
+ || (my_major == rq_major && my_minor == rq_minor
+ && my_micro > rq_micro)
+ || (my_major == rq_major && my_minor == rq_minor
+ && my_micro == rq_micro
+ && strcmp (my_plvl, rq_plvl) >= 0))
+ return ver;
+ return NULL;
+}
+
+
+/**
+ * cdk_strlist_free:
+ * @sl: the string list
+ *
+ * Release the string list object.
+ **/
+void
+cdk_strlist_free (cdk_strlist_t sl)
+{
+ cdk_strlist_t sl2;
+
+ for(; sl; sl = sl2)
+ {
+ sl2 = sl->next;
+ cdk_free (sl);
+ }
+}
+
+
+/**
+ * cdk_strlist_add:
+ * @list: destination string list
+ * @string: the string to add
+ *
+ * Add the given list to the string list.
+ **/
+cdk_strlist_t
+cdk_strlist_add (cdk_strlist_t *list, const char *string)
+{
+ cdk_strlist_t sl;
+
+ if (!string)
+ return NULL;
+
+ sl = cdk_calloc (1, sizeof *sl + strlen (string) + 1);
+ if (!sl)
+ return NULL;
+ strcpy (sl->d, string);
+ sl->next = *list;
+ *list = sl;
+ return sl;
+}
+
+
+/**
+ * cdk_strlist_next:
+ * @root: the opaque string list.
+ * @r_str: optional argument to store the string data.
+ *
+ * Return the next string list node from @root. The optional
+ * argument @r_str return the data of the current (!) node.
+ **/
+cdk_strlist_t
+cdk_strlist_next (cdk_strlist_t root, const char **r_str)
+{
+ cdk_strlist_t node;
+
+ if (root && r_str)
+ *r_str = root->d;
+ for (node = root->next; node; node = node->next)
+ return node;
+
+ return NULL;
+}
+
+
+const char*
+_cdk_memistr (const char *buf, size_t buflen, const char *sub)
+{
+ const byte *t, *s;
+ size_t n;
+
+ for (t = (byte*)buf, n = buflen, s = (byte*)sub ; n ; t++, n--)
+ {
+ if (toupper (*t) == toupper (*s))
+ {
+ for (buf = t++, buflen = n--, s++;
+ n && toupper (*t) == toupper ((byte)*s); t++, s++, n--)
+ ;
+ if (!*s)
+ return buf;
+ t = (byte*)buf;
+ n = buflen;
+ s = (byte*)sub;
+ }
+ }
+
+ return NULL;
+}
+
+
+/* Map the gcrypt error to a valid opencdk error constant. */
+cdk_error_t
+_cdk_map_gcry_error (gcry_error_t err)
+{
+ /* FIXME: We need to catch them all. */
+ switch (gpg_err_code (err))
+ {
+ case GPG_ERR_NO_ERROR: return CDK_Success;
+ case GPG_ERR_INV_VALUE: return CDK_Inv_Value;
+ case GPG_ERR_GENERAL: return CDK_General_Error;
+ case GPG_ERR_INV_PACKET: return CDK_Inv_Packet;
+ case GPG_ERR_TOO_SHORT: return CDK_Too_Short;
+ case GPG_ERR_TOO_LARGE: return CDK_Inv_Value;
+ case GPG_ERR_NO_PUBKEY:
+ case GPG_ERR_NO_SECKEY: return CDK_Error_No_Key;
+ case GPG_ERR_BAD_SIGNATURE: return CDK_Bad_Sig;
+ case GPG_ERR_NO_DATA: return CDK_No_Data;
+ default:
+ break;
+ }
+
+ return (cdk_error_t)err;
+}
+
+
+/* Remove all trailing white spaces from the string. */
+void
+_cdk_trim_string (char *s, int canon)
+{
+ while (s && *s &&
+ (s[strlen (s)-1] == '\t' ||
+ s[strlen (s)-1] == '\r' ||
+ s[strlen (s)-1] == '\n' ||
+ s[strlen (s)-1] == ' '))
+ s[strlen (s) -1] = '\0';
+ if (canon)
+ strcat (s, "\r\n");
+}
+
+
+int
+_cdk_check_args (int overwrite, const char *in, const char *out)
+{
+ struct stat stbuf;
+
+ if (!in || !out)
+ return CDK_Inv_Value;
+ if (strlen (in) == strlen (out) && strcmp (in, out) == 0)
+ return CDK_Inv_Mode;
+ if (!overwrite && !stat (out, &stbuf))
+ return CDK_Inv_Mode;
+ return 0;
+}
+
+#ifdef _WIN32
+#include <io.h>
+#include <fcntl.h>
+
+FILE *
+my_tmpfile (void)
+{
+ /* Because the tmpfile() version of wine is not really useful,
+ we implement our own version to avoid problems with 'make check'. */
+ static const char *letters = "abcdefghijklmnopqrstuvwxyz";
+ char buf[512], rnd[24];
+ FILE *fp;
+ int fd, i;
+
+ gcry_create_nonce (rnd, DIM (rnd));
+ for (i=0; i < DIM (rnd)-1; i++)
+ {
+ char c = letters[(unsigned char)rnd[i] % 26];
+ rnd[i] = c;
+ }
+ rnd[DIM (rnd)-1]=0;
+ if (!GetTempPath (464, buf))
+ return NULL;
+ strcat (buf, "_cdk_");
+ strcat (buf, rnd);
+
+ /* We need to make sure the file will be deleted when it is closed. */
+ fd = _open (buf, _O_CREAT | _O_EXCL | _O_TEMPORARY |
+ _O_RDWR | _O_BINARY, _S_IREAD | _S_IWRITE);
+ if (fd == -1)
+ return NULL;
+ fp = fdopen (fd, "w+b");
+ if (fp != NULL)
+ return fp;
+ _close (fd);
+ return NULL;
+}
+#else
+FILE*
+my_tmpfile (void)
+{
+ return tmpfile ();
+}
+#endif
diff --git a/libextra/opencdk/new-packet.c b/lib/opencdk/new-packet.c
index 1c7e5da4aa..c824ed0e81 100644
--- a/libextra/opencdk/new-packet.c
+++ b/lib/opencdk/new-packet.c
@@ -3,15 +3,20 @@
*
* This file is part of OpenCDK.
*
- * OpenCDK is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * OpenCDK is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * The OpenCDK library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
diff --git a/libextra/opencdk/opencdk.h b/lib/opencdk/opencdk.h
index 83ca487e91..da2a869f95 100644
--- a/libextra/opencdk/opencdk.h
+++ b/lib/opencdk/opencdk.h
@@ -281,12 +281,17 @@ enum cdk_crypto_mode_t {
CDK_CRYPTYPE_IMPORT = 6
};
-
+#define CDK_KEY_USG_ENCR CDK_KEY_USG_COMM_ENCR|CDK_KEY_USG_STORAGE_ENCR
+#define CDK_KEY_USG_SIGN CDK_KEY_USG_DATA_SIGN|CDK_KEY_USG_CERT_SIGN
/* A list of valid public key usages. */
enum cdk_key_usage_t {
- CDK_KEY_USG_ENCR = 1, /* Key can be used for encryption. */
- CDK_KEY_USG_SIGN = 2, /* Key can be used for signing and certifying. */
- CDK_KEY_USG_AUTH = 4 /* Key can be used for authentication. */
+ CDK_KEY_USG_CERT_SIGN = 1,
+ CDK_KEY_USG_DATA_SIGN = 2,
+ CDK_KEY_USG_COMM_ENCR = 4,
+ CDK_KEY_USG_STORAGE_ENCR = 8,
+ CDK_KEY_USG_SPLIT_KEY = 16,
+ CDK_KEY_USG_AUTH = 32,
+ CDK_KEY_USG_SHARED_KEY = 128
};
diff --git a/libextra/opencdk/packet.h b/lib/opencdk/packet.h
index 03547acea0..03547acea0 100644
--- a/libextra/opencdk/packet.h
+++ b/lib/opencdk/packet.h
diff --git a/libextra/opencdk/pubkey.c b/lib/opencdk/pubkey.c
index e3498e0a95..5a072b56ba 100644
--- a/libextra/opencdk/pubkey.c
+++ b/lib/opencdk/pubkey.c
@@ -4,15 +4,20 @@
*
* This file is part of OpenCDK.
*
- * OpenCDK is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * The OpenCDK library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
*
- * OpenCDK is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -600,14 +605,15 @@ _cdk_pk_algo_usage (int algo)
return usage;
}
-
+/* You can use a NULL buf to get the output size only
+ */
static cdk_error_t
mpi_to_buffer (gcry_mpi_t a, byte *buf, size_t buflen,
size_t *r_nwritten, size_t *r_nbits)
{
size_t nbits;
- if (!a || !buf || !r_nwritten)
+ if (!a || !r_nwritten)
return CDK_Inv_Value;
nbits = gcry_mpi_get_nbits (a);
@@ -616,6 +622,7 @@ mpi_to_buffer (gcry_mpi_t a, byte *buf, size_t buflen,
if ((nbits+7)/8+2 > buflen)
return CDK_Too_Short;
*r_nwritten = (nbits+7)/8+2;
+
if (gcry_mpi_print (GCRYMPI_FMT_PGP, buf, buflen, r_nwritten, a))
return CDK_Wrong_Format;
return 0;
diff --git a/libextra/opencdk/read-packet.c b/lib/opencdk/read-packet.c
index b1f50b6e22..040f564c49 100644
--- a/libextra/opencdk/read-packet.c
+++ b/lib/opencdk/read-packet.c
@@ -3,15 +3,20 @@
*
* This file is part of OpenCDK.
*
- * OpenCDK is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * OpenCDK is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * The OpenCDK library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -73,40 +78,7 @@ read_16 (cdk_stream_t s)
static int
read_s2k (cdk_stream_t inp, cdk_s2k_t s2k)
{
- size_t nread;
-
- if (!inp || !s2k)
- return CDK_Inv_Value;
-
- if (DEBUG_PKT)
- _cdk_log_debug ("read_s2k:\n");
-
- s2k->mode = cdk_stream_getc (inp);
- if (cdk_stream_eof (inp))
- return CDK_Inv_Packet;
- if (s2k->mode != CDK_S2K_SIMPLE && s2k->mode != CDK_S2K_SALTED &&
- s2k->mode != CDK_S2K_ITERSALTED)
- return CDK_Inv_Packet;
- s2k->hash_algo = cdk_stream_getc (inp);
- if (s2k->mode == CDK_S2K_SIMPLE) /* No additional elements. */
- memset (s2k->salt, 0, sizeof (s2k->salt));
- else if (s2k->mode == CDK_S2K_SALTED ||
- s2k->mode == CDK_S2K_ITERSALTED)
- {
- if (stream_read (inp, s2k->salt, DIM (s2k->salt), &nread))
- return CDK_Inv_Packet;
- if (nread != DIM (s2k->salt))
- return CDK_Inv_Packet;
- if (s2k->mode == CDK_S2K_ITERSALTED)
- {
- s2k->count = cdk_stream_getc (inp);
- if (cdk_stream_eof (inp))
- return CDK_Inv_Packet;
- }
- }
- else
- return CDK_Inv_Mode;
- return 0;
+ return CDK_Not_Implemented;
}
diff --git a/libextra/opencdk/seskey.c b/lib/opencdk/seskey.c
index 0f5d0f90c0..ebf5381db8 100644
--- a/libextra/opencdk/seskey.c
+++ b/lib/opencdk/seskey.c
@@ -4,15 +4,20 @@
*
* This file is part of OpenCDK.
*
- * OpenCDK is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * The OpenCDK library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
*
- * OpenCDK is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
@@ -345,7 +350,7 @@ _cdk_sk_unprotect_auto (cdk_ctx_t hd, cdk_pkt_seckey_t sk)
* @hd: the session handle
* @enc: the public key encrypted packet
* @sk: the secret key.
- *
+ *
* Try to extract the DEK from the public key encrypted packet.
**/
cdk_error_t
diff --git a/libextra/opencdk/sig-check.c b/lib/opencdk/sig-check.c
index 948fe2993b..f81ae12e4e 100644
--- a/libextra/opencdk/sig-check.c
+++ b/lib/opencdk/sig-check.c
@@ -4,15 +4,20 @@
*
* This file is part of OpenCDK.
*
- * OpenCDK is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * OpenCDK is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * The OpenCDK library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
diff --git a/libextra/opencdk/stream.c b/lib/opencdk/stream.c
index d934ce690b..2e43b8bff4 100644
--- a/libextra/opencdk/stream.c
+++ b/lib/opencdk/stream.c
@@ -3,15 +3,20 @@
*
* This file is part of OpenCDK.
*
- * OpenCDK is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * The OpenCDK library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
*
- * OpenCDK is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -53,7 +58,7 @@ FILE *my_tmpfile (void);
* @file: The file to open
* @ret_s: The new STREAM object
*
- * Create a new stream based on an existing file. The stream is
+ * Creates a new stream based on an existing file. The stream is
* opened in read-only mode.
**/
cdk_error_t
@@ -137,9 +142,11 @@ cdk_stream_new_from_cbs (cdk_stream_cbs_t cbs, void *opa,
/**
- * cdk_stream_new: Create a new stream into into the given file.
+ * cdk_stream_new:
* @file: The name of the new file
* @ret_s: The new STREAM object
+ *
+ * Create a new stream into into the given file.
**/
cdk_error_t
cdk_stream_new (const char *file, cdk_stream_t *ret_s)
@@ -180,10 +187,11 @@ cdk_stream_new (const char *file, cdk_stream_t *ret_s)
/**
- * cdk_stream_create: create a new stream.
+ * cdk_stream_create:
* @file: the filename
* @ret_s: the object
*
+ * Creates a new stream.
* The difference to cdk_stream_new is, that no filtering can be used with
* this kind of stream and everything is written directly to the stream.
**/
@@ -225,7 +233,7 @@ cdk_stream_create (const char *file, cdk_stream_t *ret_s)
* cdk_stream_tmp_new:
* @r_out: the new temp stream.
*
- * Allocate a new tempory stream which is not associated with a file.
+ * Allocates a new tempory stream which is not associated with a file.
*/
cdk_error_t
cdk_stream_tmp_new (cdk_stream_t *r_out)
@@ -241,7 +249,7 @@ cdk_stream_tmp_new (cdk_stream_t *r_out)
* @buflen: how large the buffer is
* @r_out: the new stream with the given contents.
*
- * Create a new tempory stream with the given contests.
+ * Creates a new tempory stream with the given contests.
*/
cdk_error_t
cdk_stream_tmp_from_mem (const void *buf, size_t buflen, cdk_stream_t *r_out)
@@ -313,7 +321,7 @@ _cdk_stream_append (const char *file, cdk_stream_t *ret_s)
* cdk_stream_is_compressed:
* @s: the stream
*
- * Return 0 if the stream is uncompressed, otherwise the
+ * Returns 0 if the stream is uncompressed, otherwise the
* compression algorithm.
*/
int
@@ -614,18 +622,19 @@ stream_id_to_filter (int type)
case fARMOR : return _cdk_filter_armor;
case fLITERAL : return _cdk_filter_literal;
case fTEXT : return _cdk_filter_text;
- case fCIPHER : return _cdk_filter_cipher;
- case fCOMPRESS: return _cdk_filter_compress;
+/* case fCIPHER : return _cdk_filter_cipher; */
+/* case fCOMPRESS: return _cdk_filter_compress; */
default : return NULL;
}
}
/**
- * cdk_stream_filter_disable: Disable the filter with the type 'type'
+ * cdk_stream_filter_disable:
* @s: The STREAM object
* @type: The numberic filter ID.
*
+ * Disables the filter with the type 'type'.
**/
cdk_error_t
cdk_stream_filter_disable (cdk_stream_t s, int type)
@@ -810,11 +819,12 @@ _cdk_stream_get_opaque (cdk_stream_t s, int fid)
/**
- * cdk_stream_read: Try to read count bytes from the STREAM object.
+ * cdk_stream_read:
* @s: The STREAM object.
* @buf: The buffer to insert the readed bytes.
* @count: Request so much bytes.
*
+ * Tries to read count bytes from the STREAM object.
* When this function is called the first time, it can take a while
* because all filters need to be processed. Please remember that you
* need to add the filters in reserved order.
@@ -892,11 +902,12 @@ cdk_stream_getc (cdk_stream_t s)
/**
- * cdk_stream_write: Try to write count bytes into the stream.
+ * cdk_stream_write:
* @s: The STREAM object
* @buf: The buffer with the values to write.
* @count: The size of the buffer.
*
+ * Tries to write count bytes into the stream.
* In this function we simply write the bytes to the stream. We can't
* use the filters here because it would mean they have to support
* partial flushing.
@@ -1108,6 +1119,8 @@ cdk_stream_set_cipher_flag (cdk_stream_t s, cdk_dek_t dek, int use_mdc)
_cdk_log_debug ("stream: enable cipher mode\n");
if (!s)
return CDK_Inv_Value;
+
+#if 0
f = filter_add (s, _cdk_filter_cipher, fCIPHER);
if (!f)
return CDK_Out_Of_Core;
@@ -1121,6 +1134,9 @@ cdk_stream_set_cipher_flag (cdk_stream_t s, cdk_dek_t dek, int use_mdc)
f->u.cfx.blkmode.size = s->blkmode;
}
return 0;
+#endif
+
+ return CDK_Not_Implemented;
}
@@ -1140,6 +1156,9 @@ cdk_stream_set_compress_flag (cdk_stream_t s, int algo, int level)
{
struct stream_filter_s *f;
+ return CDK_Not_Implemented;
+
+#if 0
if (!s)
return CDK_Inv_Value;
f = filter_add (s, _cdk_filter_compress, fCOMPRESS);
@@ -1149,6 +1168,7 @@ cdk_stream_set_compress_flag (cdk_stream_t s, int algo, int level)
f->u.zfx.algo = algo;
f->u.zfx.level = level;
return 0;
+#endif
}
@@ -1207,7 +1227,7 @@ cdk_stream_set_hash_flag (cdk_stream_t s, int digest_algo)
* @s: the stream object
* @val: 1=on, 0=off
*
- * Enable or disable the cache section of a stream object.
+ * Enables or disable the cache section of a stream object.
**/
cdk_error_t
cdk_stream_enable_cache (cdk_stream_t s, int val)
@@ -1292,34 +1312,49 @@ cdk_stream_kick_off (cdk_stream_t inp, cdk_stream_t out)
* @ret_buf: the buffer to store the content
* @ret_buflen: length of the buffer
*
- * Map the data of the given stream into a memory section. @ret_count
+ * Maps the data of the given stream into a memory section. @ret_count
* contains the length of the buffer.
**/
cdk_error_t
cdk_stream_mmap_part (cdk_stream_t s, off_t off, size_t len,
byte **ret_buf, size_t *ret_buflen)
{
- off_t oldpos;
- int n;
cdk_error_t rc;
+ off_t oldpos;
+ int n;
- if (!s || !ret_buf || !ret_buflen)
+ if (!ret_buf || !ret_buflen)
+ return CDK_Inv_Value;
+ *ret_buf = NULL;
+ *ret_buflen = 0;
+
+ if (!s)
return CDK_Inv_Value;
+
+ /* Memory mapping is not supported on custom I/O objects. */
if (s->cbs_hd)
- return CDK_Inv_Mode;
+ {
+ _cdk_log_debug ("cdk_stream_mmap_part: not supported on callbacks\n");
+ return CDK_Inv_Mode;
+ }
- *ret_buflen = 0;
- *ret_buf = NULL;
oldpos = cdk_stream_tell (s);
rc = cdk_stream_flush (s);
- if (!rc)
- rc = cdk_stream_seek (s, off);
+ if (rc)
+ return rc;
+ rc = cdk_stream_seek (s, off);
if (rc)
return rc;
if (!len)
len = cdk_stream_get_length (s);
- if (!len || len > MAX_MAP_SIZE)
- return 0;
+ if (!len)
+ {
+ _cdk_log_debug ("cdk_stream_mmap_part: invalid file size %lu\n", len);
+ return s->error;
+ }
+ if (len > MAX_MAP_SIZE)
+ return CDK_Too_Short;
+
*ret_buf = cdk_calloc (1, len+1);
*ret_buflen = len;
n = cdk_stream_read (s, *ret_buf, len);
diff --git a/libextra/opencdk/stream.h b/lib/opencdk/stream.h
index df44c6c6b8..df44c6c6b8 100644
--- a/libextra/opencdk/stream.h
+++ b/lib/opencdk/stream.h
diff --git a/libextra/opencdk/types.h b/lib/opencdk/types.h
index c53a0850ae..c53a0850ae 100644
--- a/libextra/opencdk/types.h
+++ b/lib/opencdk/types.h
diff --git a/libextra/opencdk/verify.c b/lib/opencdk/verify.c
index de6a50ebb9..0f4c7bc859 100644
--- a/libextra/opencdk/verify.c
+++ b/lib/opencdk/verify.c
@@ -3,15 +3,20 @@
*
* This file is part of OpenCDK.
*
- * OpenCDK is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * OpenCDK is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * The OpenCDK library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
diff --git a/libextra/opencdk/write-packet.c b/lib/opencdk/write-packet.c
index 6b8f8eaecb..fb1146e1dd 100644
--- a/libextra/opencdk/write-packet.c
+++ b/lib/opencdk/write-packet.c
@@ -3,15 +3,20 @@
*
* This file is part of OpenCDK.
*
- * OpenCDK is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * OpenCDK is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * The OpenCDK library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
diff --git a/lib/openpgp/Makefile.am b/lib/openpgp/Makefile.am
new file mode 100644
index 0000000000..93c479ee9f
--- /dev/null
+++ b/lib/openpgp/Makefile.am
@@ -0,0 +1,50 @@
+## Process this file with automake to produce Makefile.in
+# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
+#
+# Author: Nikos Mavrogiannopoulos
+#
+# This file is part of GNUTLS-EXTRA.
+#
+# GNUTLS-EXTRA is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 3 of the
+# License, or (at your option) any later version.
+#
+# GNUTLS-EXTRA is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNUTLS-EXTRA; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+AM_CPPFLAGS = -I$(top_srcdir)/lgl -I$(top_builddir)/lgl \
+ -I$(top_srcdir)/crypto -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/includes -I../../includes \
+ -I$(top_srcdir)/lib/opencdk
+
+if ENABLE_MINITASN1
+AM_CPPFLAGS += -I$(top_srcdir)/lib/minitasn1
+else
+AM_CPPFLAGS += $(LIBTASN1_CFLAGS)
+endif
+
+noinst_LTLIBRARIES = libgnutls_openpgp.la
+
+COBJECTS = pgp.c pgpverify.c extras.c compat.c privkey.c output.c
+
+libgnutls_openpgp_la_SOURCES = $(COBJECTS) openpgp.h gnutls_openpgp.h
+
+EXTRA_DIST = pgp-api.texi
+
+pgp-api.texi: $(COBJECTS)
+ @echo "" > pgp-api.texi
+ @for i in ../gnutls_openpgp.c $(COBJECTS); do \
+ echo -n "Creating documentation for file $$i... " && \
+ $(top_srcdir)/doc/scripts/gdoc -texinfo $$i >> pgp-api.texi && \
+ echo "ok"; \
+ done
+
+dist-hook: pgp-api.texi
diff --git a/lib/openpgp/compat.c b/lib/openpgp/compat.c
new file mode 100644
index 0000000000..c04d861ab7
--- /dev/null
+++ b/lib/openpgp/compat.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation
+ *
+ * Author: Timo Schulz, Nikos Mavrogiannopoulos
+ *
+ * This file is part of GNUTLS-EXTRA.
+ *
+ * GNUTLS-EXTRA is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNUTLS-EXTRA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Compatibility functions on OpenPGP key parsing.
+ */
+
+#include <gnutls_int.h>
+#include <gnutls_errors.h>
+#include <gnutls_openpgp.h>
+#include <openpgp.h>
+
+/*-
+ * gnutls_openpgp_verify_key - Verify all signatures on the key
+ * @cert_list: the structure that holds the certificates.
+ * @cert_list_lenght: the items in the cert_list.
+ * @status: the output of the verification function
+ *
+ * Verify all signatures in the certificate list. When the key
+ * is not available, the signature is skipped.
+ *
+ * The return value is one of the CertificateStatus entries.
+ *
+ * NOTE: this function does not verify using any "web of trust". You
+ * may use GnuPG for that purpose, or any other external PGP application.
+ -*/
+int
+_gnutls_openpgp_verify_key (const gnutls_certificate_credentials_t cred,
+ const gnutls_datum_t * cert_list,
+ int cert_list_length, unsigned int *status)
+{
+ int ret = 0;
+ gnutls_openpgp_crt_t key = NULL;
+ unsigned int verify = 0, verify_self = 0;
+
+ if (!cert_list || cert_list_length != 1)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_NO_CERTIFICATE_FOUND;
+ }
+
+ ret = gnutls_openpgp_crt_init (&key);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ return ret;
+ }
+
+ ret = gnutls_openpgp_crt_import (key, &cert_list[0], GNUTLS_OPENPGP_FMT_RAW);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ goto leave;
+ }
+
+#ifndef KEYRING_HACK
+ if (cred->keyring != NULL)
+ {
+ ret = gnutls_openpgp_crt_verify_ring (key, cred->keyring, 0, &verify);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ goto leave;
+ }
+ }
+#else
+ {
+ gnutls_openpgp_keyring_t kring;
+
+ ret = gnutls_openpgp_keyring_init( &kring);
+ if ( ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ ret = gnutls_openpgp_keyring_import( kring, &cred->keyring, cred->keyring_format);
+ if ( ret < 0) {
+ gnutls_assert();
+ gnutls_openpgp_keyring_deinit( kring);
+ return ret;
+ }
+
+ ret = gnutls_openpgp_crt_verify_ring (key, kring, 0, &verify);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ gnutls_openpgp_keyring_deinit( kring);
+ return ret;
+ }
+ gnutls_openpgp_keyring_deinit( kring);
+ }
+#endif
+
+ /* Now try the self signature. */
+ ret = gnutls_openpgp_crt_verify_self (key, 0, &verify_self);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ goto leave;
+ }
+
+ *status = verify_self | verify;
+
+#ifndef KEYRING_HACK
+ /* If we only checked the self signature. */
+ if (!cred->keyring)
+#else
+ if (!cred->keyring.data || !cred->keyring.size)
+#endif
+ *status |= GNUTLS_CERT_SIGNER_NOT_FOUND;
+
+
+ ret = 0;
+
+leave:
+ gnutls_openpgp_crt_deinit (key);
+
+ return ret;
+}
+
+/*-
+ * gnutls_openpgp_fingerprint - Gets the fingerprint
+ * @cert: the raw data that contains the OpenPGP public key.
+ * @fpr: the buffer to save the fingerprint.
+ * @fprlen: the integer to save the length of the fingerprint.
+ *
+ * Returns the fingerprint of the OpenPGP key. Depence on the algorithm,
+ * the fingerprint can be 16 or 20 bytes.
+ -*/
+int
+_gnutls_openpgp_fingerprint (const gnutls_datum_t * cert,
+ unsigned char *fpr, size_t * fprlen)
+{
+ gnutls_openpgp_crt_t key;
+ int ret;
+
+ ret = gnutls_openpgp_crt_init (&key);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ return ret;
+ }
+
+ ret = gnutls_openpgp_crt_import (key, cert, GNUTLS_OPENPGP_FMT_RAW);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ return ret;
+ }
+
+ ret = gnutls_openpgp_crt_get_fingerprint (key, fpr, fprlen);
+ gnutls_openpgp_crt_deinit (key);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ return ret;
+ }
+
+ return 0;
+}
+
+/*-
+ * gnutls_openpgp_get_raw_key_creation_time - Extract the timestamp
+ * @cert: the raw data that contains the OpenPGP public key.
+ *
+ * Returns the timestamp when the OpenPGP key was created.
+ -*/
+time_t
+_gnutls_openpgp_get_raw_key_creation_time (const gnutls_datum_t * cert)
+{
+ gnutls_openpgp_crt_t key;
+ int ret;
+ time_t tim;
+
+ ret = gnutls_openpgp_crt_init (&key);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ return ret;
+ }
+
+ ret = gnutls_openpgp_crt_import (key, cert, GNUTLS_OPENPGP_FMT_RAW);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ return ret;
+ }
+
+ tim = gnutls_openpgp_crt_get_creation_time (key);
+
+ gnutls_openpgp_crt_deinit (key);
+
+ return tim;
+}
+
+
+/*-
+ * gnutls_openpgp_get_raw_key_expiration_time - Extract the expire date
+ * @cert: the raw data that contains the OpenPGP public key.
+ *
+ * Returns the time when the OpenPGP key expires. A value of '0' means
+ * that the key doesn't expire at all.
+ -*/
+time_t
+_gnutls_openpgp_get_raw_key_expiration_time (const gnutls_datum_t * cert)
+{
+ gnutls_openpgp_crt_t key;
+ int ret;
+ time_t tim;
+
+ ret = gnutls_openpgp_crt_init (&key);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ return ret;
+ }
+
+ ret = gnutls_openpgp_crt_import (key, cert, GNUTLS_OPENPGP_FMT_RAW);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ return ret;
+ }
+
+ tim = gnutls_openpgp_crt_get_expiration_time (key);
+
+ gnutls_openpgp_crt_deinit (key);
+
+ return tim;
+}
diff --git a/lib/openpgp/extras.c b/lib/openpgp/extras.c
new file mode 100644
index 0000000000..2ce4ce256d
--- /dev/null
+++ b/lib/openpgp/extras.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation
+ *
+ * Author: Nikos Mavrogiannopoulos, Timo Schulz
+ *
+ * This file is part of GNUTLS-EXTRA.
+ *
+ * GNUTLS-EXTRA is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNUTLS-EXTRA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Functions on OpenPGP keyring parsing
+ */
+
+#include <gnutls_int.h>
+#include <gnutls_datum.h>
+#include <gnutls_global.h>
+#include <gnutls_errors.h>
+#include <gnutls_openpgp.h>
+#include <gnutls_num.h>
+#include <openpgp.h>
+
+/* Keyring stuff.
+ */
+
+/**
+ * gnutls_openpgp_keyring_init - This function initializes a gnutls_openpgp_keyring_t structure
+ * @keyring: The structure to be initialized
+ *
+ * This function will initialize an OpenPGP keyring structure.
+ *
+ * Returns 0 on success.
+ *
+ **/
+int
+gnutls_openpgp_keyring_init (gnutls_openpgp_keyring_t * keyring)
+{
+ *keyring = gnutls_calloc (1, sizeof (gnutls_openpgp_keyring_int));
+
+ if (*keyring)
+ return 0; /* success */
+ return GNUTLS_E_MEMORY_ERROR;
+}
+
+
+/**
+ * gnutls_openpgp_keyring_deinit - This function deinitializes memory used by a gnutls_openpgp_keyring_t structure
+ * @keyring: The structure to be initialized
+ *
+ * This function will deinitialize a keyring structure.
+ *
+ **/
+void
+gnutls_openpgp_keyring_deinit (gnutls_openpgp_keyring_t keyring)
+{
+ if (!keyring)
+ return;
+
+ if (keyring->db)
+ {
+ cdk_keydb_free (keyring->db);
+ keyring->db = NULL;
+ }
+
+ /* In some cases the stream is also stored outside the keydb context
+ and we need to close it here then. */
+ if (keyring->db_stream)
+ {
+ cdk_stream_close (keyring->db_stream);
+ keyring->db_stream = NULL;
+ }
+
+ gnutls_free (keyring);
+}
+
+/**
+ * gnutls_openpgp_keyring_check_id - Check if a key id exists in the keyring
+ * @ring: holds the keyring to check against
+ * @keyid: will hold the keyid to check for.
+ * @flags: unused (should be 0)
+ *
+ * Check if a given key ID exists in the keyring.
+ *
+ * Returns 0 on success (if keyid exists) and a negative error code
+ * on failure.
+ **/
+int
+gnutls_openpgp_keyring_check_id (gnutls_openpgp_keyring_t ring,
+ gnutls_openpgp_keyid_t keyid,
+ unsigned int flags)
+{
+ cdk_pkt_pubkey_t pk;
+ uint32_t id[2];
+
+ id[0] = _gnutls_read_uint32 (keyid.keyid);
+ id[1] = _gnutls_read_uint32 (&keyid.keyid[4]);
+
+ if (!cdk_keydb_get_pk (ring->db, id, &pk))
+ {
+ cdk_pk_release (pk);
+ return 0;
+ }
+
+ _gnutls_debug_log ("PGP: key not found %08lX\n", (unsigned long)id[1]);
+ return GNUTLS_E_NO_CERTIFICATE_FOUND;
+}
+
+/**
+ * gnutls_openpgp_keyring_import - Import a raw- or Base64-encoded OpenPGP keyring
+ * @keyring: The structure to store the parsed key.
+ * @data: The RAW or BASE64 encoded keyring.
+ * @format: One of #gnutls_openpgp_keyring_fmt elements.
+ *
+ * This function will convert the given RAW or Base64 encoded keyring to the
+ * native #gnutls_openpgp_keyring_t format. The output will be stored in
+ * 'keyring'.
+ *
+ * Returns 0 on success.
+ *
+ **/
+int
+gnutls_openpgp_keyring_import (gnutls_openpgp_keyring_t keyring,
+ const gnutls_datum_t *data,
+ gnutls_openpgp_crt_fmt_t format)
+{
+ cdk_error_t err;
+ cdk_stream_t input;
+
+ _gnutls_debug_log ("PGP: keyring import format '%s'\n",
+ format == GNUTLS_OPENPGP_FMT_RAW? "raw" : "base64");
+
+ if (format == GNUTLS_OPENPGP_FMT_RAW)
+ {
+ err = cdk_keydb_new (&keyring->db, CDK_DBTYPE_DATA,
+ data->data, data->size);
+ if (err)
+ gnutls_assert ();
+ return _gnutls_map_cdk_rc (err);
+ }
+
+ /* Create a new stream from the given data, which means to
+ allocate a new stream and to write the data in the stream.
+ Then push the armor filter to decode the data and to store
+ it in the raw format. */
+ err = cdk_stream_tmp_from_mem (data->data, data->size, &input);
+ if (!err)
+ err = cdk_stream_set_armor_flag (input, 0);
+ if (!err)
+ err = cdk_keydb_new_from_stream (&keyring->db, 0, input);
+ if (err)
+ {
+ cdk_stream_close (input);
+ gnutls_assert ();
+ }
+ else
+ /* The keydb function will not close the stream itself, so we need to
+ store it separately to close it later. */
+ keyring->db_stream = input;
+
+ return _gnutls_map_cdk_rc (err);
+}
+
diff --git a/lib/openpgp/gnutls_openpgp.h b/lib/openpgp/gnutls_openpgp.h
new file mode 100644
index 0000000000..067de99831
--- /dev/null
+++ b/lib/openpgp/gnutls_openpgp.h
@@ -0,0 +1,99 @@
+#include <config.h>
+
+#ifdef ENABLE_OPENPGP
+
+#ifndef GNUTLS_OPENPGP_LOCAL_H
+#define GNUTLS_OPENPGP_LOCAL_H
+
+#include <auth_cert.h>
+#include <opencdk.h>
+
+typedef struct
+{
+ int type;
+ size_t size;
+ uint8_t *data;
+} keybox_blob;
+
+typedef enum
+{
+ KBX_BLOB_FILE = 0x00,
+ KBX_BLOB_DATA = 0x01
+} keyring_blob_types;
+
+/* OpenCDK compatible */
+typedef enum
+{
+ KEY_ATTR_NONE = 0,
+ KEY_ATTR_SHORT_KEYID = 3,
+ KEY_ATTR_KEYID = 4,
+ KEY_ATTR_FPR = 5
+} key_attr_t;
+
+int
+gnutls_certificate_set_openpgp_key_file (gnutls_certificate_credentials_t
+ res, const char *CERTFILE,
+ const char *KEYFILE, gnutls_openpgp_crt_fmt_t);
+
+int gnutls_openpgp_count_key_names (const gnutls_datum_t * cert);
+
+int gnutls_certificate_set_openpgp_keyring_file
+ (gnutls_certificate_credentials_t c, const char *file, gnutls_openpgp_crt_fmt_t);
+
+int
+gnutls_certificate_set_openpgp_keyring_mem (gnutls_certificate_credentials_t
+ c, const opaque * data,
+ size_t dlen, gnutls_openpgp_crt_fmt_t);
+
+int gnutls_openpgp_get_key (gnutls_datum_t * key,
+ gnutls_openpgp_keyring_t keyring,
+ key_attr_t by, opaque * pattern);
+
+int gnutls_openpgp_recv_key (const char *host,
+ short port, uint32_t keyid,
+ gnutls_datum_t * key);
+
+/* internal */
+int _gnutls_openpgp_raw_crt_to_gcert (gnutls_cert * cert,
+ const gnutls_datum_t * raw);
+
+int
+_gnutls_openpgp_raw_privkey_to_gkey (gnutls_privkey * pkey,
+ const gnutls_datum_t * raw_key);
+
+int
+_gnutls_openpgp_request_key (gnutls_session_t,
+ gnutls_datum_t * ret,
+ const gnutls_certificate_credentials_t cred,
+ opaque * key_fpr, int key_fpr_size);
+
+int _gnutls_openpgp_verify_key (const gnutls_certificate_credentials_t,
+ const gnutls_datum_t * cert_list,
+ int cert_list_length, unsigned int *status);
+int _gnutls_openpgp_fingerprint (const gnutls_datum_t * cert,
+ unsigned char *fpr, size_t * fprlen);
+time_t _gnutls_openpgp_get_raw_key_creation_time (const gnutls_datum_t *
+ cert);
+time_t _gnutls_openpgp_get_raw_key_expiration_time (const gnutls_datum_t *
+ cert);
+
+int
+gnutls_openpgp_privkey_init (gnutls_openpgp_privkey_t * key);
+
+int
+gnutls_openpgp_privkey_init (gnutls_openpgp_privkey_t * key);
+
+void
+gnutls_openpgp_privkey_deinit (gnutls_openpgp_privkey_t key);
+
+int
+gnutls_openpgp_privkey_import (gnutls_openpgp_privkey_t key,
+ const gnutls_datum_t * data,
+ gnutls_openpgp_crt_fmt_t format,
+ const char *pass, unsigned int flags);
+
+int _gnutls_openpgp_find_valid_subkey( gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t* keyid);
+
+#endif /*GNUTLS_OPENPGP_LOCAL_H */
+
+#endif /*ENABLE_OPENPGP */
diff --git a/lib/openpgp/openpgp.h b/lib/openpgp/openpgp.h
new file mode 100644
index 0000000000..3ec9ba9111
--- /dev/null
+++ b/lib/openpgp/openpgp.h
@@ -0,0 +1,107 @@
+#ifndef OPENPGP_LOCAL_H
+# define OPENPGP_LOCAL_H
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef ENABLE_OPENPGP
+
+#include <opencdk.h>
+#include <gnutls/openpgp.h>
+
+#define KEYID_IMPORT(dst, src) \
+ dst[0] = _gnutls_read_uint32( src.keyid); \
+ dst[1] = _gnutls_read_uint32( src.keyid+4)
+
+/* Internal context to store the OpenPGP key. */
+typedef struct gnutls_openpgp_crt_int
+{
+ cdk_kbnode_t knode;
+} gnutls_openpgp_crt_int;
+
+/* Internal context to store the private OpenPGP key. */
+typedef struct gnutls_openpgp_privkey_int
+{
+ cdk_kbnode_t knode;
+} gnutls_openpgp_privkey_int;
+
+
+typedef struct gnutls_openpgp_keyring_int
+{
+ cdk_keydb_hd_t db;
+ cdk_stream_t db_stream;
+} gnutls_openpgp_keyring_int;
+
+int _gnutls_map_cdk_rc (int rc);
+int gnutls_openpgp_crt_get_name (gnutls_openpgp_crt_t key,
+ int idx, char *buf, size_t * sizeof_buf);
+int gnutls_openpgp_crt_get_fingerprint (gnutls_openpgp_crt_t key,
+ void *fpr, size_t * fprlen);
+gnutls_pk_algorithm_t
+gnutls_openpgp_crt_get_pk_algorithm (gnutls_openpgp_crt_t key,
+ unsigned int *bits);
+int gnutls_openpgp_crt_get_version (gnutls_openpgp_crt_t key);
+time_t gnutls_openpgp_crt_get_creation_time (gnutls_openpgp_crt_t key);
+time_t gnutls_openpgp_crt_get_expiration_time (gnutls_openpgp_crt_t key);
+int gnutls_openpgp_crt_get_id (gnutls_openpgp_crt_t key,
+ gnutls_openpgp_keyid_t* keyid);
+
+int gnutls_openpgp_crt_init (gnutls_openpgp_crt_t * key);
+void gnutls_openpgp_crt_deinit (gnutls_openpgp_crt_t key);
+int gnutls_openpgp_crt_import (gnutls_openpgp_crt_t key,
+ const gnutls_datum_t * data,
+ gnutls_openpgp_crt_fmt_t format);
+int gnutls_openpgp_crt_export (gnutls_openpgp_crt_t key,
+ gnutls_openpgp_crt_fmt_t format,
+ void *output_data, size_t * output_data_size);
+
+void gnutls_openpgp_keyring_deinit (gnutls_openpgp_keyring_t keyring);
+int gnutls_openpgp_keyring_init (gnutls_openpgp_keyring_t * keyring);
+int gnutls_openpgp_keyring_import (gnutls_openpgp_keyring_t keyring,
+ const gnutls_datum_t * data,
+ gnutls_openpgp_crt_fmt_t format);
+int gnutls_openpgp_keyring_check_id (gnutls_openpgp_keyring_t ring,
+ gnutls_openpgp_keyid_t keyid,
+ unsigned int flags);
+
+int gnutls_openpgp_crt_verify_ring (gnutls_openpgp_crt_t key,
+ gnutls_openpgp_keyring_t keyring,
+ unsigned int flags, unsigned int *verify);
+
+int gnutls_openpgp_crt_verify_self (gnutls_openpgp_crt_t key,
+ unsigned int flags, unsigned int *verify);
+
+int _gnutls_openpgp_crt_to_gcert (gnutls_cert * gcert,
+ gnutls_openpgp_crt_t cert, gnutls_openpgp_keyid_t keyid);
+int _gnutls_openpgp_privkey_to_gkey (gnutls_privkey * dest,
+ gnutls_openpgp_privkey_t src, gnutls_openpgp_keyid_t);
+
+void gnutls_openpgp_privkey_deinit (gnutls_openpgp_privkey_t key);
+
+cdk_packet_t _gnutls_get_valid_subkey(cdk_kbnode_t knode, int key_type);
+
+unsigned int _gnutls_get_pgp_key_usage(unsigned int pgp_usage);
+
+int
+_gnutls_openpgp_crt_get_mpis (gnutls_openpgp_crt_t cert, uint32_t keyid[2],
+ mpi_t * params, int *params_size);
+
+int
+_gnutls_openpgp_privkey_get_mpis (gnutls_openpgp_privkey_t pkey, uint32_t keyid[2],
+ mpi_t * params, int *params_size);
+
+cdk_packet_t _gnutls_openpgp_find_key( cdk_kbnode_t knode, uint32_t keyid[2], unsigned int priv);
+
+int _gnutls_read_pgp_mpi( cdk_packet_t pkt, unsigned int priv, size_t idx, mpi_t* m);
+
+int _gnutls_openpgp_find_subkey_idx( cdk_kbnode_t knode, uint32_t keyid[2],
+ unsigned int priv);
+
+#else /* no opencdk */
+
+typedef void *gnutls_openpgp_keyring_t;
+
+#endif /* ENABLE_OPENPGP */
+
+#endif /* OPENPGP_LOCAL_H */
diff --git a/lib/openpgp/output.c b/lib/openpgp/output.c
new file mode 100644
index 0000000000..71b997133f
--- /dev/null
+++ b/lib/openpgp/output.c
@@ -0,0 +1,402 @@
+/*
+ * Copyright (C) 2007 Free Software Foundation
+ *
+ * Author: Simon Josefsson, Nikos Mavrogiannopoulos
+ *
+ * This file is part of GNUTLS.
+ *
+ * The GNUTLS library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+/* Functions for printing X.509 Certificate structures
+ */
+
+#include <gnutls_int.h>
+#include <gnutls/openpgp.h>
+#include <gnutls_errors.h>
+
+/* I18n of error codes. */
+#include "gettext.h"
+#define _(String) dgettext (PACKAGE, String)
+#define N_(String) gettext_noop (String)
+
+#define addf _gnutls_string_append_printf
+#define adds _gnutls_string_append_str
+
+static void
+hexdump (gnutls_string * str, const char *data, size_t len, const char *spc)
+{
+ size_t j;
+
+ if (spc)
+ adds (str, spc);
+ for (j = 0; j < len; j++)
+ {
+ if (((j + 1) % 16) == 0)
+ {
+ addf (str, "%.2x\n", (unsigned char) data[j]);
+ if (spc && j != (len - 1))
+ adds (str, spc);
+ }
+ else if (j == (len - 1))
+ addf (str, "%.2x", (unsigned char) data[j]);
+ else
+ addf (str, "%.2x:", (unsigned char) data[j]);
+ }
+ if ((j % 16) != 0)
+ adds (str, "\n");
+}
+
+static void
+hexprint (gnutls_string * str, const char *data, size_t len)
+{
+ size_t j;
+
+ if (len == 0)
+ adds (str, "00");
+ else
+ {
+ for (j = 0; j < len; j++)
+ addf (str, "%.2x", (unsigned char) data[j]);
+ }
+}
+
+
+static void
+asciiprint (gnutls_string * str, const char *data, size_t len)
+{
+ size_t j;
+
+ for (j = 0; j < len; j++)
+ if (isprint (data[j]))
+ addf (str, "%c", (unsigned char) data[j]);
+ else
+ addf (str, ".");
+}
+
+static void
+print_key_usage (gnutls_string * str, gnutls_openpgp_crt_t cert, unsigned int idx)
+{
+ unsigned int key_usage;
+ int err;
+
+ addf (str, _("\t\tKey Usage:\n"));
+
+
+ if (idx == -1)
+ err = gnutls_openpgp_crt_get_key_usage (cert, &key_usage);
+ else
+ err = gnutls_openpgp_crt_get_subkey_usage (cert, idx, &key_usage);
+ if (err < 0)
+ {
+ addf (str, _("error: get_key_usage: %s\n"), gnutls_strerror (err));
+ return;
+ }
+
+ if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE)
+ addf (str, _("\t\t\tDigital signature.\n"));
+ if (key_usage & GNUTLS_KEY_NON_REPUDIATION)
+ addf (str, _("\t\t\tNon repudiation.\n"));
+ if (key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT)
+ addf (str, _("\t\t\tKey encipherment.\n"));
+ if (key_usage & GNUTLS_KEY_DATA_ENCIPHERMENT)
+ addf (str, _("\t\t\tData encipherment.\n"));
+ if (key_usage & GNUTLS_KEY_KEY_AGREEMENT)
+ addf (str, _("\t\t\tKey agreement.\n"));
+ if (key_usage & GNUTLS_KEY_KEY_CERT_SIGN)
+ addf (str, _("\t\t\tCertificate signing.\n"));
+ if (key_usage & GNUTLS_KEY_CRL_SIGN)
+ addf (str, _("\t\t\tCRL signing.\n"));
+ if (key_usage & GNUTLS_KEY_ENCIPHER_ONLY)
+ addf (str, _("\t\t\tKey encipher only.\n"));
+ if (key_usage & GNUTLS_KEY_DECIPHER_ONLY)
+ addf (str, _("\t\t\tKey decipher only.\n"));
+}
+
+/* idx == -1 indicates main key
+ * otherwise the subkey.
+ */
+static void
+print_key_id (gnutls_string * str, gnutls_openpgp_crt_t cert, int idx)
+{
+ gnutls_openpgp_keyid_t id;
+ int err;
+
+ if (idx < 0)
+ err = gnutls_openpgp_crt_get_id (cert, &id);
+ else
+ err = gnutls_openpgp_crt_get_subkey_id( cert, idx, &id);
+
+ if (err < 0)
+ addf (str, "error: get_id: %s\n", gnutls_strerror (err));
+ else
+ {
+ addf (str, _("\tID (hex): "));
+ hexprint (str, id.keyid, sizeof(id.keyid));
+ addf (str, "\n");
+ }
+}
+
+/* idx == -1 indicates main key
+ * otherwise the subkey.
+ */
+static void
+print_key_fingerprint (gnutls_string * str, gnutls_openpgp_crt_t cert)
+{
+ char fpr[128];
+ size_t fpr_size = sizeof (fpr);
+ int err;
+
+ err = gnutls_openpgp_crt_get_fingerprint (cert, fpr, &fpr_size);
+ if (err < 0)
+ addf (str, "error: get_fingerprint: %s\n", gnutls_strerror (err));
+ else
+ {
+ addf (str, _("\tFingerprint (hex): "));
+ hexprint (str, fpr, fpr_size);
+ addf (str, "\n");
+ }
+}
+
+static void
+print_key_revoked (gnutls_string * str, gnutls_openpgp_crt_t cert, int idx)
+{
+ char fpr[128];
+ size_t fpr_size = sizeof (fpr);
+ int err;
+
+ if (idx < 0)
+ err = gnutls_openpgp_crt_get_revoked_status (cert);
+ else
+ err = gnutls_openpgp_crt_get_subkey_revoked_status( cert, idx);
+
+ if (err != 0)
+ addf (str, "Revoked: True");
+}
+
+static void
+print_key_times(gnutls_string * str, gnutls_openpgp_crt_t cert, int idx)
+{
+ time_t tim;
+
+ addf (str, _("\tTime stamps:\n"));
+
+ if (idx == -1)
+ tim = gnutls_openpgp_crt_get_creation_time (cert);
+ else
+ tim = gnutls_openpgp_crt_get_subkey_creation_time (cert, idx);
+
+ {
+ char s[42];
+ size_t max = sizeof (s);
+ struct tm t;
+
+ if (gmtime_r (&tim, &t) == NULL)
+ addf (str, "error: gmtime_r (%d)\n", t);
+ else if (strftime (s, max, "%a %b %e %H:%M:%S UTC %Y", &t) == 0)
+ addf (str, "error: strftime (%d)\n", t);
+ else
+ addf (str, _("\t\tCreation: %s\n"), s);
+ }
+
+ if (idx == -1)
+ tim = gnutls_openpgp_crt_get_expiration_time (cert);
+ else
+ tim = gnutls_openpgp_crt_get_subkey_expiration_time (cert, idx);
+ {
+ char s[42];
+ size_t max = sizeof (s);
+ struct tm t;
+
+ if (gmtime_r (&tim, &t) == NULL)
+ addf (str, "error: gmtime_r (%d)\n", t);
+ else if (strftime (s, max, "%a %b %e %H:%M:%S UTC %Y", &t) == 0)
+ addf (str, "error: strftime (%d)\n", t);
+ else
+ addf (str, _("\t\tExpiration: %s\n"), s);
+ }
+}
+
+static void
+print_key_info(gnutls_string * str, gnutls_openpgp_crt_t cert, int idx)
+{
+ int err;
+ unsigned int bits;
+
+ if (idx == -1)
+ err = gnutls_openpgp_crt_get_pk_algorithm (cert, &bits);
+ else
+ err = gnutls_openpgp_crt_get_subkey_pk_algorithm (cert, idx, &bits);
+
+ if (err < 0)
+ addf (str, "error: get_pk_algorithm: %s\n", gnutls_strerror (err));
+ else
+ {
+ const char *name = gnutls_pk_algorithm_get_name (err);
+ if (name == NULL)
+ name = "Unknown";
+
+ addf (str, _("\tPublic Key Algorithm: %s\n"), name);
+#if 0
+ switch (err)
+ {
+ case GNUTLS_PK_RSA:
+ {
+ gnutls_datum_t m, e;
+
+ err = gnutls_openpgp_crt_get_pk_rsa_raw (cert, &m, &e);
+ if (err < 0)
+ addf (str, "error: get_pk_rsa_raw: %s\n",
+ gnutls_strerror (err));
+ else
+ {
+ addf (str, _("\t\tModulus (bits %d):\n"), bits);
+ hexdump (str, m.data, m.size, "\t\t\t");
+ addf (str, _("\t\tExponent:\n"));
+ hexdump (str, e.data, e.size, "\t\t\t");
+ }
+
+ gnutls_free (m.data);
+ gnutls_free (e.data);
+ }
+ break;
+
+ case GNUTLS_PK_DSA:
+ {
+ gnutls_datum_t p, q, g, y;
+
+ err = gnutls_openpgp_crt_get_pk_dsa_raw (cert, &p, &q, &g, &y);
+ if (err < 0)
+ addf (str, "error: get_pk_dsa_raw: %s\n",
+ gnutls_strerror (err));
+ else
+ {
+ addf (str, _("\t\tPublic key (bits %d):\n"), bits);
+ hexdump (str, y.data, y.size, "\t\t\t");
+ addf (str, _("\t\tP:\n"));
+ hexdump (str, p.data, p.size, "\t\t\t");
+ addf (str, _("\t\tQ:\n"));
+ hexdump (str, q.data, q.size, "\t\t\t");
+ addf (str, _("\t\tG:\n"));
+ hexdump (str, g.data, g.size, "\t\t\t");
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+#endif
+ }
+}
+
+
+static void
+print_cert (gnutls_string * str, gnutls_openpgp_crt_t cert, unsigned int format)
+{
+int i, subkeys;
+int err;
+char dn[1024];
+size_t dn_size = sizeof (dn);
+
+ /* Version. */
+ {
+ int version = gnutls_openpgp_crt_get_version (cert);
+ if (version < 0)
+ addf (str, "error: get_version: %s\n", gnutls_strerror (version));
+ else
+ addf (str, _("\tVersion: %d\n"), version);
+ }
+
+ /* ID. */
+ print_key_id( str, cert, -1);
+
+ print_key_fingerprint( str, cert);
+
+ /* Names. */
+ i = 0;
+ do {
+
+ err = gnutls_openpgp_crt_get_name (cert, i++, dn, &dn_size);
+
+ if (err < 0 && err != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+ addf (str, "error: get_name: %s\n", gnutls_strerror (err));
+ break;
+ }
+
+ if (err > 0)
+ addf (str, _("\tName[%d]: %s\n"), i, dn);
+
+ } while( err > 0);
+
+ print_key_times( str, cert, -1);
+
+ print_key_info( str, cert, -1);
+ print_key_usage( str, cert, -1);
+ print_key_revoked( str, cert, -1);
+
+ subkeys = gnutls_openpgp_crt_get_subkey_count( cert);
+ if (subkeys < 0)
+ return;
+
+ for (i=0;i<subkeys;i++) {
+ addf( str, _("\n\tSubkey[%d]:\n"), i);
+
+ print_key_id( str, cert, i);
+ print_key_times( str, cert, i);
+ print_key_info( str, cert, i);
+ print_key_usage( str, cert, i);
+ print_key_revoked( str, cert, i);
+ }
+
+}
+
+/**
+ * gnutls_openpgp_crt_print - Pretty print OpenPGP certificates
+ * @cert: The structure to be printed
+ * @format: Indicate the format to use
+ * @out: Newly allocated datum with zero terminated string.
+ *
+ * This function will pretty print an OpenPGP certificate, suitable for
+ * display to a human.
+ *
+ * The format should be zero for future compatibility.
+ *
+ * The output @out needs to be deallocate using gnutls_free().
+ *
+ * Returns 0 on success.
+ **/
+int
+gnutls_openpgp_crt_print (gnutls_openpgp_crt_t cert,
+ gnutls_certificate_print_formats_t format,
+ gnutls_datum_t *out)
+{
+ gnutls_string str;
+
+ _gnutls_string_init (&str, gnutls_malloc, gnutls_realloc, gnutls_free);
+
+ _gnutls_string_append_str (&str, _("OpenPGP Certificate Information:\n"));
+
+ print_cert (&str, cert, format);
+
+ _gnutls_string_append_data (&str, "\0", 1);
+ out->data = str.data;
+ out->size = strlen (str.data);
+
+ return 0;
+}
+
diff --git a/lib/openpgp/pgp.c b/lib/openpgp/pgp.c
new file mode 100644
index 0000000000..e0f0472bf6
--- /dev/null
+++ b/lib/openpgp/pgp.c
@@ -0,0 +1,1079 @@
+/*
+ * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
+ *
+ * Author: Timo Schulz, Nikos Mavrogiannopoulos
+ *
+ * This file is part of GNUTLS-EXTRA.
+ *
+ * GNUTLS-EXTRA is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNUTLS-EXTRA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Functions on OpenPGP key parsing
+ */
+
+#include <gnutls_int.h>
+#include <gnutls_datum.h>
+#include <gnutls_global.h>
+#include <gnutls_errors.h>
+#include <openpgp.h>
+#include <x509/rfc2818.h>
+#include <gnutls_num.h>
+
+/**
+ * gnutls_openpgp_crt_init - This function initializes a gnutls_openpgp_crt_t structure
+ * @key: The structure to be initialized
+ *
+ * This function will initialize an OpenPGP key structure.
+ *
+ * Returns 0 on success.
+ *
+ **/
+int
+gnutls_openpgp_crt_init (gnutls_openpgp_crt_t * key)
+{
+ *key = gnutls_calloc (1, sizeof (gnutls_openpgp_crt_int));
+
+ if (*key)
+ return 0; /* success */
+ return GNUTLS_E_MEMORY_ERROR;
+}
+
+/**
+ * gnutls_openpgp_crt_deinit - This function deinitializes memory used by a gnutls_openpgp_crt_t structure
+ * @key: The structure to be initialized
+ *
+ * This function will deinitialize a key structure.
+ **/
+void
+gnutls_openpgp_crt_deinit (gnutls_openpgp_crt_t key)
+{
+ if (!key)
+ return;
+
+ if (key->knode)
+ {
+ cdk_kbnode_release (key->knode);
+ key->knode = NULL;
+ }
+
+ gnutls_free (key);
+}
+
+/**
+ * gnutls_openpgp_crt_import - This function will import a RAW or BASE64 encoded key
+ * @key: The structure to store the parsed key.
+ * @data: The RAW or BASE64 encoded key.
+ * @format: One of gnutls_openpgp_crt_fmt_t elements.
+ *
+ * This function will convert the given RAW or Base64 encoded key
+ * to the native gnutls_openpgp_crt_t format. The output will be stored in 'key'.
+ *
+ * Returns 0 on success.
+ **/
+int
+gnutls_openpgp_crt_import (gnutls_openpgp_crt_t key,
+ const gnutls_datum_t * data,
+ gnutls_openpgp_crt_fmt_t format)
+{
+ cdk_stream_t inp;
+ int rc;
+
+ if (format == GNUTLS_OPENPGP_FMT_RAW)
+ rc = cdk_kbnode_read_from_mem (&key->knode, data->data, data->size);
+ else
+ {
+ rc = cdk_stream_tmp_from_mem (data->data, data->size, &inp);
+ if (rc)
+ {
+ rc = _gnutls_map_cdk_rc (rc);
+ gnutls_assert ();
+ return rc;
+ }
+ if (cdk_armor_filter_use (inp))
+ rc = cdk_stream_set_armor_flag (inp, 0);
+ if (!rc)
+ rc = cdk_keydb_get_keyblock (inp, &key->knode);
+ cdk_stream_close (inp);
+ if (rc)
+ {
+ rc = _gnutls_map_cdk_rc (rc);
+ gnutls_assert ();
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * gnutls_openpgp_crt_export - This function will export a RAW or BASE64 encoded key
+ * @key: Holds the key.
+ * @format: One of gnutls_openpgp_crt_fmt_t elements.
+ * @output_data: will contain the key base64 encoded or raw
+ * @output_data_size: holds the size of output_data (and will be replaced by the actual size of parameters)
+ *
+ * This function will convert the given key to RAW or Base64 format.
+ * If the buffer provided is not long enough to hold the output, then
+ * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
+ *
+ * Returns 0 on success.
+ *
+ **/
+int
+gnutls_openpgp_crt_export (gnutls_openpgp_crt_t key,
+ gnutls_openpgp_crt_fmt_t format,
+ void *output_data, size_t * output_data_size)
+{
+ size_t input_data_size = *output_data_size;
+ size_t calc_size;
+ int rc;
+
+ rc = cdk_kbnode_write_to_mem (key->knode, output_data, output_data_size);
+ if (rc)
+ {
+ rc = _gnutls_map_cdk_rc (rc);
+ gnutls_assert ();
+ return rc;
+ }
+
+ /* If the caller uses output_data == NULL then return what he expects.
+ */
+ if (!output_data)
+ {
+ gnutls_assert();
+ return GNUTLS_E_SHORT_MEMORY_BUFFER;
+ }
+
+ if (format == GNUTLS_OPENPGP_FMT_BASE64)
+ {
+ unsigned char *in = cdk_calloc (1, *output_data_size);
+ memcpy (in, output_data, *output_data_size);
+
+ /* Calculate the size of the encoded data and check if the provided
+ buffer is large enough. */
+ rc = cdk_armor_encode_buffer (in, *output_data_size,
+ NULL, 0, &calc_size, CDK_ARMOR_PUBKEY);
+ if (rc || calc_size > input_data_size)
+ {
+ cdk_free (in);
+ *output_data_size = calc_size;
+ gnutls_assert ();
+ return GNUTLS_E_SHORT_MEMORY_BUFFER;
+ }
+
+ rc = cdk_armor_encode_buffer (in, *output_data_size,
+ output_data, input_data_size, &calc_size,
+ CDK_ARMOR_PUBKEY);
+ cdk_free (in);
+ *output_data_size = calc_size;
+ }
+
+ return 0;
+}
+
+
+/**
+ * gnutls_openpgp_crt_get_fingerprint - Gets the fingerprint
+ * @key: the raw data that contains the OpenPGP public key.
+ * @fpr: the buffer to save the fingerprint, must hold at least 20 bytes.
+ * @fprlen: the integer to save the length of the fingerprint.
+ *
+ * Returns the fingerprint of the OpenPGP key. Depends on the algorithm,
+ * the fingerprint can be 16 or 20 bytes.
+ **/
+int
+gnutls_openpgp_crt_get_fingerprint (gnutls_openpgp_crt_t key,
+ void *fpr, size_t * fprlen)
+{
+ cdk_packet_t pkt;
+ cdk_pkt_pubkey_t pk = NULL;
+
+ if (!fpr || !fprlen)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ *fprlen = 0;
+
+ pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY);
+ if (!pkt)
+ return GNUTLS_E_OPENPGP_GETKEY_FAILED;
+
+ pk = pkt->pkt.public_key;
+ *fprlen = 20;
+
+ /* FIXME: Check if the draft allows old PGP keys. */
+ if (is_RSA (pk->pubkey_algo) && pk->version < 4)
+ *fprlen = 16;
+ cdk_pk_get_fingerprint (pk, fpr);
+
+ return 0;
+}
+
+int
+_gnutls_openpgp_count_key_names (gnutls_openpgp_crt_t key)
+{
+ cdk_kbnode_t p, ctx;
+ cdk_packet_t pkt;
+ int nuids;
+
+ if (key == NULL)
+ {
+ gnutls_assert ();
+ return 0;
+ }
+
+ ctx = NULL;
+ nuids = 0;
+ while ((p = cdk_kbnode_walk (key->knode, &ctx, 0)))
+ {
+ pkt = cdk_kbnode_get_packet (p);
+ if (pkt->pkttype == CDK_PKT_USER_ID)
+ nuids++;
+ }
+
+ return nuids;
+}
+
+
+/**
+ * gnutls_openpgp_crt_get_name - Extracts the userID
+ * @key: the structure that contains the OpenPGP public key.
+ * @idx: the index of the ID to extract
+ * @buf: a pointer to a structure to hold the name
+ * @sizeof_buf: holds the maximum size of @buf, on return hold the
+ * actual/required size of @buf.
+ *
+ * Extracts the userID from the parsed OpenPGP key.
+ *
+ * Returns 0 on success, and GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
+ * if the index of the ID does not exist.
+ *
+ **/
+int
+gnutls_openpgp_crt_get_name (gnutls_openpgp_crt_t key,
+ int idx, char *buf, size_t * sizeof_buf)
+{
+ cdk_kbnode_t ctx = NULL, p;
+ cdk_packet_t pkt = NULL;
+ cdk_pkt_userid_t uid = NULL;
+ int pos = 0;
+
+ if (!key || !buf)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ if (idx < 0 || idx > _gnutls_openpgp_count_key_names (key))
+ return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+
+ if (!idx)
+ pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_USER_ID);
+ else
+ {
+ pos = 0;
+ while ((p = cdk_kbnode_walk (key->knode, &ctx, 0)))
+ {
+ pkt = cdk_kbnode_get_packet (p);
+ if (pkt->pkttype == CDK_PKT_USER_ID && ++pos == idx)
+ break;
+ }
+ }
+
+ if (!pkt)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
+
+ uid = pkt->pkt.user_id;
+ if (uid->len >= *sizeof_buf)
+ {
+ gnutls_assert ();
+ *sizeof_buf = uid->len + 1;
+ return GNUTLS_E_SHORT_MEMORY_BUFFER;
+ }
+
+ memcpy (buf, uid->name, uid->len);
+ buf[uid->len] = '\0'; /* make sure it's a string */
+ *sizeof_buf = uid->len + 1;
+
+ if (uid->is_revoked)
+ return GNUTLS_E_OPENPGP_UID_REVOKED;
+
+ return 0;
+}
+
+/**
+ * gnutls_openpgp_crt_get_pk_algorithm - This function returns the key's PublicKey algorithm
+ * @key: is an OpenPGP key
+ * @bits: if bits is non null it will hold the size of the parameters' in bits
+ *
+ * This function will return the public key algorithm of an OpenPGP
+ * certificate.
+ *
+ * If bits is non null, it should have enough size to hold the parameters
+ * size in bits. For RSA the bits returned is the modulus.
+ * For DSA the bits returned are of the public exponent.
+ *
+ * Returns a member of the GNUTLS_PKAlgorithm enumeration on success,
+ * or a negative value on error.
+ *
+ **/
+gnutls_pk_algorithm_t
+gnutls_openpgp_crt_get_pk_algorithm (gnutls_openpgp_crt_t key,
+ unsigned int *bits)
+{
+ cdk_packet_t pkt;
+ int algo;
+
+ if (!key)
+ return GNUTLS_PK_UNKNOWN;
+
+ algo = 0;
+ pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY);
+ if (pkt)
+ {
+ if (bits)
+ *bits = cdk_pk_get_nbits (pkt->pkt.public_key);
+ algo = pkt->pkt.public_key->pubkey_algo;
+ if (is_RSA (algo))
+ algo = GNUTLS_PK_RSA;
+ else if (is_DSA (algo))
+ algo = GNUTLS_PK_DSA;
+ else
+ algo = GNUTLS_E_UNKNOWN_PK_ALGORITHM;
+ }
+
+ return algo;
+}
+
+
+/**
+ * gnutls_openpgp_crt_get_version - Extracts the version of the key.
+ * @key: the structure that contains the OpenPGP public key.
+ *
+ * Extract the version of the OpenPGP key.
+ **/
+int
+gnutls_openpgp_crt_get_version (gnutls_openpgp_crt_t key)
+{
+ cdk_packet_t pkt;
+ int version;
+
+ if (!key)
+ return -1;
+
+ pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY);
+ if (pkt)
+ version = pkt->pkt.public_key->version;
+ else
+ version = 0;
+
+ return version;
+}
+
+
+/**
+ * gnutls_openpgp_crt_get_creation_time - Extract the timestamp
+ * @key: the structure that contains the OpenPGP public key.
+ *
+ * Returns the timestamp when the OpenPGP key was created.
+ **/
+time_t
+gnutls_openpgp_crt_get_creation_time (gnutls_openpgp_crt_t key)
+{
+ cdk_packet_t pkt;
+ time_t timestamp;
+
+ if (!key)
+ return (time_t) - 1;
+
+ pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY);
+ if (pkt)
+ timestamp = pkt->pkt.public_key->timestamp;
+ else
+ timestamp = 0;
+
+ return timestamp;
+}
+
+
+/**
+ * gnutls_openpgp_crt_get_expiration_time - Extract the expire date
+ * @key: the structure that contains the OpenPGP public key.
+ *
+ * Returns the time when the OpenPGP key expires. A value of '0' means
+ * that the key doesn't expire at all.
+ **/
+time_t
+gnutls_openpgp_crt_get_expiration_time (gnutls_openpgp_crt_t key)
+{
+ cdk_packet_t pkt;
+ time_t expiredate;
+
+ if (!key)
+ return (time_t) - 1;
+
+ pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY);
+ if (pkt)
+ expiredate = pkt->pkt.public_key->expiredate;
+ else
+ expiredate = 0;
+
+ return expiredate;
+}
+
+/**
+ * gnutls_openpgp_crt_get_id - Gets the keyID
+ * @key: the structure that contains the OpenPGP public key.
+ * @keyid: the buffer to save the keyid.
+ *
+ * Returns the 64-bit keyID of the OpenPGP key.
+ **/
+int
+gnutls_openpgp_crt_get_id (gnutls_openpgp_crt_t key, gnutls_openpgp_keyid_t* keyid)
+{
+ cdk_packet_t pkt;
+ uint32_t kid[2];
+
+ if (!key || !keyid)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY);
+ if (!pkt)
+ return GNUTLS_E_OPENPGP_GETKEY_FAILED;
+
+ cdk_pk_get_keyid (pkt->pkt.public_key, kid);
+ _gnutls_write_uint32( kid[0], keyid->keyid);
+ _gnutls_write_uint32( kid[1], keyid->keyid+4);
+
+ return 0;
+}
+
+/**
+ * gnutls_openpgp_crt_get_revoked_status - Gets the revoked status of the key
+ * @key: the structure that contains the OpenPGP public key.
+ *
+ * Returns the true (1) or false (0) based on whether this key has been revoked
+ * or not.
+ *
+ **/
+int
+gnutls_openpgp_crt_get_revoked_status (gnutls_openpgp_crt_t key)
+{
+ cdk_packet_t pkt;
+
+ if (!key)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY);
+ if (!pkt)
+ return GNUTLS_E_OPENPGP_GETKEY_FAILED;
+
+ if (pkt->pkt.public_key->is_revoked != 0) return 1;
+ return 0;
+}
+
+/**
+ * gnutls_openpgp_crt_check_hostname - This function compares the given hostname with the hostname in the key
+ * @key: should contain an gnutls_openpgp_crt_t structure
+ * @hostname: A null terminated string that contains a DNS name
+ *
+ * This function will check if the given key's owner matches
+ * the given hostname. This is a basic implementation of the matching
+ * described in RFC2818 (HTTPS), which takes into account wildcards.
+ *
+ * Returns non zero on success, and zero on failure.
+ *
+ **/
+int
+gnutls_openpgp_crt_check_hostname (gnutls_openpgp_crt_t key,
+ const char *hostname)
+{
+ char dnsname[MAX_CN];
+ size_t dnsnamesize;
+ int ret;
+ int i;
+
+ /* Check through all included names. */
+ for (i = 0; !(ret < 0); i++)
+ {
+ dnsnamesize = sizeof (dnsname);
+ ret = gnutls_openpgp_crt_get_name (key, i, dnsname, &dnsnamesize);
+ /* FIXME: ret is not used */
+ if (_gnutls_hostname_compare (dnsname, hostname))
+ return 1;
+ }
+
+ /* not found a matching name */
+ return 0;
+}
+
+unsigned int _gnutls_get_pgp_key_usage(unsigned int cdk_usage)
+{
+unsigned int usage = 0;
+
+ if (cdk_usage & CDK_KEY_USG_CERT_SIGN)
+ usage |= GNUTLS_KEY_KEY_CERT_SIGN;
+ if (cdk_usage & CDK_KEY_USG_DATA_SIGN)
+ usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
+ if (cdk_usage & CDK_KEY_USG_COMM_ENCR)
+ usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
+ if (cdk_usage & CDK_KEY_USG_STORAGE_ENCR)
+ usage |= GNUTLS_KEY_DATA_ENCIPHERMENT;
+ if (cdk_usage & CDK_KEY_USG_AUTH)
+ usage |= GNUTLS_KEY_KEY_AGREEMENT;
+
+ return usage;
+}
+
+/**
+ * gnutls_openpgp_crt_get_key_usage - This function returns the key's usage
+ * @key: should contain a gnutls_openpgp_crt_t structure
+ * @key_usage: where the key usage bits will be stored
+ *
+ * This function will return certificate's key usage, by checking the
+ * key algorithm. The key usage value will ORed values of the:
+ * GNUTLS_KEY_DIGITAL_SIGNATURE, GNUTLS_KEY_KEY_ENCIPHERMENT.
+ *
+ * A negative value may be returned in case of parsing error.
+ *
+ */
+int
+gnutls_openpgp_crt_get_key_usage (gnutls_openpgp_crt_t key,
+ unsigned int *key_usage)
+{
+ cdk_packet_t pkt;
+
+ if (!key)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY);
+ if (!pkt)
+ return GNUTLS_E_OPENPGP_GETKEY_FAILED;
+
+ *key_usage = _gnutls_get_pgp_key_usage(pkt->pkt.public_key->pubkey_usage);
+
+ return 0;
+}
+
+/**
+ * gnutls_openpgp_crt_get_subkey_count - This function returns the number of subkeys
+ * @key: is an OpenPGP key
+ *
+ * This function will return the number of subkeys present in the given
+ * OpenPGP certificate.
+ *
+ * Returns then number of subkeys or a negative value on error.
+ *
+ **/
+int
+gnutls_openpgp_crt_get_subkey_count (gnutls_openpgp_crt_t key)
+{
+ cdk_kbnode_t p, ctx;
+ cdk_packet_t pkt;
+ int subkeys;
+
+ if (key == NULL)
+ {
+ gnutls_assert ();
+ return 0;
+ }
+
+ ctx = NULL;
+ subkeys = 0;
+ while ((p = cdk_kbnode_walk (key->knode, &ctx, 0)))
+ {
+ pkt = cdk_kbnode_get_packet (p);
+ if (pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY)
+ subkeys++;
+ }
+
+ return subkeys;
+}
+
+/* returns the subkey with the given index */
+static cdk_packet_t _get_public_subkey(gnutls_openpgp_crt_t key, unsigned int indx)
+{
+ cdk_kbnode_t p, ctx;
+ cdk_packet_t pkt;
+ int subkeys;
+
+ if (key == NULL)
+ {
+ gnutls_assert ();
+ return NULL;
+ }
+
+ ctx = NULL;
+ subkeys = 0;
+ while ((p = cdk_kbnode_walk (key->knode, &ctx, 0)))
+ {
+ pkt = cdk_kbnode_get_packet (p);
+ if (pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY && indx == subkeys++)
+ return pkt;
+ }
+
+ return NULL;
+}
+
+/* returns the key with the given keyid
+ * depending on what requested:
+ * pkt->pkt.secret_key;
+ * pkt->pkt.public_key;
+ */
+cdk_packet_t _gnutls_openpgp_find_key( cdk_kbnode_t knode, uint32_t keyid[2],
+ unsigned int priv)
+{
+ cdk_pkt_pubkey_t ret;
+ cdk_kbnode_t p, ctx;
+ cdk_packet_t pkt;
+ int subkeys;
+ uint32_t local_keyid[2];
+
+ ctx = NULL;
+ while ((p = cdk_kbnode_walk (knode, &ctx, 0)))
+ {
+ pkt = cdk_kbnode_get_packet (p);
+
+ if ( (priv == 0 && (pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY || pkt->pkttype == CDK_PKT_PUBLIC_KEY)) || \
+ (priv != 0 && (pkt->pkttype == CDK_PKT_SECRET_SUBKEY || pkt->pkttype == CDK_PKT_SECRET_KEY)))
+ {
+ if (priv == 0)
+ cdk_pk_get_keyid (pkt->pkt.public_key, local_keyid);
+ else
+ cdk_pk_get_keyid (pkt->pkt.secret_key->pk, local_keyid);
+
+ if (local_keyid[0] == keyid[0] && \
+ local_keyid[1] == keyid[1])
+ {
+ return pkt;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/* returns the key with the given keyid
+ * depending on what requested:
+ * pkt->pkt.secret_key;
+ * pkt->pkt.public_key;
+ */
+int _gnutls_openpgp_find_subkey_idx( cdk_kbnode_t knode, uint32_t keyid[2],
+ unsigned int priv)
+{
+ cdk_pkt_pubkey_t ret;
+ cdk_kbnode_t p, ctx;
+ cdk_packet_t pkt;
+ int subkeys, i=0;
+ uint32_t local_keyid[2];
+
+ ctx = NULL;
+ while ((p = cdk_kbnode_walk (knode, &ctx, 0)))
+ {
+ pkt = cdk_kbnode_get_packet (p);
+
+ if ( (priv == 0 && (pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY)) || \
+ (priv != 0 && (pkt->pkttype == CDK_PKT_SECRET_SUBKEY)))
+ {
+ if (priv == 0)
+ cdk_pk_get_keyid (pkt->pkt.public_key, local_keyid);
+ else
+ cdk_pk_get_keyid (pkt->pkt.secret_key->pk, local_keyid);
+
+ if (local_keyid[0] == keyid[0] && \
+ local_keyid[1] == keyid[1])
+ {
+ return i;
+ }
+ i++;
+ }
+ }
+
+ gnutls_assert();
+ return GNUTLS_E_OPENPGP_SUBKEY_ERROR;
+}
+
+/**
+ * gnutls_openpgp_crt_get_subkey_revoked_status - Gets the revoked status of the key
+ * @key: the structure that contains the OpenPGP public key.
+ * @idx: is the subkey index
+ *
+ * Returns the true (1) or false (0) based on whether this key has been revoked
+ * or not. A negative value indicates an error.
+ *
+ **/
+int
+gnutls_openpgp_crt_get_subkey_revoked_status (gnutls_openpgp_crt_t key, unsigned int idx)
+{
+ cdk_packet_t pkt;
+
+ if (!key)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ pkt = _get_public_subkey( key, idx);
+ if (!pkt)
+ return GNUTLS_E_OPENPGP_GETKEY_FAILED;
+
+ if (pkt->pkt.public_key->is_revoked != 0) return 1;
+ return 0;
+}
+
+/**
+ * gnutls_openpgp_crt_get_subkey_pk_algorithm - This function returns the subkey's PublicKey algorithm
+ * @key: is an OpenPGP key
+ * @idx: is the subkey index
+ * @bits: if bits is non null it will hold the size of the parameters' in bits
+ *
+ * This function will return the public key algorithm of a subkey of an OpenPGP
+ * certificate.
+ *
+ * If bits is non null, it should have enough size to hold the parameters
+ * size in bits. For RSA the bits returned is the modulus.
+ * For DSA the bits returned are of the public exponent.
+ *
+ * Returns a member of the gnutls_pk_algorithm_t enumeration on success,
+ * or a negative value on error.
+ *
+ **/
+gnutls_pk_algorithm_t
+gnutls_openpgp_crt_get_subkey_pk_algorithm (gnutls_openpgp_crt_t key,
+ unsigned int idx, unsigned int *bits)
+{
+ cdk_packet_t pkt;
+ int algo;
+
+ if (!key)
+ return GNUTLS_PK_UNKNOWN;
+
+ pkt = _get_public_subkey( key, idx);
+
+ algo = 0;
+ if (pkt)
+ {
+ if (bits)
+ *bits = cdk_pk_get_nbits (pkt->pkt.public_key);
+ algo = pkt->pkt.public_key->pubkey_algo;
+ if (is_RSA (algo))
+ algo = GNUTLS_PK_RSA;
+ else if (is_DSA (algo))
+ algo = GNUTLS_PK_DSA;
+ else
+ algo = GNUTLS_E_UNKNOWN_PK_ALGORITHM;
+ }
+
+ return algo;
+}
+
+/**
+ * gnutls_openpgp_crt_get_subkey_creation_time - Extract the timestamp
+ * @key: the structure that contains the OpenPGP public key.
+ * @idx: the subkey index
+ *
+ * Returns the timestamp when the OpenPGP key was created.
+ **/
+time_t
+gnutls_openpgp_crt_get_subkey_creation_time (gnutls_openpgp_crt_t key, unsigned int idx)
+{
+ cdk_packet_t pkt;
+ time_t timestamp;
+
+ if (!key)
+ return (time_t) - 1;
+
+ pkt = _get_public_subkey( key, idx);
+ if (pkt)
+ timestamp = pkt->pkt.public_key->timestamp;
+ else
+ timestamp = 0;
+
+ return timestamp;
+}
+
+
+/**
+ * gnutls_openpgp_crt_get_subkey_expiration_time - Extract the expire date
+ * @key: the structure that contains the OpenPGP public key.
+ * @idx: the subkey index
+ *
+ * Returns the time when the OpenPGP key expires. A value of '0' means
+ * that the key doesn't expire at all.
+ **/
+time_t
+gnutls_openpgp_crt_get_subkey_expiration_time (gnutls_openpgp_crt_t key, unsigned int idx)
+{
+ cdk_packet_t pkt;
+ time_t expiredate;
+
+ if (!key)
+ return (time_t) - 1;
+
+ pkt = _get_public_subkey( key, idx);
+ if (pkt)
+ expiredate = pkt->pkt.public_key->expiredate;
+ else
+ expiredate = 0;
+
+ return expiredate;
+}
+
+/**
+ * gnutls_openpgp_crt_get_subkey_id - Gets the keyID
+ * @key: the structure that contains the OpenPGP public key.
+ * @idx: the subkey index
+ * @keyid: the buffer to save the keyid.
+ *
+ * Returns the 64-bit keyID of the OpenPGP key.
+ **/
+int
+gnutls_openpgp_crt_get_subkey_id (gnutls_openpgp_crt_t key, unsigned int idx, gnutls_openpgp_keyid_t* keyid)
+{
+ cdk_packet_t pkt;
+ uint32_t kid[2];
+
+ if (!key || !keyid)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ pkt = _get_public_subkey( key, idx);
+ if (!pkt)
+ return GNUTLS_E_OPENPGP_GETKEY_FAILED;
+
+ cdk_pk_get_keyid (pkt->pkt.public_key, kid);
+ _gnutls_write_uint32( kid[0], keyid->keyid);
+ _gnutls_write_uint32( kid[1], keyid->keyid+4);
+
+ return 0;
+}
+
+/**
+ * gnutls_openpgp_crt_get_subkey_idx - Returns the subkey's index
+ * @key: the structure that contains the OpenPGP public key.
+ * @keyid: the keyid.
+ *
+ * Returns the index of the subkey or a negative error value.
+ *
+ **/
+int
+gnutls_openpgp_crt_get_subkey_idx (gnutls_openpgp_crt_t key, gnutls_openpgp_keyid_t keyid)
+{
+ cdk_packet_t pkt;
+ int ret;
+ uint32_t kid[2];
+
+ if (!key)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ KEYID_IMPORT( kid, keyid);
+ ret = _gnutls_openpgp_find_subkey_idx( key->knode, kid, 0);
+
+ if (ret < 0)
+ {
+ gnutls_assert();
+ }
+
+ return ret;
+}
+
+/**
+ * gnutls_openpgp_crt_get_subkey_usage - This function returns the key's usage
+ * @key: should contain a gnutls_openpgp_crt_t structure
+ * @idx: the subkey index
+ * @key_usage: where the key usage bits will be stored
+ *
+ * This function will return certificate's key usage, by checking the
+ * key algorithm. The key usage value will ORed values of the:
+ * GNUTLS_KEY_DIGITAL_SIGNATURE, GNUTLS_KEY_KEY_ENCIPHERMENT.
+ *
+ * A negative value may be returned in case of parsing error.
+ *
+ */
+int
+gnutls_openpgp_crt_get_subkey_usage (gnutls_openpgp_crt_t key, unsigned int idx,
+ unsigned int *key_usage)
+{
+ cdk_packet_t pkt;
+
+ if (!key)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ pkt = _get_public_subkey( key, idx);
+ if (!pkt)
+ return GNUTLS_E_OPENPGP_SUBKEY_ERROR;
+
+ *key_usage = _gnutls_get_pgp_key_usage(pkt->pkt.public_key->pubkey_usage);
+
+ return 0;
+}
+
+int _gnutls_read_pgp_mpi( cdk_packet_t pkt, unsigned int priv, size_t idx, mpi_t* m)
+{
+size_t buf_size = 512;
+opaque * buf = gnutls_malloc( buf_size);
+int err;
+int max_pub_params;
+
+ if (priv !=0)
+ max_pub_params = cdk_pk_get_npkey(pkt->pkt.secret_key->pk->pubkey_algo);
+
+ if (buf == NULL)
+ {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ /* FIXME: Note that opencdk doesn't like the buf to be NULL.
+ */
+ if (priv == 0)
+ err = cdk_pk_get_mpi (pkt->pkt.public_key, idx, buf, buf_size, &buf_size, NULL);
+ else
+ {
+ if (idx < max_pub_params)
+ err = cdk_pk_get_mpi (pkt->pkt.secret_key->pk, idx, buf, buf_size, &buf_size, NULL);
+ else
+ {
+ err = cdk_sk_get_mpi (pkt->pkt.secret_key, idx-max_pub_params, buf, buf_size, &buf_size, NULL);
+ }
+ }
+
+ if (err == CDK_Too_Short)
+ {
+ buf = gnutls_realloc_fast( buf, buf_size);
+ if (buf == NULL)
+ {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ if (priv == 0)
+ err = cdk_pk_get_mpi (pkt->pkt.public_key, idx, buf, buf_size, &buf_size, NULL);
+ else
+ {
+ if (idx < max_pub_params)
+ err = cdk_pk_get_mpi (pkt->pkt.secret_key->pk, idx, buf, buf_size, &buf_size, NULL);
+ else
+ {
+ err = cdk_sk_get_mpi (pkt->pkt.secret_key, idx-max_pub_params, buf, buf_size, &buf_size, NULL);
+ }
+ }
+ }
+
+ if (err != CDK_Success)
+ {
+_gnutls_x509_log( "err: %d/%d\n", err, idx);
+ gnutls_assert();
+ gnutls_free( buf);
+ return _gnutls_map_cdk_rc( err);
+ }
+
+ err = _gnutls_mpi_scan_pgp (m, buf, &buf_size);
+ gnutls_free( buf);
+
+ if (err < 0)
+ {
+ gnutls_assert();
+ return err;
+ }
+
+ return 0;
+}
+
+
+/* Extracts DSA and RSA parameters from a certificate.
+ */
+int
+_gnutls_openpgp_crt_get_mpis (gnutls_openpgp_crt_t cert, uint32_t keyid[2],
+ mpi_t * params, int *params_size)
+{
+ int result, i;
+ int pk_algorithm, local_params;
+ cdk_packet_t pkt;
+
+ /* Read the algorithm's OID
+ */
+ pk_algorithm = gnutls_openpgp_crt_get_pk_algorithm (cert, NULL);
+
+ switch (pk_algorithm)
+ {
+ case GNUTLS_PK_RSA:
+ local_params = RSA_PUBLIC_PARAMS;
+ break;
+ case GNUTLS_PK_DSA:
+ local_params = DSA_PUBLIC_PARAMS;
+ break;
+ default:
+ gnutls_assert ();
+ return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
+ }
+
+ if (*params_size < local_params)
+ {
+ gnutls_assert();
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
+
+ *params_size = local_params;
+
+ pkt = _gnutls_openpgp_find_key( cert->knode, keyid, 0);
+ if (pkt == NULL)
+ {
+ gnutls_assert();
+ return GNUTLS_E_OPENPGP_GETKEY_FAILED;
+ }
+
+ for (i = 0; i < local_params; i++)
+ {
+ result = _gnutls_read_pgp_mpi( pkt, 0, i, &params[i]);
+ if (result < 0)
+ {
+ gnutls_assert();
+ goto error;
+ }
+ }
+
+ return 0;
+
+error:
+ {
+ int j;
+ for (j=0;j<i;j++)
+ _gnutls_mpi_release( &params[j]);
+ }
+
+ return result;
+}
diff --git a/lib/openpgp/pgpverify.c b/lib/openpgp/pgpverify.c
new file mode 100644
index 0000000000..34b06a0834
--- /dev/null
+++ b/lib/openpgp/pgpverify.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation
+ *
+ * Author: Timo Schulz, Nikos Mavrogiannopoulos
+ *
+ * This file is part of GNUTLS-EXTRA.
+ *
+ * GNUTLS-EXTRA is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNUTLS-EXTRA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Functions on OpenPGP key parsing
+ */
+
+#include <gnutls_int.h>
+#include <openpgp.h>
+#include <gnutls_errors.h>
+#include <gnutls_openpgp.h>
+#include <gnutls_num.h>
+#include <x509/verify.h> /* lib/x509/verify.h */
+
+
+/**
+ * gnutls_openpgp_crt_verify_ring - Verify all signatures in the key
+ * @key: the structure that holds the key.
+ * @keyring: holds the keyring to check against
+ * @flags: unused (should be 0)
+ * @verify: will hold the certificate verification output.
+ *
+ * Verify all signatures in the key, using the given set of keys (keyring).
+ *
+ * The key verification output will be put in @verify and will be
+ * one or more of the gnutls_certificate_status_t enumerated elements bitwise or'd.
+ *
+ * GNUTLS_CERT_INVALID: A signature on the key is invalid.
+ *
+ * GNUTLS_CERT_REVOKED: The key has been revoked.
+ *
+ * Note that this function does not verify using any "web of
+ * trust". You may use GnuPG for that purpose, or any other external
+ * PGP application.
+ *
+ * Returns 0 on success.
+ **/
+int
+gnutls_openpgp_crt_verify_ring (gnutls_openpgp_crt_t key,
+ gnutls_openpgp_keyring_t keyring,
+ unsigned int flags, unsigned int *verify)
+{
+ gnutls_openpgp_keyid_t id;
+ cdk_error_t rc;
+ int status;
+
+ if (!key || !keyring)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_NO_CERTIFICATE_FOUND;
+ }
+
+ *verify = 0;
+
+ rc = cdk_pk_check_sigs (key->knode, keyring->db, &status);
+ if (rc == CDK_Error_No_Key)
+ {
+ rc = GNUTLS_E_NO_CERTIFICATE_FOUND;
+ gnutls_assert ();
+ return rc;
+ }
+ else if (rc != CDK_Success)
+ {
+ _gnutls_x509_log("cdk_pk_check_sigs: error %d\n", rc);
+ rc = _gnutls_map_cdk_rc (rc);
+ gnutls_assert ();
+ return rc;
+ }
+ _gnutls_x509_log("status: %x\n", status);
+
+ if (status & CDK_KEY_INVALID)
+ *verify |= GNUTLS_CERT_INVALID;
+ if (status & CDK_KEY_REVOKED)
+ *verify |= GNUTLS_CERT_REVOKED;
+ if (status & CDK_KEY_NOSIGNER)
+ *verify |= GNUTLS_CERT_SIGNER_NOT_FOUND;
+
+ /* Check if the key is included in the ring. */
+ if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME))
+ {
+ rc = gnutls_openpgp_crt_get_id (key, &id);
+ if (rc < 0)
+ {
+ gnutls_assert ();
+ return rc;
+ }
+
+ rc = gnutls_openpgp_keyring_check_id (keyring, id, 0);
+ /* If it exists in the keyring don't treat it as unknown. */
+ if (rc == 0 && *verify & GNUTLS_CERT_SIGNER_NOT_FOUND)
+ *verify ^= GNUTLS_CERT_SIGNER_NOT_FOUND;
+ }
+
+ return 0;
+}
+
+
+/**
+ * gnutls_openpgp_crt_verify_self - Verify the self signature on the key
+ * @key: the structure that holds the key.
+ * @flags: unused (should be 0)
+ * @verify: will hold the key verification output.
+ *
+ * Verifies the self signature in the key.
+ * The key verification output will be put in @verify and will be
+ * one or more of the gnutls_certificate_status_t enumerated elements bitwise or'd.
+ *
+ * GNUTLS_CERT_INVALID: The self signature on the key is invalid.
+ *
+ * Returns 0 on success.
+ **/
+int
+gnutls_openpgp_crt_verify_self (gnutls_openpgp_crt_t key,
+ unsigned int flags, unsigned int *verify)
+{
+ int status;
+ cdk_error_t rc;
+
+ rc = cdk_pk_check_self_sig (key->knode, &status);
+ if (rc || status != CDK_KEY_VALID)
+ *verify |= GNUTLS_CERT_INVALID;
+ else
+ *verify = 0;
+
+ return 0;
+}
+
diff --git a/lib/openpgp/privkey.c b/lib/openpgp/privkey.c
new file mode 100644
index 0000000000..1083e30f22
--- /dev/null
+++ b/lib/openpgp/privkey.c
@@ -0,0 +1,575 @@
+/*
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GNUTLS-EXTRA.
+ *
+ * GNUTLS-EXTRA is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNUTLS-EXTRA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Functions on OpenPGP privkey parsing
+ */
+
+#include <gnutls_int.h>
+#include <gnutls_datum.h>
+#include <gnutls_global.h>
+#include <gnutls_errors.h>
+#include <gnutls_num.h>
+#include <openpgp.h>
+#include <gnutls_openpgp.h>
+#include <x509/rfc2818.h>
+#include <gnutls_cert.h>
+
+/**
+ * gnutls_openpgp_privkey_init - This function initializes a gnutls_openpgp_privkey_t structure
+ * @key: The structure to be initialized
+ *
+ * This function will initialize an OpenPGP key structure.
+ *
+ * Returns 0 on success.
+ *
+ **/
+int
+gnutls_openpgp_privkey_init (gnutls_openpgp_privkey_t * key)
+{
+ *key = gnutls_calloc (1, sizeof (gnutls_openpgp_privkey_int));
+
+ if (*key)
+ return 0; /* success */
+ return GNUTLS_E_MEMORY_ERROR;
+}
+
+/**
+ * gnutls_openpgp_privkey_deinit - This function deinitializes memory used by a gnutls_openpgp_privkey_t structure
+ * @key: The structure to be initialized
+ *
+ * This function will deinitialize a key structure.
+ *
+ **/
+void
+gnutls_openpgp_privkey_deinit (gnutls_openpgp_privkey_t key)
+{
+ if (!key)
+ return;
+
+ if (key->knode)
+ {
+ cdk_kbnode_release (key->knode);
+ key->knode = NULL;
+ }
+
+ gnutls_free (key);
+}
+
+/**
+ * gnutls_openpgp_privkey_import - This function will import a RAW or BASE64 encoded key
+ * @key: The structure to store the parsed key.
+ * @data: The RAW or BASE64 encoded key.
+ * @format: One of gnutls_openpgp_crt_fmt_t elements.
+ * @pass: Unused for now
+ * @flags: should be zero
+ *
+ * This function will convert the given RAW or Base64 encoded key
+ * to the native gnutls_openpgp_privkey_t format. The output will be stored in 'key'.
+ *
+ * Returns 0 on success.
+ *
+ **/
+int
+gnutls_openpgp_privkey_import (gnutls_openpgp_privkey_t key,
+ const gnutls_datum_t * data,
+ gnutls_openpgp_crt_fmt_t format,
+ const char *pass, unsigned int flags)
+{
+ cdk_stream_t inp;
+ int rc;
+
+ if (format == GNUTLS_OPENPGP_FMT_RAW)
+ rc = cdk_kbnode_read_from_mem (&key->knode, data->data, data->size);
+ else
+ {
+ rc = cdk_stream_tmp_from_mem (data->data, data->size, &inp);
+ if (rc)
+ {
+ rc = _gnutls_map_cdk_rc (rc);
+ gnutls_assert ();
+ return rc;
+ }
+ if (cdk_armor_filter_use (inp))
+ rc = cdk_stream_set_armor_flag (inp, 0);
+ if (!rc)
+ rc = cdk_keydb_get_keyblock (inp, &key->knode);
+ cdk_stream_close (inp);
+ if (rc)
+ {
+ rc = _gnutls_map_cdk_rc (rc);
+ gnutls_assert ();
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+
+/**
+ * gnutls_openpgp_privkey_get_pk_algorithm - This function returns the key's PublicKey algorithm
+ * @key: is an OpenPGP key
+ * @bits: if bits is non null it will hold the size of the parameters' in bits
+ *
+ * This function will return the public key algorithm of an OpenPGP
+ * certificate.
+ *
+ * If bits is non null, it should have enough size to hold the parameters
+ * size in bits. For RSA the bits returned is the modulus.
+ * For DSA the bits returned are of the public exponent.
+ *
+ * Returns a member of the GNUTLS_PKAlgorithm enumeration on success,
+ * or a negative value on error.
+ *
+ **/
+gnutls_pk_algorithm_t
+gnutls_openpgp_privkey_get_pk_algorithm (gnutls_openpgp_privkey_t key,
+ unsigned int *bits)
+{
+ cdk_packet_t pkt;
+ int algo;
+
+ if (!key)
+ return GNUTLS_PK_UNKNOWN;
+
+ algo = 0;
+ pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
+ if (pkt)
+ {
+ if (bits)
+ *bits = cdk_pk_get_nbits (pkt->pkt.secret_key->pk);
+ algo = pkt->pkt.secret_key->pk->pubkey_algo;
+ if (is_RSA (algo))
+ algo = GNUTLS_PK_RSA;
+ else if (is_DSA (algo))
+ algo = GNUTLS_PK_DSA;
+ else
+ algo = GNUTLS_PK_UNKNOWN;
+ }
+
+ return algo;
+}
+
+/**
+ * gnutls_openpgp_privkey_get_revoked_ status - Gets the revoked status of the key
+ * @key: the structure that contains the OpenPGP public key.
+ *
+ * Returns the true (1) or false (0) based on whether this key has been revoked
+ * or not. A negative value indicates an error.
+ *
+ **/
+int
+gnutls_openpgp_privkey_get_revoked_status (gnutls_openpgp_privkey_t key)
+{
+ cdk_packet_t pkt;
+
+ if (!key)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
+ if (!pkt)
+ return GNUTLS_E_OPENPGP_GETKEY_FAILED;
+
+ if (pkt->pkt.secret_key->is_revoked != 0) return 1;
+ return 0;
+}
+
+/**
+ * gnutls_openpgp_privkey_get_fingerprint - Gets the fingerprint
+ * @key: the raw data that contains the OpenPGP secret key.
+ * @fpr: the buffer to save the fingerprint, must hold at least 20 bytes.
+ * @fprlen: the integer to save the length of the fingerprint.
+ *
+ * Returns the fingerprint of the OpenPGP key. Depends on the algorithm,
+ * the fingerprint can be 16 or 20 bytes.
+ **/
+int
+gnutls_openpgp_privkey_get_fingerprint (gnutls_openpgp_privkey_t key,
+ void *fpr, size_t * fprlen)
+{
+ cdk_packet_t pkt;
+ cdk_pkt_pubkey_t pk = NULL;
+
+ if (!fpr || !fprlen)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ *fprlen = 0;
+
+ pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
+ if (!pkt)
+ {
+ gnutls_assert();
+ return GNUTLS_E_OPENPGP_GETKEY_FAILED;
+ }
+
+ pk = pkt->pkt.secret_key->pk;
+ *fprlen = 20;
+
+ if (is_RSA (pk->pubkey_algo) && pk->version < 4)
+ *fprlen = 16;
+
+ cdk_pk_get_fingerprint (pk, fpr);
+
+ return 0;
+}
+
+/**
+ * gnutls_openpgp_privkey_get_key_id - Gets the keyID
+ * @key: the structure that contains the OpenPGP secret key.
+ * @keyid: the buffer to save the keyid.
+ *
+ * Returns the 64-bit keyID of the OpenPGP key.
+ **/
+int
+gnutls_openpgp_privkey_get_key_id (gnutls_openpgp_privkey_t key, gnutls_openpgp_keyid_t* keyid)
+{
+ cdk_packet_t pkt;
+ uint32_t kid[2];
+
+ if (!key || !keyid)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
+ if (!pkt)
+ return GNUTLS_E_OPENPGP_GETKEY_FAILED;
+
+ cdk_sk_get_keyid (pkt->pkt.secret_key, kid);
+ _gnutls_write_uint32( kid[0], keyid->keyid);
+ _gnutls_write_uint32( kid[1], keyid->keyid+4);
+
+ return 0;
+}
+
+
+/**
+ * gnutls_openpgp_privkey_get_subkey_count - This function returns the number of subkeys
+ * @key: is an OpenPGP key
+ *
+ * This function will return the number of subkeys present in the given
+ * OpenPGP certificate.
+ *
+ * Returns then number of subkeys or a negative value on error.
+ *
+ **/
+int
+gnutls_openpgp_privkey_get_subkey_count (gnutls_openpgp_privkey_t key)
+{
+ cdk_kbnode_t p, ctx;
+ cdk_packet_t pkt;
+ int subkeys;
+
+ if (key == NULL)
+ {
+ gnutls_assert ();
+ return 0;
+ }
+
+ ctx = NULL;
+ subkeys = 0;
+ while ((p = cdk_kbnode_walk (key->knode, &ctx, 0)))
+ {
+ pkt = cdk_kbnode_get_packet (p);
+ if (pkt->pkttype == CDK_PKT_SECRET_SUBKEY)
+ subkeys++;
+ }
+
+ return subkeys;
+}
+
+/* returns the subkey with the given index */
+static cdk_packet_t _get_secret_subkey(gnutls_openpgp_privkey_t key, unsigned int indx)
+{
+ cdk_kbnode_t p, ctx;
+ cdk_packet_t pkt;
+ int subkeys;
+
+ ctx = NULL;
+ subkeys = 0;
+ while ((p = cdk_kbnode_walk (key->knode, &ctx, 0)))
+ {
+ pkt = cdk_kbnode_get_packet (p);
+ if (pkt->pkttype == CDK_PKT_SECRET_SUBKEY && indx == subkeys++)
+ return pkt;
+ }
+
+ return NULL;
+}
+
+/**
+ * gnutls_openpgp_privkey_get_subkey_revoked_ status - Gets the revoked status of the key
+ * @key: the structure that contains the OpenPGP public key.
+ * @idx: is the subkey index
+ *
+ * Returns the true (1) or false (0) based on whether this key has been revoked
+ * or not. A negative value indicates an error.
+ *
+ **/
+int
+gnutls_openpgp_privkey_get_subkey_revoked_status (gnutls_openpgp_privkey_t key, unsigned int idx)
+{
+ cdk_packet_t pkt;
+
+ if (!key)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ pkt = _get_secret_subkey( key, idx);
+ if (!pkt)
+ return GNUTLS_E_OPENPGP_GETKEY_FAILED;
+
+ if (pkt->pkt.secret_key->is_revoked != 0) return 1;
+ return 0;
+}
+
+/**
+ * gnutls_openpgp_privkey_get_subkey_pk_algorithm - This function returns the subkey's PublicKey algorithm
+ * @key: is an OpenPGP key
+ * @idx: is the subkey index
+ * @bits: if bits is non null it will hold the size of the parameters' in bits
+ *
+ * This function will return the public key algorithm of a subkey of an OpenPGP
+ * certificate.
+ *
+ * If bits is non null, it should have enough size to hold the parameters
+ * size in bits. For RSA the bits returned is the modulus.
+ * For DSA the bits returned are of the public exponent.
+ *
+ * Returns a member of the gnutls_pk_algorithm_t enumeration on success,
+ * or a negative value on error.
+ *
+ **/
+gnutls_pk_algorithm_t
+gnutls_openpgp_privkey_get_subkey_pk_algorithm (gnutls_openpgp_privkey_t key,
+ unsigned int idx, unsigned int *bits)
+{
+ cdk_packet_t pkt;
+ int algo;
+
+ if (!key)
+ return GNUTLS_PK_UNKNOWN;
+
+ pkt = _get_secret_subkey( key, idx);
+
+ algo = 0;
+ if (pkt)
+ {
+ if (bits)
+ *bits = cdk_pk_get_nbits (pkt->pkt.secret_key->pk);
+ algo = pkt->pkt.secret_key->pubkey_algo;
+ if (is_RSA (algo))
+ algo = GNUTLS_PK_RSA;
+ else if (is_DSA (algo))
+ algo = GNUTLS_PK_DSA;
+ else
+ algo = GNUTLS_E_UNKNOWN_PK_ALGORITHM;
+ }
+
+ return algo;
+}
+
+/**
+ * gnutls_openpgp_privkey_get_subkey_idx - Returns the subkey's index
+ * @key: the structure that contains the OpenPGP public key.
+ * @keyid: the keyid.
+ *
+ * Returns the index of the subkey or a negative error value.
+ *
+ **/
+int
+gnutls_openpgp_privkey_get_subkey_idx (gnutls_openpgp_privkey_t key, gnutls_openpgp_keyid_t keyid)
+{
+ cdk_packet_t pkt;
+ int ret;
+ uint32_t kid[2];
+
+ if (!key)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ KEYID_IMPORT( kid, keyid);
+ ret = _gnutls_openpgp_find_subkey_idx( key->knode, kid, 1);
+
+ if (ret < 0)
+ {
+ gnutls_assert();
+ }
+
+ return ret;
+}
+
+/**
+ * gnutls_openpgp_privkey_get_subkey_creation_time - Extract the timestamp
+ * @key: the structure that contains the OpenPGP public key.
+ * @idx: the subkey index
+ *
+ * Returns the timestamp when the OpenPGP key was created.
+ **/
+time_t
+gnutls_openpgp_privkey_get_subkey_creation_time (gnutls_openpgp_privkey_t key, unsigned int idx)
+{
+ cdk_packet_t pkt;
+ time_t timestamp;
+
+ if (!key)
+ return (time_t) - 1;
+
+ pkt = _get_secret_subkey( key, idx);
+ if (pkt)
+ timestamp = pkt->pkt.secret_key->pk->timestamp;
+ else
+ timestamp = 0;
+
+ return timestamp;
+}
+
+/**
+ * gnutls_openpgp_privkey_get_subkey_expiration_time - Extract the expire date
+ * @key: the structure that contains the OpenPGP public key.
+ * @idx: the subkey index
+ *
+ * Returns the time when the OpenPGP key expires. A value of '0' means
+ * that the key doesn't expire at all.
+ **/
+time_t
+gnutls_openpgp_privkey_get_subkey_expiration_time (gnutls_openpgp_privkey_t key, unsigned int idx)
+{
+ cdk_packet_t pkt;
+ time_t expiredate;
+
+ if (!key)
+ return (time_t) - 1;
+
+ pkt = _get_secret_subkey( key, idx);
+ if (pkt)
+ expiredate = pkt->pkt.secret_key->expiredate;
+ else
+ expiredate = 0;
+
+ return expiredate;
+}
+
+/**
+ * gnutls_openpgp_privkey_get_subkey_id - Gets the keyID
+ * @key: the structure that contains the OpenPGP secret key.
+ * @idx: the subkey index
+ * @keyid: the buffer to save the keyid.
+ *
+ * Returns the 64-bit keyID of the OpenPGP key.
+ **/
+int
+gnutls_openpgp_privkey_get_subkey_id (gnutls_openpgp_privkey_t key, unsigned int idx, gnutls_openpgp_keyid_t* keyid)
+{
+ cdk_packet_t pkt;
+ uint32_t kid[2];
+
+ if (!key || !keyid)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ pkt = _get_secret_subkey( key, idx);
+ if (!pkt)
+ return GNUTLS_E_OPENPGP_GETKEY_FAILED;
+
+ cdk_sk_get_keyid (pkt->pkt.secret_key, kid);
+ _gnutls_write_uint32( kid[0], keyid->keyid);
+ _gnutls_write_uint32( kid[1], keyid->keyid+4);
+
+ return 0;
+}
+
+/* Extracts DSA and RSA parameters from a certificate.
+ */
+int
+_gnutls_openpgp_privkey_get_mpis (gnutls_openpgp_privkey_t pkey, uint32_t keyid[2],
+ mpi_t * params, int *params_size)
+{
+ int result, i;
+ int pk_algorithm, local_params;
+ cdk_packet_t pkt;
+
+ /* Read the algorithm's OID
+ */
+ pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (pkey, NULL);
+
+ switch (pk_algorithm)
+ {
+ case GNUTLS_PK_RSA:
+ local_params = RSA_PRIVATE_PARAMS;
+ break;
+ case GNUTLS_PK_DSA:
+ local_params = DSA_PRIVATE_PARAMS;
+ break;
+ default:
+ gnutls_assert ();
+ return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
+ }
+
+ if (*params_size < local_params)
+ {
+ gnutls_assert();
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
+
+ *params_size = local_params;
+
+ pkt = _gnutls_openpgp_find_key( pkey->knode, keyid, 1);
+ if (pkt == NULL)
+ {
+ gnutls_assert();
+ return GNUTLS_E_OPENPGP_GETKEY_FAILED;
+ }
+
+ for (i = 0; i < local_params; i++)
+ {
+ result = _gnutls_read_pgp_mpi( pkt, 1, i, &params[i]);
+ if (result < 0)
+ {
+ gnutls_assert();
+ goto error;
+ }
+ }
+
+ return 0;
+
+error:
+ {
+ int j;
+ for (j=0;j<i;j++)
+ _gnutls_mpi_release( &params[j]);
+ }
+
+ return result;
+}
diff --git a/libextra/Makefile.am b/libextra/Makefile.am
index 68edc77ece..5d03a9f512 100644
--- a/libextra/Makefile.am
+++ b/libextra/Makefile.am
@@ -22,7 +22,7 @@
AM_CPPFLAGS = -I$(top_srcdir)/lgl -I$(top_builddir)/lgl \
-I$(top_srcdir)/lib -I../includes -I$(top_srcdir)/includes \
- -I$(top_srcdir)/lib/minitasn1 -I$(srcdir)/openpgp \
+ -I$(top_srcdir)/lib/minitasn1 \
$(LIBGCRYPT_CFLAGS)
if ENABLE_MINITASN1
@@ -33,14 +33,6 @@ endif
SUBDIRS =
-if ENABLE_OPENPGP
-if ENABLE_INCLUDED_OPENCDK
-SUBDIRS += opencdk
-AM_CPPFLAGS += -I$(srcdir)/opencdk
-endif
-SUBDIRS += openpgp
-endif
-
bin_SCRIPTS = libgnutls-extra-config
m4datadir = $(datadir)/aclocal
@@ -91,15 +83,6 @@ endif
libgnutls_extra_la_LIBADD =
libgnutls_extra_la_LDFLAGS = -no-undefined -L$(top_srcdir)/lib/.libs
-if ENABLE_OPENPGP
-libgnutls_extra_la_SOURCES += gnutls_openpgp.c
-libgnutls_extra_la_LIBADD += openpgp/libgnutls_openpgp.la
-if ENABLE_INCLUDED_OPENCDK
-libgnutls_extra_la_LIBADD += opencdk/libminiopencdk.la
-else
-libgnutls_extra_la_LDFLAGS += $(LTLIBOPENCDK)
-endif
-endif
# TLS/IA
diff --git a/libextra/gnutls_extra.c b/libextra/gnutls_extra.c
index 3bb038f645..da22415a79 100644
--- a/libextra/gnutls_extra.c
+++ b/libextra/gnutls_extra.c
@@ -22,9 +22,7 @@
#include <gnutls_int.h>
#include <gnutls_errors.h>
#include <gnutls_extensions.h>
-#include <gnutls_openpgp.h>
#include <gnutls_extra.h>
-#include <gnutls_extra_hooks.h>
#include <gnutls_algorithms.h>
#ifdef USE_LZO
# ifdef USE_MINILZO
@@ -137,22 +135,6 @@ gnutls_global_init_extra (void)
}
#endif
- /* Register the openpgp functions. This is because some
- * of them are defined to be NULL in the main library.
- */
- _gnutls_add_openpgp_functions (_gnutls_openpgp_verify_key,
- _gnutls_openpgp_get_raw_key_creation_time,
- _gnutls_openpgp_get_raw_key_expiration_time,
- _gnutls_openpgp_fingerprint,
- _gnutls_openpgp_request_key,
- _gnutls_openpgp_raw_key_to_gcert,
- _gnutls_openpgp_raw_privkey_to_gkey,
- _gnutls_openpgp_crt_to_gcert,
- _gnutls_openpgp_privkey_to_gkey,
- gnutls_openpgp_crt_deinit,
- gnutls_openpgp_keyring_deinit,
- gnutls_openpgp_privkey_deinit);
-
return 0;
}
diff --git a/libextra/opencdk/cipher.c b/libextra/opencdk/cipher.c
deleted file mode 100644
index de58cc07d6..0000000000
--- a/libextra/opencdk/cipher.c
+++ /dev/null
@@ -1,529 +0,0 @@
-/* cipher.c - Cipher filters
- * Copyright (C) 2002, 2003, 2007 Timo Schulz
- * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation
- *
- * This file is part of OpenCDK.
- *
- * OpenCDK is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * OpenCDK is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-#include <stdio.h>
-#include <assert.h>
-#include <sys/stat.h>
-
-#include "opencdk.h"
-#include "main.h"
-#include "filters.h"
-
-
-/* The maximal cipher block size in octets. */
-#define MAX_CIPHER_BLKSIZE 16
-
-
-static off_t
-fp_get_length (FILE *fp)
-{
- struct stat statbuf;
-
- if (fstat (fileno (fp), &statbuf))
- return (off_t)-1;
- return statbuf.st_size;
-}
-
-
-static cdk_error_t
-hash_encode (void *opaque, FILE *in, FILE *out)
-{
- md_filter_t *mfx = opaque;
- byte buf[BUFSIZE];
- gcry_error_t err;
- int nread;
-
- if (!mfx)
- return CDK_Inv_Value;
-
- _cdk_log_debug ("hash filter: encode algo=%d\n", mfx->digest_algo);
-
- if (!mfx->md)
- {
- err = gcry_md_open (&mfx->md, mfx->digest_algo, 0);
- if (err)
- return map_gcry_error (err);
- }
-
- while (!feof (in))
- {
- nread = fread (buf, 1, BUFSIZE, in);
- if (!nread)
- break;
- gcry_md_write (mfx->md, buf, nread);
- }
-
- wipemem (buf, sizeof (buf));
- return 0;
-}
-
-
-cdk_error_t
-_cdk_filter_hash (void *opaque, int ctl, FILE *in, FILE *out)
-{
- if (ctl == STREAMCTL_READ)
- return hash_encode (opaque, in, out);
- else if (ctl == STREAMCTL_FREE)
- {
- md_filter_t *mfx = opaque;
- if (mfx)
- {
- _cdk_log_debug ("free hash filter\n");
- gcry_md_close (mfx->md);
- mfx->md = NULL;
- return 0;
- }
- }
- return CDK_Inv_Mode;
-}
-
-
-static cdk_error_t
-write_header (cipher_filter_t *cfx, FILE *out)
-{
- cdk_pkt_encrypted_t ed;
- cdk_packet_t pkt;
- cdk_error_t rc;
- cdk_dek_t dek = cfx->dek;
- byte temp[MAX_CIPHER_BLKSIZE+2];
- size_t blocksize;
- int use_mdc, nprefix;
- gcry_error_t err;
-
- blocksize = gcry_cipher_get_algo_blklen (dek->algo);
- if (blocksize < 8 || blocksize > 16)
- return CDK_Inv_Algo;
-
- /* It might be possible the receiver does not understand the MDC
- output and thus we offer to supress the MDC packet. */
- use_mdc = dek->use_mdc;
- if (blocksize == 8)
- use_mdc = 0;
-
- /* We need to increase the data length because the MDC packet will
- be also included. It has a fixed length of 22 octets. */
- if (use_mdc && cfx->datalen)
- cfx->datalen += 22;
-
- cdk_pkt_alloc (&pkt, CDK_PKT_ENCRYPTED_MDC);
- ed = pkt->pkt.encrypted;
- if (!cfx->blkmode.on)
- {
- ed->len = cfx->datalen;
- ed->extralen = blocksize + 2;
- }
- else
- cfx->blkmode.nleft = DEF_BLOCKSIZE;
-
- if (use_mdc)
- {
- ed->mdc_method = GCRY_MD_SHA1;
- err = gcry_md_open (&cfx->mdc, GCRY_MD_SHA1, 0);
- if (err)
- return map_gcry_error (err);
- }
-
- /* When we use partial bodies, the MDC feature or a blocksize
- larger than 8, we force the use of the new packet format. */
- if (cfx->blkmode.on || use_mdc || blocksize != 8)
- pkt->old_ctb = 0;
- else
- pkt->old_ctb = 1;
- pkt->pkttype = use_mdc? CDK_PKT_ENCRYPTED_MDC : CDK_PKT_ENCRYPTED;
- rc = _cdk_pkt_write_fp (out, pkt);
- cdk_pkt_release (pkt);
- if (rc)
- return rc;
-
- nprefix = blocksize;
- gcry_randomize (temp, nprefix, GCRY_STRONG_RANDOM);
- temp[nprefix] = temp[nprefix - 2];
- temp[nprefix + 1] = temp[nprefix - 1];
- err = gcry_cipher_open (&cfx->hd, dek->algo, GCRY_CIPHER_MODE_CFB,
- use_mdc? 0 : GCRY_CIPHER_ENABLE_SYNC);
- if (err)
- return map_gcry_error (err);
- err = gcry_cipher_setiv (cfx->hd, NULL, 0);
- if (err)
- return map_gcry_error (err);
- err = gcry_cipher_setkey (cfx->hd, dek->key, dek->keylen);
- if (err)
- return map_gcry_error (err);
- if (cfx->mdc)
- gcry_md_write (cfx->mdc, temp, nprefix + 2);
- gcry_cipher_encrypt (cfx->hd, temp, nprefix + 2, NULL, 0);
- gcry_cipher_sync (cfx->hd);
- fwrite (temp, 1, nprefix+2, out);
- if (cfx->blkmode.on)
- {
- cfx->blkmode.nleft -= (nprefix+2);
- if (use_mdc)
- cfx->blkmode.nleft--; /* 1 byte version */
- }
- return rc;
-}
-
-
-static cdk_error_t
-write_mdc_packet (FILE *out, cipher_filter_t *cfx)
-{
- byte pktdata[22];
- int dlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
-
- if (!out || !cfx)
- return CDK_Inv_Value;
- if (dlen != 20)
- return CDK_Inv_Algo;
-
- /* We must hash the prefix of the MDC packet here */
- pktdata[0] = 0xD3;
- pktdata[1] = 0x14;
- gcry_md_write (cfx->mdc, pktdata, 2);
- gcry_md_final (cfx->mdc);
- memcpy (pktdata + 2, gcry_md_read (cfx->mdc, GCRY_MD_SHA1), dlen);
- gcry_cipher_encrypt (cfx->hd, pktdata, dlen+2, NULL, 0);
- fwrite (pktdata, 1, dlen+2, out);
- wipemem (pktdata, sizeof (pktdata));
- return 0;
-}
-
-
-static inline int
-num2bits (size_t n)
-{
- size_t i;
-
- for (i = 0; n > 1; i++)
- n >>= 1;
- return i;
-}
-
-
-static cdk_error_t
-write_partial_block (FILE *in, FILE *out, off_t *r_len,
- cipher_filter_t *cfx)
-{
- gcry_error_t err;
- byte buf[DEF_BLOCKSIZE];
- size_t n;
- int nread;
-
- if (!out || !cfx)
- return CDK_Inv_Value;
-
- if (!cfx->blkmode.nleft && *r_len > 0)
- {
- if (*r_len > DEF_BLOCKSIZE)
- {
- /*_cdk_log_debug ("write_partial_block: size %lu block %d\n",
- *r_len, DEF_BLOCKSIZE);*/
- fputc ((0xE0|DEF_BLOCKBITS), out);
- cfx->blkmode.nleft = DEF_BLOCKSIZE;
- (*r_len) -= DEF_BLOCKSIZE;
- }
- else if (*r_len > 512)
- {
- n = num2bits (*r_len);
- cfx->blkmode.nleft = (1 << n);
- /*_cdk_log_debug ("write_partial_block: size %lu bits %d block %d\n",
- *r_len, n, (1<<n));*/
- fputc ((0xE0|n), out);
- (*r_len) -= cfx->blkmode.nleft;
- }
- else
- {
- size_t pktlen = *r_len;
-
- /* If we use the MDC mode, we need to increase the final
- partial body length to hold the mdc packet itself. */
- if (cfx->mdc)
- pktlen += 22;
-
- if (pktlen < 192)
- fputc (pktlen, out);
- else if (pktlen < 8384)
- {
- pktlen -= 192;
- fputc ((pktlen/256) + 192, out);
- fputc ((pktlen % 256), out);
- }
- cfx->blkmode.nleft = pktlen;
- /*_cdk_log_debug ("write_partial_block: end %d block\n", pktlen);*/
- (*r_len) -= pktlen;
- }
- }
- else
- (*r_len) -= cfx->blkmode.nleft;
-
- n = cfx->blkmode.nleft < DIM (buf)? cfx->blkmode.nleft : DIM (buf);
- nread = fread (buf, 1, n, in);
- if (!nread)
- return CDK_EOF;
- if (cfx->mdc)
- gcry_md_write (cfx->mdc, buf, nread);
- err = gcry_cipher_encrypt (cfx->hd, buf, nread, NULL, 0);
- if (err)
- return map_gcry_error (err);
- fwrite (buf, 1, nread, out);
- cfx->blkmode.nleft -= nread;
- return 0;
-}
-
-
-static cdk_error_t
-cipher_encode_file (void *opaque, FILE *in, FILE *out)
-{
- cipher_filter_t *cfx = opaque;
- byte buf[BUFSIZE];
- off_t len, len2;
- int nread;
- cdk_error_t rc;
-
- if (!cfx || !in || !out)
- return CDK_Inv_Value;
-
- len = len2 = fp_get_length (in);
- if (len == (off_t)-1)
- return CDK_File_Error;
- while (!feof (in))
- {
- if (cfx->blkmode.on)
- {
- rc = write_partial_block (in, out, &len2, cfx);
- if (rc == CDK_EOF)
- break;
- if (rc)
- {
- wipemem (buf, sizeof (buf));
- return rc;
- }
- continue;
- }
- nread = fread (buf, 1, DIM (buf), in);
- if (!nread)
- break;
- if (cfx->mdc)
- gcry_md_write (cfx->mdc, buf, nread);
- gcry_cipher_encrypt (cfx->hd, buf, nread, NULL, 0);
- fwrite (buf, 1, nread, out);
- }
- if (cfx->mdc)
- rc = write_mdc_packet (out, cfx);
- else
- rc = 0;
-
- wipemem (buf, sizeof (buf));
- return rc;
-}
-
-
-static cdk_error_t
-read_header (cipher_filter_t * cfx, FILE * in)
-{
- cdk_dek_t dek;
- byte temp[32];
- int blocksize, nprefix;
- int i, c;
- gcry_error_t err;
-
- if (!cfx || !in)
- return CDK_Inv_Value;
-
- dek = cfx->dek;
- blocksize = gcry_cipher_get_algo_blklen (dek->algo);
- if (blocksize < 8 || blocksize > 16)
- return CDK_Inv_Algo;
-
- nprefix = blocksize;
- if (cfx->datalen > 0 && cfx->datalen < (nprefix + 2))
- return CDK_Inv_Value;
- if (cfx->mdc_method)
- {
- err = gcry_md_open (&cfx->mdc, cfx->mdc_method, 0);
- if (err)
- return map_gcry_error (err);
- }
- err = gcry_cipher_open (&cfx->hd, dek->algo, GCRY_CIPHER_MODE_CFB,
- cfx->mdc_method? 0 : GCRY_CIPHER_ENABLE_SYNC);
- if (err)
- return map_gcry_error (err);
- err = gcry_cipher_setiv (cfx->hd, NULL, 0);
- if (err)
- return map_gcry_error (err);
- err = gcry_cipher_setkey (cfx->hd, dek->key, dek->keylen);
- if (err)
- return map_gcry_error (err);
-
- for (i = 0; i < (nprefix + 2); i++ )
- {
- c = fgetc (in);
- if (c == EOF)
- return CDK_File_Error;
- temp[i] = c;
- }
- gcry_cipher_decrypt (cfx->hd, temp, nprefix + 2, NULL, 0);
- gcry_cipher_sync (cfx->hd);
- i = nprefix;
- if (temp[i - 2] != temp[i] || temp[i - 1] != temp[i + 1])
- return CDK_Chksum_Error;
- if (cfx->mdc)
- gcry_md_write (cfx->mdc, temp, nprefix + 2);
- if (cfx->blkmode.on)
- cfx->blkmode.size -= (nprefix + 2);
- return 0;
-}
-
-
-static cdk_error_t
-finalize_mdc (gcry_md_hd_t md, const byte *buf, size_t nread)
-{
- byte mdcbuf[20];
- int dlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
- cdk_error_t rc;
-
- if (dlen != 20)
- return CDK_Inv_Algo;
-
- if (buf[nread - dlen - 2] == 0xD3 && buf[nread - dlen - 1] == 0x14)
- {
- gcry_md_write (md, buf, nread - dlen);
- gcry_md_final (md);
- memcpy (mdcbuf, gcry_md_read (md, GCRY_MD_SHA1), dlen);
- if (memcmp (mdcbuf, buf + nread - dlen, dlen))
- rc = CDK_Bad_MDC;
- else
- rc = CDK_Success;
- wipemem (mdcbuf, sizeof (mdcbuf));
- return rc;
- }
-
- return CDK_Inv_Packet;
-}
-
-
-static cdk_error_t
-cipher_decode_file (void *opaque, FILE *in, FILE *out)
-{
- cipher_filter_t *cfx = opaque;
- cdk_error_t rc;
- byte buf[BUFSIZE];
- int nread, nreq;
-
- if (!cfx || !in || !out)
- return CDK_Inv_Value;
-
- while (!feof (in))
- {
- /*_cdk_log_debug ("partial on=%d size=%lu\n",
- cfx->blkmode.on, cfx->blkmode.size);*/
- nreq = cfx->blkmode.on? cfx->blkmode.size : DIM (buf);
- nread = fread (buf, 1, nreq, in);
- if (!nread)
- break;
- gcry_cipher_decrypt (cfx->hd, buf, nread, NULL, 0);
- if (feof (in) && cfx->mdc)
- {
- rc = finalize_mdc (cfx->mdc, buf, nread);
- if (rc)
- {
- wipemem (buf, sizeof (buf));
- return rc;
- }
- /* We need to correct the size here to avoid the MDC
- packet will be written to the output. */
- nread -= 22;
- }
- else if (cfx->mdc)
- gcry_md_write (cfx->mdc, buf, nread);
- fwrite (buf, 1, nread, out);
- if (cfx->blkmode.on)
- {
- cfx->blkmode.size = _cdk_pkt_read_len (in, &cfx->blkmode.on);
- if (cfx->blkmode.size == (size_t)EOF)
- return CDK_Inv_Packet;
- }
- }
-
- wipemem (buf, sizeof (buf));
- return 0;
-}
-
-
-static cdk_error_t
-cipher_decode (void * opaque, FILE * in, FILE * out)
-{
- cipher_filter_t *cfx = opaque;
- cdk_error_t rc;
-
- _cdk_log_debug ("cipher filter: decode\n");
-
- if (!cfx || !in || !out)
- return CDK_Inv_Value;
-
- rc = read_header (cfx, in);
- if (!rc)
- rc = cipher_decode_file (cfx, in, out);
- return rc;
-}
-
-
-static cdk_error_t
-cipher_encode (void *opaque, FILE *in, FILE *out)
-{
- cipher_filter_t *cfx = opaque;
- cdk_error_t rc;
-
- _cdk_log_debug ("cipher filter: encode\n");
-
- if (!cfx || !in || !out)
- return CDK_Inv_Value;
-
- cfx->datalen = fp_get_length (in);
- if (cfx->datalen < BUFSIZE && cfx->blkmode.on)
- cfx->blkmode.on = 0;
- rc = write_header (cfx, out);
- if (!rc)
- rc = cipher_encode_file (cfx, in, out);
- return rc;
-}
-
-
-cdk_error_t
-_cdk_filter_cipher (void * opaque, int ctl, FILE * in, FILE * out)
-{
- if (ctl == STREAMCTL_READ)
- return cipher_decode (opaque, in, out);
- else if (ctl == STREAMCTL_WRITE)
- return cipher_encode( opaque, in, out );
- else if (ctl == STREAMCTL_FREE)
- {
- cipher_filter_t * cfx = opaque;
- if (cfx)
- {
- _cdk_log_debug( "free cipher filter\n" );
- gcry_md_close( cfx->mdc );
- cfx->mdc = NULL;
- gcry_cipher_close( cfx->hd );
- cfx->hd = NULL;
- return 0;
- }
- }
- return CDK_Inv_Mode;
-}
-
diff --git a/libextra/opencdk/compress.c b/libextra/opencdk/compress.c
deleted file mode 100644
index f9dd0ca2a7..0000000000
--- a/libextra/opencdk/compress.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/* compress.c - Compression filters
- * Copyright (C) 2002, 2003 Timo Schulz
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation
- *
- * This file is part of OpenCDK.
- *
- * OpenCDK is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * OpenCDK is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-#include <stdio.h>
-#include <time.h>
-#ifdef HAVE_LIBZ
-# include <zlib.h>
-#endif
-
-#include "opencdk.h"
-#include "main.h"
-#include "filters.h"
-
-#ifdef HAVE_LIBZ
-static int
-compress_data (z_stream *zs, int flush, byte *inbuf, size_t insize, FILE *out)
-{
- int nbytes, zrc;
- byte buf[4096];
-
- zs->next_in = inbuf;
- zs->avail_in = insize;
-
- do
- {
- zs->next_out = buf;
- zs->avail_out = DIM (buf);
-
- zrc = deflate (zs, flush);
- if (zrc == Z_STREAM_END && flush == Z_FINISH)
- ;
- else if (zrc != Z_OK)
- break;
- nbytes = DIM (buf) - zs->avail_out;
- fwrite (buf, 1, nbytes, out);
- }
- while (zs->avail_out == 0 || (flush == Z_FINISH && zrc != Z_STREAM_END));
- return zrc;
-}
-
-
-static int
-decompress_data (compress_filter_t *zfx, z_stream *zs,
- FILE *in, size_t *ret_len)
-{
- int nread, nold;
- int rc, zrc;
-
- rc = 0;
- nread = 0;
- while (zs->avail_out != 0)
- {
- if (!zs->avail_in)
- {
- nread = fread (zfx->inbuf, 1, zfx->inbufsize, in);
- zs->next_in = zfx->inbuf;
- zs->avail_in = nread;
- }
- nold = zs->avail_out;
- zrc = inflate (zs, Z_SYNC_FLUSH);
- if (zrc != Z_OK && zrc != Z_STREAM_END)
- {
- rc = CDK_Zlib_Error;
- break;
- }
- *ret_len = zfx->outbufsize - zs->avail_out;
- if (nold == zs->avail_out)
- break;
- if (zrc == Z_STREAM_END)
- {
- rc = EOF; /* eof */
- break;
- }
- }
- if (!nread && feof (in))
- rc = -1;
- return rc;
-}
-
-
-static cdk_error_t
-compress_decode (void *opaque, FILE *in, FILE *out)
-{
- compress_filter_t *zfx = opaque;
- z_stream * zs;
- size_t nbytes;
- int zrc;
- cdk_error_t rc = 0;
-
- _cdk_log_debug ("compress filter: decode (algo=%d)\n", zfx->algo);
-
- if (!zfx || !in || !out)
- return CDK_Inv_Value;
-
- zs = cdk_calloc (1, sizeof *zs);
- if (!zs)
- return CDK_Out_Of_Core;
- if (zfx->algo == CDK_COMPRESS_ZIP)
- zrc = inflateInit2 (zs, -13);
- else
- zrc = inflateInit (zs);
- if (zrc != Z_OK)
- return CDK_Zlib_Error;
-
- zfx->outbufsize = 8192;
- zfx->inbufsize = 2048;
- memset (zfx->inbuf, 0, sizeof zfx->inbuf);
- zs->avail_in = 0;
-
- nbytes = 0;
- while (rc != -1)
- {
- zs->next_out = zfx->outbuf;
- zs->avail_out = 8192;
- rc = decompress_data (zfx, zs, in, &nbytes);
- fwrite (zfx->outbuf, 1, nbytes, out);
- }
- inflateEnd (zs);
- cdk_free (zs);
- if (rc == CDK_EOF)
- rc = 0;
- return rc;
-}
-
-
-static cdk_error_t
-compress_encode(void *opaque, FILE *in, FILE *out)
-{
- compress_filter_t *zfx = opaque;
- z_stream *zs;
- struct cdk_pkt_compressed_s cd;
- struct cdk_packet_s pkt;
- int zrc, nread;
- cdk_error_t rc;
-
- _cdk_log_debug ("compress filter: encode\n");
-
- if (!zfx || !in || !out)
- return CDK_Inv_Value;
-
- if (!zfx->algo)
- zfx->algo = CDK_COMPRESS_ZIP;
-
- memset (&cd, 0, sizeof (cd));
- cd.len = 0;
- cd.algorithm = zfx->algo;
- pkt.pkttype = CDK_PKT_COMPRESSED;
- pkt.pkt.compressed = &cd;
- rc = _cdk_pkt_write_fp (out, &pkt);
- if (rc)
- return rc;
-
- zs = cdk_calloc (1, sizeof *zs);
- if (!zs)
- return CDK_Out_Of_Core;
- if (zfx->algo == CDK_COMPRESS_ZIP)
- rc = deflateInit2 (zs, zfx->level, Z_DEFLATED, -13, 8,
- Z_DEFAULT_STRATEGY);
- else
- rc = deflateInit (zs, zfx->level);
- if (rc != Z_OK)
- {
- cdk_free (zs);
- return CDK_Zlib_Error;
- }
- zfx->outbufsize = 8192;
- memset (zfx->outbuf, 0, sizeof zfx->outbuf);
-
- while (!feof (in))
- {
- nread = fread (zfx->outbuf, 1, zfx->outbufsize, in);
- if (!nread)
- break;
- zrc = compress_data (zs, Z_NO_FLUSH, zfx->outbuf, nread, out);
- if (zrc)
- {
- rc = CDK_Zlib_Error;
- break;
- }
- }
- if (!rc)
- {
- nread = 0;
- zrc = compress_data (zs, Z_FINISH, zfx->outbuf, nread, out);
- if (zrc != Z_STREAM_END)
- rc = CDK_Zlib_Error;
- }
- deflateEnd (zs);
- cdk_free (zs);
- return rc;
-}
-
-
-cdk_error_t
-_cdk_filter_compress (void *opaque, int ctl, FILE *in, FILE *out)
-{
- if (ctl == STREAMCTL_READ)
- return compress_decode (opaque, in, out);
- else if (ctl == STREAMCTL_WRITE)
- return compress_encode (opaque, in, out);
- else if (ctl == STREAMCTL_FREE)
- {
- compress_filter_t * zfx = opaque;
- if (zfx)
- {
- _cdk_log_debug ("free compress filter\n");
- zfx->level = 0;
- zfx->algo = 0;
- return 0;
- }
- }
- return CDK_Inv_Mode;
-}
-
-#else
-cdk_error_t
-_cdk_filter_compress (void *opaque, int ctl, FILE *in, FILE *out)
-{
- return CDK_Not_Implemented;
-}
-#endif /* HAVE_LIBZ */
-
-
diff --git a/libextra/opencdk/misc.c b/libextra/opencdk/misc.c
deleted file mode 100644
index eb047f054e..0000000000
--- a/libextra/opencdk/misc.c
+++ /dev/null
@@ -1,564 +0,0 @@
-/* misc.c
- * Copyright (C) 2002, 2003 Timo Schulz
- * Copyright (C) 1998-2002, 2007 Free Software Foundation, Inc.
- *
- * This file is part of OpenCDK.
- *
- * OpenCDK is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * OpenCDK is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/stat.h>
-
-#include "opencdk.h"
-#include "main.h"
-
-
-u32
-_cdk_buftou32 (const byte *buf)
-{
- u32 u;
-
- if (!buf)
- return 0;
- u = buf[0] << 24;
- u |= buf[1] << 16;
- u |= buf[2] << 8;
- u |= buf[3];
- return u;
-}
-
-
-void
-_cdk_u32tobuf (u32 u, byte *buf)
-{
- if (!buf)
- return;
- buf[0] = u >> 24;
- buf[1] = u >> 16;
- buf[2] = u >> 8;
- buf[3] = u ;
-}
-
-
-static const char *
-parse_version_number (const char *s, int *number)
-{
- int val = 0;
-
- if (*s == '0' && isdigit (s[1]))
- return NULL;
- /* leading zeros are not allowed */
- for (; isdigit(*s); s++)
- {
- val *= 10;
- val += *s - '0';
- }
- *number = val;
- return val < 0? NULL : s;
-}
-
-
-static const char *
-parse_version_string (const char * s, int * major, int * minor, int * micro)
-{
- s = parse_version_number( s, major );
- if( !s || *s != '.' )
- return NULL;
- s++;
- s = parse_version_number (s, minor);
- if (!s || *s != '.')
- return NULL;
- s++;
- s = parse_version_number(s, micro);
- if (!s)
- return NULL;
- return s; /* patchlevel */
-}
-
-
-/**
- * cdk_check_version:
- * @req_version: The requested version
- *
- * Check that the the version of the library is at minimum the requested
- * one and return the version string; return NULL if the condition is
- * not satisfied. If a NULL is passed to this function, no check is done,
- *but the version string is simply returned.
- **/
-const char *
-cdk_check_version (const char *req_version)
-{
- const char *ver = VERSION;
- int my_major, my_minor, my_micro;
- int rq_major, rq_minor, rq_micro;
- const char *my_plvl, *rq_plvl;
-
- if (!req_version)
- return ver;
- my_plvl = parse_version_string (ver, &my_major, &my_minor, &my_micro);
- if (!my_plvl)
- return NULL;
- /* very strange our own version is bogus */
- rq_plvl = parse_version_string (req_version, &rq_major, &rq_minor,
- &rq_micro);
- if (!rq_plvl)
- return NULL; /* req version string is invalid */
- if (my_major > rq_major
- || (my_major == rq_major && my_minor > rq_minor)
- || (my_major == rq_major && my_minor == rq_minor
- && my_micro > rq_micro)
- || (my_major == rq_major && my_minor == rq_minor
- && my_micro == rq_micro
- && strcmp (my_plvl, rq_plvl) >= 0))
- return ver;
- return NULL;
-}
-
-
-/**
- * cdk_strlist_free:
- * @sl: the string list
- *
- * Release the string list object.
- **/
-void
-cdk_strlist_free (cdk_strlist_t sl)
-{
- cdk_strlist_t sl2;
-
- for(; sl; sl = sl2)
- {
- sl2 = sl->next;
- cdk_free (sl);
- }
-}
-
-
-/**
- * cdk_strlist_add:
- * @list: destination string list
- * @string: the string to add
- *
- * Add the given list to the string list.
- **/
-cdk_strlist_t
-cdk_strlist_add (cdk_strlist_t *list, const char *string)
-{
- cdk_strlist_t sl;
-
- if (!string)
- return NULL;
-
- sl = cdk_calloc (1, sizeof *sl + strlen (string) + 1);
- if (!sl)
- return NULL;
- strcpy (sl->d, string);
- sl->next = *list;
- *list = sl;
- return sl;
-}
-
-
-/**
- * cdk_strlist_next:
- * @root: the opaque string list.
- * @r_str: optional argument to store the string data.
- *
- * Return the next string list node from @root. The optional
- * argument @r_str return the data of the current (!) node.
- **/
-cdk_strlist_t
-cdk_strlist_next (cdk_strlist_t root, const char **r_str)
-{
- cdk_strlist_t node;
-
- if (root && r_str)
- *r_str = root->d;
- for (node = root->next; node; node = node->next)
- return node;
-
- return NULL;
-}
-
-
-const char*
-_cdk_memistr (const char *buf, size_t buflen, const char *sub)
-{
- const byte *t, *s;
- size_t n;
-
- for (t = (byte*)buf, n = buflen, s = (byte*)sub ; n ; t++, n--)
- {
- if (toupper (*t) == toupper (*s))
- {
- for (buf = t++, buflen = n--, s++;
- n && toupper (*t) == toupper ((byte)*s); t++, s++, n--)
- ;
- if (!*s)
- return buf;
- t = (byte*)buf;
- n = buflen;
- s = (byte*)sub;
- }
- }
-
- return NULL;
-}
-
-
-/**
- * cdk_utf8_encode:
- * @string:
- *
- * Encode the given string in utf8 and return it.
- **/
-char*
-cdk_utf8_encode (const char *string)
-{
- const byte *s;
- char *buffer;
- byte *p;
- size_t length;
-
- /* FIXME: We should use iconv if possible for utf8 issues. */
- for (s = (const byte*)string, length = 0; *s; s++)
- {
- length++;
- if (*s & 0x80)
- length++;
- }
-
- buffer = cdk_calloc (1, length + 1);
- for (p = (byte*)buffer, s = (byte*)string; *s; s++)
- {
- if (*s & 0x80)
- {
- *p++ = 0xc0 | ((*s >> 6) & 3);
- *p++ = 0x80 | (*s & 0x3f);
- }
- else
- *p++ = *s;
- }
- *p = 0;
- return buffer;
-}
-
-
-/**
- * cdk_utf8_decode:
- * @string: the string to decode
- * @length: the length of the string
- * @delim: the delimiter
- *
- * Decode the given utf8 string and return the native representation.
- **/
-char *
-cdk_utf8_decode (const char * string, size_t length, int delim)
-{
- int nleft;
- int i;
- byte encbuf[8];
- int encidx;
- const byte *s;
- size_t n;
- byte *buffer = NULL, *p = NULL;
- unsigned long val = 0;
- size_t slen;
- int resync = 0;
-
- /* 1. pass (p==NULL): count the extended utf-8 characters */
- /* 2. pass (p!=NULL): create string */
- for (;;)
- {
- for (slen = length, nleft = encidx = 0, n = 0, s = (byte*)string; slen;
- s++, slen--)
- {
- if (resync)
- {
- if (!(*s < 128 || (*s >= 0xc0 && *s <= 0xfd)))
- {
- /* still invalid */
- if (p)
- {
- sprintf ((char*)p, "\\x%02x", *s);
- p += 4;
- }
- n += 4;
- continue;
- }
- resync = 0;
- }
- if (!nleft)
- {
- if (!(*s & 0x80))
- { /* plain ascii */
- if (*s < 0x20 || *s == 0x7f || *s == delim ||
- (delim && *s == '\\'))
- {
- n++;
- if (p)
- *p++ = '\\';
- switch (*s)
- {
- case '\n':
- n++;
- if (p)
- *p++ = 'n';
- break;
- case '\r':
- n++;
- if (p)
- *p++ = 'r';
- break;
- case '\f':
- n++;
- if (p)
- *p++ = 'f';
- break;
- case '\v':
- n++;
- if (p)
- *p++ = 'v';
- break;
- case '\b':
- n++;
- if (p)
- *p++ = 'b';
- break;
- case 0:
- n++;
- if (p)
- *p++ = '0';
- break;
- default:
- n += 3;
- if (p)
- {
- sprintf ((char*)p, "x%02x", *s);
- p += 3;
- }
- break;
- }
- }
- else
- {
- if (p)
- *p++ = *s;
- n++;
- }
- }
- else if ((*s & 0xe0) == 0xc0)
- { /* 110x xxxx */
- val = *s & 0x1f;
- nleft = 1;
- encidx = 0;
- encbuf[encidx++] = *s;
- }
- else if ((*s & 0xf0) == 0xe0)
- { /* 1110 xxxx */
- val = *s & 0x0f;
- nleft = 2;
- encidx = 0;
- encbuf[encidx++] = *s;
- }
- else if ((*s & 0xf8) == 0xf0)
- { /* 1111 0xxx */
- val = *s & 0x07;
- nleft = 3;
- encidx = 0;
- encbuf[encidx++] = *s;
- }
- else if ((*s & 0xfc) == 0xf8)
- { /* 1111 10xx */
- val = *s & 0x03;
- nleft = 4;
- encidx = 0;
- encbuf[encidx++] = *s;
- }
- else if ((*s & 0xfe) == 0xfc)
- { /* 1111 110x */
- val = *s & 0x01;
- nleft = 5;
- encidx = 0;
- encbuf[encidx++] = *s;
- }
- else
- { /* invalid encoding: print as \xnn */
- if (p)
- {
- sprintf ((char*)p, "\\x%02x", *s);
- p += 4;
- }
- n += 4;
- resync = 1;
- }
- }
- else if (*s < 0x80 || *s >= 0xc0)
- { /* invalid */
- if (p)
- {
- for (i = 0; i < encidx; i++)
- {
- sprintf ((char*)p, "\\x%02x", encbuf[i]);
- p += 4;
- }
- sprintf ((char*)p, "\\x%02x", *s);
- p += 4;
- }
- n += 4 + 4 * encidx;
- nleft = 0;
- encidx = 0;
- resync = 1;
- }
- else
- {
- encbuf[encidx++] = *s;
- val <<= 6;
- val |= *s & 0x3f;
- if (!--nleft)
- { /* ready native set */
- if (val >= 0x80 && val < 256)
- {
- n++; /* we can simply print this character */
- if (p)
- *p++ = val;
- }
- else
- { /* we do not have a translation: print utf8 */
- if (p)
- {
- for (i = 0; i < encidx; i++)
- {
- sprintf ((char*)p, "\\x%02x", encbuf[i]);
- p += 4;
- }
- }
- n += encidx * 4;
- encidx = 0;
- }
- }
- }
-
- }
- if (!buffer) /* allocate the buffer after the first pass */
- buffer = p = cdk_malloc (n + 1);
- else
- {
- *p = 0; /* make a string */
- return (char*)buffer;
- }
- }
-}
-
-
-/* Map the gcrypt error to a valid opencdk error constant. */
-cdk_error_t
-_cdk_map_gcry_error (gcry_error_t err)
-{
- /* FIXME: We need to catch them all. */
- switch (gpg_err_code (err))
- {
- case GPG_ERR_NO_ERROR: return CDK_Success;
- case GPG_ERR_INV_VALUE: return CDK_Inv_Value;
- case GPG_ERR_GENERAL: return CDK_General_Error;
- case GPG_ERR_INV_PACKET: return CDK_Inv_Packet;
- case GPG_ERR_TOO_SHORT: return CDK_Too_Short;
- case GPG_ERR_TOO_LARGE: return CDK_Inv_Value;
- case GPG_ERR_NO_PUBKEY:
- case GPG_ERR_NO_SECKEY: return CDK_Error_No_Key;
- case GPG_ERR_BAD_SIGNATURE: return CDK_Bad_Sig;
- case GPG_ERR_NO_DATA: return CDK_No_Data;
- default:
- break;
- }
-
- return (cdk_error_t)err;
-}
-
-
-/* Remove all trailing white spaces from the string. */
-void
-_cdk_trim_string (char *s, int canon)
-{
- while (s && *s &&
- (s[strlen (s)-1] == '\t' ||
- s[strlen (s)-1] == '\r' ||
- s[strlen (s)-1] == '\n' ||
- s[strlen (s)-1] == ' '))
- s[strlen (s) -1] = '\0';
- if (canon)
- strcat (s, "\r\n");
-}
-
-
-int
-_cdk_check_args (int overwrite, const char *in, const char *out)
-{
- struct stat stbuf;
-
- if (!in || !out)
- return CDK_Inv_Value;
- if (strlen (in) == strlen (out) && strcmp (in, out) == 0)
- return CDK_Inv_Mode;
- if (!overwrite && !stat (out, &stbuf))
- return CDK_Inv_Mode;
- return 0;
-}
-
-#ifdef _WIN32
-#include <io.h>
-#include <fcntl.h>
-
-FILE *
-my_tmpfile (void)
-{
- /* Because the tmpfile() version of wine is not really useful,
- we implement our own version to avoid problems with 'make check'. */
- static const char *letters = "abcdefghijklmnopqrstuvwxyz";
- char buf[512], rnd[24];
- FILE *fp;
- int fd, i;
-
- gcry_create_nonce (rnd, DIM (rnd));
- for (i=0; i < DIM (rnd)-1; i++)
- {
- char c = letters[(unsigned char)rnd[i] % 26];
- rnd[i] = c;
- }
- rnd[DIM (rnd)-1]=0;
- if (!GetTempPath (464, buf))
- return NULL;
- strcat (buf, "_cdk_");
- strcat (buf, rnd);
-
- /* We need to make sure the file will be deleted when it is closed. */
- fd = _open (buf, _O_CREAT | _O_EXCL | _O_TEMPORARY |
- _O_RDWR | _O_BINARY, _S_IREAD | _S_IWRITE);
- if (fd == -1)
- return NULL;
- fp = fdopen (fd, "w+b");
- if (fp != NULL)
- return fp;
- _close (fd);
- return NULL;
-}
-#else
-FILE*
-my_tmpfile (void)
-{
- return tmpfile ();
-}
-#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index 37ad263684..d5c8910c1f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -36,35 +36,35 @@ endif
gnutls_serv_SOURCES = serv.gaa serv-gaa.h serv-gaa.c list.h serv.c \
common.h common.c select.c
-gnutls_serv_LDADD = ../lib/libgnutls.la ../libextra/libgnutls-extra.la \
+gnutls_serv_LDADD = ../lib/libgnutls.la \
$(LIBGCRYPT_LIBS) $(LIBTASN1_LIBS) ../gl/libgnu.la
if ENABLE_SRP
srptool_SOURCES = crypt.gaa crypt-gaa.h crypt-gaa.c crypt.c
-srptool_LDADD = ../lib/libgnutls.la ../libextra/libgnutls-extra.la \
+srptool_LDADD = ../lib/libgnutls.la \
$(LIBGCRYPT_LIBS) $(LIBTASN1_LIBS) \
../gl/libgnu.la ../lgl/liblgnu.la
endif
psktool_SOURCES = psk.gaa psk-gaa.h psk-gaa.c psk.c
-psktool_LDADD = ../lib/libgnutls.la ../libextra/libgnutls-extra.la \
+psktool_LDADD = ../lib/libgnutls.la \
$(LIBGCRYPT_LIBS) $(LIBTASN1_LIBS) \
../gl/libgnu.la ../lgl/liblgnu.la
gnutls_cli_SOURCES = cli.gaa cli-gaa.h cli-gaa.c cli.c common.h \
common.c select.c
-gnutls_cli_LDADD = ../lib/libgnutls.la ../libextra/libgnutls-extra.la \
+gnutls_cli_LDADD = ../lib/libgnutls.la \
$(LIBGCRYPT_LIBS) $(LIBTASN1_LIBS) ../gl/libgnu.la
gnutls_cli_debug_SOURCES = tls_test.gaa tls_test-gaa.h tls_test-gaa.c \
tls_test.c tests.h tests.c common.h common.c
gnutls_cli_debug_LDADD = ../lib/libgnutls.la \
- ../libextra/libgnutls-extra.la $(LIBGCRYPT_LIBS) \
+ $(LIBGCRYPT_LIBS) \
$(LIBTASN1_LIBS) ../gl/libgnu.la
certtool_SOURCES = certtool.gaa certtool-gaa.h certtool-cfg.h \
certtool-gaa.c certtool.c prime.c certtool-cfg.c
-certtool_LDADD = ../lib/libgnutls.la $(LIBGCRYPT_LIBS) \
+certtool_LDADD = ../lib/libgnutls.la $(LIBGCRYPT_LIBS) \
$(LIBTASN1_LIBS) ../gl/libgnu.la @LTLIBREADLINE@
if HAVE_LIBCFG
certtool_LDADD += -lcfg+
diff --git a/src/certtool-gaa.c b/src/certtool-gaa.c
index d6835e2c38..77130b6b10 100644
--- a/src/certtool-gaa.c
+++ b/src/certtool-gaa.c
@@ -147,6 +147,7 @@ void gaa_help(void)
__gaa_helpsingle(0, "load-ca-certificate", "FILE ", "Certificate authority's certificate file to use.");
__gaa_helpsingle(0, "password", "PASSWORD ", "Password to use.");
__gaa_helpsingle('i', "certificate-info", "", "Print information on a certificate.");
+ __gaa_helpsingle(0, "pgp-certificate-info", "", "Print information on a OpenPGP certificate.");
__gaa_helpsingle('l', "crl-info", "", "Print information on a CRL.");
__gaa_helpsingle(0, "p12-info", "", "Print information on a PKCS #12 structure.");
__gaa_helpsingle(0, "p7-info", "", "Print information on a PKCS #7 structure.");
@@ -155,7 +156,7 @@ void gaa_help(void)
__gaa_helpsingle(0, "fix-key", "", "Regenerate the parameters in a private key.");
__gaa_helpsingle(0, "v1", "", "Generate an X.509 version 1 certificate (no extensions).");
__gaa_helpsingle(0, "to-p12", "", "Generate a PKCS #12 structure.");
- __gaa_helpsingle(0, "to-p8", "", "Generate a PKCS #8 structure.");
+ __gaa_helpsingle(0, "to-p8", "", "Generate a PKCS #8 key structure.");
__gaa_helpsingle('8', "pkcs8", "", "Use PKCS #8 format for private keys.");
__gaa_helpsingle(0, "dsa", "", "Use DSA keys.");
__gaa_helpsingle(0, "hash", "STR ", "Hash algorithm to use for signing (MD5,SHA1,RMD160,SHA256,SHA384,SHA512).");
@@ -184,33 +185,33 @@ typedef struct _gaainfo gaainfo;
struct _gaainfo
{
-#line 112 "certtool.gaa"
+#line 114 "certtool.gaa"
int debug;
-#line 108 "certtool.gaa"
+#line 110 "certtool.gaa"
char *template;
-#line 105 "certtool.gaa"
+#line 107 "certtool.gaa"
char *infile;
-#line 102 "certtool.gaa"
+#line 104 "certtool.gaa"
char *outfile;
-#line 99 "certtool.gaa"
+#line 101 "certtool.gaa"
int quick_random;
-#line 96 "certtool.gaa"
+#line 98 "certtool.gaa"
int bits;
-#line 93 "certtool.gaa"
+#line 95 "certtool.gaa"
int outcert_format;
-#line 90 "certtool.gaa"
+#line 92 "certtool.gaa"
int incert_format;
-#line 87 "certtool.gaa"
+#line 89 "certtool.gaa"
int export;
-#line 84 "certtool.gaa"
+#line 86 "certtool.gaa"
char *hash;
-#line 81 "certtool.gaa"
+#line 83 "certtool.gaa"
int dsa;
-#line 78 "certtool.gaa"
+#line 80 "certtool.gaa"
int pkcs8;
-#line 71 "certtool.gaa"
+#line 73 "certtool.gaa"
int v1_cert;
-#line 68 "certtool.gaa"
+#line 70 "certtool.gaa"
int fix_key;
#line 53 "certtool.gaa"
char *pass;
@@ -280,7 +281,7 @@ static int gaa_error = 0;
#define GAA_MULTIPLE_OPTION 3
#define GAA_REST 0
-#define GAA_NB_OPTION 41
+#define GAA_NB_OPTION 42
#define GAAOPTID_version 1
#define GAAOPTID_help 2
#define GAAOPTID_debug 3
@@ -304,24 +305,25 @@ static int gaa_error = 0;
#define GAAOPTID_p7_info 21
#define GAAOPTID_p12_info 22
#define GAAOPTID_crl_info 23
-#define GAAOPTID_certificate_info 24
-#define GAAOPTID_password 25
-#define GAAOPTID_load_ca_certificate 26
-#define GAAOPTID_load_ca_privkey 27
-#define GAAOPTID_load_certificate 28
-#define GAAOPTID_load_request 29
-#define GAAOPTID_load_privkey 30
-#define GAAOPTID_get_dh_params 31
-#define GAAOPTID_generate_dh_params 32
-#define GAAOPTID_verify_crl 33
-#define GAAOPTID_verify_chain 34
-#define GAAOPTID_generate_request 35
-#define GAAOPTID_generate_privkey 36
-#define GAAOPTID_update_certificate 37
-#define GAAOPTID_generate_crl 38
-#define GAAOPTID_generate_proxy 39
-#define GAAOPTID_generate_certificate 40
-#define GAAOPTID_generate_self_signed 41
+#define GAAOPTID_pgp_certificate_info 24
+#define GAAOPTID_certificate_info 25
+#define GAAOPTID_password 26
+#define GAAOPTID_load_ca_certificate 27
+#define GAAOPTID_load_ca_privkey 28
+#define GAAOPTID_load_certificate 29
+#define GAAOPTID_load_request 30
+#define GAAOPTID_load_privkey 31
+#define GAAOPTID_get_dh_params 32
+#define GAAOPTID_generate_dh_params 33
+#define GAAOPTID_verify_crl 34
+#define GAAOPTID_verify_chain 35
+#define GAAOPTID_generate_request 36
+#define GAAOPTID_generate_privkey 37
+#define GAAOPTID_update_certificate 38
+#define GAAOPTID_generate_crl 39
+#define GAAOPTID_generate_proxy 40
+#define GAAOPTID_generate_certificate 41
+#define GAAOPTID_generate_self_signed 42
#line 168 "gaa.skel"
@@ -640,6 +642,7 @@ static int gaa_get_option_num(char *str, int status)
GAA_CHECK1STR("", GAAOPTID_p7_info);
GAA_CHECK1STR("", GAAOPTID_p12_info);
GAA_CHECK1STR("l", GAAOPTID_crl_info);
+ GAA_CHECK1STR("", GAAOPTID_pgp_certificate_info);
GAA_CHECK1STR("i", GAAOPTID_certificate_info);
GAA_CHECK1STR("", GAAOPTID_get_dh_params);
GAA_CHECK1STR("", GAAOPTID_generate_dh_params);
@@ -679,6 +682,7 @@ static int gaa_get_option_num(char *str, int status)
GAA_CHECKSTR("p7-info", GAAOPTID_p7_info);
GAA_CHECKSTR("p12-info", GAAOPTID_p12_info);
GAA_CHECKSTR("crl-info", GAAOPTID_crl_info);
+ GAA_CHECKSTR("pgp-certificate-info", GAAOPTID_pgp_certificate_info);
GAA_CHECKSTR("certificate-info", GAAOPTID_certificate_info);
GAA_CHECKSTR("password", GAAOPTID_password);
GAA_CHECKSTR("load-ca-certificate", GAAOPTID_load_ca_certificate);
@@ -743,14 +747,14 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
{
case GAAOPTID_version:
OK = 0;
-#line 117 "certtool.gaa"
+#line 119 "certtool.gaa"
{ certtool_version(); exit(0); ;};
return GAA_OK;
break;
case GAAOPTID_help:
OK = 0;
-#line 115 "certtool.gaa"
+#line 117 "certtool.gaa"
{ gaa_help(); exit(0); ;};
return GAA_OK;
@@ -760,7 +764,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_debug.arg1, gaa_getint, GAATMP_debug.size1);
gaa_index++;
-#line 113 "certtool.gaa"
+#line 115 "certtool.gaa"
{ gaaval->debug = GAATMP_debug.arg1 ;};
return GAA_OK;
@@ -770,7 +774,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_template.arg1, gaa_getstr, GAATMP_template.size1);
gaa_index++;
-#line 109 "certtool.gaa"
+#line 111 "certtool.gaa"
{ gaaval->template = GAATMP_template.arg1 ;};
return GAA_OK;
@@ -780,7 +784,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_infile.arg1, gaa_getstr, GAATMP_infile.size1);
gaa_index++;
-#line 106 "certtool.gaa"
+#line 108 "certtool.gaa"
{ gaaval->infile = GAATMP_infile.arg1 ;};
return GAA_OK;
@@ -790,14 +794,14 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_outfile.arg1, gaa_getstr, GAATMP_outfile.size1);
gaa_index++;
-#line 103 "certtool.gaa"
+#line 105 "certtool.gaa"
{ gaaval->outfile = GAATMP_outfile.arg1 ;};
return GAA_OK;
break;
case GAAOPTID_disable_quick_random:
OK = 0;
-#line 100 "certtool.gaa"
+#line 102 "certtool.gaa"
{ gaaval->quick_random = 0; ;};
return GAA_OK;
@@ -807,28 +811,28 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_bits.arg1, gaa_getint, GAATMP_bits.size1);
gaa_index++;
-#line 97 "certtool.gaa"
+#line 99 "certtool.gaa"
{ gaaval->bits = GAATMP_bits.arg1 ;};
return GAA_OK;
break;
case GAAOPTID_outder:
OK = 0;
-#line 94 "certtool.gaa"
+#line 96 "certtool.gaa"
{ gaaval->outcert_format=1 ;};
return GAA_OK;
break;
case GAAOPTID_inder:
OK = 0;
-#line 91 "certtool.gaa"
+#line 93 "certtool.gaa"
{ gaaval->incert_format=1 ;};
return GAA_OK;
break;
case GAAOPTID_export_ciphers:
OK = 0;
-#line 88 "certtool.gaa"
+#line 90 "certtool.gaa"
{ gaaval->export=1 ;};
return GAA_OK;
@@ -838,88 +842,95 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_hash.arg1, gaa_getstr, GAATMP_hash.size1);
gaa_index++;
-#line 85 "certtool.gaa"
+#line 87 "certtool.gaa"
{ gaaval->hash = GAATMP_hash.arg1 ;};
return GAA_OK;
break;
case GAAOPTID_dsa:
OK = 0;
-#line 82 "certtool.gaa"
+#line 84 "certtool.gaa"
{ gaaval->dsa=1 ;};
return GAA_OK;
break;
case GAAOPTID_pkcs8:
OK = 0;
-#line 79 "certtool.gaa"
+#line 81 "certtool.gaa"
{ gaaval->pkcs8=1 ;};
return GAA_OK;
break;
case GAAOPTID_to_p8:
OK = 0;
-#line 76 "certtool.gaa"
+#line 78 "certtool.gaa"
{ gaaval->action = 18; ;};
return GAA_OK;
break;
case GAAOPTID_to_p12:
OK = 0;
-#line 74 "certtool.gaa"
+#line 76 "certtool.gaa"
{ gaaval->action = 8; ;};
return GAA_OK;
break;
case GAAOPTID_v1:
OK = 0;
-#line 72 "certtool.gaa"
+#line 74 "certtool.gaa"
{ gaaval->v1_cert = 1; ;};
return GAA_OK;
break;
case GAAOPTID_fix_key:
OK = 0;
-#line 69 "certtool.gaa"
+#line 71 "certtool.gaa"
{ gaaval->fix_key = 1; ;};
return GAA_OK;
break;
case GAAOPTID_key_info:
OK = 0;
-#line 66 "certtool.gaa"
+#line 68 "certtool.gaa"
{ gaaval->action = 6; ;};
return GAA_OK;
break;
case GAAOPTID_smime_to_p7:
OK = 0;
-#line 64 "certtool.gaa"
+#line 66 "certtool.gaa"
{ gaaval->action = 15; ;};
return GAA_OK;
break;
case GAAOPTID_p7_info:
OK = 0;
-#line 62 "certtool.gaa"
+#line 64 "certtool.gaa"
{ gaaval->action = 12; ;};
return GAA_OK;
break;
case GAAOPTID_p12_info:
OK = 0;
-#line 60 "certtool.gaa"
+#line 62 "certtool.gaa"
{ gaaval->action = 9; ;};
return GAA_OK;
break;
case GAAOPTID_crl_info:
OK = 0;
-#line 58 "certtool.gaa"
+#line 60 "certtool.gaa"
{ gaaval->action = 11; ;};
return GAA_OK;
break;
+ case GAAOPTID_pgp_certificate_info:
+ OK = 0;
+#line 58 "certtool.gaa"
+{ gaaval->action = 19; ;};
+
+ return GAA_OK;
+ break;
case GAAOPTID_certificate_info:
OK = 0;
#line 56 "certtool.gaa"
@@ -1088,7 +1099,7 @@ int gaa(int argc, char **argv, gaainfo *gaaval)
if(inited == 0)
{
-#line 119 "certtool.gaa"
+#line 121 "certtool.gaa"
{ gaaval->bits = 2048; gaaval->pkcs8 = 0; gaaval->privkey = NULL; gaaval->ca=NULL; gaaval->ca_privkey = NULL;
gaaval->debug=1; gaaval->request = NULL; gaaval->infile = NULL; gaaval->outfile = NULL; gaaval->cert = NULL;
gaaval->incert_format = 0; gaaval->outcert_format = 0; gaaval->action=-1; gaaval->pass = NULL; gaaval->v1_cert = 0;
diff --git a/src/certtool-gaa.h b/src/certtool-gaa.h
index 2965344059..a7f70bbc6f 100644
--- a/src/certtool-gaa.h
+++ b/src/certtool-gaa.h
@@ -8,33 +8,33 @@ typedef struct _gaainfo gaainfo;
struct _gaainfo
{
-#line 112 "certtool.gaa"
+#line 114 "certtool.gaa"
int debug;
-#line 108 "certtool.gaa"
+#line 110 "certtool.gaa"
char *template;
-#line 105 "certtool.gaa"
+#line 107 "certtool.gaa"
char *infile;
-#line 102 "certtool.gaa"
+#line 104 "certtool.gaa"
char *outfile;
-#line 99 "certtool.gaa"
+#line 101 "certtool.gaa"
int quick_random;
-#line 96 "certtool.gaa"
+#line 98 "certtool.gaa"
int bits;
-#line 93 "certtool.gaa"
+#line 95 "certtool.gaa"
int outcert_format;
-#line 90 "certtool.gaa"
+#line 92 "certtool.gaa"
int incert_format;
-#line 87 "certtool.gaa"
+#line 89 "certtool.gaa"
int export;
-#line 84 "certtool.gaa"
+#line 86 "certtool.gaa"
char *hash;
-#line 81 "certtool.gaa"
+#line 83 "certtool.gaa"
int dsa;
-#line 78 "certtool.gaa"
+#line 80 "certtool.gaa"
int pkcs8;
-#line 71 "certtool.gaa"
+#line 73 "certtool.gaa"
int v1_cert;
-#line 68 "certtool.gaa"
+#line 70 "certtool.gaa"
int fix_key;
#line 53 "certtool.gaa"
char *pass;
diff --git a/src/certtool.c b/src/certtool.c
index 56b71dec84..ff006ff169 100644
--- a/src/certtool.c
+++ b/src/certtool.c
@@ -26,6 +26,7 @@
#include <string.h>
#include <ctype.h>
#include <gnutls/x509.h>
+#include <gnutls/openpgp.h>
#include <time.h>
#include "certtool-gaa.h"
#include <gnutls/pkcs12.h>
@@ -55,6 +56,7 @@ gnutls_x509_privkey_t load_ca_private_key (void);
gnutls_x509_crt_t load_ca_cert (void);
gnutls_x509_crt_t load_cert (int mand);
void certificate_info (void);
+void pgp_certificate_info (void);
void crl_info (void);
void privkey_info (void);
static void print_certificate_info (gnutls_x509_crt_t crt, FILE * out,
@@ -897,6 +899,9 @@ gaa_parser (int argc, char **argv)
case 18:
generate_pkcs8 ();
break;
+ case 19:
+ pgp_certificate_info();
+ break;
default:
gaa_help ();
exit (0);
@@ -959,6 +964,52 @@ certificate_info (void)
}
}
+void
+pgp_certificate_info (void)
+{
+ gnutls_openpgp_crt_t crt;
+ size_t size;
+ int ret, i, count;
+ gnutls_datum_t pem, out_data;
+
+ pem.data = fread_file (infile, &size);
+ pem.size = size;
+
+ ret = gnutls_openpgp_crt_init( &crt);
+ if (ret < 0)
+ error (EXIT_FAILURE, 0, "openpgp_crt_init: %s", gnutls_strerror (ret));
+
+ ret = gnutls_openpgp_crt_import (crt, &pem, info.incert_format);
+
+ if (ret < 0)
+ error (EXIT_FAILURE, 0, "Import error: %s", gnutls_strerror (ret));
+
+ free (pem.data);
+
+ if (info.outcert_format == GNUTLS_OPENPGP_FMT_BASE64)
+ {
+ ret = gnutls_openpgp_crt_print (crt, 0, &out_data);
+
+ if (ret == 0)
+ {
+ fprintf (outfile, "%s\n", out_data.data);
+ gnutls_free (out_data.data);
+ }
+ }
+
+ size = sizeof (buffer);
+ ret = gnutls_openpgp_crt_export (crt, info.outcert_format, buffer,
+ &size);
+ if (ret < 0) {
+ error (EXIT_FAILURE, 0, "Export error: %s", gnutls_strerror (ret));
+ fwrite (buffer, 1, size, outfile);
+ }
+
+ fprintf (outfile, "%s\n", buffer);
+
+ gnutls_openpgp_crt_deinit( crt);
+}
+
static void
print_hex_datum (gnutls_datum_t * dat)
{
diff --git a/src/certtool.gaa b/src/certtool.gaa
index 51c3545136..9575ab4184 100644
--- a/src/certtool.gaa
+++ b/src/certtool.gaa
@@ -55,6 +55,8 @@ option (password) STR "PASSWORD" { $pass = $1 } "Password to use."
option (i, certificate-info) { $action = 2; } "Print information on a certificate."
+option (pgp-certificate-info) { $action = 19; } "Print information on a OpenPGP certificate."
+
option (l, crl-info) { $action = 11; } "Print information on a CRL."
option (p12-info) { $action = 9; } "Print information on a PKCS #12 structure."
diff --git a/src/cli.c b/src/cli.c
index 1136d9d0e3..599f0e71eb 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -419,8 +419,10 @@ const char *err;
gnutls_certificate_client_set_retrieve_function (xcred, cert_callback);
/* send the fingerprint */
+#ifdef ENABLE_OPENPGP
if (fingerprint != 0)
gnutls_openpgp_send_cert (session, GNUTLS_OPENPGP_CERT_FINGERPRINT);
+#endif
/* use the max record size extension */
if (record_max_size > 0 && disable_extensions == 0)
@@ -532,12 +534,6 @@ main (int argc, char **argv)
exit (1);
}
- if ((ret = gnutls_global_init_extra ()) < 0)
- {
- fprintf (stderr, "global_init_extra: %s\n", gnutls_strerror (ret));
-// exit (1);
- }
-
gaa_parser (argc, argv);
if (hostname == NULL)
{
diff --git a/src/serv.c b/src/serv.c
index 0ff113d750..b16c18be78 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -837,12 +837,6 @@ main (int argc, char **argv)
gnutls_global_set_log_function (tls_log_func);
gnutls_global_set_log_level (debug);
- if ((ret = gnutls_global_init_extra ()) < 0)
- {
- fprintf (stderr, "global_init_extra: %s\n", gnutls_strerror (ret));
- exit (1);
- }
-
/* Note that servers must generate parameters for
* Diffie Hellman. See gnutls_dh_params_generate(), and
* gnutls_dh_params_set().
diff --git a/src/tls_test.c b/src/tls_test.c
index fcb0bba9bb..1422a46a91 100644
--- a/src/tls_test.c
+++ b/src/tls_test.c
@@ -187,12 +187,6 @@ main (int argc, char **argv)
gnutls_global_set_log_function (tls_log_func);
gnutls_global_set_log_level (debug);
- if (gnutls_global_init_extra () < 0)
- {
- fprintf (stderr, "global state initialization error\n");
- exit (1);
- }
-
printf ("Resolving '%s'...\n", hostname);
/* get server name */
memset (&hints, 0, sizeof (hints));