summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2010-12-16 17:06:45 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2010-12-16 17:06:45 +0100
commitd8e2f838bfb81141e7f44cbd2f7adcc756f26044 (patch)
tree45653966472bd2644c9604b15e9135279c7b1686
parente0e3e4324d753041aba8dfe70fc7b755cba2616d (diff)
downloadgnutls-d8e2f838bfb81141e7f44cbd2f7adcc756f26044.tar.gz
Added gnutls_pubkey_import_privkey(), that will copy the public key from a gnutls_privkey_t structure.
-rw-r--r--lib/abstract_int.h9
-rw-r--r--lib/gnutls_privkey.c90
-rw-r--r--lib/gnutls_pubkey.c28
-rw-r--r--lib/includes/gnutls/abstract.h10
-rw-r--r--lib/libgnutls.map1
5 files changed, 135 insertions, 3 deletions
diff --git a/lib/abstract_int.h b/lib/abstract_int.h
new file mode 100644
index 0000000000..70fc880c1c
--- /dev/null
+++ b/lib/abstract_int.h
@@ -0,0 +1,9 @@
+#ifndef _ABSTRACT_INT_H
+# define _ABSTRACT_INT_H
+
+#include <gnutls/abstract.h>
+
+int _gnutls_privkey_get_public_mpis (gnutls_privkey_t key,
+ bigint_t * params, int *params_size);
+
+#endif
diff --git a/lib/gnutls_privkey.c b/lib/gnutls_privkey.c
index 86e45edd43..4dbd85f99d 100644
--- a/lib/gnutls_privkey.c
+++ b/lib/gnutls_privkey.c
@@ -35,6 +35,7 @@
#include <openpgp/openpgp_int.h>
#include <openpgp/gnutls_openpgp.h>
#include <gnutls_sig.h>
+#include <abstract_int.h>
struct gnutls_privkey_st
{
@@ -103,6 +104,95 @@ gnutls_privkey_get_pk_algorithm (gnutls_privkey_t key, unsigned int *bits)
}
+static int privkey_to_pubkey(gnutls_pk_algorithm_t pk,
+ const bigint_t * params, int params_size,
+ bigint_t *new_params, int* new_params_size)
+{
+ int ret, i;
+
+ switch(pk) {
+ case GNUTLS_PK_RSA:
+ if (*new_params_size < RSA_PUBLIC_PARAMS || params_size < RSA_PRIVATE_PARAMS)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ new_params[0] = _gnutls_mpi_copy(params[0]);
+ new_params[1] = _gnutls_mpi_copy(params[1]);
+
+ *new_params_size = RSA_PUBLIC_PARAMS;
+
+ if (new_params[0] == NULL || new_params[1] == NULL)
+ {
+ gnutls_assert();
+ ret = GNUTLS_E_MEMORY_ERROR;
+ goto cleanup;
+ }
+
+ break;
+ case GNUTLS_PK_DSA:
+ if (*new_params_size < DSA_PUBLIC_PARAMS || params_size < DSA_PRIVATE_PARAMS)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ new_params[0] = _gnutls_mpi_copy(params[0]);
+ new_params[1] = _gnutls_mpi_copy(params[1]);
+ new_params[2] = _gnutls_mpi_copy(params[2]);
+ new_params[3] = _gnutls_mpi_copy(params[3]);
+
+ *new_params_size = DSA_PUBLIC_PARAMS;
+
+ if (new_params[0] == NULL || new_params[1] == NULL ||
+ new_params[2] == NULL || new_params[3] == NULL)
+ {
+ gnutls_assert();
+ ret = GNUTLS_E_MEMORY_ERROR;
+ goto cleanup;
+ }
+
+ break;
+ default:
+ gnutls_assert();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ return 0;
+cleanup:
+ for (i=0;i<*new_params_size;i++)
+ _gnutls_mpi_release(new_params[i]);
+ return ret;
+}
+
+
+/* Returns the public key of the private key (if possible)
+ */
+int _gnutls_privkey_get_public_mpis (gnutls_privkey_t key,
+ bigint_t * params, int *params_size)
+{
+ int ret;
+
+ switch (key->type)
+ {
+ case GNUTLS_PRIVKEY_X509:
+ ret = privkey_to_pubkey( gnutls_privkey_get_pk_algorithm(key, NULL),
+ key->key.x509->params, key->key.x509->params_size,
+ params, params_size);
+ if (ret < 0)
+ {
+ gnutls_assert();
+ return ret;
+ }
+ default:
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ return 0;
+}
+
/**
* gnutls_privkey_init:
* @key: The structure to be initialized
diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c
index 7169aecb80..113d5a0da0 100644
--- a/lib/gnutls_pubkey.c
+++ b/lib/gnutls_pubkey.c
@@ -37,6 +37,7 @@
#include <gnutls_num.h>
#include <x509/common.h>
#include <x509_b64.h>
+#include <abstract_int.h>
#define PK_PEM_HEADER "PUBLIC KEY"
@@ -188,6 +189,33 @@ gnutls_pubkey_import_x509 (gnutls_pubkey_t key, gnutls_x509_crt_t crt,
}
/**
+ * gnutls_pubkey_import_privkey:
+ * @key: The public key
+ * @pkey: The private key
+ * @usage: GNUTLS_KEY_* key usage flags.
+ * @flags: should be zero
+ *
+ * This function will import the given public key to the abstract
+ * #gnutls_pubkey_t structure.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
+ * negative error value.
+ **/
+int
+gnutls_pubkey_import_privkey (gnutls_pubkey_t key, gnutls_privkey_t pkey,
+ unsigned int usage, unsigned int flags)
+{
+ key->pk_algorithm = gnutls_privkey_get_pk_algorithm (pkey, &key->bits);
+
+ key->key_usage = usage;
+
+ key->params_size = sizeof (key->params) / sizeof (key->params[0]);
+
+ return _gnutls_privkey_get_public_mpis (pkey, key->params,
+ &key->params_size);
+}
+
+/**
* gnutls_pubkey_get_preferred_hash_algorithm:
* @key: Holds the certificate
* @hash: The result of the call with the hash algorithm used for signature
diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h
index 2e68632b23..5fcbc3cd89 100644
--- a/lib/includes/gnutls/abstract.h
+++ b/lib/includes/gnutls/abstract.h
@@ -12,6 +12,9 @@
struct gnutls_pubkey_st;
typedef struct gnutls_pubkey_st *gnutls_pubkey_t;
+struct gnutls_privkey_st;
+typedef struct gnutls_privkey_st *gnutls_privkey_t;
+
int gnutls_pubkey_init (gnutls_pubkey_t * key);
void gnutls_pubkey_deinit (gnutls_pubkey_t key);
int gnutls_pubkey_get_pk_algorithm (gnutls_pubkey_t key, unsigned int *bits);
@@ -24,6 +27,10 @@ int gnutls_pubkey_import_openpgp (gnutls_pubkey_t pkey,
gnutls_openpgp_crt_t crt,
gnutls_openpgp_keyid_t keyid,
unsigned int flags);
+int
+gnutls_pubkey_import_privkey (gnutls_pubkey_t key, gnutls_privkey_t pkey,
+ unsigned int usage, unsigned int flags);
+
int gnutls_pubkey_get_preferred_hash_algorithm (gnutls_pubkey_t key,
gnutls_digest_algorithm_t *
@@ -78,9 +85,6 @@ gnutls_pubkey_get_verify_algorithm (gnutls_pubkey_t key,
/* Private key operations */
-struct gnutls_privkey_st;
-typedef struct gnutls_privkey_st *gnutls_privkey_t;
-
int gnutls_privkey_init (gnutls_privkey_t * key);
void gnutls_privkey_deinit (gnutls_privkey_t key);
int gnutls_privkey_get_pk_algorithm (gnutls_privkey_t key,
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 908da1585b..4ad0ab32b4 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -698,6 +698,7 @@ GNUTLS_2_12
gnutls_openpgp_crt_verify_hash;
gnutls_x509_privkey_sign_data2;
gnutls_pkcs11_privkey_sign_hash2;
+ gnutls_pubkey_import_privkey;
} GNUTLS_2_10;
GNUTLS_PRIVATE {