gnutls-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU gnutls branch, new, updated. gnutls_2_9_10-59-gc17f26a


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU gnutls branch, new, updated. gnutls_2_9_10-59-gc17f26a
Date: Sat, 22 May 2010 18:48:43 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU gnutls".

http://git.savannah.gnu.org/cgit/gnutls.git/commit/?id=c17f26a6835c94d5c8e03479490e15d00c247501

The branch, new has been updated
       via  c17f26a6835c94d5c8e03479490e15d00c247501 (commit)
       via  548da8184e5b117dc783e71a582347602173d302 (commit)
      from  37c20949a8300ecfe770ef6a9919442e27bdb016 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit c17f26a6835c94d5c8e03479490e15d00c247501
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat May 22 20:46:36 2010 +0200

    Added gnutls_pubkey_verify_hash(), gnutls_pubkey_get_verify_algorithm().

commit 548da8184e5b117dc783e71a582347602173d302
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat May 22 20:15:22 2010 +0200

    Added gnutls_pubkey_import_pkcs11(), gnutls_pubkey_import_rsa_raw(),
    gnutls_pubkey_import_dsa_raw(), gnutls_pkcs11_obj_export().

-----------------------------------------------------------------------

Summary of changes:
 NEWS                           |    8 +
 configure.ac                   |    2 +-
 lib/gnutls_pubkey.c            |  390 ++++++++++++++++++++++++++++++++--------
 lib/includes/gnutls/abstract.h |   18 ++-
 lib/includes/gnutls/pkcs11.h   |    3 +
 lib/libgnutls.map              |   10 +-
 lib/pkcs11.c                   |  281 ++++++++++++++++++++++++++---
 lib/pkcs11_int.h               |    5 +
 lib/x509/common.h              |    6 +
 lib/x509/verify.c              |   33 +---
 lib/x509/x509.c                |   36 +++-
 lib/x509/x509_int.h            |   10 +-
 src/pkcs11.c                   |   94 ++++++++---
 13 files changed, 734 insertions(+), 162 deletions(-)

diff --git a/NEWS b/NEWS
index 46e18e3..65b132a 100644
--- a/NEWS
+++ b/NEWS
@@ -34,6 +34,7 @@ 
pkcs11:token=Root%20CA%20Certificates;serial=1%3AROOTS%3ADEFAULT;model=1%2E0;man
 gnutls_certificate_set_server_retrieve_function: DEPRECATED
 gnutls_certificate_set_client_retrieve_function: DEPRECATED
 gnutls_sign_callback_set: DEPRECATED
+gnutls_pkcs11_type_get_name: ADDED
 gnutls_certificate_set_retrieve_function: ADDED
 gnutls_pkcs11_init: ADDED
 gnutls_pkcs11_deinit: ADDED
@@ -45,7 +46,9 @@ gnutls_pkcs11_obj_import_url: ADDED
 gnutls_pkcs11_obj_export_url: ADDED
 gnutls_pkcs11_obj_deinit: ADDED
 gnutls_pkcs11_obj_list_deinit: ADDED
+gnutls_pkcs11_obj_export: ADDED
 gnutls_pkcs11_obj_list_import_url: ADDED
+gnutls_pkcs11_obj_export: ADDED
 gnutls_x509_crt_import_pkcs11: ADDED
 gnutls_pkcs11_obj_get_type: ADDED
 gnutls_x509_crt_list_import_pkcs11: ADDED
@@ -85,9 +88,14 @@ gnutls_pubkey_get_pk_dsa_raw: ADDED
 gnutls_pubkey_export: ADDED
 gnutls_pubkey_get_key_id: ADDED
 gnutls_pubkey_get_key_usage: ADDED
+gnutls_pubkey_verify_hash: ADDED
+gnutls_pubkey_get_verify_algorithm: ADDED
 gnutls_pkcs11_type_get_name: ADDED
 gnutls_pubkey_import_pkcs11_url: ADDED
 gnutls_pubkey_import: ADDED
+gnutls_pubkey_import_pkcs11: ADDED
+gnutls_pubkey_import_dsa_raw: ADDED
+gnutls_pubkey_import_rsa_raw: ADDED
 gnutls_x509_crt_set_pubkey: ADDED
 gnutls_x509_crq_set_pubkey: ADDED
 
diff --git a/configure.ac b/configure.ac
index 2256081..51af883 100644
--- a/configure.ac
+++ b/configure.ac
@@ -205,7 +205,7 @@ AC_ARG_ENABLE([gcc-warnings],
 
 if test "$gl_gcc_warnings" = yes; then
   gl_WARN_ADD([-Werror], [WERROR_CFLAGS])
-  gl_WARN_ADD([-Wframe-larger-than=2100], [WSTACK_CFLAGS])
+  gl_WARN_ADD([-Wframe-larger-than=5120], [WSTACK_CFLAGS])
 
   nw="$nw -Wsystem-headers"         # Don't let system headers trigger warnings
   nw="$nw -Wc++-compat"             # We don't care about C++ compilers
diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c
index 985f473..d5a3cba 100644
--- a/lib/gnutls_pubkey.c
+++ b/lib/gnutls_pubkey.c
@@ -35,6 +35,9 @@
 #include <x509_int.h>
 #include <openpgp/openpgp_int.h>
 #include <pkcs11_int.h>
+#include <gnutls_num.h>
+#include <x509/common.h>
+#include <x509_b64.h>
 
 #define PK_PEM_HEADER "PUBLIC KEY"
 
@@ -181,6 +184,56 @@ int gnutls_pubkey_import_x509(gnutls_pubkey_t key, 
gnutls_x509_crt_t crt,
 }
 
 /**
+ * gnutls_pubkey_import_pkcs11:
+ * @key: The public key
+ * @obj: The parameters to be imported
+ * @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_pkcs11(gnutls_pubkey_t key,
+                               gnutls_pkcs11_obj_t obj,
+                               unsigned int flags)
+{
+       int ret;
+
+       ret = gnutls_pkcs11_obj_get_type(obj);
+       if (ret != GNUTLS_PKCS11_OBJ_PUBKEY) {
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+
+       key->key_usage = obj->key_usage;
+
+       switch (obj->pk_algorithm) {
+       case GNUTLS_PK_RSA:
+               ret = gnutls_pubkey_import_rsa_raw(key, &obj->pubkey[0],
+                                                  &obj->pubkey[1]);
+               break;
+       case GNUTLS_PK_DSA:
+               ret = gnutls_pubkey_import_dsa_raw(key, &obj->pubkey[0],
+                                                  &obj->pubkey[1],
+                                                  &obj->pubkey[2],
+                                                  &obj->pubkey[3]);
+               break;
+       default:
+               gnutls_assert();
+               return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+       }
+
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       return 0;
+}
+
+/**
  * gnutls_pubkey_import_openpgp:
  * @key: The public key
  * @crt: The certificate to be imported
@@ -356,7 +409,7 @@ gnutls_pubkey_get_key_id(gnutls_pubkey_t key, unsigned int 
flags,
 
 /**
  * gnutls_pubkey_get_pk_rsa_raw:
- * @crt: Holds the certificate
+ * @key: Holds the certificate
  * @m: will hold the modulus
  * @e: will hold the public exponent
  *
@@ -371,7 +424,6 @@ gnutls_pubkey_get_pk_rsa_raw(gnutls_pubkey_t key,
                             gnutls_datum_t * m, gnutls_datum_t * e)
 {
        int ret;
-       int i;
 
        if (key == NULL) {
                gnutls_assert();
@@ -401,7 +453,7 @@ gnutls_pubkey_get_pk_rsa_raw(gnutls_pubkey_t key,
 
 /**
  * gnutls_pubkey_get_pk_dsa_raw:
- * @crt: Holds the certificate
+ * @key: Holds the public key
  * @p: will hold the p
  * @q: will hold the q
  * @g: will hold the g
@@ -419,9 +471,6 @@ gnutls_pubkey_get_pk_dsa_raw(gnutls_pubkey_t key,
                             gnutls_datum_t * g, gnutls_datum_t * y)
 {
        int ret;
-       bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
-       int params_size = MAX_PUBLIC_PARAMS_SIZE;
-       int i;
 
        if (key == NULL) {
                gnutls_assert();
@@ -486,8 +535,8 @@ gnutls_pubkey_get_pk_dsa_raw(gnutls_pubkey_t key,
  * negative error value.
  **/
 int gnutls_pubkey_import(gnutls_pubkey_t key,
-                    const gnutls_datum_t * data,
-                    gnutls_x509_crt_fmt_t format)
+                        const gnutls_datum_t * data,
+                        gnutls_x509_crt_fmt_t format)
 {
        int result = 0, need_free = 0;
        gnutls_datum_t _data;
@@ -532,10 +581,10 @@ int gnutls_pubkey_import(gnutls_pubkey_t key,
                goto cleanup;
        }
 
-       result = asn1_der_decoding (&spk, _data.data, _data.size, NULL);
+       result = asn1_der_decoding(&spk, _data.data, _data.size, NULL);
        if (result != ASN1_SUCCESS) {
-               gnutls_assert ();
-               result = _gnutls_asn2err (result);
+               gnutls_assert();
+               result = _gnutls_asn2err(result);
                goto cleanup;
        }
 
@@ -546,15 +595,15 @@ int gnutls_pubkey_import(gnutls_pubkey_t key,
                gnutls_assert();
                goto cleanup;
        }
-       
+
        /* this has already been called by get_asn_mpis() thus it cannot
         * fail.
         */
-       key->pk_algorithm = _gnutls_x509_get_pk_algorithm (spk, "", NULL);
+       key->pk_algorithm = _gnutls_x509_get_pk_algorithm(spk, "", NULL);
 
        result = 0;
 
-cleanup:
+      cleanup:
        asn1_delete_structure(&spk);
 
        if (need_free)
@@ -562,61 +611,77 @@ cleanup:
        return result;
 }
 
-int gnutls_x509_crt_set_pubkey (gnutls_x509_crt_t crt,
-                              gnutls_pubkey_t key)
+/**
+ * gnutls_x509_crt_set_pubkey:
+ * @crt: should contain a #gnutls_x509_crt_t structure
+ * @key: holds a public key
+ *
+ * This function will set the public parameters from the given public
+ * key to the request. 
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
+ *   negative error value.
+ **/
+int gnutls_x509_crt_set_pubkey(gnutls_x509_crt_t crt, gnutls_pubkey_t key)
 {
-  int result;
+       int result;
 
-  if (crt == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
-    }
+       if (crt == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
 
-  result = _gnutls_x509_encode_and_copy_PKI_params (crt->cert,
-                                                   
"tbsCertificate.subjectPublicKeyInfo",
-                                                   key->pk_algorithm,
-                                                   key->params,
-                                                   key->params_size);
+       result = _gnutls_x509_encode_and_copy_PKI_params(crt->cert,
+                                                        
"tbsCertificate.subjectPublicKeyInfo",
+                                                        key->pk_algorithm,
+                                                        key->params,
+                                                        key->params_size);
 
-  if (result < 0)
-    {
-      gnutls_assert ();
-      return result;
-    }
+       if (result < 0) {
+               gnutls_assert();
+               return result;
+       }
 
        if (key->key_usage)
                gnutls_x509_crt_set_key_usage(crt, key->key_usage);
 
-  return 0;
+       return 0;
 }
 
-int gnutls_x509_crq_set_pubkey (gnutls_x509_crq_t crq,
-                              gnutls_pubkey_t key)
+/**
+ * gnutls_x509_crq_set_pubkey:
+ * @crq: should contain a #gnutls_x509_crq_t structure
+ * @key: holds a public key
+ *
+ * This function will set the public parameters from the given public
+ * key to the request. 
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
+ *   negative error value.
+ **/
+int gnutls_x509_crq_set_pubkey(gnutls_x509_crq_t crq, gnutls_pubkey_t key)
 {
-  int result;
+       int result;
 
-  if (crq == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
-    }
+       if (crq == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
 
-  result = _gnutls_x509_encode_and_copy_PKI_params
-    (crq->crq,
-     "certificationRequestInfo.subjectPKInfo",
-     key->pk_algorithm, key->params, key->params_size);
+       result = _gnutls_x509_encode_and_copy_PKI_params
+           (crq->crq,
+            "certificationRequestInfo.subjectPKInfo",
+            key->pk_algorithm, key->params, key->params_size);
 
-  if (result < 0)
-    {
-      gnutls_assert ();
-      return result;
-    }
+       if (result < 0) {
+               gnutls_assert();
+               return result;
+       }
 
        if (key->key_usage)
                gnutls_x509_crq_set_key_usage(crq, key->key_usage);
 
-  return 0;
+       return 0;
 }
 
 /**
@@ -629,42 +694,211 @@ int gnutls_x509_crq_set_pubkey (gnutls_x509_crq_t crq,
  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
  *   negative error value.
  **/
-int
-gnutls_pubkey_set_key_usage (gnutls_pubkey_t key, unsigned int usage)
+int gnutls_pubkey_set_key_usage(gnutls_pubkey_t key, unsigned int usage)
 {
        key->key_usage = usage;
-       
+
        return 0;
 }
 
-int gnutls_pubkey_import_pkcs11_url( gnutls_pubkey_t key, const char* url)
+int gnutls_pubkey_import_pkcs11_url(gnutls_pubkey_t key, const char *url)
 {
-    gnutls_pkcs11_obj_t pcrt;
-    int ret;
-    
-    ret = gnutls_pkcs11_obj_init ( &pcrt);
-    if (ret < 0) {
-        gnutls_assert();
-        return ret;
-    }
+       gnutls_pkcs11_obj_t pcrt;
+       int ret;
 
-    ret = gnutls_pkcs11_obj_import_url (pcrt, url);
-    if (ret < 0) {
-        gnutls_assert();
-        goto cleanup;
-    }
+       ret = gnutls_pkcs11_obj_init(&pcrt);
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
 
-    ret = gnutls_pubkey_import(key, &pcrt->raw, GNUTLS_X509_FMT_DER);
-    if (ret < 0) {
-        gnutls_assert();
-        goto cleanup;
+       ret = gnutls_pkcs11_obj_import_url(pcrt, url);
+       if (ret < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       ret = gnutls_pubkey_import_pkcs11(key, pcrt, 0);
+       if (ret < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       ret = 0;
+      cleanup:
+
+       gnutls_pkcs11_obj_deinit(pcrt);
+
+       return ret;
+}
+
+/**
+ * gnutls_pubkey_import_rsa_raw:
+ * @key: Is a structure will hold the parameters
+ * @m: holds the modulus
+ * @e: holds the public exponent
+ *
+ * This function will replace the parameters in the given structure.
+ * The new parameters should be stored in the appropriate
+ * gnutls_datum.
+ *
+ * Returns: %GNUTLS_E_SUCCESS on success, or an negative error code.
+ **/
+int
+gnutls_pubkey_import_rsa_raw(gnutls_pubkey_t key,
+                            const gnutls_datum_t * m,
+                            const gnutls_datum_t * e)
+{
+       size_t siz = 0;
+
+       if (key == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+
+       siz = m->size;
+       if (_gnutls_mpi_scan_nz(&key->params[0], m->data, siz)) {
+               gnutls_assert();
+               return GNUTLS_E_MPI_SCAN_FAILED;
+       }
+
+       siz = e->size;
+       if (_gnutls_mpi_scan_nz(&key->params[1], e->data, siz)) {
+               gnutls_assert();
+               _gnutls_mpi_release(&key->params[0]);
+               return GNUTLS_E_MPI_SCAN_FAILED;
+       }
+
+       key->params_size = RSA_PUBLIC_PARAMS;
+       key->pk_algorithm = GNUTLS_PK_RSA;
+
+       return 0;
+}
+
+/**
+ * gnutls_pubkey_import_dsa_raw:
+ * @key: The structure to store the parsed key
+ * @p: holds the p
+ * @q: holds the q
+ * @g: holds the g
+ * @y: holds the y
+ *
+ * This function will convert the given DSA raw parameters to the
+ * native #gnutls_pubkey_t format.  The output will be stored
+ * in @key.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_pubkey_import_dsa_raw(gnutls_pubkey_t key,
+                            const gnutls_datum_t * p,
+                            const gnutls_datum_t * q,
+                            const gnutls_datum_t * g,
+                            const gnutls_datum_t * y)
+{
+       size_t siz = 0;
+
+       if (key == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+
+       siz = p->size;
+       if (_gnutls_mpi_scan_nz(&key->params[0], p->data, siz)) {
+               gnutls_assert();
+               return GNUTLS_E_MPI_SCAN_FAILED;
+       }
+
+       siz = q->size;
+       if (_gnutls_mpi_scan_nz(&key->params[1], q->data, siz)) {
+               gnutls_assert();
+               _gnutls_mpi_release(&key->params[0]);
+               return GNUTLS_E_MPI_SCAN_FAILED;
+       }
+
+       siz = g->size;
+       if (_gnutls_mpi_scan_nz(&key->params[2], g->data, siz)) {
+               gnutls_assert();
+               _gnutls_mpi_release(&key->params[1]);
+               _gnutls_mpi_release(&key->params[0]);
+               return GNUTLS_E_MPI_SCAN_FAILED;
+       }
+
+       siz = y->size;
+       if (_gnutls_mpi_scan_nz(&key->params[3], y->data, siz)) {
+               gnutls_assert();
+               _gnutls_mpi_release(&key->params[2]);
+               _gnutls_mpi_release(&key->params[1]);
+               _gnutls_mpi_release(&key->params[0]);
+               return GNUTLS_E_MPI_SCAN_FAILED;
+       }
+
+       key->params_size = DSA_PUBLIC_PARAMS;
+       key->pk_algorithm = GNUTLS_PK_DSA;
+
+       return 0;
+
+}
+
+/**
+ * gnutls_pubkey_verify_hash:
+ * @key: Holds the certificate
+ * @flags: should be 0 for now
+ * @hash: holds the hash digest to be verified
+ * @signature: contains the signature
+ *
+ * This function will verify the given signed digest, using the
+ * parameters from the certificate.
+ *
+ * Returns: In case of a verification failure 0 is returned, and 1 on
+ * success.
+ **/
+int
+gnutls_pubkey_verify_hash (gnutls_pubkey_t key, unsigned int flags,
+                            const gnutls_datum_t * hash,
+                            const gnutls_datum_t * signature)
+{
+  int ret;
+
+  if (key == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
     }
-    
-    ret = 0;
-cleanup:
 
-    gnutls_pkcs11_obj_deinit(pcrt);
-    
-    return ret;
+   ret =
+    pubkey_verify_sig (NULL, hash, signature, key->pk_algorithm,
+               key->params, key->params_size);
+
+  return ret;
 }
 
+/**
+ * gnutls_pubkey_get_verify_algorithm:
+ * @key: Holds the certificate
+ * @signature: contains the signature
+ * @hash: The result of the call with the hash algorithm used for signature
+ *
+ * This function will read the certifcate and the signed data to
+ * determine the hash algorithm used to generate the signature.
+ *
+ * Returns: the 0 if the hash algorithm is found. A negative value is
+ * returned on error.
+ **/
+int
+gnutls_pubkey_get_verify_algorithm (gnutls_pubkey_t key,
+                                     const gnutls_datum_t * signature,
+                                     gnutls_digest_algorithm_t * hash)
+{
+  if (key == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  return _gnutls_x509_verify_algorithm ((gnutls_mac_algorithm_t *) hash,
+                       signature, key->pk_algorithm, key->params,
+                       key->params_size);
+
+}
diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h
index 8305f9c..5e14890 100644
--- a/lib/includes/gnutls/abstract.h
+++ b/lib/includes/gnutls/abstract.h
@@ -17,6 +17,7 @@ void gnutls_pubkey_deinit (gnutls_pubkey_t key);
 int gnutls_pubkey_get_pk_algorithm (gnutls_pubkey_t key, unsigned int* bits);
 
 int gnutls_pubkey_import_x509(gnutls_pubkey_t pkey, gnutls_x509_crt_t crt, 
unsigned int flags);
+int gnutls_pubkey_import_pkcs11(gnutls_pubkey_t pkey, gnutls_pkcs11_obj_t crt, 
unsigned int flags);
 int gnutls_pubkey_import_openpgp(gnutls_pubkey_t pkey,
                                 gnutls_openpgp_crt_t crt,
                                 gnutls_openpgp_keyid_t keyid,
@@ -45,7 +46,14 @@ int gnutls_pubkey_import (gnutls_pubkey_t key,
 
 
 int gnutls_pubkey_import_pkcs11_url( gnutls_pubkey_t key, const char* url);
-
+int gnutls_pubkey_import_dsa_raw (gnutls_pubkey_t key,
+                                   const gnutls_datum_t * p,
+                                   const gnutls_datum_t * q,
+                                   const gnutls_datum_t * g,
+                                   const gnutls_datum_t * y);
+int gnutls_pubkey_import_rsa_raw (gnutls_pubkey_t pubkey,
+                             const gnutls_datum_t * m,
+                             const gnutls_datum_t * e);
 
 int gnutls_x509_crt_set_pubkey (gnutls_x509_crt_t crt,
                               gnutls_pubkey_t key);
@@ -53,6 +61,14 @@ int gnutls_x509_crt_set_pubkey (gnutls_x509_crt_t crt,
 int gnutls_x509_crq_set_pubkey (gnutls_x509_crq_t crq,
                               gnutls_pubkey_t key);
 
+int
+gnutls_pubkey_verify_hash (gnutls_pubkey_t key, unsigned int flags,
+                            const gnutls_datum_t * hash,
+                            const gnutls_datum_t * signature);
+int
+gnutls_pubkey_get_verify_algorithm (gnutls_pubkey_t key,
+                                     const gnutls_datum_t * signature,
+                                     gnutls_digest_algorithm_t * hash);
 
 /* Private key operations */
 
diff --git a/lib/includes/gnutls/pkcs11.h b/lib/includes/gnutls/pkcs11.h
index b5d1d6e..cc2f861 100644
--- a/lib/includes/gnutls/pkcs11.h
+++ b/lib/includes/gnutls/pkcs11.h
@@ -138,6 +138,9 @@ int gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t, 
const char * url);
 int gnutls_pkcs11_obj_export_url (gnutls_pkcs11_obj_t, char** url);
 void gnutls_pkcs11_obj_deinit ( gnutls_pkcs11_obj_t);
 
+int gnutls_pkcs11_obj_export(gnutls_pkcs11_obj_t obj,
+                    void *output_data, size_t * output_data_size);
+
 /**
  * @brief Release array of certificate references.
  * @param certificates Array to free.
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index cfe30f2..2bdf696 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -634,6 +634,8 @@ GNUTLS_2_11
        gnutls_pkcs11_privkey_sign_data;
        gnutls_pkcs11_privkey_sign_hash;
        gnutls_pkcs11_privkey_decrypt_data;
+       gnutls_pkcs11_obj_export;
+       gnutls_pkcs11_type_get_name;
 
        gnutls_privkey_init;
        gnutls_privkey_deinit;
@@ -659,9 +661,13 @@ GNUTLS_2_11
        gnutls_pubkey_export;
        gnutls_pubkey_get_key_id;
        gnutls_pubkey_get_key_usage;
-       gnutls_pkcs11_type_get_name;
-
+       gnutls_pubkey_import_pkcs11;
+       gnutls_pubkey_import_dsa_raw;
+       gnutls_pubkey_import_rsa_raw;
        gnutls_pubkey_import_pkcs11_url;
+       gnutls_pubkey_get_verify_algorithm;
+       gnutls_pubkey_verify_hash;
+       gnutls_pkcs11_obj_export;
        gnutls_pubkey_import;
        gnutls_x509_crt_set_pubkey;
        gnutls_x509_crq_set_pubkey;
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
index 9eaeab6..5121e91 100644
--- a/lib/pkcs11.c
+++ b/lib/pkcs11.c
@@ -447,6 +447,16 @@ size_t l;
         }
     }
 
+    if ((p1=strstr(url, "objecttype="))!= NULL) {
+        p1+=sizeof("objecttype=")-1;
+        l=sizeof (info->model);
+
+        ret = unescape_string (info->type,
+                        p1, &l, ';');
+        if (ret < 0) {
+                goto cleanup;
+        }
+    }
 
     if (((p1=strstr(url, ";id="))!= NULL) || ((p1=strstr(url, ":id="))!= 
NULL)) {
         p1+=sizeof(";id=")-1;
@@ -633,9 +643,52 @@ int gnutls_pkcs11_obj_init(gnutls_pkcs11_obj_t * crt)
  **/
 void gnutls_pkcs11_obj_deinit(gnutls_pkcs11_obj_t crt)
 {
+    _gnutls_free_datum(&crt->raw);
     free(crt);
 }
 
+/**
+ * gnutls_pkcs11_obj_export:
+ * @key: Holds the object
+ * @output_data: will contain a certificate PEM or DER encoded
+ * @output_data_size: holds the size of output_data (and will be
+ *   replaced by the actual size of parameters)
+ *
+ * This function will export the pkcs11 object data. It is normal
+ * for PKCS #11 data to be inaccesible and in that case 
%GNUTLS_E_INVALID_REQUEST
+ * will be returned.
+ *
+ * If the buffer provided is not long enough to hold the output, then
+ * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
+ * be returned.
+ *
+ * If the structure is PEM encoded, it will have a header
+ * of "BEGIN CERTIFICATE".
+ *
+ * Return value: In case of failure a negative value will be
+ *   returned, and 0 on success.
+ **/
+int
+gnutls_pkcs11_obj_export(gnutls_pkcs11_obj_t obj,
+                    void *output_data,
+                    size_t * output_data_size)
+{
+       if (obj == NULL || obj->raw.data == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+
+    if (output_data==NULL || *output_data_size < obj->raw.size) {
+        *output_data_size = obj->raw.size;
+        gnutls_assert();
+        return GNUTLS_E_SHORT_MEMORY_BUFFER;
+    }
+    *output_data_size = obj->raw.size;
+    
+    memcpy(output_data, obj->raw.data, obj->raw.size);
+    return 0;
+}
+
 static void terminate_string(unsigned char *str, size_t len)
 {
     unsigned char *ptr = str + len - 1;
@@ -740,7 +793,7 @@ static int pkcs11_obj_import(unsigned int class, 
gnutls_pkcs11_obj_t crt, const
 {
     char *s;
     int ret;
-    
+
     switch(class) {
         case CKO_CERTIFICATE:
             crt->type = GNUTLS_PKCS11_OBJ_X509_CRT;
@@ -802,16 +855,176 @@ static int pkcs11_obj_import(unsigned int class, 
gnutls_pkcs11_obj_t crt, const
     return 0;
 }
 
+static int pkcs11_obj_import_pubkey(pakchois_session_t *pks, 
ck_object_handle_t obj, 
+    gnutls_pkcs11_obj_t crt, const gnutls_datum_t * id, 
+    const gnutls_datum_t* label, struct ck_token_info* tinfo)
+{
+
+    struct ck_attribute a[4];
+    ck_key_type_t key_type;
+    opaque tmp1[2048];
+    opaque tmp2[2048];
+    int ret;
+    unsigned int tval;
+
+    a[0].type = CKA_KEY_TYPE;
+    a[0].value = &key_type;
+    a[0].value_len = sizeof(key_type);
+
+    if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
+        switch(key_type) {
+            case CKK_RSA:
+                a[0].type = CKA_MODULUS;
+                a[0].value = tmp1;
+                a[0].value_len = sizeof(tmp1);
+                a[1].type = CKA_PUBLIC_EXPONENT;
+                a[1].value = tmp2;
+                a[1].value_len = sizeof(tmp2);
+
+                if (pakchois_get_attribute_value(pks, obj, a, 2) == CKR_OK) {
+
+                    ret = _gnutls_set_datum(&crt->pubkey[0], a[0].value, 
a[0].value_len);
+                    
+                    if (ret >= 0)
+                        ret = _gnutls_set_datum(&crt->pubkey[1], a[1].value, 
a[1].value_len);
+                    
+                    if (ret < 0) {
+                        gnutls_assert();
+                        _gnutls_free_datum(&crt->pubkey[1]);
+                        _gnutls_free_datum(&crt->pubkey[0]);
+                        return GNUTLS_E_MEMORY_ERROR;
+                    }
+                } else {
+                    gnutls_assert();
+                    return GNUTLS_E_PKCS11_ERROR;
+                }
+                crt->pk_algorithm = GNUTLS_PK_RSA;
+                break;
+            case CKK_DSA:
+                a[0].type = CKA_PRIME;
+                a[0].value = tmp1;
+                a[0].value_len = sizeof(tmp1);
+                a[1].type = CKA_SUBPRIME;
+                a[1].value = tmp2;
+                a[1].value_len = sizeof(tmp2);
+            
+                if (pakchois_get_attribute_value(pks, obj, a, 2) == CKR_OK) {
+                    ret = _gnutls_set_datum(&crt->pubkey[0], a[0].value, 
a[0].value_len);
+                    
+                    if (ret >= 0)
+                        ret = _gnutls_set_datum(&crt->pubkey[1], a[1].value, 
a[1].value_len);
+                    
+                    if (ret < 0) {
+                        gnutls_assert();
+                        _gnutls_free_datum(&crt->pubkey[1]);
+                        _gnutls_free_datum(&crt->pubkey[0]);
+                        return GNUTLS_E_MEMORY_ERROR;
+                    }
+                } else {
+                    gnutls_assert();
+                    return GNUTLS_E_PKCS11_ERROR;
+                }
+
+                a[0].type = CKA_BASE;
+                a[0].value = tmp1;
+                a[0].value_len = sizeof(tmp1);
+                a[1].type = CKA_VALUE;
+                a[1].value = tmp2;
+                a[1].value_len = sizeof(tmp2);
+            
+                if (pakchois_get_attribute_value(pks, obj, a, 2) == CKR_OK) {
+                    ret = _gnutls_set_datum(&crt->pubkey[2], a[0].value, 
a[0].value_len);
+                    
+                    if (ret >= 0)
+                        ret = _gnutls_set_datum(&crt->pubkey[3], a[1].value, 
a[1].value_len);
+                    
+                    if (ret < 0) {
+                        gnutls_assert();
+                        _gnutls_free_datum(&crt->pubkey[0]);
+                        _gnutls_free_datum(&crt->pubkey[1]);
+                        _gnutls_free_datum(&crt->pubkey[2]);
+                        _gnutls_free_datum(&crt->pubkey[3]);
+                        return GNUTLS_E_MEMORY_ERROR;
+                    }
+                } else {
+                    gnutls_assert();
+                    return GNUTLS_E_PKCS11_ERROR;
+                }
+                crt->pk_algorithm = GNUTLS_PK_RSA;
+                break;
+            default:
+                gnutls_assert();
+                return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+        }   
+    }
+    
+    /* read key usage flags */
+    a[0].type = CKA_ENCRYPT;
+    a[0].value = &tval;
+    a[0].value_len = sizeof(tval);
+
+    if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
+        if (tval != 0) {
+            crt->key_usage |= GNUTLS_KEY_DATA_ENCIPHERMENT;
+        }
+    }
+
+    a[0].type = CKA_VERIFY;
+    a[0].value = &tval;
+    a[0].value_len = sizeof(tval);
+
+    if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
+        if (tval != 0) {
+            crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE| \
+            
GNUTLS_KEY_KEY_CERT_SIGN|GNUTLS_KEY_CRL_SIGN|GNUTLS_KEY_NON_REPUDIATION;
+        }
+    }
+
+    a[0].type = CKA_VERIFY_RECOVER;
+    a[0].value = &tval;
+    a[0].value_len = sizeof(tval);
+
+    if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
+        if (tval != 0) {
+            crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE| \
+            
GNUTLS_KEY_KEY_CERT_SIGN|GNUTLS_KEY_CRL_SIGN|GNUTLS_KEY_NON_REPUDIATION;
+        }
+    }
+
+    a[0].type = CKA_DERIVE;
+    a[0].value = &tval;
+    a[0].value_len = sizeof(tval);
+
+    if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
+        if (tval != 0) {
+            crt->key_usage |= GNUTLS_KEY_KEY_AGREEMENT;
+        }
+    }
+
+    a[0].type = CKA_WRAP;
+    a[0].value = &tval;
+    a[0].value_len = sizeof(tval);
+
+    if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
+        if (tval != 0) {
+            crt->key_usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
+        }
+    }
+
+    return pkcs11_obj_import(CKO_PUBLIC_KEY, crt, NULL, id, label, tinfo);
+}
+
+
 
-static int find_cert_url(pakchois_session_t *pks, struct token_info *info, 
void* input)
+static int find_obj_url(pakchois_session_t *pks, struct token_info *info, 
void* input)
 {
     struct url_find_data_st* find_data = input;
     struct ck_attribute a[4];
     ck_object_class_t class;
-    ck_certificate_type_t type;
+    ck_certificate_type_t type = -1;
     ck_rv_t rv;
     ck_object_handle_t obj;
-    unsigned long count;
+    unsigned long count, a_vals;
     int found = 0, ret;
     opaque* cert_data = NULL;
     char label_tmp[PKCS11_LABEL_SIZE];
@@ -843,10 +1056,20 @@ static int find_cert_url(pakchois_session_t *pks, struct 
token_info *info, void*
             return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
     }
 
+    class = CKO_CERTIFICATE; /* default  */
+
     if (find_data->crt->info.type[0] != 0) {
-        if (strcmp(find_data->crt->info.type, "cert") != 0) {
-            gnutls_assert();
-            return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+        if (strcmp(find_data->crt->info.type, "cert") == 0) {
+            class = CKO_CERTIFICATE;
+            type = CKC_X_509;
+        } else if (strcmp(find_data->crt->info.type, "public") == 0) {
+            class = CKO_PUBLIC_KEY;
+        } else if (strcmp(find_data->crt->info.type, "private") == 0) {
+            class = CKO_PRIVATE_KEY;
+        } else if (strcmp(find_data->crt->info.type, "secretkey") == 0) {
+            class = CKO_SECRET_KEY;
+        } else if (strcmp(find_data->crt->info.type, "data") == 0) {
+            class = CKO_DATA;
         }
     }
 
@@ -858,22 +1081,26 @@ static int find_cert_url(pakchois_session_t *pks, struct 
token_info *info, void*
         return GNUTLS_E_MEMORY_ERROR;
     }
     
-    /* Find objects with cert class and X.509 cert type. */
-    class = CKO_CERTIFICATE;
-    type = CKC_X_509;
+    /* Find objects with given class and type */
 
     a[0].type = CKA_CLASS;
     a[0].value = &class;
     a[0].value_len = sizeof class;
-    a[1].type = CKA_CERTIFICATE_TYPE;
-    a[1].value = &type;
-    a[1].value_len = sizeof type;
-    a[2].type = CKA_ID;
-    a[2].value = find_data->crt->info.certid_raw;
-    a[2].value_len = find_data->crt->info.certid_raw_size;
 
-        
-    rv = pakchois_find_objects_init(pks, a, 3);
+    a[1].type = CKA_ID;
+    a[1].value = find_data->crt->info.certid_raw;
+    a[1].value_len = find_data->crt->info.certid_raw_size;
+    
+    a_vals = 2;
+    
+    if (type != -1) {
+        a[2].type = CKA_CERTIFICATE_TYPE;
+        a[2].value = &type;
+        a[2].value_len = sizeof type;
+        a_vals++;
+    }
+
+    rv = pakchois_find_objects_init(pks, a, a_vals);
     if (rv != CKR_OK) {
         gnutls_assert();
         _gnutls_debug_log("pk11: FindObjectsInit failed.\n");
@@ -896,7 +1123,11 @@ static int find_cert_url(pakchois_session_t *pks, struct 
token_info *info, void*
             gnutls_datum_t data = { a[0].value, a[0].value_len };
             gnutls_datum_t label = { a[1].value, a[1].value_len };
             
-            ret = pkcs11_obj_import(CKO_CERTIFICATE, find_data->crt, &data, 
&id, &label, &info->tinfo);
+            if (class == CKO_PUBLIC_KEY) {
+                ret = pkcs11_obj_import_pubkey(pks, obj, find_data->crt, &id, 
&label, &info->tinfo);
+            } else {
+                ret = pkcs11_obj_import(class, find_data->crt, &data, &id, 
&label, &info->tinfo);
+            }
             if (ret < 0) {
                 gnutls_assert();
                 goto cleanup;
@@ -951,7 +1182,7 @@ int gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t 
cert, const char * url)
         return ret;
     }
 
-    ret = _pkcs11_traverse_tokens(find_cert_url, &find_data, 0);
+    ret = _pkcs11_traverse_tokens(find_obj_url, &find_data, 0);
     if (ret < 0) {
         gnutls_assert();
         return ret;
@@ -1218,7 +1449,6 @@ static int find_privkeys(pakchois_session_t *pks, struct 
token_info* info, struc
     ck_object_handle_t obj;
     unsigned long count, current;
     char certid_tmp[PKCS11_ID_SIZE];
-    int ret;
 
     class = CKO_PRIVATE_KEY;
 
@@ -1490,7 +1720,11 @@ static int find_objs(pakchois_session_t *pks, struct 
token_info *info, void* inp
                 goto fail;
             }
 
-            ret = pkcs11_obj_import(class, 
find_data->p_list[find_data->current], &value, &id, &label, &info->tinfo);
+           if (class == CKO_PUBLIC_KEY) {
+                ret = pkcs11_obj_import_pubkey(pks, obj, 
find_data->p_list[find_data->current], &id, &label, &info->tinfo);
+            } else {
+                ret = pkcs11_obj_import(class, 
find_data->p_list[find_data->current], &value, &id, &label, &info->tinfo);
+            }
             if (ret < 0) {
                 gnutls_assert();
                 goto fail;
@@ -1706,9 +1940,6 @@ static int find_flags(pakchois_session_t *pks, struct 
token_info *info, void* in
  **/
 int gnutls_pkcs11_token_get_flags(const char* url, unsigned int *flags)
 {
-    const char* str;
-    size_t len;
-    
     struct flags_find_data_st find_data;
     int ret;
 
diff --git a/lib/pkcs11_int.h b/lib/pkcs11_int.h
index 86cbba1..6e1b3ac 100644
--- a/lib/pkcs11_int.h
+++ b/lib/pkcs11_int.h
@@ -33,6 +33,11 @@ struct gnutls_pkcs11_obj_st {
     gnutls_datum_t raw;
     gnutls_pkcs11_obj_type_t type;
     struct pkcs11_url_info info;
+    
+    /* only when pubkey */
+    gnutls_datum_t pubkey[MAX_PUBLIC_PARAMS_SIZE];
+    gnutls_pk_algorithm pk_algorithm;
+    unsigned int key_usage;
 };
 
 /* thus function is called for every token in the traverse_tokens
diff --git a/lib/x509/common.h b/lib/x509/common.h
index bf73cb9..2892fb6 100644
--- a/lib/x509/common.h
+++ b/lib/x509/common.h
@@ -137,4 +137,10 @@ int _gnutls_get_key_id (gnutls_pk_algorithm_t pk, 
bigint_t* params, int params_s
 
 void _asnstr_append_name(char* name, size_t name_size, const char* part1, 
const char* part2);
 
+int pubkey_verify_sig (const gnutls_datum_t * tbs,
+           const gnutls_datum_t * hash,
+           const gnutls_datum_t * signature,
+           gnutls_pk_algorithm_t pk, bigint_t * issuer_params,
+           int issuer_params_size);
+
 #endif
diff --git a/lib/x509/verify.c b/lib/x509/verify.c
index 569f4a4..b74c06f 100644
--- a/lib/x509/verify.c
+++ b/lib/x509/verify.c
@@ -823,8 +823,8 @@ dsa_verify_sig (const gnutls_datum_t * text,
 /* Verifies the signature data, and returns 0 if not verified,
  * or 1 otherwise.
  */
-static int
-verify_sig (const gnutls_datum_t * tbs,
+int
+pubkey_verify_sig (const gnutls_datum_t * tbs,
            const gnutls_datum_t * hash,
            const gnutls_datum_t * signature,
            gnutls_pk_algorithm_t pk, bigint_t * issuer_params,
@@ -865,42 +865,25 @@ verify_sig (const gnutls_datum_t * tbs,
 int
 _gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash,
                               const gnutls_datum_t * signature,
-                              const gnutls_x509_crt_t issuer)
+                              gnutls_pk_algorithm pk,
+                              bigint_t* issuer_params, unsigned int 
issuer_params_size)
 {
-  bigint_t issuer_params[MAX_PUBLIC_PARAMS_SIZE];
   opaque digest[MAX_HASH_SIZE];
   gnutls_datum_t decrypted;
-  int issuer_params_size;
   int digest_size;
-  int ret, i;
+  int ret;
 
-  switch (gnutls_x509_crt_get_pk_algorithm (issuer, NULL))
+  switch(pk)
     {
     case GNUTLS_PK_DSA:
       if (hash)
        *hash = GNUTLS_MAC_SHA1;
       return 0;
-
     case GNUTLS_PK_RSA:
-      issuer_params_size = MAX_PUBLIC_PARAMS_SIZE;
-      ret =
-       _gnutls_x509_crt_get_mpis (issuer, issuer_params,
-                                  &issuer_params_size);
-      if (ret < 0)
-       {
-         gnutls_assert ();
-         return ret;
-       }
-
       ret =
        _gnutls_pkcs1_rsa_decrypt (&decrypted, signature,
                                   issuer_params, issuer_params_size, 1);
 
-      /* release allocated mpis */
-      for (i = 0; i < issuer_params_size; i++)
-       {
-         _gnutls_mpi_release (&issuer_params[i]);
-       }
 
       if (ret < 0)
        {
@@ -960,7 +943,7 @@ _gnutls_x509_verify_signature (const gnutls_datum_t * tbs,
     }
 
   ret =
-    verify_sig (tbs, hash, signature,
+    pubkey_verify_sig (tbs, hash, signature,
                gnutls_x509_crt_get_pk_algorithm (issuer, NULL),
                issuer_params, issuer_params_size);
   if (ret < 0)
@@ -991,7 +974,7 @@ _gnutls_x509_privkey_verify_signature (const gnutls_datum_t 
* tbs,
 {
   int ret;
 
-  ret = verify_sig (tbs, NULL, signature, issuer->pk_algorithm,
+  ret = pubkey_verify_sig (tbs, NULL, signature, issuer->pk_algorithm,
                    issuer->params, issuer->params_size);
   if (ret < 0)
     {
diff --git a/lib/x509/x509.c b/lib/x509/x509.c
index 4244f93..0e00b41 100644
--- a/lib/x509/x509.c
+++ b/lib/x509/x509.c
@@ -2193,11 +2193,11 @@ int
 _gnutls_get_key_id (gnutls_pk_algorithm_t pk, bigint_t* params, int 
params_size,
                   unsigned char *output_data, size_t * output_data_size)
 {
-  int i, result = 0;
+  int result = 0;
   gnutls_datum_t der = { NULL, 0 };
   digest_hd_st hd;
 
-  if (output_data==NULL || *output_data_size < 0)
+  if (output_data==NULL || *output_data_size < 20)
     {
       gnutls_assert();
       *output_data_size = 20;
@@ -2253,8 +2253,6 @@ rsadsa_get_key_id (gnutls_x509_crt_t crt, int pk,
   bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
   int params_size = MAX_PUBLIC_PARAMS_SIZE;
   int i, result = 0;
-  gnutls_datum_t der = { NULL, 0 };
-  digest_hd_st hd;
 
   result = _gnutls_x509_crt_get_mpis (crt, params, &params_size);
   if (result < 0)
@@ -2506,14 +2504,37 @@ gnutls_x509_crt_get_verify_algorithm (gnutls_x509_crt_t 
crt,
                                      const gnutls_datum_t * signature,
                                      gnutls_digest_algorithm_t * hash)
 {
+  bigint_t issuer_params[MAX_PUBLIC_PARAMS_SIZE];
+  int issuer_params_size;
+  int ret, i;
+
   if (crt == NULL)
     {
       gnutls_assert ();
       return GNUTLS_E_INVALID_REQUEST;
     }
 
-  return _gnutls_x509_verify_algorithm ((gnutls_mac_algorithm_t *) hash,
-                                       signature, crt);
+  issuer_params_size = MAX_PUBLIC_PARAMS_SIZE;
+  ret =
+       _gnutls_x509_crt_get_mpis (crt, issuer_params,
+                                  &issuer_params_size);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  ret = _gnutls_x509_verify_algorithm ((gnutls_mac_algorithm_t *) hash,
+                       signature, gnutls_x509_crt_get_pk_algorithm (crt, NULL),
+                       issuer_params, issuer_params_size);
+
+  /* release allocated mpis */
+  for (i = 0; i < issuer_params_size; i++)
+    {
+      _gnutls_mpi_release (&issuer_params[i]);
+    }
+
+  return ret;
 }
 
 /**
@@ -2525,6 +2546,9 @@ gnutls_x509_crt_get_verify_algorithm (gnutls_x509_crt_t 
crt,
  *
  * This function will verify the given signed data, using the
  * parameters from the certificate.
+ * 
+ * Note: Use gnutls_x509_crt_verify_hash() instead. This function
+ * does not do the implied hashing of the data.
  *
  * Returns: In case of a verification failure 0 is returned, and 1 on
  * success.
diff --git a/lib/x509/x509_int.h b/lib/x509/x509_int.h
index c1f4126..f4000a5 100644
--- a/lib/x509/x509_int.h
+++ b/lib/x509/x509_int.h
@@ -180,9 +180,13 @@ int _gnutls_parse_general_name (ASN1_TYPE src, const char 
*src_name,
 /* verify.c */
 int gnutls_x509_crt_is_issuer (gnutls_x509_crt_t cert,
                               gnutls_x509_crt_t issuer);
-int _gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash,
-                                  const gnutls_datum_t * signature,
-                                  const gnutls_x509_crt_t crt);
+
+int
+_gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash,
+                              const gnutls_datum_t * signature,
+                              gnutls_pk_algorithm pk,
+                              bigint_t* issuer_params, unsigned int 
issuer_params_size);
+
 int _gnutls_x509_verify_signature (const gnutls_datum_t * tbs,
                                   const gnutls_datum_t * hash,
                                   const gnutls_datum_t * signature,
diff --git a/src/pkcs11.c b/src/pkcs11.c
index a9f1605..500aaa3 100644
--- a/src/pkcs11.c
+++ b/src/pkcs11.c
@@ -3,6 +3,7 @@
 #include <gnutls/gnutls.h>
 #include <gnutls/extra.h>
 #include <gnutls/pkcs11.h>
+#include <gnutls/abstract.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include "certtool-common.h"
@@ -174,6 +175,7 @@ void pkcs11_export(FILE* outfile, const char* url)
 {
 gnutls_pkcs11_obj_t crt;
 gnutls_x509_crt_t xcrt;
+gnutls_pubkey_t pubkey;
 int ret;
 size_t size;
 
@@ -194,34 +196,84 @@ size_t size;
                exit(1);
        }
        
-       ret = gnutls_x509_crt_init(&xcrt);
-       if (ret < 0) {
-               fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, 
gnutls_strerror(ret));
-               exit(1);
-       }
-
-       ret = gnutls_x509_crt_import_pkcs11(xcrt, crt);
-       if (ret < 0) {
-               fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, 
gnutls_strerror(ret));
-               exit(1);
-       }
-       
-       size = buffer_size;
-       ret = gnutls_x509_crt_export (xcrt, GNUTLS_X509_FMT_PEM, buffer, &size);
-       if (ret < 0) {
-               fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, 
gnutls_strerror(ret));
-               exit(1);
+       switch(gnutls_pkcs11_obj_get_type(crt)) {
+               case GNUTLS_PKCS11_OBJ_X509_CRT:
+                       ret = gnutls_x509_crt_init(&xcrt);
+                       if (ret < 0) {
+                               fprintf(stderr, "Error in %s:%d: %s\n", 
__func__, __LINE__, gnutls_strerror(ret));
+                               exit(1);
+                       }
+
+                       ret = gnutls_x509_crt_import_pkcs11(xcrt, crt);
+                       if (ret < 0) {
+                               fprintf(stderr, "Error in %s:%d: %s\n", 
__func__, __LINE__, gnutls_strerror(ret));
+                               exit(1);
+                       }
+                       
+                       size = buffer_size;
+                       ret = gnutls_x509_crt_export (xcrt, 
GNUTLS_X509_FMT_PEM, buffer, &size);
+                       if (ret < 0) {
+                               fprintf(stderr, "Error in %s:%d: %s\n", 
__func__, __LINE__, gnutls_strerror(ret));
+                               exit(1);
+                       }
+                       fwrite (buffer, 1, size, outfile);
+                       
+                       gnutls_x509_crt_deinit(xcrt);
+                       break;
+               case GNUTLS_PKCS11_OBJ_PUBKEY:
+                       ret = gnutls_pubkey_init(&pubkey);
+                       if (ret < 0) {
+                               fprintf(stderr, "Error in %s:%d: %s\n", 
__func__, __LINE__, gnutls_strerror(ret));
+                               exit(1);
+                       }
+
+                       ret = gnutls_pubkey_import_pkcs11(pubkey, crt, 0);
+                       if (ret < 0) {
+                               fprintf(stderr, "Error in %s:%d: %s\n", 
__func__, __LINE__, gnutls_strerror(ret));
+                               exit(1);
+                       }
+                       
+                       size = buffer_size;
+                       ret = gnutls_pubkey_export (pubkey, 
GNUTLS_X509_FMT_PEM, buffer, &size);
+                       if (ret < 0) {
+                               fprintf(stderr, "Error in %s:%d: %s\n", 
__func__, __LINE__, gnutls_strerror(ret));
+                               exit(1);
+                       }
+                       fwrite (buffer, 1, size, outfile);
+                       
+                       gnutls_pubkey_deinit(pubkey);
+                       break;
+               default: {
+                       gnutls_datum data, enc;
+                       
+                       size = buffer_size;
+                       ret = gnutls_pkcs11_obj_export (crt, buffer, &size);
+                       if (ret < 0) {
+                               break;
+                       }
+                       
+                       data.data = buffer;
+                       data.size = size;
+                       
+                       ret = gnutls_pem_base64_encode_alloc("DATA", &data, 
&enc);
+                       if (ret < 0) {
+                               fprintf(stderr, "Error in %s:%d: %s\n", 
__func__, __LINE__, gnutls_strerror(ret));
+                               exit(1);
+                       }
+                                               
+                       fwrite (enc.data, 1, enc.size, outfile);
+                       
+                       gnutls_free(enc.data);
+                       break;
+               }
        }
-       fwrite (buffer, 1, size, outfile);
        fputs("\n\n", outfile);
 
-       gnutls_x509_crt_deinit(xcrt);
+       
        gnutls_pkcs11_obj_deinit(crt);
        
        return;
 
-       
-
 }
 
 void pkcs11_token_list(FILE* outfile)


hooks/post-receive
-- 
GNU gnutls



reply via email to

[Prev in Thread] Current Thread [Next in Thread]