summaryrefslogtreecommitdiff
path: root/libextra
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2007-10-24 23:44:45 +0300
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2007-10-24 23:44:45 +0300
commit3a9bb9663e20587447699352ad78b231e35ad9f0 (patch)
tree90877fd0409d3bef96afcaacb9fa2016772e367b /libextra
parente3b8eea08c24fd71a66669f4e7424d2636c9aaca (diff)
downloadgnutls-3a9bb9663e20587447699352ad78b231e35ad9f0.tar.gz
Several changes to openpgp code:
* gnutls_certificate_set_openpgp_* functions were modified to include format * KEYRING_HACK is defined to overcome a bug in opencdk which makes keyrings reentrant. Once fixed, the KEYRING_HACK code should be removed.
Diffstat (limited to 'libextra')
-rw-r--r--libextra/gnutls_openpgp.c395
-rw-r--r--libextra/openpgp/compat.c33
-rw-r--r--libextra/openpgp/gnutls_openpgp.h31
-rw-r--r--libextra/openpgp/openpgp.h7
4 files changed, 221 insertions, 245 deletions
diff --git a/libextra/gnutls_openpgp.c b/libextra/gnutls_openpgp.c
index 8151deed04..36b54077b4 100644
--- a/libextra/gnutls_openpgp.c
+++ b/libextra/gnutls_openpgp.c
@@ -28,7 +28,7 @@
#include "gnutls_cert.h"
#include "gnutls_datum.h"
#include "gnutls_global.h"
-#include <openpgp/gnutls_openpgp.h>
+#include "openpgp/gnutls_openpgp.h"
#include "read-file.h"
#include <gnutls_str.h>
#include <gnutls_sig.h>
@@ -123,7 +123,7 @@ kbx_blob_new (keybox_blob ** r_ctx)
}
-void
+static void
kbx_blob_release (keybox_blob * ctx)
{
if (!ctx)
@@ -133,7 +133,7 @@ kbx_blob_release (keybox_blob * ctx)
}
-cdk_keydb_hd_t
+static cdk_keydb_hd_t
kbx_to_keydb (keybox_blob * blob)
{
cdk_keydb_hd_t db;
@@ -166,7 +166,7 @@ kbx_to_keydb (keybox_blob * blob)
/* Extract a keybox blob from the given position. */
-keybox_blob *
+static keybox_blob *
kbx_read_blob (const gnutls_datum_t * keyring, size_t pos)
{
keybox_blob *blob = NULL;
@@ -441,6 +441,85 @@ _gnutls_openpgp_raw_key_to_gcert (gnutls_cert * cert,
return rc;
}
+/**
+ * gnutls_certificate_set_openpgp_key - Used to set keys in a gnutls_certificate_credentials_t structure
+ * @res: is an #gnutls_certificate_credentials_t structure.
+ * @key: contains an openpgp public key
+ * @pkey: is an openpgp private key
+ *
+ * This function sets a certificate/private key pair in the
+ * gnutls_certificate_credentials_t structure. This function may be called
+ * more than once (in case multiple keys/certificates exist for the
+ * server).
+ *
+ **/
+int
+gnutls_certificate_set_openpgp_key (gnutls_certificate_credentials_t
+ res, gnutls_openpgp_crt_t crt,
+ gnutls_openpgp_privkey_t pkey)
+{
+ int ret;
+
+ /* this should be first */
+
+ res->pkey = gnutls_realloc_fast (res->pkey,
+ (res->ncerts + 1) *
+ sizeof (gnutls_privkey));
+ if (res->pkey == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ ret = _gnutls_openpgp_privkey_to_gkey (&res->pkey[res->ncerts], pkey);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ return ret;
+ }
+
+ res->cert_list = gnutls_realloc_fast (res->cert_list,
+ (1 +
+ res->ncerts) *
+ sizeof (gnutls_cert *));
+ if (res->cert_list == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ res->cert_list_length = gnutls_realloc_fast (res->cert_list_length,
+ (1 +
+ res->ncerts) * sizeof (int));
+ if (res->cert_list_length == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ res->cert_list[res->ncerts] = gnutls_calloc (1, sizeof (gnutls_cert));
+ if (res->cert_list[res->ncerts] == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ res->cert_list_length[res->ncerts] = 1;
+
+ ret = _gnutls_openpgp_crt_to_gcert (res->cert_list[res->ncerts], crt);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ return ret;
+ }
+
+ res->ncerts++;
+
+ /* FIXME: Check if the keys match. */
+
+ return 0;
+}
+
/*-
* gnutls_openpgp_get_key - Retrieve a key from the keyring.
@@ -555,148 +634,49 @@ stream_to_datum (cdk_stream_t inp, gnutls_datum_t * raw)
**/
int
gnutls_certificate_set_openpgp_key_mem (gnutls_certificate_credentials_t
- res, const gnutls_datum_t * cert,
- const gnutls_datum_t * key)
+ res, const gnutls_datum_t * icert,
+ const gnutls_datum_t * ikey,
+ gnutls_openpgp_crt_fmt_t format)
{
- gnutls_datum_t raw;
- cdk_kbnode_t knode = NULL, ctx = NULL, p;
- cdk_packet_t pkt;
- int i = 0;
- int rc = 0;
- cdk_stream_t inp = NULL;
-
- if (!res || !key || !cert)
- {
- gnutls_assert ();
- return GNUTLS_E_INVALID_REQUEST;
- }
-
- rc = cdk_stream_tmp_from_mem (cert->data, cert->size, &inp);
- if (rc)
- {
- rc = _gnutls_map_cdk_rc (rc);
- gnutls_assert ();
- return rc;
- }
-
- if (cdk_armor_filter_use (inp))
- cdk_stream_set_armor_flag (inp, 0);
-
- res->cert_list = gnutls_realloc_fast (res->cert_list,
- (1 + res->ncerts) *
- sizeof (gnutls_cert *));
- if (res->cert_list == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- res->cert_list_length = gnutls_realloc_fast (res->cert_list_length,
- (1 +
- res->ncerts) * sizeof (int));
- if (res->cert_list_length == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- res->cert_list[res->ncerts] = gnutls_calloc (1, sizeof (gnutls_cert));
- if (res->cert_list[res->ncerts] == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- i = 1;
- rc = cdk_keydb_get_keyblock (inp, &knode);
-
- while (knode && (p = cdk_kbnode_walk (knode, &ctx, 0)))
- {
- pkt = cdk_kbnode_get_packet (p);
- if (i > MAX_PUBLIC_PARAMS_SIZE)
- {
- gnutls_assert ();
- break;
- }
- if (pkt->pkttype == CDK_PKT_PUBLIC_KEY)
- {
- int n = res->ncerts;
-
- cdk_pkt_pubkey_t pk = pkt->pkt.public_key;
- res->cert_list_length[n] = 1;
-
- if (stream_to_datum (inp, &res->cert_list[n][0].raw))
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
- rc = openpgp_pk_to_gnutls_cert (&res->cert_list[n][0], pk);
- if (rc < 0)
- {
- gnutls_assert ();
- return rc;
- }
- i++;
- }
- }
-
- if (rc == CDK_EOF && i > 1)
- rc = 0;
-
- cdk_stream_close (inp);
-
- if (rc)
- {
- cdk_kbnode_release (knode);
- gnutls_assert ();
- rc = _gnutls_map_cdk_rc (rc);
- goto leave;
- }
-
- res->ncerts++;
- res->pkey = gnutls_realloc_fast (res->pkey,
- (res->ncerts) * sizeof (gnutls_privkey));
- if (!res->pkey)
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- /* ncerts has been incremented before */
-
- rc = cdk_stream_tmp_from_mem (key->data, key->size, &inp);
- if (rc)
- {
- gnutls_assert ();
- return GNUTLS_E_INTERNAL_ERROR;
- }
-
- if (cdk_armor_filter_use (inp))
- cdk_stream_set_armor_flag (inp, 0);
+ gnutls_openpgp_privkey_t key;
+ gnutls_openpgp_crt_t cert;
+ int ret;
+
+ ret = gnutls_openpgp_privkey_init( &key);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
- memset (&raw, 0, sizeof raw);
+ ret = gnutls_openpgp_privkey_import( key, ikey, format, NULL, 0);
+ if (ret < 0) {
+ gnutls_assert();
+ gnutls_openpgp_privkey_deinit( key);
+ return ret;
+ }
- if (stream_to_datum (inp, &raw))
- {
- gnutls_assert ();
- return GNUTLS_E_INTERNAL_ERROR;
- }
- cdk_stream_close (inp);
+ ret = gnutls_openpgp_crt_init( &cert);
+ if (ret < 0) {
+ gnutls_assert();
+ gnutls_openpgp_privkey_deinit( key);
+ return ret;
+ }
- rc = _gnutls_openpgp_raw_privkey_to_gkey (&res->pkey[res->ncerts - 1],
- &raw,
- GNUTLS_OPENPGP_FMT_RAW);
- if (rc)
- {
- gnutls_assert ();
- }
+ ret = gnutls_openpgp_crt_import( cert, icert, format);
+ if (ret < 0) {
+ gnutls_assert();
+ gnutls_openpgp_privkey_deinit( key);
+ gnutls_openpgp_crt_deinit( cert);
+ return ret;
+ }
- _gnutls_free_datum (&raw);
-leave:
- cdk_kbnode_release (knode);
+ ret = gnutls_certificate_set_openpgp_key( res, cert, key);
- return rc;
+ gnutls_openpgp_privkey_deinit( key);
+ gnutls_openpgp_crt_deinit( cert);
+
+ return ret;
}
@@ -713,7 +693,8 @@ leave:
int
gnutls_certificate_set_openpgp_key_file (gnutls_certificate_credentials_t
res, const char *certfile,
- const char *keyfile)
+ const char *keyfile,
+ gnutls_openpgp_crt_fmt_t format)
{
struct stat statbuf;
gnutls_datum_t key, cert;
@@ -749,7 +730,7 @@ gnutls_certificate_set_openpgp_key_file (gnutls_certificate_credentials_t
return GNUTLS_E_FILE_ERROR;
}
- rc = gnutls_certificate_set_openpgp_key_mem (res, &cert, &key);
+ rc = gnutls_certificate_set_openpgp_key_mem (res, &cert, &key, format);
free (cert.data);
free (key.data);
@@ -812,7 +793,7 @@ 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_certificate_credentials_t c, const char *file, gnutls_openpgp_crt_fmt_t format)
{
gnutls_datum ring;
size_t size;
@@ -832,7 +813,7 @@ int rc;
return GNUTLS_E_FILE_ERROR;
}
- rc = gnutls_certificate_set_openpgp_keyring_mem (c, ring.data, ring.size);
+ rc = gnutls_certificate_set_openpgp_keyring_mem (c, ring.data, ring.size, format);
free( ring.data);
@@ -854,8 +835,9 @@ int rc;
int
gnutls_certificate_set_openpgp_keyring_mem (gnutls_certificate_credentials_t
c, const opaque * data,
- size_t dlen)
+ size_t dlen, gnutls_openpgp_crt_fmt_t format)
{
+#ifndef KEYRING_HACK
cdk_stream_t inp;
size_t count;
uint8_t *buf;
@@ -877,7 +859,7 @@ gnutls_certificate_set_openpgp_keyring_mem (gnutls_certificate_credentials_t
return rc;
}
- rc = gnutls_openpgp_keyring_import( c->keyring, &ddata, GNUTLS_OPENPGP_FMT_BASE64);
+ rc = gnutls_openpgp_keyring_import( c->keyring, &ddata, format);
if ( rc < 0) {
gnutls_assert();
gnutls_openpgp_keyring_deinit( c->keyring);
@@ -885,6 +867,21 @@ gnutls_certificate_set_openpgp_keyring_mem (gnutls_certificate_credentials_t
}
return 0;
+#else
+
+ c->keyring_format = format;
+
+ c->keyring.data = gnutls_malloc( dlen+1);
+ if (c->keyring.data == NULL)
+ {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+ memcpy(c->keyring.data, data, dlen);
+ c->keyring.data[dlen]=0;
+ c->keyring.size = dlen;
+
+#endif
}
/*-
@@ -904,6 +901,9 @@ _gnutls_openpgp_request_key (gnutls_session_t session, gnutls_datum_t * ret,
opaque * key_fpr, int key_fpr_size)
{
int rc = 0;
+#ifdef KEYRING_HACK
+ gnutls_openpgp_keyring_t kring;
+#endif
if (!ret || !cred || !key_fpr)
{
@@ -914,9 +914,27 @@ _gnutls_openpgp_request_key (gnutls_session_t session, gnutls_datum_t * ret,
if (key_fpr_size != 16 && key_fpr_size != 20)
return GNUTLS_E_HASH_FAILED; /* only MD5 and SHA1 are supported */
+#ifndef KEYRING_HACK
rc = gnutls_openpgp_get_key (ret, cred->keyring, KEY_ATTR_FPR, key_fpr);
- if (rc >= 0) /* key was found */
+#else
+ rc = gnutls_openpgp_keyring_init( &kring);
+ if ( rc < 0) {
+ gnutls_assert();
return rc;
+ }
+
+ rc = gnutls_openpgp_keyring_import( kring, &cred->keyring, cred->keyring_format);
+ if ( rc < 0) {
+ gnutls_assert();
+ gnutls_openpgp_keyring_deinit( kring);
+ return rc;
+ }
+#endif
+ if (rc >= 0) /* key was found */
+ {
+ rc = 0;
+ goto error;
+ }
else
rc = GNUTLS_E_OPENPGP_GETKEY_FAILED;
@@ -929,10 +947,15 @@ _gnutls_openpgp_request_key (gnutls_session_t session, gnutls_datum_t * ret,
if (rc < 0)
{
gnutls_assert ();
- return GNUTLS_E_OPENPGP_GETKEY_FAILED;
+ rc = GNUTLS_E_OPENPGP_GETKEY_FAILED;
+ goto error;
}
}
+ error:
+#ifdef KEYRING_HACK
+ gnutls_openpgp_keyring_deinit( kring);
+#endif
return rc;
}
@@ -1040,84 +1063,6 @@ _gnutls_openpgp_crt_to_gcert (gnutls_cert * gcert, gnutls_openpgp_crt_t cert)
}
-/**
- * gnutls_certificate_set_openpgp_key - Used to set keys in a gnutls_certificate_credentials_t structure
- * @res: is an #gnutls_certificate_credentials_t structure.
- * @key: contains an openpgp public key
- * @pkey: is an openpgp private key
- *
- * This function sets a certificate/private key pair in the
- * gnutls_certificate_credentials_t structure. This function may be called
- * more than once (in case multiple keys/certificates exist for the
- * server).
- *
- **/
-int
-gnutls_certificate_set_openpgp_key (gnutls_certificate_credentials_t
- res, gnutls_openpgp_crt_t key,
- gnutls_openpgp_privkey_t pkey)
-{
- int ret;
-
- /* this should be first */
-
- res->pkey = gnutls_realloc_fast (res->pkey,
- (res->ncerts + 1) *
- sizeof (gnutls_privkey));
- if (res->pkey == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- ret = _gnutls_openpgp_privkey_to_gkey (&res->pkey[res->ncerts], pkey);
- if (ret < 0)
- {
- gnutls_assert ();
- return ret;
- }
-
- res->cert_list = gnutls_realloc_fast (res->cert_list,
- (1 +
- res->ncerts) *
- sizeof (gnutls_cert *));
- if (res->cert_list == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- res->cert_list_length = gnutls_realloc_fast (res->cert_list_length,
- (1 +
- res->ncerts) * sizeof (int));
- if (res->cert_list_length == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- res->cert_list[res->ncerts] = gnutls_calloc (1, sizeof (gnutls_cert));
- if (res->cert_list[res->ncerts] == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- res->cert_list_length[res->ncerts] = 1;
-
- ret = _gnutls_openpgp_crt_to_gcert (res->cert_list[res->ncerts], key);
- if (ret < 0)
- {
- gnutls_assert ();
- return ret;
- }
-
- res->ncerts++;
-
- /* FIXME: Check if the keys match. */
-
- return 0;
-}
/**
* gnutls_openpgp_privkey_sign_hash - This function will sign the given data using the private key params
diff --git a/libextra/openpgp/compat.c b/libextra/openpgp/compat.c
index 4f7e784108..02385db6f9 100644
--- a/libextra/openpgp/compat.c
+++ b/libextra/openpgp/compat.c
@@ -73,6 +73,7 @@ _gnutls_openpgp_verify_key (const gnutls_certificate_credentials_t cred,
goto leave;
}
+#ifndef KEYRING_HACK
if (cred->keyring != NULL)
{
ret = gnutls_openpgp_crt_verify_ring (key, cred->keyring, 0, &verify);
@@ -82,6 +83,33 @@ _gnutls_openpgp_verify_key (const gnutls_certificate_credentials_t cred,
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);
@@ -93,10 +121,15 @@ _gnutls_openpgp_verify_key (const gnutls_certificate_credentials_t cred,
*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:
diff --git a/libextra/openpgp/gnutls_openpgp.h b/libextra/openpgp/gnutls_openpgp.h
index 9c4124dbac..9894b084ba 100644
--- a/libextra/openpgp/gnutls_openpgp.h
+++ b/libextra/openpgp/gnutls_openpgp.h
@@ -33,23 +33,17 @@ typedef enum
int
gnutls_certificate_set_openpgp_key_file (gnutls_certificate_credentials_t
res, const char *CERTFILE,
- const char *KEYFILE);
+ const char *KEYFILE, gnutls_openpgp_crt_fmt_t);
int gnutls_openpgp_count_key_names (const gnutls_datum_t * cert);
-int gnutls_openpgp_add_keyring_mem (gnutls_datum_t * keyring,
- const void *data, size_t len);
-
-int gnutls_openpgp_add_keyring_file (gnutls_datum_t * keyring,
- const char *name);
-
int gnutls_certificate_set_openpgp_keyring_file
- (gnutls_certificate_credentials_t c, const char *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);
+ size_t dlen, gnutls_openpgp_crt_fmt_t);
int gnutls_openpgp_get_key (gnutls_datum_t * key,
gnutls_openpgp_keyring_t keyring,
@@ -74,10 +68,6 @@ _gnutls_openpgp_request_key (gnutls_session_t,
const gnutls_certificate_credentials_t cred,
opaque * key_fpr, int key_fpr_size);
-keybox_blob *kbx_read_blob (const gnutls_datum_t * keyring, size_t pos);
-cdk_keydb_hd_t kbx_to_keydb (keybox_blob * blob);
-void kbx_blob_release (keybox_blob * ctx);
-
int _gnutls_openpgp_verify_key (const gnutls_certificate_credentials_t,
const gnutls_datum_t * cert_list,
int cert_list_length, unsigned int *status);
@@ -88,6 +78,21 @@ time_t _gnutls_openpgp_get_raw_key_creation_time (const gnutls_datum_t *
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);
+
#endif /*GNUTLS_OPENPGP_H */
#endif /*ENABLE_OPENPGP */
diff --git a/libextra/openpgp/openpgp.h b/libextra/openpgp/openpgp.h
index 84a1ad7625..ecdee694cc 100644
--- a/libextra/openpgp/openpgp.h
+++ b/libextra/openpgp/openpgp.h
@@ -5,13 +5,6 @@
# include <config.h>
#endif
-/* The format the OpenPGP key is stored in. */
-typedef enum gnutls_openpgp_crt_fmt_t
-{
- GNUTLS_OPENPGP_FMT_RAW,
- GNUTLS_OPENPGP_FMT_BASE64
-} gnutls_openpgp_crt_fmt_t;
-
#ifdef ENABLE_OPENPGP
#include <opencdk.h>