]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added gnutls_pubkey_t abstract type to handle public keys. It can currently
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 22 May 2010 13:13:20 +0000 (15:13 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Thu, 3 Jun 2010 17:52:29 +0000 (19:52 +0200)
import/export public keys from existing certificate types as well as from PKCS #11
URL. This allows generating a certificate or certificate request from a given public key
(currently one could only generate them from a given private key).

PKCS#11 API augmented to allow reading arbitrary objects instead of just certificates.
Certtool updated to list those objects.

20 files changed:
lib/Makefile.am
lib/gnutls_pubkey.c [new file with mode: 0644]
lib/gnutls_x509.c
lib/includes/gnutls/abstract.h
lib/includes/gnutls/pkcs11.h
lib/libgnutls.map
lib/pkcs11.c
lib/pkcs11_int.h
lib/pkcs11_privkey.c
lib/x509/common.c
lib/x509/common.h
lib/x509/mpi.c
lib/x509/x509.c
lib/x509/x509_int.h
src/certtool-common.h
src/certtool-gaa.c
src/certtool-gaa.h
src/certtool.c
src/certtool.gaa
src/pkcs11.c

index 70145bdc66de865b28e2f7b1fef298ce53fe37f9..6eeb5a216ad66a60204339afead245347fb47eb8 100644 (file)
@@ -83,7 +83,7 @@ COBJECTS = gnutls_record.c gnutls_compress.c debug.c gnutls_cipher.c  \
        crypto.c random.c pk-libgcrypt.c mpi-libgcrypt.c cryptodev.c    \
        rnd-libgcrypt.c cipher-libgcrypt.c ext_signature.c \
        crypto-api.c ext_safe_renegotiation.c gnutls_mbuffers.c \
-       gnutls_privkey.c pkcs11.c pkcs11_privkey.c
+       gnutls_privkey.c pkcs11.c pkcs11_privkey.c gnutls_pubkey.c
 
 if ENABLE_PKCS11
 COBJECTS += pkcs11.c pkcs11_privkey.c
diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c
new file mode 100644 (file)
index 0000000..985f473
--- /dev/null
@@ -0,0 +1,670 @@
+/*
+ * GnuTLS PKCS#11 support
+ * Copyright (C) 2010 Free Software Foundation
+ * 
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA
+*/
+
+#include <gnutls_int.h>
+#include <pakchois/pakchois.h>
+#include <gnutls/pkcs11.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <gnutls_errors.h>
+#include <gnutls_datum.h>
+#include <pkcs11_int.h>
+#include <gnutls/abstract.h>
+#include <sign.h>
+#include <gnutls_pk.h>
+#include <x509_int.h>
+#include <openpgp/openpgp_int.h>
+#include <pkcs11_int.h>
+
+#define PK_PEM_HEADER "PUBLIC KEY"
+
+
+struct gnutls_pubkey_st {
+       gnutls_pk_algorithm_t pk_algorithm;
+       unsigned int bits;      /* an indication of the security parameter */
+
+       /* the size of params depends on the public
+        * key algorithm
+        * RSA: [0] is modulus
+        *      [1] is public exponent
+        * DSA: [0] is p
+        *      [1] is q
+        *      [2] is g
+        *      [3] is public key
+        */
+       bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
+       int params_size;        /* holds the size of MPI params */
+
+       unsigned int key_usage; /* bits from GNUTLS_KEY_* */
+};
+
+/**
+ * gnutls_pubkey_get_pk_algorithm:
+ * @key: should contain a #gnutls_pubkey_t structure
+ * @bits: If set will return the number of bits of the parameters (may be NULL)
+ *
+ * This function will return the public key algorithm of a public
+ * key and if possible will return a number of bits that indicates
+ * the security parameter of the key.
+ *
+ * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
+ *   success, or a negative value on error.
+ **/
+int gnutls_pubkey_get_pk_algorithm(gnutls_pubkey_t key, unsigned int *bits)
+{
+       if (bits)
+               *bits = key->bits;
+
+       return key->pk_algorithm;
+}
+
+/**
+ * gnutls_pubkey_get_key_usage:
+ * @key: should contain a #gnutls_pubkey_t structure
+ * @usage: If set will return the number of bits of the parameters (may be NULL)
+ *
+ * This function will return the key usage of the public key.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
+ *   negative error value.
+ **/
+int gnutls_pubkey_get_key_usage(gnutls_pubkey_t key, unsigned int *usage)
+{
+       if (usage)
+               *usage = key->key_usage;
+
+       return 0;
+}
+
+/**
+ * gnutls_pubkey_init:
+ * @key: The structure to be initialized
+ *
+ * This function will initialize an public key structure.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
+ *   negative error value.
+ **/
+int gnutls_pubkey_init(gnutls_pubkey_t * key)
+{
+       *key = gnutls_calloc(1, sizeof(struct gnutls_pubkey_st));
+       if (*key == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_MEMORY_ERROR;
+       }
+
+       return 0;
+}
+
+/**
+ * gnutls_pubkey_deinit:
+ * @key: The structure to be deinitialized
+ *
+ * This function will deinitialize a public key structure.
+ **/
+void gnutls_pubkey_deinit(gnutls_pubkey_t key)
+{
+       gnutls_free(key);
+}
+
+/**
+ * gnutls_pubkey_import_x509:
+ * @key: The public key
+ * @crt: The certificate 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_x509(gnutls_pubkey_t key, gnutls_x509_crt_t crt,
+                             unsigned int flags)
+{
+       int ret;
+
+       key->pk_algorithm =
+           gnutls_x509_crt_get_pk_algorithm(crt, &key->bits);
+
+       ret = gnutls_x509_crt_get_key_usage(crt, &key->key_usage, NULL);
+       if (ret < 0)
+               key->key_usage = 0;
+
+       key->params_size = sizeof(key->params) / sizeof(key->params[0]);
+       switch (key->pk_algorithm) {
+       case GNUTLS_PK_RSA:
+               ret =
+                   _gnutls_x509_crt_get_mpis(crt, key->params,
+                                             &key->params_size);
+               if (ret < 0) {
+                       gnutls_assert();
+                       return ret;
+               }
+               break;
+       case GNUTLS_PK_DSA:
+               ret =
+                   _gnutls_x509_crt_get_mpis(crt, key->params,
+                                             &key->params_size);
+               if (ret < 0) {
+                       gnutls_assert();
+                       return ret;
+               }
+
+               break;
+       default:
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+
+       return 0;
+}
+
+/**
+ * gnutls_pubkey_import_openpgp:
+ * @key: The public key
+ * @crt: The certificate 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_openpgp(gnutls_pubkey_t key,
+                                gnutls_openpgp_crt_t crt,
+                                gnutls_openpgp_keyid_t keyid,
+                                unsigned int flags)
+{
+       int ret;
+       uint32_t kid32[2];
+
+       ret = gnutls_openpgp_crt_get_preferred_key_id(crt, keyid);
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       KEYID_IMPORT(kid32, keyid);
+
+       key->pk_algorithm =
+           gnutls_openpgp_crt_get_pk_algorithm(crt, &key->bits);
+
+       ret = gnutls_openpgp_crt_get_key_usage(crt, &key->key_usage);
+       if (ret < 0)
+               key->key_usage = 0;
+
+       switch (key->pk_algorithm) {
+       case GNUTLS_PK_RSA:
+               ret =
+                   _gnutls_openpgp_crt_get_mpis(crt, kid32, key->params,
+                                                &key->params_size);
+               if (ret < 0) {
+                       gnutls_assert();
+                       return ret;
+               }
+               break;
+       case GNUTLS_PK_DSA:
+               ret =
+                   _gnutls_openpgp_crt_get_mpis(crt, kid32, key->params,
+                                                &key->params_size);
+               if (ret < 0) {
+                       gnutls_assert();
+                       return ret;
+               }
+               break;
+       default:
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+
+       return 0;
+}
+
+/**
+ * gnutls_pubkey_export:
+ * @key: Holds the certificate
+ * @format: the format of output params. One of PEM or DER.
+ * @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 certificate to DER or PEM format.
+ *
+ * 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_pubkey_export(gnutls_pubkey_t key,
+                    gnutls_x509_crt_fmt_t format, void *output_data,
+                    size_t * output_data_size)
+{
+       int result;
+       ASN1_TYPE spk = ASN1_TYPE_EMPTY;
+
+       if (key == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+
+       if ((result = asn1_create_element
+            (_gnutls_get_pkix(), "PKIX1.SubjectPublicKeyInfo", &spk))
+           != ASN1_SUCCESS) {
+               gnutls_assert();
+               return _gnutls_asn2err(result);
+       }
+
+       result =
+           _gnutls_x509_encode_and_copy_PKI_params(spk, "",
+                                                   key->pk_algorithm,
+                                                   key->params,
+                                                   key->params_size);
+       if (result < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       result = _gnutls_x509_export_int_named(spk, "",
+                                              format, PK_PEM_HEADER,
+                                              output_data,
+                                              output_data_size);
+       if (result < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       result = 0;
+
+      cleanup:
+       asn1_delete_structure(&spk);
+
+       return result;
+
+}
+
+/**
+ * gnutls_pubkey_get_key_id:
+ * @key: Holds the public key
+ * @flags: should be 0 for now
+ * @output_data: will contain the key ID
+ * @output_data_size: holds the size of output_data (and will be
+ *   replaced by the actual size of parameters)
+ *
+ * This function will return a unique ID the depends on the public
+ * key parameters. This ID can be used in checking whether a
+ * certificate corresponds to the given public key.
+ *
+ * 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.  The output will normally be a SHA-1 hash output,
+ * which is 20 bytes.
+ *
+ * Return value: In case of failure a negative value will be
+ *   returned, and 0 on success.
+ **/
+int
+gnutls_pubkey_get_key_id(gnutls_pubkey_t key, unsigned int flags,
+                        unsigned char *output_data,
+                        size_t * output_data_size)
+{
+       int ret = 0;
+
+       if (key == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+
+       ret =
+           _gnutls_get_key_id(key->pk_algorithm, key->params,
+                              key->params_size, output_data,
+                              output_data_size);
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       return 0;
+}
+
+/**
+ * gnutls_pubkey_get_pk_rsa_raw:
+ * @crt: Holds the certificate
+ * @m: will hold the modulus
+ * @e: will hold the public exponent
+ *
+ * This function will export the RSA public key's parameters found in
+ * the given structure.  The new parameters will be allocated using
+ * gnutls_malloc() and will be stored in the appropriate datum.
+ *
+ * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
+ **/
+int
+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();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+
+       if (key->pk_algorithm != GNUTLS_PK_RSA) {
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+
+       ret = _gnutls_mpi_dprint(key->params[0], m);
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       ret = _gnutls_mpi_dprint(key->params[1], e);
+       if (ret < 0) {
+               gnutls_assert();
+               _gnutls_free_datum(m);
+               return ret;
+       }
+
+       return 0;
+}
+
+/**
+ * gnutls_pubkey_get_pk_dsa_raw:
+ * @crt: Holds the certificate
+ * @p: will hold the p
+ * @q: will hold the q
+ * @g: will hold the g
+ * @y: will hold the y
+ *
+ * This function will export the DSA public key's parameters found in
+ * the given certificate.  The new parameters will be allocated using
+ * gnutls_malloc() and will be stored in the appropriate datum.
+ *
+ * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
+ **/
+int
+gnutls_pubkey_get_pk_dsa_raw(gnutls_pubkey_t key,
+                            gnutls_datum_t * p, gnutls_datum_t * q,
+                            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();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+
+       if (key->pk_algorithm != GNUTLS_PK_DSA) {
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+
+       /* P */
+       ret = _gnutls_mpi_dprint(key->params[0], p);
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       /* Q */
+       ret = _gnutls_mpi_dprint(key->params[1], q);
+       if (ret < 0) {
+               gnutls_assert();
+               _gnutls_free_datum(p);
+               return ret;
+       }
+
+
+       /* G */
+       ret = _gnutls_mpi_dprint(key->params[2], g);
+       if (ret < 0) {
+               gnutls_assert();
+               _gnutls_free_datum(p);
+               _gnutls_free_datum(q);
+               return ret;
+       }
+
+
+       /* Y */
+       ret = _gnutls_mpi_dprint(key->params[3], y);
+       if (ret < 0) {
+               gnutls_assert();
+               _gnutls_free_datum(p);
+               _gnutls_free_datum(g);
+               _gnutls_free_datum(q);
+               return ret;
+       }
+
+       return 0;
+}
+
+/**
+ * gnutls_pubkey_import:
+ * @key: The structure to store the parsed certificate. 
+ * @data: The DER or PEM encoded certificate. 
+ * @format: One of DER or PEM 
+ * 
+ * This function will convert the given DER or PEM encoded Public key 
+ * to the native gnutls_pubkey_t format.The output will be stored * in @ key. 
+ * If the Certificate is PEM encoded it should have a header of "PUBLIC KEY". 
+ * 
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
+ * negative error value.
+ **/
+int gnutls_pubkey_import(gnutls_pubkey_t key,
+                    const gnutls_datum_t * data,
+                    gnutls_x509_crt_fmt_t format)
+{
+       int result = 0, need_free = 0;
+       gnutls_datum_t _data;
+       ASN1_TYPE spk;
+
+       if (key == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+
+       _data.data = data->data;
+       _data.size = data->size;
+
+       /* If the Certificate is in PEM format then decode it
+        */
+       if (format == GNUTLS_X509_FMT_PEM) {
+               opaque *out;
+
+               /* Try the first header */
+               result =
+                   _gnutls_fbase64_decode(PK_PEM_HEADER, data->data,
+                                          data->size, &out);
+
+               if (result <= 0) {
+                       if (result == 0)
+                               result = GNUTLS_E_INTERNAL_ERROR;
+                       gnutls_assert();
+                       return result;
+               }
+
+               _data.data = out;
+               _data.size = result;
+
+               need_free = 1;
+       }
+
+       if ((result = asn1_create_element
+            (_gnutls_get_pkix(), "PKIX1.SubjectPublicKeyInfo", &spk))
+           != ASN1_SUCCESS) {
+               gnutls_assert();
+               result = _gnutls_asn2err(result);
+               goto cleanup;
+       }
+
+       result = asn1_der_decoding (&spk, _data.data, _data.size, NULL);
+       if (result != ASN1_SUCCESS) {
+               gnutls_assert ();
+               result = _gnutls_asn2err (result);
+               goto cleanup;
+       }
+
+       key->params_size = sizeof(key->params) / sizeof(key->params[0]);
+       result =
+           _gnutls_get_asn_mpis(spk, "", key->params, &key->params_size);
+       if (result < 0) {
+               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);
+
+       result = 0;
+
+cleanup:
+       asn1_delete_structure(&spk);
+
+       if (need_free)
+               _gnutls_free_datum(&_data);
+       return result;
+}
+
+int gnutls_x509_crt_set_pubkey (gnutls_x509_crt_t crt,
+                              gnutls_pubkey_t key)
+{
+  int result;
+
+  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);
+
+  if (result < 0)
+    {
+      gnutls_assert ();
+      return result;
+    }
+
+       if (key->key_usage)
+               gnutls_x509_crt_set_key_usage(crt, key->key_usage);
+
+  return 0;
+}
+
+int gnutls_x509_crq_set_pubkey (gnutls_x509_crq_t crq,
+                              gnutls_pubkey_t key)
+{
+  int result;
+
+  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);
+
+  if (result < 0)
+    {
+      gnutls_assert ();
+      return result;
+    }
+
+       if (key->key_usage)
+               gnutls_x509_crq_set_key_usage(crq, key->key_usage);
+
+  return 0;
+}
+
+/**
+ * gnutls_pubkey_set_key_usage:
+ * @crt: a certificate of type #gnutls_x509_crt_t
+ * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
+ *
+ * This function will set the keyUsage certificate extension.
+ *
+ * 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)
+{
+       key->key_usage = usage;
+       
+       return 0;
+}
+
+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;
+    }
+
+    ret = gnutls_pkcs11_obj_import_url (pcrt, url);
+    if (ret < 0) {
+        gnutls_assert();
+        goto cleanup;
+    }
+
+    ret = gnutls_pubkey_import(key, &pcrt->raw, GNUTLS_X509_FMT_DER);
+    if (ret < 0) {
+        gnutls_assert();
+        goto cleanup;
+    }
+    
+    ret = 0;
+cleanup:
+
+    gnutls_pkcs11_obj_deinit(pcrt);
+    
+    return ret;
+}
+
index 2241d94bfc3b53c4832b289610af430adff80fd5..9f772a9d1d11cec3bf2e79e616aed9dca9287765 100644 (file)
@@ -566,10 +566,10 @@ static int read_cas_url (gnutls_certificate_credentials_t res, const char* url)
 {
 int ret;
 gnutls_x509_crt_t * xcrt_list = NULL;
-gnutls_pkcs11_crt_t *pcrt_list=NULL;
+gnutls_pkcs11_obj_t *pcrt_list=NULL;
 unsigned int pcrt_list_size = 0;
 
-       ret = gnutls_pkcs11_crt_list_import_url( NULL, &pcrt_list_size, url, GNUTLS_PKCS11_CRT_ATTR_TRUSTED);
+       ret = gnutls_pkcs11_obj_list_import_url( NULL, &pcrt_list_size, url, GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED);
        if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) {
                gnutls_assert();
                return ret;
@@ -586,7 +586,7 @@ unsigned int pcrt_list_size = 0;
                return GNUTLS_E_MEMORY_ERROR;
        }
        
-       ret = gnutls_pkcs11_crt_list_import_url( pcrt_list, &pcrt_list_size, url, GNUTLS_PKCS11_CRT_ATTR_TRUSTED);
+       ret = gnutls_pkcs11_obj_list_import_url( pcrt_list, &pcrt_list_size, url, GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED);
        if (ret < 0) {
                gnutls_assert();
                goto cleanup;
index 8e75dce677fbb112919e17ecaffeef0a36e3a031..8305f9cddd7883aefa83fd03e1e3f6e2fe32edfa 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __GNUTLS_PRIVKEY_H
-#define __GNUTLS_PRIVKEY_H
+#ifndef __GNUTLS_ABSTRACT_H
+#define __GNUTLS_ABSTRACT_H
 
 #include <stdarg.h>
 #include <gnutls/gnutls.h>
@@ -7,6 +7,55 @@
 #include <gnutls/pkcs11.h>
 #include <gnutls/openpgp.h>
 
+/* Public key operations */
+
+struct gnutls_pubkey_st;
+typedef struct gnutls_pubkey_st* gnutls_pubkey_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);
+
+int gnutls_pubkey_import_x509(gnutls_pubkey_t pkey, gnutls_x509_crt_t crt, unsigned int flags);
+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_get_pk_rsa_raw (gnutls_pubkey_t crt,
+                               gnutls_datum_t * m, gnutls_datum_t * e);
+int gnutls_pubkey_get_pk_dsa_raw (gnutls_pubkey_t crt,
+                               gnutls_datum_t * p, gnutls_datum_t * q,
+                               gnutls_datum_t * g, gnutls_datum_t * y);
+
+int gnutls_pubkey_export (gnutls_pubkey_t key,
+                             gnutls_x509_crt_fmt_t format,
+                             void *output_data, size_t * output_data_size);
+
+int gnutls_pubkey_get_key_id (gnutls_pubkey_t key, unsigned int flags,
+                           unsigned char *output_data,
+                           size_t * output_data_size);
+
+int gnutls_pubkey_get_key_usage(gnutls_pubkey_t key, unsigned int *usage);
+int gnutls_pubkey_set_key_usage (gnutls_pubkey_t key, unsigned int usage);
+
+int gnutls_pubkey_import (gnutls_pubkey_t key,
+                             const gnutls_datum_t * data,
+                             gnutls_x509_crt_fmt_t format);
+
+
+int gnutls_pubkey_import_pkcs11_url( gnutls_pubkey_t key, const char* url);
+
+
+int gnutls_x509_crt_set_pubkey (gnutls_x509_crt_t crt,
+                              gnutls_pubkey_t key);
+
+int gnutls_x509_crq_set_pubkey (gnutls_x509_crq_t crq,
+                              gnutls_pubkey_t key);
+
+
+/* Private key operations */
+
 struct gnutls_privkey_st;
 typedef struct gnutls_privkey_st* gnutls_privkey_t;
 
@@ -15,6 +64,7 @@ void gnutls_privkey_deinit (gnutls_privkey_t key);
 int gnutls_privkey_get_pk_algorithm (gnutls_privkey_t key, unsigned int* bits);
 gnutls_privkey_type_t gnutls_privkey_get_type (gnutls_privkey_t key);
 
+
 #define GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE 1
 int gnutls_privkey_import_pkcs11 (gnutls_privkey_t pkey, gnutls_pkcs11_privkey_t key, unsigned int flags);
 int gnutls_privkey_import_x509 (gnutls_privkey_t pkey, gnutls_x509_privkey_t key, unsigned int flags);
index 05d4b20270f855738ede6d975f2200320bfd4fc5..b5d1d6ef73fac8d5e092bda4ab1cc7ecb0f8acd4 100644 (file)
@@ -67,8 +67,8 @@ typedef int (*gnutls_pkcs11_pin_callback_t)(void *userdata, int attempt,
 /**
  * @brief PKCS#11 certificate reference.
  */
-struct gnutls_pkcs11_crt_st;
-typedef struct gnutls_pkcs11_crt_st* gnutls_pkcs11_crt_t;
+struct gnutls_pkcs11_obj_st;
+typedef struct gnutls_pkcs11_obj_st* gnutls_pkcs11_obj_t;
 
 
 
@@ -132,30 +132,11 @@ int gnutls_pkcs11_add_provider (const char * name, const char * params);
  * @param certificate  Certificate reference to free.
  * @return gnutls stauts.
  */
-int gnutls_pkcs11_crt_init ( gnutls_pkcs11_crt_t *certificate);
+int gnutls_pkcs11_obj_init ( gnutls_pkcs11_obj_t *certificate);
 
-/**
- * @brief Deserialize a certificate reference.
- * @param serialized   Serialized certificate.
- * @param p_certificate        Certificate reference.
- * @return gnutls status.
- */
-int gnutls_pkcs11_crt_import_url (gnutls_pkcs11_crt_t p_certificate, const char * url);
-
-/**
- * @brief Serialize a certificate reference.
- * @param certificate  Certificate reference to serialize.
- * @param serialized   Serialize result (string). Use gnutls_free() to free it.
- * @return gnutls status.
- */
-int gnutls_pkcs11_crt_export_url (gnutls_pkcs11_crt_t certificate, char** url);
-
-/**
- * @brief Free certificate reference.
- * @param certificate  Certificate reference to free.
- * @return gnutls stauts.
- */
-void gnutls_pkcs11_crt_deinit ( gnutls_pkcs11_crt_t certificate);
+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);
 
 /**
  * @brief Release array of certificate references.
@@ -163,25 +144,27 @@ void gnutls_pkcs11_crt_deinit ( gnutls_pkcs11_crt_t certificate);
  * @param ncertificates        Array size.
  * @return gnutls status.
  */
-int gnutls_pkcs11_crt_list_deinit (gnutls_pkcs11_crt_t * certificates, const unsigned int ncertificates);
+int gnutls_pkcs11_obj_list_deinit (gnutls_pkcs11_obj_t * , const unsigned int nobjs);
 
 typedef enum {
-       GNUTLS_PKCS11_CRT_ID_HEX=1,
-       GNUTLS_PKCS11_CRT_LABEL,
-       GNUTLS_PKCS11_CRT_TOKEN_LABEL,
-       GNUTLS_PKCS11_CRT_TOKEN_SERIAL,
-       GNUTLS_PKCS11_CRT_TOKEN_MANUFACTURER,
-       GNUTLS_PKCS11_CRT_TOKEN_MODEL,
-       GNUTLS_PKCS11_CRT_ID,
-} gnutls_pkcs11_cert_info_t;
+       GNUTLS_PKCS11_OBJ_ID_HEX=1,
+       GNUTLS_PKCS11_OBJ_LABEL,
+       GNUTLS_PKCS11_OBJ_TOKEN_LABEL,
+       GNUTLS_PKCS11_OBJ_TOKEN_SERIAL,
+       GNUTLS_PKCS11_OBJ_TOKEN_MANUFACTURER,
+       GNUTLS_PKCS11_OBJ_TOKEN_MODEL,
+       GNUTLS_PKCS11_OBJ_ID,
+} gnutls_pkcs11_obj_info_t;
 
-int gnutls_pkcs11_crt_get_info(gnutls_pkcs11_crt_t crt, gnutls_pkcs11_cert_info_t itype, void* output, size_t* output_size);
+int gnutls_pkcs11_obj_get_info(gnutls_pkcs11_obj_t crt, gnutls_pkcs11_obj_info_t itype, void* output, size_t* output_size);
 
 typedef enum {
-       GNUTLS_PKCS11_CRT_ATTR_ALL=1,
-       GNUTLS_PKCS11_CRT_ATTR_TRUSTED, /* marked as trusted */
-       GNUTLS_PKCS11_CRT_ATTR_WITH_PK, /* with corresponding private key */
-} gnutls_pkcs11_crt_attr_t;
+       GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL=1, /* all certificates */
+       GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED, /* certificates marked as trusted */
+       GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY, /* certificates with corresponding private key */
+       GNUTLS_PKCS11_OBJ_ATTR_PUBKEY, /* public keys */
+       GNUTLS_PKCS11_OBJ_ATTR_ALL, /* everything! */
+} gnutls_pkcs11_obj_attr_t;
 
 /* token info */
 typedef enum {
@@ -191,36 +174,32 @@ typedef enum {
        GNUTLS_PKCS11_TOKEN_MODEL,
 } gnutls_pkcs11_token_info_t;
 
+typedef enum {
+       GNUTLS_PKCS11_OBJ_UNKNOWN,
+       GNUTLS_PKCS11_OBJ_X509_CRT,
+       GNUTLS_PKCS11_OBJ_PUBKEY,
+       GNUTLS_PKCS11_OBJ_PRIVKEY,
+       GNUTLS_PKCS11_OBJ_SECRET_KEY,
+       GNUTLS_PKCS11_OBJ_DATA,
+} gnutls_pkcs11_obj_type_t;
+
 int gnutls_pkcs11_token_get_url (unsigned int seq, char** url);
 int gnutls_pkcs11_token_get_info(const char* url, gnutls_pkcs11_token_info_t, void* output, size_t *output_size);
 
 #define GNUTLS_PKCS11_TOKEN_HW 1
 int gnutls_pkcs11_token_get_flags(const char* url, unsigned int *flags);
 
-/**
- * @brief Enumerate available certificates.
- * @param p_list       Location to store the list.
- * @param n_list       Location to store end list length.
- * @param url          Enumerate only certificates found in token(s) pointed by url
- * @param attributes Only export certificates that match this attribute
- * @return gnutls status.
- * @note the p_list is should not be initialized.
- */
-int gnutls_pkcs11_crt_list_import_url (gnutls_pkcs11_crt_t * p_list, unsigned int *const n_list, const char* url, gnutls_pkcs11_crt_attr_t flags);
+int gnutls_pkcs11_obj_list_import_url (gnutls_pkcs11_obj_t * p_list, unsigned int *const n_list, const char* url, gnutls_pkcs11_obj_attr_t flags);
 
-int gnutls_x509_crt_import_pkcs11( gnutls_x509_crt_t crt, gnutls_pkcs11_crt_t pkcs11_crt);
+int gnutls_x509_crt_import_pkcs11( gnutls_x509_crt_t crt, gnutls_pkcs11_obj_t pkcs11_crt);
 int gnutls_x509_crt_import_pkcs11_url( gnutls_x509_crt_t crt, const char* url);
 
-/**
- * @brief Return the type of the certificate
- * @param certificate  Certificate reference.
- * @return gnutls status.
- */
-gnutls_certificate_type_t gnutls_pkcs11_crt_get_type (gnutls_pkcs11_crt_t certificate);
+gnutls_pkcs11_obj_type_t gnutls_pkcs11_obj_get_type (gnutls_pkcs11_obj_t certificate);
+const char* gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_type_t);
 
 int gnutls_x509_crt_list_import_pkcs11 (gnutls_x509_crt_t * certs,
                                    unsigned int cert_max,
-                                   gnutls_pkcs11_crt_t * const pkcs11_certs,
+                                   gnutls_pkcs11_obj_t * const pkcs11_certs,
                                    unsigned int flags);
 
 
@@ -228,7 +207,7 @@ int gnutls_x509_crt_list_import_pkcs11 (gnutls_x509_crt_t * certs,
 int gnutls_pkcs11_privkey_init (gnutls_pkcs11_privkey_t * key);
 void gnutls_pkcs11_privkey_deinit (gnutls_pkcs11_privkey_t key);
 int gnutls_pkcs11_privkey_get_pk_algorithm (gnutls_pkcs11_privkey_t key, unsigned int* bits);
-int gnutls_pkcs11_privkey_get_info(gnutls_pkcs11_privkey_t crt, gnutls_pkcs11_cert_info_t itype, void* output, size_t* output_size);
+int gnutls_pkcs11_privkey_get_info(gnutls_pkcs11_privkey_t crt, gnutls_pkcs11_obj_info_t itype, void* output, size_t* output_size);
 int gnutls_pkcs11_privkey_import_url (gnutls_pkcs11_privkey_t key,
                                  const char* url);
 
index b900ff3303d77583abc18a145ef5e40b50e52588..503cf2f4304239bdd35defea89b58f5ff608f0aa 100644 (file)
@@ -611,17 +611,17 @@ GNUTLS_2_11
         gnutls_pkcs11_set_pin_function;
        gnutls_pkcs11_set_token_function;
         gnutls_pkcs11_add_provider;
-        gnutls_pkcs11_crt_init;
-        gnutls_pkcs11_crt_import_url;
-        gnutls_pkcs11_crt_export_url;
-        gnutls_pkcs11_crt_deinit;
-        gnutls_pkcs11_crt_list_deinit;
-        gnutls_pkcs11_crt_list_import_url;
+        gnutls_pkcs11_obj_init;
+        gnutls_pkcs11_obj_import_url;
+        gnutls_pkcs11_obj_export_url;
+        gnutls_pkcs11_obj_deinit;
+        gnutls_pkcs11_obj_list_deinit;
+        gnutls_pkcs11_obj_list_import_url;
         gnutls_x509_crt_import_pkcs11;
-        gnutls_pkcs11_crt_get_type;
+        gnutls_pkcs11_obj_get_type;
         gnutls_x509_crt_list_import_pkcs11;
        gnutls_x509_crt_import_pkcs11_url;
-       gnutls_pkcs11_crt_get_info;
+       gnutls_pkcs11_obj_get_info;
        gnutls_pkcs11_token_get_info;
        gnutls_pkcs11_token_get_url;
        gnutls_pkcs11_privkey_init;
@@ -647,7 +647,22 @@ GNUTLS_2_11
        gnutls_x509_crq_privkey_sign;
        gnutls_x509_crl_privkey_sign;
        gnutls_x509_crt_privkey_sign;
+       gnutls_pubkey_init;
+       gnutls_pubkey_deinit;
+       gnutls_pubkey_get_pk_algorithm;
+       gnutls_pubkey_import_x509;
+       gnutls_pubkey_import_openpgp;
+       gnutls_pubkey_get_pk_rsa_raw;
+       gnutls_pubkey_get_pk_dsa_raw;
+       gnutls_pubkey_export;
+       gnutls_pubkey_get_key_id;
+       gnutls_pubkey_get_key_usage;
+       gnutls_pkcs11_type_get_name;
 
+       gnutls_pubkey_import_pkcs11_url;
+       gnutls_pubkey_import;
+       gnutls_x509_crt_set_pubkey;
+       gnutls_x509_crq_set_pubkey;
 } GNUTLS_2_10;
 
 GNUTLS_PRIVATE {
index 7af5797750664b421863022616fd301a940e70f9..32b11d26f0265aa88a71459b2a1b6b9c7d611b71 100644 (file)
@@ -43,14 +43,8 @@ struct gnutls_pkcs11_provider_s {
     ck_slot_id_t *slots;
 };
 
-struct gnutls_pkcs11_crt_st {
-    gnutls_datum_t raw;
-    gnutls_certificate_type_t type;
-    struct pkcs11_url_info info;
-};
-
 struct url_find_data_st {
-    gnutls_pkcs11_crt_t crt;
+    gnutls_pkcs11_obj_t crt;
 };
 
 struct flags_find_data_st {
@@ -59,10 +53,10 @@ struct flags_find_data_st {
 };
 
 struct crt_find_data_st {
-    gnutls_pkcs11_crt_t *p_list;
+    gnutls_pkcs11_obj_t *p_list;
     unsigned int* n_list;
     unsigned int current;
-    gnutls_pkcs11_crt_attr_t flags;
+    gnutls_pkcs11_obj_attr_t flags;
     struct pkcs11_url_info info;
 };
 
@@ -143,8 +137,8 @@ fail:
 
 
 /**
- * gnutls_pkcs11_crt_get_info:
- * @crt: should contain a #gnutls_pkcs11_crt_t structure
+ * gnutls_pkcs11_obj_get_info:
+ * @crt: should contain a #gnutls_pkcs11_obj_t structure
  * @itype: Denotes the type of information requested
  * @output: where output will be stored
  * @output_size: contains the maximum size of the output and will be overwritten with actual
@@ -156,20 +150,24 @@ fail:
  *
  * Returns: zero on success or a negative value on error.
  **/
+<<<<<<< HEAD:lib/pkcs11.c
 int gnutls_pkcs11_crt_get_info(gnutls_pkcs11_crt_t crt, gnutls_pkcs11_cert_info_t itype,
+=======
+int gnutls_pkcs11_obj_get_info(gnutls_pkcs11_obj_t crt, gnutls_pkcs11_obj_info_t itype, 
+>>>>>>> Added gnutls_pubkey_t abstract type to handle public keys. It can currently:lib/pkcs11.c
     void* output, size_t* output_size)
 {
     return pkcs11_get_info(&crt->info, itype, output, output_size);
 }
 
-int pkcs11_get_info(struct pkcs11_url_info *info, gnutls_pkcs11_cert_info_t itype, 
+int pkcs11_get_info(struct pkcs11_url_info *info, gnutls_pkcs11_obj_info_t itype, 
     void* output, size_t* output_size)
 {
     const char* str = NULL;
     size_t len;
 
     switch(itype) {
-        case GNUTLS_PKCS11_CRT_ID:
+        case GNUTLS_PKCS11_OBJ_ID:
             if (*output_size < info->certid_raw_size) {
                 *output_size = info->certid_raw_size;
                 return GNUTLS_E_SHORT_MEMORY_BUFFER;
@@ -178,22 +176,22 @@ int pkcs11_get_info(struct pkcs11_url_info *info, gnutls_pkcs11_cert_info_t ityp
             *output_size = info->certid_raw_size;
             
             return 0;
-        case GNUTLS_PKCS11_CRT_ID_HEX:
+        case GNUTLS_PKCS11_OBJ_ID_HEX:
             str = info->id;
             break;
-        case GNUTLS_PKCS11_CRT_LABEL:
+        case GNUTLS_PKCS11_OBJ_LABEL:
             str = info->label;
             break;
-        case GNUTLS_PKCS11_CRT_TOKEN_LABEL:
+        case GNUTLS_PKCS11_OBJ_TOKEN_LABEL:
             str = info->token;
             break;
-        case GNUTLS_PKCS11_CRT_TOKEN_SERIAL:
+        case GNUTLS_PKCS11_OBJ_TOKEN_SERIAL:
             str = info->serial;
             break;
-        case GNUTLS_PKCS11_CRT_TOKEN_MANUFACTURER:
+        case GNUTLS_PKCS11_OBJ_TOKEN_MANUFACTURER:
             str = info->manufacturer;
             break;
-        case GNUTLS_PKCS11_CRT_TOKEN_MODEL:
+        case GNUTLS_PKCS11_OBJ_TOKEN_MODEL:
             str = info->model;
             break;
         default:
@@ -583,6 +581,15 @@ int pkcs11_info_to_url(const struct pkcs11_url_info* info, char** url)
         init = 1;
     }
 
+    if (info->type[0]) {
+        ret = append(&str, info->type, "objecttype", init);
+        if (ret < 0) {
+                gnutls_assert();
+                goto cleanup;
+        }
+        init = 1;
+    }
+
     if (info->id[0] != 0) {
         ret = _gnutls_string_append_printf(&str, ";id=%s", info->id);
         if (ret < 0) {
@@ -603,7 +610,7 @@ cleanup:
 }
 
 /**
- * gnutls_pkcs11_crt_init:
+ * gnutls_pkcs11_obj_init:
  * @crt: The structure to be initialized
  *
  * This function will initialize a pkcs11 certificate structure.
@@ -611,9 +618,9 @@ cleanup:
  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
  *   negative error value.
  **/
-int gnutls_pkcs11_crt_init(gnutls_pkcs11_crt_t * crt)
+int gnutls_pkcs11_obj_init(gnutls_pkcs11_obj_t * crt)
 {
-    *crt = gnutls_calloc(1, sizeof(struct gnutls_pkcs11_crt_st));
+    *crt = gnutls_calloc(1, sizeof(struct gnutls_pkcs11_obj_st));
     if (*crt == NULL) {
         gnutls_assert();
         return GNUTLS_E_MEMORY_ERROR;
@@ -623,12 +630,12 @@ int gnutls_pkcs11_crt_init(gnutls_pkcs11_crt_t * crt)
 }
 
 /**
- * gnutls_pkcs11_crt_deinit:
+ * gnutls_pkcs11_obj_deinit:
  * @key: The structure to be initialized
  *
  * This function will deinitialize a certificate structure.
  **/
-void gnutls_pkcs11_crt_deinit(gnutls_pkcs11_crt_t crt)
+void gnutls_pkcs11_obj_deinit(gnutls_pkcs11_obj_t crt)
 {
     free(crt);
 }
@@ -711,19 +718,62 @@ finish:
     return ret;
 }
 
-/* imports a raw certificate from a token to a pkcs11_crt_t structure.
+static const char* pkcs11_obj_type_to_str(gnutls_pkcs11_obj_type_t type)
+{
+    switch(type) {
+        case GNUTLS_PKCS11_OBJ_X509_CRT:
+            return "cert";
+        case GNUTLS_PKCS11_OBJ_PUBKEY:
+            return "public";
+        case GNUTLS_PKCS11_OBJ_PRIVKEY:
+            return "private";
+        case GNUTLS_PKCS11_OBJ_SECRET_KEY:
+            return "secretkey";
+        case GNUTLS_PKCS11_OBJ_DATA:
+            return "data";
+        case GNUTLS_PKCS11_OBJ_UNKNOWN:
+        default:
+            return "unknown";
+    }
+}
+
+/* imports a raw certificate from a token to a pkcs11_obj_t structure.
  */
-static int pkcs11_crt_import(gnutls_pkcs11_crt_t crt, const gnutls_datum_t* data, 
+static int pkcs11_obj_import(unsigned int class, gnutls_pkcs11_obj_t crt, const gnutls_datum_t* data, 
    const gnutls_datum_t * id, const gnutls_datum_t * label, struct ck_token_info* tinfo)
 {
     char *s;
     int ret;
     
-    crt->type = GNUTLS_CRT_X509;
-    ret = _gnutls_set_datum(&crt->raw, data->data, data->size);
-    if (ret < 0) {
-        gnutls_assert();
-        return ret;
+    switch(class) {
+        case CKO_CERTIFICATE:
+            crt->type = GNUTLS_PKCS11_OBJ_X509_CRT;
+            break;
+        case CKO_PUBLIC_KEY:
+            crt->type = GNUTLS_PKCS11_OBJ_PUBKEY;
+            break;
+        case CKO_PRIVATE_KEY:
+            crt->type = GNUTLS_PKCS11_OBJ_PRIVKEY;
+            break;
+        case CKO_SECRET_KEY:
+            crt->type = GNUTLS_PKCS11_OBJ_SECRET_KEY;
+            break;
+        case CKO_DATA:
+            crt->type = GNUTLS_PKCS11_OBJ_DATA;
+            break;
+        default:
+            crt->type = GNUTLS_PKCS11_OBJ_UNKNOWN;
+    }
+    
+    if (crt->type != GNUTLS_PKCS11_OBJ_UNKNOWN)
+        strcpy(crt->info.type, pkcs11_obj_type_to_str(crt->type));
+
+    if (data && data->data) {
+        ret = _gnutls_set_datum(&crt->raw, data->data, data->size);
+        if (ret < 0) {
+            gnutls_assert();
+            return ret;
+        }
     }
 
     terminate_string(tinfo->manufacturer_id, sizeof tinfo->manufacturer_id);
@@ -737,19 +787,21 @@ static int pkcs11_crt_import(gnutls_pkcs11_crt_t crt, const gnutls_datum_t* data
     snprintf(crt->info.model, sizeof(crt->info.model), "%s", tinfo->model);
     snprintf(crt->info.serial, sizeof(crt->info.serial), "%s", tinfo->serial_number);
 
-    memcpy(crt->info.label, label->data, label->size);
-    crt->info.label[label->size] = 0;
+    if (label && label->data) {
+        memcpy(crt->info.label, label->data, label->size);
+        crt->info.label[label->size] = 0;
+    }
 
-    strcpy(crt->info.type, "cert");
+    if (id && id->data) {
+        s = _gnutls_bin2hex(id->data, id->size, crt->info.id, sizeof(crt->info.id), ":");
+        if (s == NULL) {
+            gnutls_assert();
+            return GNUTLS_E_PKCS11_ERROR;
+        }
     
-    s = _gnutls_bin2hex(id->data, id->size, crt->info.id, sizeof(crt->info.id), ":");
-    if (s == NULL) {
-        gnutls_assert();
-        return GNUTLS_E_PKCS11_ERROR;
+        memmove(crt->info.certid_raw, id->data, id->size);
+        crt->info.certid_raw_size = id->size;
     }
-    
-    memmove(crt->info.certid_raw, id->data, id->size);
-    crt->info.certid_raw_size = id->size;
 
     return 0;
 }
@@ -848,7 +900,7 @@ 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_crt_import(find_data->crt, &data, &id, &label, &info->tinfo);
+            ret = pkcs11_obj_import(CKO_CERTIFICATE, find_data->crt, &data, &id, &label, &info->tinfo);
             if (ret < 0) {
                 gnutls_assert();
                 goto cleanup;
@@ -882,14 +934,14 @@ cleanup:
  * @url: a PKCS 11 url identifying the key
  *
  * This function will "import" a PKCS 11 URL identifying a certificate
- * key to the #gnutls_pkcs11_crt_t structure. This does not involve any
- * parsing (such as X.509 or OpenPGP) since the #gnutls_pkcs11_crt_t is
+ * key to the #gnutls_pkcs11_obj_t structure. This does not involve any
+ * parsing (such as X.509 or OpenPGP) since the #gnutls_pkcs11_obj_t is
  * format agnostic. Only data are transferred.
  *
  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
  *   negative error value.
  **/
-int gnutls_pkcs11_crt_import_url (gnutls_pkcs11_crt_t cert, const char * url)
+int gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t cert, const char * url)
 {
     int ret;
     struct url_find_data_st find_data;
@@ -1037,7 +1089,7 @@ int gnutls_pkcs11_token_get_info(const char* url, gnutls_pkcs11_token_info_t tty
 }
 
 /**
- * gnutls_pkcs11_crt_export_url:
+ * gnutls_pkcs11_obj_export_url:
  * @crt: Holds the PKCS 11 certificate
  * @url: will contain an allocated url
  *
@@ -1046,7 +1098,7 @@ int gnutls_pkcs11_token_get_info(const char* url, gnutls_pkcs11_token_info_t tty
  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
  *   negative error value.
  **/
-int gnutls_pkcs11_crt_export_url (gnutls_pkcs11_crt_t cert, char ** url)
+int gnutls_pkcs11_obj_export_url (gnutls_pkcs11_obj_t cert, char ** url)
 {
 int ret;
 
@@ -1060,7 +1112,7 @@ int ret;
 }
 
 /**
- * gnutls_pkcs11_crt_get_type:
+ * gnutls_pkcs11_obj_get_type:
  * @certificate: Holds the PKCS 11 certificate
  *
  * This function will return the type of the certificate being
@@ -1068,9 +1120,9 @@ int ret;
  *
  * Returns: The type of the certificate.
  **/
-gnutls_certificate_type_t gnutls_pkcs11_crt_get_type (gnutls_pkcs11_crt_t certificate)
+gnutls_pkcs11_obj_type_t gnutls_pkcs11_obj_get_type (gnutls_pkcs11_obj_t obj)
 {
-    return certificate->type;
+    return obj->type;
 }
 
 struct pkey_list {
@@ -1174,12 +1226,6 @@ static int find_privkeys(pakchois_session_t *pks, struct token_info* info, struc
 
     class = CKO_PRIVATE_KEY;
 
-    ret = pkcs11_login(pks, info);
-    if (ret < 0) {
-        gnutls_assert();
-        return ret;
-    }
-
     /* Find an object with private key class and a certificate ID
      * which matches the certificate. */
     /* FIXME: also match the cert subject. */
@@ -1252,7 +1298,7 @@ static int find_privkeys(pakchois_session_t *pks, struct token_info* info, struc
 /* Recover certificate list from tokens */
 
 
-static int find_crts(pakchois_session_t *pks, struct token_info *info, void* input)
+static int find_objs(pakchois_session_t *pks, struct token_info *info, void* input)
 {
     struct crt_find_data_st* find_data = input;
     struct ck_attribute a[4];
@@ -1267,6 +1313,7 @@ static int find_crts(pakchois_session_t *pks, struct token_info *info, void* inp
     char label_tmp[PKCS11_LABEL_SIZE];
     int ret, i;
     struct pkey_list plist; /* private key holder */
+    int tot_values = 0;
 
     if (info == NULL) { /* final call */
         if (find_data->current <= *find_data->n_list)
@@ -1301,15 +1348,14 @@ static int find_crts(pakchois_session_t *pks, struct token_info *info, void* inp
             return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
     }
 
-    if (find_data->info.type[0] != 0) {
-        if (strcmp(find_data->info.type, "cert") != 0) {
+    memset(&plist, 0, sizeof(plist));
+    if (find_data->flags==GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY) {
+        ret = pkcs11_login(pks, info);
+        if (ret < 0) {
             gnutls_assert();
-            return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+            return ret;
         }
-    }
 
-    memset(&plist, 0, sizeof(plist));
-    if (find_data->flags==GNUTLS_PKCS11_CRT_ATTR_WITH_PK) {
         ret = find_privkeys(pks, info, &plist);
         if (ret < 0) {
             gnutls_assert();
@@ -1320,6 +1366,12 @@ static int find_crts(pakchois_session_t *pks, struct token_info *info, void* inp
             gnutls_assert();
             return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
         }
+    } else if (find_data->flags==GNUTLS_PKCS11_OBJ_ATTR_ALL) {
+        ret = pkcs11_login(pks, info);
+        if (ret < 0) {
+            gnutls_assert();
+            return ret;
+        }
     }
 
     cert_data = gnutls_malloc(MAX_CERT_SIZE);
@@ -1329,27 +1381,51 @@ static int find_crts(pakchois_session_t *pks, struct token_info *info, void* inp
     }
 
     /* Find objects with cert class and X.509 cert type. */
-    class = CKO_CERTIFICATE;
-    type = CKC_X_509;
-    trusted = 1;
-
-    a[0].type = CKA_CLASS;
-    a[0].value = &class;
-    a[0].value_len = sizeof class;
     
-    if (find_data->flags == GNUTLS_PKCS11_CRT_ATTR_ALL || find_data->flags==GNUTLS_PKCS11_CRT_ATTR_WITH_PK) {
+    if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL || find_data->flags==GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY) {
+        class = CKO_CERTIFICATE;
+        type = CKC_X_509;
+        trusted = 1;
+
+        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;
-    }
+        
+        tot_values = 2;
+    } else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED) {
+        class = CKO_CERTIFICATE;
+        type = CKC_X_509;
+        trusted = 1;
+
+        a[0].type = CKA_CLASS;
+        a[0].value = &class;
+        a[0].value_len = sizeof class;
 
-    if (find_data->flags == GNUTLS_PKCS11_CRT_ATTR_TRUSTED) {
         a[1].type = CKA_TRUSTED;
         a[1].value = &trusted;
         a[1].value_len = sizeof trusted;
+        
+        tot_values = 2;
+    } else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PUBKEY) {
+        class = CKO_PUBLIC_KEY;
+
+        a[0].type = CKA_CLASS;
+        a[0].value = &class;
+        a[0].value_len = sizeof class;
+        
+        tot_values = 1;
+    } else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL) {
+        tot_values = 0;
+    } else {
+        gnutls_assert();
+        return GNUTLS_E_INVALID_REQUEST;
     }
 
-    rv = pakchois_find_objects_init(pks, a, 2);
+    rv = pakchois_find_objects_init(pks, a, tot_values);
     if (rv != CKR_OK) {
         gnutls_assert();
         _gnutls_debug_log("pk11: FindObjectsInit failed.\n");
@@ -1358,54 +1434,75 @@ static int find_crts(pakchois_session_t *pks, struct token_info *info, void* inp
 
     while (pakchois_find_objects(pks, &obj, 1, &count) == CKR_OK
            && count == 1) {
+        gnutls_datum_t label, id, value;
+
+        a[0].type = CKA_LABEL;
+        a[0].value = label_tmp;
+        a[0].value_len = sizeof label_tmp;
+
+        if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
+            label.data = a[0].value;
+            label.size = a[0].value_len;
+        } else {
+            label.data = NULL;
+            label.size = 0;
+        }
+
+        a[0].type = CKA_ID;
+        a[0].value = certid_tmp;
+        a[0].value_len = sizeof certid_tmp;
+        if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
+            id.data = a[0].value;
+            id.size = a[0].value_len;
+        } else {
+            id.data = NULL;
+            id.size = 0;
+        }        
 
         a[0].type = CKA_VALUE;
         a[0].value = cert_data;
         a[0].value_len = MAX_CERT_SIZE;
-        a[1].type = CKA_ID;
-        a[1].value = certid_tmp;
-        a[1].value_len = sizeof(certid_tmp);
-        a[2].type = CKA_LABEL;
-        a[2].value = label_tmp;
-        a[2].value_len = sizeof label_tmp;
-
-        if (pakchois_get_attribute_value(pks, obj, a, 3) == CKR_OK) {
-            gnutls_datum_t data = { a[0].value, a[0].value_len };
-            gnutls_datum_t id = { a[1].value, a[1].value_len };
-            gnutls_datum_t label = { a[2].value, a[2].value_len };
-
-            /* XXX check also ID with find_data->info.id */
+        if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
+            value.data = a[0].value;
+            value.size = a[0].value_len;
+        } else {
+            value.data = NULL;
+            value.size = 0;
+        }        
 
-            if (find_data->flags == GNUTLS_PKCS11_CRT_ATTR_WITH_PK) {
-                for (i=0;i<plist.key_ids_size;i++) {
-                    if (plist.key_ids[i].length != a[1].value_len || memcmp(plist.key_ids[i].data, a[1].value, a[1].value_len)!=0) {
-                        /* not found */
-                        continue;
-                    }
-                }
-            }
+        if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL) {
+            a[0].type = CKA_CLASS;
+            a[0].value = &class;
+            a[0].value_len = sizeof class;
 
-            if (find_data->current < *find_data->n_list) {
+            pakchois_get_attribute_value(pks, obj, a, 1);
+        }
 
-                ret = gnutls_pkcs11_crt_init(&find_data->p_list[find_data->current]);
-                if (ret < 0) {
-                    gnutls_assert();
-                    goto fail;
+        if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY) {
+            for (i=0;i<plist.key_ids_size;i++) {
+                if (plist.key_ids[i].length != a[1].value_len || memcmp(plist.key_ids[i].data, a[1].value, a[1].value_len)!=0) {
+                    /* not found */
+                    continue;
                 }
+            }
+        }
 
-                ret = pkcs11_crt_import(find_data->p_list[find_data->current], &data, &id, &label, &info->tinfo);
-                if (ret < 0) {
-                    gnutls_assert();
-                    goto fail;
-                }
+        if (find_data->current < *find_data->n_list) {
+            ret = gnutls_pkcs11_obj_init(&find_data->p_list[find_data->current]);
+            if (ret < 0) {
+                gnutls_assert();
+                goto fail;
             }
-            
-            find_data->current++;
 
+            ret = pkcs11_obj_import(class, find_data->p_list[find_data->current], &value, &id, &label, &info->tinfo);
+            if (ret < 0) {
+                gnutls_assert();
+                goto fail;
+            }
         }
-        else {
-            _gnutls_debug_log("pk11: Skipped cert, missing attrs.\n");
-        }
+                
+        find_data->current++;
+
     }
 
     gnutls_free(cert_data);
@@ -1423,7 +1520,7 @@ fail:
         gnutls_free( plist.key_ids);
     }
     for (i=0;i<find_data->current;i++) {
-        gnutls_pkcs11_crt_deinit(find_data->p_list[i]);
+        gnutls_pkcs11_obj_deinit(find_data->p_list[i]);
     }
     find_data->current = 0;
 
@@ -1431,11 +1528,11 @@ fail:
 }
 
 /**
- * gnutls_pkcs11_crt_list_import_url:
+ * gnutls_pkcs11_obj_list_import_url:
  * @p_list: An uninitialized certificate list (may be NULL)
  * @n_list: initially should hold the maximum size of the list. Will contain the actual size.
  * @url: A PKCS 11 url identifying a set of certificates
- * @flags: Attributes of type #gnutls_pkcs11_crt_attr_t that can be used to limit output
+ * @flags: Attributes of type #gnutls_pkcs11_obj_attr_t that can be used to limit output
  *
  * This function will initialize and set value to a certificate list
  * specified by a PKCS 11 URL.
@@ -1443,7 +1540,7 @@ fail:
  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
  *   negative error value.
  **/
-int gnutls_pkcs11_crt_list_import_url (gnutls_pkcs11_crt_t * p_list, unsigned int *n_list, const char* url, gnutls_pkcs11_crt_attr_t flags)
+int gnutls_pkcs11_obj_list_import_url (gnutls_pkcs11_obj_t * p_list, unsigned int *n_list, const char* url, gnutls_pkcs11_obj_attr_t flags)
 {
     int ret;
     struct crt_find_data_st find_data;
@@ -1464,7 +1561,7 @@ int gnutls_pkcs11_crt_list_import_url (gnutls_pkcs11_crt_t * p_list, unsigned in
         return ret;
     }
 
-    ret = _pkcs11_traverse_tokens(find_crts, &find_data, 0);
+    ret = _pkcs11_traverse_tokens(find_objs, &find_data, 0);
     if (ret < 0) {
         gnutls_assert();
         return ret;
@@ -1479,7 +1576,7 @@ int gnutls_pkcs11_crt_list_import_url (gnutls_pkcs11_crt_t * p_list, unsigned in
  * @url: A PKCS 11 url
  *
  * This function will import a PKCS 11 certificate directly from a token
- * without involving the #gnutls_pkcs11_crt_t structure. This function will
+ * without involving the #gnutls_pkcs11_obj_t structure. This function will
  * fail if the certificate stored is not of X.509 type.
  *
  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
@@ -1487,16 +1584,16 @@ int gnutls_pkcs11_crt_list_import_url (gnutls_pkcs11_crt_t * p_list, unsigned in
  **/
 int gnutls_x509_crt_import_pkcs11_url( gnutls_x509_crt_t crt, const char* url)
 {
-    gnutls_pkcs11_crt_t pcrt;
+    gnutls_pkcs11_obj_t pcrt;
     int ret;
-
-    ret = gnutls_pkcs11_crt_init ( &pcrt);
+    
+    ret = gnutls_pkcs11_obj_init ( &pcrt);
     if (ret < 0) {
         gnutls_assert();
         return ret;
     }
 
-    ret = gnutls_pkcs11_crt_import_url (pcrt, url);
+    ret = gnutls_pkcs11_obj_import_url (pcrt, url);
     if (ret < 0) {
         gnutls_assert();
         goto cleanup;
@@ -1511,8 +1608,8 @@ int gnutls_x509_crt_import_pkcs11_url( gnutls_x509_crt_t crt, const char* url)
     ret = 0;
 cleanup:
 
-    gnutls_pkcs11_crt_deinit(pcrt);
-
+    gnutls_pkcs11_obj_deinit(pcrt);
+    
     return ret;
 }
 
@@ -1520,7 +1617,7 @@ cleanup:
 /**
  * gnutls_x509_crt_import_pkcs11:
  * @crt: A certificate of type #gnutls_x509_crt_t
- * @pkcs11_crt: A PKCS 11 certificate
+ * @pkcs11_obj: A PKCS 11 object that contains a certificate
  *
  * This function will import a PKCS 11 certificate to a #gnutls_x509_crt_t
  * structure.
@@ -1528,13 +1625,13 @@ cleanup:
  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
  *   negative error value.
  **/
-int gnutls_x509_crt_import_pkcs11( gnutls_x509_crt_t crt, gnutls_pkcs11_crt_t pkcs11_crt)
+int gnutls_x509_crt_import_pkcs11( gnutls_x509_crt_t crt, gnutls_pkcs11_obj_t pkcs11_crt)
 {
     return gnutls_x509_crt_import(crt, &pkcs11_crt->raw, GNUTLS_X509_FMT_DER);
 }
 
 int gnutls_x509_crt_list_import_pkcs11 (gnutls_x509_crt_t * certs,
-    unsigned int cert_max, gnutls_pkcs11_crt_t * const pkcs11_certs,
+    unsigned int cert_max, gnutls_pkcs11_obj_t * const pkcs11_certs,
     unsigned int flags)
 {
     int i, j;
@@ -1640,3 +1737,21 @@ int gnutls_pkcs11_token_get_flags(const char* url, unsigned int *flags)
 }
 
 
+const char* gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_type_t type)
+{
+    switch(type) {
+        case GNUTLS_PKCS11_OBJ_X509_CRT:
+            return "X.509 Certificate";
+        case GNUTLS_PKCS11_OBJ_PUBKEY:
+            return "Public key";
+        case GNUTLS_PKCS11_OBJ_PRIVKEY:
+            return "Private key";
+        case GNUTLS_PKCS11_OBJ_SECRET_KEY:
+            return "Secret key";
+        case GNUTLS_PKCS11_OBJ_DATA:
+            return "Data";
+        case GNUTLS_PKCS11_OBJ_UNKNOWN:
+        default:
+            return "Unknown";
+    }
+}
index c0708321f174800075a3808797bc321f5999d535..86cbba1ce4760346d2153181fec6789962fe6774 100644 (file)
@@ -29,6 +29,12 @@ struct pkcs11_url_info
     size_t certid_raw_size;
 };
 
+struct gnutls_pkcs11_obj_st {
+    gnutls_datum_t raw;
+    gnutls_pkcs11_obj_type_t type;
+    struct pkcs11_url_info info;
+};
+
 /* thus function is called for every token in the traverse_tokens
  * function. Once everything is traversed it is called with NULL tinfo.
  * It should return 0 if found what it was looking for.
@@ -38,7 +44,7 @@ typedef int (*find_func_t)(pakchois_session_t *pks, struct token_info* tinfo, vo
 int _pkcs11_traverse_tokens (find_func_t find_func, void* input, int leave_session);
 int pkcs11_url_to_info(const char* url, struct pkcs11_url_info* info);
 
-int pkcs11_get_info(struct pkcs11_url_info *info, gnutls_pkcs11_cert_info_t itype, 
+int pkcs11_get_info(struct pkcs11_url_info *info, gnutls_pkcs11_obj_info_t itype, 
     void* output, size_t* output_size);
 int pkcs11_login(pakchois_session_t *pks, struct token_info *info);
 
@@ -48,4 +54,5 @@ extern void* token_data;
 void pkcs11_rescan_slots(void);
 int pkcs11_info_to_url(const struct pkcs11_url_info* info, char** url);
 
+
 #endif
index 665e3f76cfdb30df737d2789a2e5a31e42760131..2ead5ab8fbdaa3e518d2240bf503a188e85dd010 100644 (file)
@@ -112,7 +112,7 @@ int gnutls_pkcs11_privkey_get_pk_algorithm(gnutls_pkcs11_privkey_t key, unsigned
  * Returns: zero on success or a negative value on error.
  **/
 int gnutls_pkcs11_privkey_get_info(gnutls_pkcs11_privkey_t pkey,
-                                  gnutls_pkcs11_cert_info_t itype,
+                                  gnutls_pkcs11_obj_info_t itype,
                                   void *output, size_t * output_size)
 {
        return pkcs11_get_info(&pkey->info, itype, output, output_size);
index 58aefda57aeeacfc361b9e5e61de760465d42b76..b3bea0e4d9031eb34cf063b3c75d20660383ea3d 100644 (file)
@@ -1138,6 +1138,18 @@ cleanup:
   return result;
 }
 
+void _asnstr_append_name(char* name, size_t name_size, const char* part1, const char* part2)
+{
+  if (part1[0] != 0) 
+    {
+         _gnutls_str_cpy (name, name_size, part1);
+         _gnutls_str_cat (name, name_size, part2);
+    }
+  else
+         _gnutls_str_cpy (name, name_size, part2+1 /* remove initial dot */);
+}
+
+
 /* Encodes and copies the private key parameters into a
  * subjectPublicKeyInfo structure.
  *
@@ -1163,8 +1175,8 @@ _gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst,
 
   /* write the OID
    */
-  _gnutls_str_cpy (name, sizeof (name), dst_name);
-  _gnutls_str_cat (name, sizeof (name), ".algorithm.algorithm");
+  _asnstr_append_name(name, sizeof(name), dst_name, ".algorithm.algorithm");
+
   result = asn1_write_value (dst, name, pk, 1);
   if (result != ASN1_SUCCESS)
     {
@@ -1176,8 +1188,8 @@ _gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst,
     {
       /* disable parameters, which are not used in RSA.
        */
-      _gnutls_str_cpy (name, sizeof (name), dst_name);
-      _gnutls_str_cat (name, sizeof (name), ".algorithm.parameters");
+         _asnstr_append_name(name, sizeof(name), dst_name, ".algorithm.parameters");
+
       result = asn1_write_value (dst, name, NULL, 0);
       if (result != ASN1_SUCCESS)
        {
@@ -1194,8 +1206,7 @@ _gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst,
 
       /* Write the DER parameters. (in bits)
        */
-      _gnutls_str_cpy (name, sizeof (name), dst_name);
-      _gnutls_str_cat (name, sizeof (name), ".subjectPublicKey");
+         _asnstr_append_name(name, sizeof(name), dst_name, ".subjectPublicKey");
       result = asn1_write_value (dst, name, der.data, der.size * 8);
 
       _gnutls_free_datum (&der);
@@ -1218,8 +1229,7 @@ _gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst,
 
       /* Write the DER parameters.
        */
-      _gnutls_str_cpy (name, sizeof (name), dst_name);
-      _gnutls_str_cat (name, sizeof (name), ".algorithm.parameters");
+         _asnstr_append_name(name, sizeof(name), dst_name, ".algorithm.parameters");
       result = asn1_write_value (dst, name, der.data, der.size);
 
       _gnutls_free_datum (&der);
@@ -1237,8 +1247,7 @@ _gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst,
          return result;
        }
 
-      _gnutls_str_cpy (name, sizeof (name), dst_name);
-      _gnutls_str_cat (name, sizeof (name), ".subjectPublicKey");
+         _asnstr_append_name(name, sizeof(name), dst_name, ".subjectPublicKey");
       result = asn1_write_value (dst, name, der.data, der.size * 8);
 
       _gnutls_free_datum (&der);
@@ -1271,9 +1280,8 @@ _gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name,
   bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
   char name[128];
 
-  _gnutls_str_cpy (name, sizeof (name), src_name);
-  _gnutls_str_cat (name, sizeof (name), ".algorithm.algorithm");
 
+  _asnstr_append_name(name, sizeof(name), src_name, ".algorithm.algorithm");
   len = sizeof (oid);
   result = asn1_read_value (src, name, oid, &len);
 
@@ -1297,8 +1305,7 @@ _gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name,
 
   /* Now read the parameters' bits 
    */
-  _gnutls_str_cpy (name, sizeof (name), src_name);
-  _gnutls_str_cat (name, sizeof (name), ".subjectPublicKey");
+  _asnstr_append_name(name, sizeof(name), src_name, ".subjectPublicKey");
 
   len = 0;
   result = asn1_read_value (src, name, NULL, &len);
@@ -1323,8 +1330,7 @@ _gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name,
       return GNUTLS_E_MEMORY_ERROR;
     }
 
-  _gnutls_str_cpy (name, sizeof (name), src_name);
-  _gnutls_str_cat (name, sizeof (name), ".subjectPublicKey");
+  _asnstr_append_name(name, sizeof(name), src_name, ".subjectPublicKey");
 
   result = asn1_read_value (src, name, str, &len);
 
index e52e32c115510926533f6a97110387e00af71495..aba51b99c2a651772334612776e4df171d1f1a46 100644 (file)
@@ -131,4 +131,12 @@ int _gnutls_x509_get_signature (ASN1_TYPE src, const char *src_name,
 
 gnutls_digest_algorithm_t _gnutls_dsa_q_to_hash(bigint_t q);
 
+int _gnutls_get_asn_mpis (ASN1_TYPE asn, const char *root,
+          bigint_t * params, int *params_size);
+
+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);
+
+void _asnstr_append_name(char* name, size_t name_size, const char* part1, const char* part2);
+
 #endif
index 7b4e7d4596e8243d66a83f3fbbd67d09475e8cf3..62f581f740eee4e5376cc2b7fe03c2afb6c68f03 100644 (file)
@@ -206,23 +206,32 @@ _gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, bigint_t * params)
 
 /* Extracts DSA and RSA parameters from a certificate.
  */
-static int
-get_mpis (int pk_algorithm, ASN1_TYPE asn, const char *root,
+int
+_gnutls_get_asn_mpis (ASN1_TYPE asn, const char *root,
          bigint_t * params, int *params_size)
 {
   int result;
   char name[256];
   gnutls_datum_t tmp = { NULL, 0 };
+  gnutls_pk_algorithm pk_algorithm;
+
+  result = _gnutls_x509_get_pk_algorithm(asn, root, NULL);
+  if (result < 0)
+    {
+      gnutls_assert();
+      return result;
+    }
+  
+  pk_algorithm = result;
 
   /* Read the algorithm's parameters
    */
-  snprintf (name, sizeof (name), "%s.subjectPublicKey", root);
+  _asnstr_append_name(name, sizeof(name), root, ".subjectPublicKey");
   result = _gnutls_x509_read_value (asn, name, &tmp, 2);
 
   if (result < 0)
     {
       gnutls_assert ();
-      fprintf (stderr, "name: %s\n", name);
       return result;
     }
 
@@ -275,7 +284,7 @@ get_mpis (int pk_algorithm, ASN1_TYPE asn, const char *root,
        */
       _gnutls_free_datum (&tmp);
 
-      snprintf (name, sizeof (name), "%s.algorithm.parameters", root);
+      _asnstr_append_name(name, sizeof(name), root, ".algorithm.parameters");
       result = _gnutls_x509_read_value (asn, name, &tmp, 0);
 
       /* FIXME: If the parameters are not included in the certificate
@@ -321,13 +330,9 @@ int
 _gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert,
                           bigint_t * params, int *params_size)
 {
-  int pk_algorithm;
-
   /* Read the algorithm's OID
    */
-  pk_algorithm = gnutls_x509_crt_get_pk_algorithm (cert, NULL);
-
-  return get_mpis (pk_algorithm, cert->cert,
+  return _gnutls_get_asn_mpis (cert->cert,
                   "tbsCertificate.subjectPublicKeyInfo", params,
                   params_size);
 }
@@ -340,13 +345,9 @@ int
 _gnutls_x509_crq_get_mpis (gnutls_x509_crq_t cert,
                           bigint_t * params, int *params_size)
 {
-  int pk_algorithm;
-
   /* Read the algorithm's OID
    */
-  pk_algorithm = gnutls_x509_crq_get_pk_algorithm (cert, NULL);
-
-  return get_mpis (pk_algorithm, cert->crq,
+  return _gnutls_get_asn_mpis (cert->crq,
                   "certificationRequestInfo.subjectPKInfo", params,
                   params_size);
 }
index 94a8b81b48604d3f513f5d6f2db6ca5382b9cec7..9c22ada3f0907d6635594122e6addd7b0325ab4c 100644 (file)
@@ -2184,22 +2184,19 @@ gnutls_x509_crt_export (gnutls_x509_crt_t cert,
                                  output_data, output_data_size);
 }
 
-
-static int
-rsadsa_get_key_id (gnutls_x509_crt_t crt, int pk,
+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)
 {
-  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)
+  if (output_data==NULL || *output_data_size < 0)
     {
-      gnutls_assert ();
-      return result;
+      gnutls_assert();
+      *output_data_size = 20;
+      return GNUTLS_E_SHORT_MEMORY_BUFFER;
     }
 
   if (pk == GNUTLS_PK_RSA)
@@ -2240,6 +2237,37 @@ rsadsa_get_key_id (gnutls_x509_crt_t crt, int pk,
 cleanup:
 
   _gnutls_free_datum (&der);
+  return result;
+}
+
+
+static int
+rsadsa_get_key_id (gnutls_x509_crt_t crt, int pk,
+                  unsigned char *output_data, size_t * output_data_size)
+{
+  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)
+    {
+      gnutls_assert ();
+      return result;
+    }
+
+  result = _gnutls_get_key_id(pk, params, params_size, output_data, output_data_size);
+  if (result < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  result = 0;
+
+cleanup:
 
   /* release all allocated MPIs
    */
@@ -2308,6 +2336,9 @@ gnutls_x509_crt_get_key_id (gnutls_x509_crt_t crt, unsigned int flags,
       return rsadsa_get_key_id (crt, pk, output_data, output_data_size);
     }
 
+  /* FIXME: what does this code do here? Isn't identical to the code
+   * in rsadsa_get_key_id?
+   */
   pubkey.size = 0;
   result = asn1_der_coding (crt->cert, "tbsCertificate.subjectPublicKeyInfo",
                            NULL, &pubkey.size, NULL);
index ea68d59d23191b8d4d3c7022b66527e47c32d925..0ad3f6b284c0f7f7d0d1d02112f33f82c854163a 100644 (file)
@@ -303,6 +303,8 @@ int _gnutls_x509_write_uint32 (ASN1_TYPE node, const char *value,
 int _gnutls_x509_write_sig_params (ASN1_TYPE dst, const char *dst_name,
                                   gnutls_pk_algorithm_t pk_algorithm,
                                   gnutls_digest_algorithm_t);
+
+
 /* pkcs12.h */
 #include <gnutls/pkcs12.h>
 
index ae6891e9abb91d0fbbb75ec11f844f3f9ee8ad6d..f5db0abd80f4c46f6ff3b2febf8e5803465cacd7 100644 (file)
@@ -29,6 +29,7 @@ enum
   ACTION_PKCS11_LIST,
   ACTION_PKCS11_TOKENS,
   ACTION_PKCS11_EXPORT_URL,
+  ACTION_PUBKEY_INFO,
 };
 
 #define TYPE_CRT 1
@@ -39,9 +40,10 @@ void pkcs11_list( FILE*outfile, const char* url, int type);
 void pkcs11_export(FILE* outfile, const char *pkcs11_url);
 void pkcs11_token_list(FILE* outfile);
 
-#define PKCS11_TYPE_ALL 1
+#define PKCS11_TYPE_CRT_ALL 1
 #define PKCS11_TYPE_TRUSTED 2
 #define PKCS11_TYPE_PK 3
+#define PKCS11_TYPE_ALL 4
 
 extern unsigned char buffer[];
 extern const int buffer_size;
index 7af11a5f5912afcbcf596945cbdc8e45871449a3..7ccd9e154429d41956957ab6f28cc5e2c6108570 100644 (file)
@@ -141,6 +141,7 @@ void gaa_help(void)
        __gaa_helpsingle(0, "generate-dh-params", "", "Generate PKCS #3 encoded Diffie-Hellman parameters.");
        __gaa_helpsingle(0, "get-dh-params", "", "Get the included PKCS #3 encoded Diffie-Hellman parameters.");
        __gaa_helpsingle(0, "load-privkey", "FILE ", "Private key file to use.");
+       __gaa_helpsingle(0, "load-pubkey", "FILE ", "Private key file to use.");
        __gaa_helpsingle(0, "load-request", "FILE ", "Certificate request file to use.");
        __gaa_helpsingle(0, "load-certificate", "FILE ", "Certificate file to use.");
        __gaa_helpsingle(0, "load-ca-privkey", "FILE ", "Certificate authority's private key file to use.");
@@ -157,6 +158,7 @@ void gaa_help(void)
        __gaa_helpsingle(0, "smime-to-p7", "", "Convert S/MIME to PKCS #7 structure.");
        __gaa_helpsingle('k', "key-info", "", "Print information on a private key.");
        __gaa_helpsingle(0, "pgp-key-info", "", "Print information on a OpenPGP private key.");
+       __gaa_helpsingle(0, "pubkey-info", "", "Print information on a public key.");
        __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.");
@@ -177,8 +179,9 @@ void gaa_help(void)
        __gaa_helpsingle(0, "pkcs-cipher", "CIPHER ", "Cipher to use for pkcs operations (3des,aes-128,aes-192,aes-256,rc2-40).");
        __gaa_helpsingle(0, "pkcs11-provider", "Library ", "Specify the pkcs11 provider library");
        __gaa_helpsingle(0, "pkcs11-export-url", "URL ", "Export data specified a pkcs11 URL");
-       __gaa_helpsingle(0, "pkcs11-list", "", "List objects specified by a PKCS#11 URL");
-       __gaa_helpsingle(0, "pkcs11-list-trusted", "", "List objects marked as trusted, specified by a PKCS#11 URL");
+       __gaa_helpsingle(0, "pkcs11-list-certs", "", "List certificates specified by a PKCS#11 URL");
+       __gaa_helpsingle(0, "pkcs11-list-trusted", "", "List certificates marked as trusted, specified by a PKCS#11 URL");
+       __gaa_helpsingle(0, "pkcs11-list-all-certs", "", "List all certificates specified by a PKCS#11 URL");
        __gaa_helpsingle(0, "pkcs11-list-all", "", "List all objects specified by a PKCS#11 URL");
        __gaa_helpsingle(0, "pkcs11-list-tokens", "", "List all available tokens");
        __gaa_helpsingle('d', "debug", "LEVEL ", "specify the debug level. Default is 1.");
@@ -198,54 +201,56 @@ typedef struct _gaainfo gaainfo;
 
 struct _gaainfo
 {
-#line 143 "certtool.gaa"
+#line 149 "certtool.gaa"
        int debug;
-#line 137 "certtool.gaa"
+#line 142 "certtool.gaa"
        int pkcs11_type;
-#line 134 "certtool.gaa"
+#line 139 "certtool.gaa"
        char* pkcs11_url;
-#line 131 "certtool.gaa"
+#line 136 "certtool.gaa"
        char* pkcs11_provider;
-#line 128 "certtool.gaa"
+#line 133 "certtool.gaa"
        char *pkcs_cipher;
-#line 125 "certtool.gaa"
+#line 130 "certtool.gaa"
        char *template;
-#line 122 "certtool.gaa"
+#line 127 "certtool.gaa"
        char *infile;
-#line 119 "certtool.gaa"
+#line 124 "certtool.gaa"
        char *outfile;
-#line 116 "certtool.gaa"
+#line 121 "certtool.gaa"
        int quick_random;
-#line 113 "certtool.gaa"
+#line 118 "certtool.gaa"
        int bits;
-#line 109 "certtool.gaa"
+#line 114 "certtool.gaa"
        int outcert_format;
-#line 105 "certtool.gaa"
+#line 110 "certtool.gaa"
        int incert_format;
-#line 102 "certtool.gaa"
+#line 107 "certtool.gaa"
        int export;
-#line 99 "certtool.gaa"
+#line 104 "certtool.gaa"
        char *hash;
-#line 96 "certtool.gaa"
+#line 101 "certtool.gaa"
        int dsa;
-#line 93 "certtool.gaa"
+#line 98 "certtool.gaa"
        int pkcs8;
-#line 85 "certtool.gaa"
+#line 90 "certtool.gaa"
        int v1_cert;
-#line 82 "certtool.gaa"
+#line 87 "certtool.gaa"
        int fix_key;
-#line 67 "certtool.gaa"
+#line 70 "certtool.gaa"
        int crq_extensions;
-#line 54 "certtool.gaa"
+#line 57 "certtool.gaa"
        char *pass;
-#line 51 "certtool.gaa"
+#line 54 "certtool.gaa"
        char *ca;
-#line 48 "certtool.gaa"
+#line 51 "certtool.gaa"
        char *ca_privkey;
-#line 45 "certtool.gaa"
+#line 48 "certtool.gaa"
        char *cert;
-#line 42 "certtool.gaa"
+#line 45 "certtool.gaa"
        char *request;
+#line 42 "certtool.gaa"
+       char *pubkey;
 #line 39 "certtool.gaa"
        char *privkey;
 #line 17 "certtool.gaa"
@@ -306,62 +311,65 @@ static int gaa_error = 0;
 #define GAA_MULTIPLE_OPTION     3
 
 #define GAA_REST                0
-#define GAA_NB_OPTION           55
+#define GAA_NB_OPTION           58
 #define GAAOPTID_version       1
 #define GAAOPTID_help  2
 #define GAAOPTID_debug 3
 #define GAAOPTID_pkcs11_list_tokens    4
 #define GAAOPTID_pkcs11_list_all       5
-#define GAAOPTID_pkcs11_list_trusted   6
-#define GAAOPTID_pkcs11_list   7
-#define GAAOPTID_pkcs11_export_url     8
-#define GAAOPTID_pkcs11_provider       9
-#define GAAOPTID_pkcs_cipher   10
-#define GAAOPTID_template      11
-#define GAAOPTID_infile        12
-#define GAAOPTID_outfile       13
-#define GAAOPTID_disable_quick_random  14
-#define GAAOPTID_bits  15
-#define GAAOPTID_outraw        16
-#define GAAOPTID_outder        17
-#define GAAOPTID_inraw 18
-#define GAAOPTID_inder 19
-#define GAAOPTID_export_ciphers        20
-#define GAAOPTID_hash  21
-#define GAAOPTID_dsa   22
-#define GAAOPTID_pkcs8 23
-#define GAAOPTID_to_p8 24
-#define GAAOPTID_to_p12        25
-#define GAAOPTID_v1    26
-#define GAAOPTID_fix_key       27
-#define GAAOPTID_pgp_key_info  28
-#define GAAOPTID_key_info      29
-#define GAAOPTID_smime_to_p7   30
-#define GAAOPTID_p7_info       31
-#define GAAOPTID_p12_info      32
-#define GAAOPTID_no_crq_extensions     33
-#define GAAOPTID_crq_info      34
-#define GAAOPTID_crl_info      35
-#define GAAOPTID_pgp_ring_info 36
-#define GAAOPTID_pgp_certificate_info  37
-#define GAAOPTID_certificate_info      38
-#define GAAOPTID_password      39
-#define GAAOPTID_load_ca_certificate   40
-#define GAAOPTID_load_ca_privkey       41
-#define GAAOPTID_load_certificate      42
-#define GAAOPTID_load_request  43
-#define GAAOPTID_load_privkey  44
-#define GAAOPTID_get_dh_params 45
-#define GAAOPTID_generate_dh_params    46
-#define GAAOPTID_verify_crl    47
-#define GAAOPTID_verify_chain  48
-#define GAAOPTID_generate_request      49
-#define GAAOPTID_generate_privkey      50
-#define GAAOPTID_update_certificate    51
-#define GAAOPTID_generate_crl  52
-#define GAAOPTID_generate_proxy        53
-#define GAAOPTID_generate_certificate  54
-#define GAAOPTID_generate_self_signed  55
+#define GAAOPTID_pkcs11_list_all_certs 6
+#define GAAOPTID_pkcs11_list_trusted   7
+#define GAAOPTID_pkcs11_list_certs     8
+#define GAAOPTID_pkcs11_export_url     9
+#define GAAOPTID_pkcs11_provider       10
+#define GAAOPTID_pkcs_cipher   11
+#define GAAOPTID_template      12
+#define GAAOPTID_infile        13
+#define GAAOPTID_outfile       14
+#define GAAOPTID_disable_quick_random  15
+#define GAAOPTID_bits  16
+#define GAAOPTID_outraw        17
+#define GAAOPTID_outder        18
+#define GAAOPTID_inraw 19
+#define GAAOPTID_inder 20
+#define GAAOPTID_export_ciphers        21
+#define GAAOPTID_hash  22
+#define GAAOPTID_dsa   23
+#define GAAOPTID_pkcs8 24
+#define GAAOPTID_to_p8 25
+#define GAAOPTID_to_p12        26
+#define GAAOPTID_v1    27
+#define GAAOPTID_fix_key       28
+#define GAAOPTID_pubkey_info   29
+#define GAAOPTID_pgp_key_info  30
+#define GAAOPTID_key_info      31
+#define GAAOPTID_smime_to_p7   32
+#define GAAOPTID_p7_info       33
+#define GAAOPTID_p12_info      34
+#define GAAOPTID_no_crq_extensions     35
+#define GAAOPTID_crq_info      36
+#define GAAOPTID_crl_info      37
+#define GAAOPTID_pgp_ring_info 38
+#define GAAOPTID_pgp_certificate_info  39
+#define GAAOPTID_certificate_info      40
+#define GAAOPTID_password      41
+#define GAAOPTID_load_ca_certificate   42
+#define GAAOPTID_load_ca_privkey       43
+#define GAAOPTID_load_certificate      44
+#define GAAOPTID_load_request  45
+#define GAAOPTID_load_pubkey   46
+#define GAAOPTID_load_privkey  47
+#define GAAOPTID_get_dh_params 48
+#define GAAOPTID_generate_dh_params    49
+#define GAAOPTID_verify_crl    50
+#define GAAOPTID_verify_chain  51
+#define GAAOPTID_generate_request      52
+#define GAAOPTID_generate_privkey      53
+#define GAAOPTID_update_certificate    54
+#define GAAOPTID_generate_crl  55
+#define GAAOPTID_generate_proxy        56
+#define GAAOPTID_generate_certificate  57
+#define GAAOPTID_generate_self_signed  58
 
 #line 168 "gaa.skel"
 
@@ -632,6 +640,12 @@ struct GAAOPTION_load_request
        int size1;
 };
 
+struct GAAOPTION_load_pubkey 
+{
+       char* arg1;
+       int size1;
+};
+
 struct GAAOPTION_load_privkey 
 {
        char* arg1;
@@ -681,6 +695,7 @@ static int gaa_get_option_num(char *str, int status)
                        GAA_CHECK1STR("", GAAOPTID_load_ca_privkey);
                        GAA_CHECK1STR("", GAAOPTID_load_certificate);
                        GAA_CHECK1STR("", GAAOPTID_load_request);
+                       GAA_CHECK1STR("", GAAOPTID_load_pubkey);
                        GAA_CHECK1STR("", GAAOPTID_load_privkey);
         case GAA_MULTIPLE_OPTION:
 #line 375 "gaa.skel"
@@ -688,8 +703,9 @@ static int gaa_get_option_num(char *str, int status)
                        GAA_CHECK1STR("h", GAAOPTID_help);
                        GAA_CHECK1STR("", GAAOPTID_pkcs11_list_tokens);
                        GAA_CHECK1STR("", GAAOPTID_pkcs11_list_all);
+                       GAA_CHECK1STR("", GAAOPTID_pkcs11_list_all_certs);
                        GAA_CHECK1STR("", GAAOPTID_pkcs11_list_trusted);
-                       GAA_CHECK1STR("", GAAOPTID_pkcs11_list);
+                       GAA_CHECK1STR("", GAAOPTID_pkcs11_list_certs);
                        GAA_CHECK1STR("", GAAOPTID_disable_quick_random);
                        GAA_CHECK1STR("", GAAOPTID_outraw);
                        GAA_CHECK1STR("", GAAOPTID_outder);
@@ -702,6 +718,7 @@ static int gaa_get_option_num(char *str, int status)
                        GAA_CHECK1STR("", GAAOPTID_to_p12);
                        GAA_CHECK1STR("", GAAOPTID_v1);
                        GAA_CHECK1STR("", GAAOPTID_fix_key);
+                       GAA_CHECK1STR("", GAAOPTID_pubkey_info);
                        GAA_CHECK1STR("", GAAOPTID_pgp_key_info);
                        GAA_CHECK1STR("k", GAAOPTID_key_info);
                        GAA_CHECK1STR("", GAAOPTID_smime_to_p7);
@@ -733,8 +750,9 @@ static int gaa_get_option_num(char *str, int status)
                        GAA_CHECKSTR("debug", GAAOPTID_debug);
                        GAA_CHECKSTR("pkcs11-list-tokens", GAAOPTID_pkcs11_list_tokens);
                        GAA_CHECKSTR("pkcs11-list-all", GAAOPTID_pkcs11_list_all);
+                       GAA_CHECKSTR("pkcs11-list-all-certs", GAAOPTID_pkcs11_list_all_certs);
                        GAA_CHECKSTR("pkcs11-list-trusted", GAAOPTID_pkcs11_list_trusted);
-                       GAA_CHECKSTR("pkcs11-list", GAAOPTID_pkcs11_list);
+                       GAA_CHECKSTR("pkcs11-list-certs", GAAOPTID_pkcs11_list_certs);
                        GAA_CHECKSTR("pkcs11-export-url", GAAOPTID_pkcs11_export_url);
                        GAA_CHECKSTR("pkcs11-provider", GAAOPTID_pkcs11_provider);
                        GAA_CHECKSTR("pkcs-cipher", GAAOPTID_pkcs_cipher);
@@ -755,6 +773,7 @@ static int gaa_get_option_num(char *str, int status)
                        GAA_CHECKSTR("to-p12", GAAOPTID_to_p12);
                        GAA_CHECKSTR("v1", GAAOPTID_v1);
                        GAA_CHECKSTR("fix-key", GAAOPTID_fix_key);
+                       GAA_CHECKSTR("pubkey-info", GAAOPTID_pubkey_info);
                        GAA_CHECKSTR("pgp-key-info", GAAOPTID_pgp_key_info);
                        GAA_CHECKSTR("key-info", GAAOPTID_key_info);
                        GAA_CHECKSTR("smime-to-p7", GAAOPTID_smime_to_p7);
@@ -771,6 +790,7 @@ static int gaa_get_option_num(char *str, int status)
                        GAA_CHECKSTR("load-ca-privkey", GAAOPTID_load_ca_privkey);
                        GAA_CHECKSTR("load-certificate", GAAOPTID_load_certificate);
                        GAA_CHECKSTR("load-request", GAAOPTID_load_request);
+                       GAA_CHECKSTR("load-pubkey", GAAOPTID_load_pubkey);
                        GAA_CHECKSTR("load-privkey", GAAOPTID_load_privkey);
                        GAA_CHECKSTR("get-dh-params", GAAOPTID_get_dh_params);
                        GAA_CHECKSTR("generate-dh-params", GAAOPTID_generate_dh_params);
@@ -809,6 +829,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
        struct GAAOPTION_load_ca_privkey GAATMP_load_ca_privkey;
        struct GAAOPTION_load_certificate GAATMP_load_certificate;
        struct GAAOPTION_load_request GAATMP_load_request;
+       struct GAAOPTION_load_pubkey GAATMP_load_pubkey;
        struct GAAOPTION_load_privkey GAATMP_load_privkey;
 
 #line 393 "gaa.skel"
@@ -832,14 +853,14 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
     {
        case GAAOPTID_version:
        OK = 0;
-#line 148 "certtool.gaa"
+#line 154 "certtool.gaa"
 { certtool_version(); exit(0); ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_help:
        OK = 0;
-#line 146 "certtool.gaa"
+#line 152 "certtool.gaa"
 { gaa_help(); exit(0); ;};
 
                return GAA_OK;
@@ -849,35 +870,42 @@ 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 144 "certtool.gaa"
+#line 150 "certtool.gaa"
 { gaaval->debug = GAATMP_debug.arg1 ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_pkcs11_list_tokens:
        OK = 0;
-#line 141 "certtool.gaa"
+#line 147 "certtool.gaa"
 { gaaval->action = ACTION_PKCS11_TOKENS; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_pkcs11_list_all:
        OK = 0;
-#line 140 "certtool.gaa"
+#line 146 "certtool.gaa"
 { gaaval->action = ACTION_PKCS11_LIST; gaaval->pkcs11_type=PKCS11_TYPE_ALL; ;};
 
+               return GAA_OK;
+               break;
+       case GAAOPTID_pkcs11_list_all_certs:
+       OK = 0;
+#line 145 "certtool.gaa"
+{ gaaval->action = ACTION_PKCS11_LIST; gaaval->pkcs11_type=PKCS11_TYPE_CRT_ALL; ;};
+
                return GAA_OK;
                break;
        case GAAOPTID_pkcs11_list_trusted:
        OK = 0;
-#line 139 "certtool.gaa"
+#line 144 "certtool.gaa"
 { gaaval->action = ACTION_PKCS11_LIST; gaaval->pkcs11_type=PKCS11_TYPE_TRUSTED; ;};
 
                return GAA_OK;
                break;
-       case GAAOPTID_pkcs11_list:
+       case GAAOPTID_pkcs11_list_certs:
        OK = 0;
-#line 138 "certtool.gaa"
+#line 143 "certtool.gaa"
 { gaaval->action = ACTION_PKCS11_LIST; gaaval->pkcs11_type=PKCS11_TYPE_PK; ;};
 
                return GAA_OK;
@@ -887,7 +915,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_pkcs11_export_url.arg1, gaa_getstr, GAATMP_pkcs11_export_url.size1);
                gaa_index++;
-#line 135 "certtool.gaa"
+#line 140 "certtool.gaa"
 { gaaval->action = ACTION_PKCS11_EXPORT_URL; gaaval->pkcs11_url = GAATMP_pkcs11_export_url.arg1; ;};
 
                return GAA_OK;
@@ -897,7 +925,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_pkcs11_provider.arg1, gaa_getstr, GAATMP_pkcs11_provider.size1);
                gaa_index++;
-#line 132 "certtool.gaa"
+#line 137 "certtool.gaa"
 { gaaval->pkcs11_provider = GAATMP_pkcs11_provider.arg1 ;};
 
                return GAA_OK;
@@ -907,7 +935,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_pkcs_cipher.arg1, gaa_getstr, GAATMP_pkcs_cipher.size1);
                gaa_index++;
-#line 129 "certtool.gaa"
+#line 134 "certtool.gaa"
 { gaaval->pkcs_cipher = GAATMP_pkcs_cipher.arg1 ;};
 
                return GAA_OK;
@@ -917,7 +945,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 126 "certtool.gaa"
+#line 131 "certtool.gaa"
 { gaaval->template = GAATMP_template.arg1 ;};
 
                return GAA_OK;
@@ -927,7 +955,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 123 "certtool.gaa"
+#line 128 "certtool.gaa"
 { gaaval->infile = GAATMP_infile.arg1 ;};
 
                return GAA_OK;
@@ -937,14 +965,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 120 "certtool.gaa"
+#line 125 "certtool.gaa"
 { gaaval->outfile = GAATMP_outfile.arg1 ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_disable_quick_random:
        OK = 0;
-#line 117 "certtool.gaa"
+#line 122 "certtool.gaa"
 { gaaval->quick_random = 0; ;};
 
                return GAA_OK;
@@ -954,42 +982,42 @@ 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 114 "certtool.gaa"
+#line 119 "certtool.gaa"
 { gaaval->bits = GAATMP_bits.arg1 ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_outraw:
        OK = 0;
-#line 111 "certtool.gaa"
+#line 116 "certtool.gaa"
 { gaaval->outcert_format=1 ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_outder:
        OK = 0;
-#line 110 "certtool.gaa"
+#line 115 "certtool.gaa"
 { gaaval->outcert_format=1 ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_inraw:
        OK = 0;
-#line 107 "certtool.gaa"
+#line 112 "certtool.gaa"
 { gaaval->incert_format=1 ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_inder:
        OK = 0;
-#line 106 "certtool.gaa"
+#line 111 "certtool.gaa"
 { gaaval->incert_format=1 ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_export_ciphers:
        OK = 0;
-#line 103 "certtool.gaa"
+#line 108 "certtool.gaa"
 { gaaval->export=1 ;};
 
                return GAA_OK;
@@ -999,126 +1027,133 @@ 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 100 "certtool.gaa"
+#line 105 "certtool.gaa"
 { gaaval->hash = GAATMP_hash.arg1 ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_dsa:
        OK = 0;
-#line 97 "certtool.gaa"
+#line 102 "certtool.gaa"
 { gaaval->dsa=1 ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_pkcs8:
        OK = 0;
-#line 94 "certtool.gaa"
+#line 99 "certtool.gaa"
 { gaaval->pkcs8=1 ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_to_p8:
        OK = 0;
-#line 90 "certtool.gaa"
+#line 95 "certtool.gaa"
 { gaaval->action = ACTION_GENERATE_PKCS8; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_to_p12:
        OK = 0;
-#line 88 "certtool.gaa"
+#line 93 "certtool.gaa"
 { gaaval->action = ACTION_TO_PKCS12; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_v1:
        OK = 0;
-#line 86 "certtool.gaa"
+#line 91 "certtool.gaa"
 { gaaval->v1_cert = 1; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_fix_key:
        OK = 0;
-#line 83 "certtool.gaa"
+#line 88 "certtool.gaa"
 { gaaval->privkey_op=1; gaaval->fix_key = 1; ;};
 
+               return GAA_OK;
+               break;
+       case GAAOPTID_pubkey_info:
+       OK = 0;
+#line 85 "certtool.gaa"
+{ gaaval->action = ACTION_PUBKEY_INFO; ;};
+
                return GAA_OK;
                break;
        case GAAOPTID_pgp_key_info:
        OK = 0;
-#line 80 "certtool.gaa"
+#line 83 "certtool.gaa"
 { gaaval->privkey_op=1; gaaval->action = ACTION_PGP_PRIVKEY_INFO; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_key_info:
        OK = 0;
-#line 78 "certtool.gaa"
+#line 81 "certtool.gaa"
 { gaaval->privkey_op=1; gaaval->action = ACTION_PRIVKEY_INFO; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_smime_to_p7:
        OK = 0;
-#line 74 "certtool.gaa"
+#line 77 "certtool.gaa"
 { gaaval->action = ACTION_SMIME_TO_P7; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_p7_info:
        OK = 0;
-#line 72 "certtool.gaa"
+#line 75 "certtool.gaa"
 { gaaval->action = ACTION_P7_INFO; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_p12_info:
        OK = 0;
-#line 70 "certtool.gaa"
+#line 73 "certtool.gaa"
 { gaaval->action = ACTION_PKCS12_INFO; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_no_crq_extensions:
        OK = 0;
-#line 68 "certtool.gaa"
+#line 71 "certtool.gaa"
 { gaaval->crq_extensions = 0; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_crq_info:
        OK = 0;
-#line 65 "certtool.gaa"
+#line 68 "certtool.gaa"
 { gaaval->action = ACTION_REQUEST; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_crl_info:
        OK = 0;
-#line 63 "certtool.gaa"
+#line 66 "certtool.gaa"
 { gaaval->action = ACTION_CRL_INFO; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_pgp_ring_info:
        OK = 0;
-#line 61 "certtool.gaa"
+#line 64 "certtool.gaa"
 { gaaval->action = ACTION_RING_INFO; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_pgp_certificate_info:
        OK = 0;
-#line 59 "certtool.gaa"
+#line 62 "certtool.gaa"
 { gaaval->action = ACTION_PGP_INFO; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_certificate_info:
        OK = 0;
-#line 57 "certtool.gaa"
+#line 60 "certtool.gaa"
 { gaaval->action = ACTION_CERT_INFO; ;};
 
                return GAA_OK;
@@ -1128,7 +1163,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_password.arg1, gaa_getstr, GAATMP_password.size1);
                gaa_index++;
-#line 55 "certtool.gaa"
+#line 58 "certtool.gaa"
 { gaaval->pass = GAATMP_password.arg1 ;};
 
                return GAA_OK;
@@ -1138,7 +1173,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_load_ca_certificate.arg1, gaa_getstr, GAATMP_load_ca_certificate.size1);
                gaa_index++;
-#line 52 "certtool.gaa"
+#line 55 "certtool.gaa"
 { gaaval->ca = GAATMP_load_ca_certificate.arg1 ;};
 
                return GAA_OK;
@@ -1148,7 +1183,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_load_ca_privkey.arg1, gaa_getstr, GAATMP_load_ca_privkey.size1);
                gaa_index++;
-#line 49 "certtool.gaa"
+#line 52 "certtool.gaa"
 { gaaval->ca_privkey = GAATMP_load_ca_privkey.arg1 ;};
 
                return GAA_OK;
@@ -1158,7 +1193,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_load_certificate.arg1, gaa_getstr, GAATMP_load_certificate.size1);
                gaa_index++;
-#line 46 "certtool.gaa"
+#line 49 "certtool.gaa"
 { gaaval->cert = GAATMP_load_certificate.arg1 ;};
 
                return GAA_OK;
@@ -1168,9 +1203,19 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_load_request.arg1, gaa_getstr, GAATMP_load_request.size1);
                gaa_index++;
-#line 43 "certtool.gaa"
+#line 46 "certtool.gaa"
 { gaaval->request = GAATMP_load_request.arg1 ;};
 
+               return GAA_OK;
+               break;
+       case GAAOPTID_load_pubkey:
+       OK = 0;
+               GAA_TESTMOREARGS;
+               GAA_FILL(GAATMP_load_pubkey.arg1, gaa_getstr, GAATMP_load_pubkey.size1);
+               gaa_index++;
+#line 43 "certtool.gaa"
+{ gaaval->pubkey = GAATMP_load_pubkey.arg1 ;};
+
                return GAA_OK;
                break;
        case GAAOPTID_load_privkey:
@@ -1284,13 +1329,13 @@ int gaa(int argc, char **argv, gaainfo *gaaval)
     if(inited == 0)
     {
 
-#line 150 "certtool.gaa"
+#line 156 "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;
        gaaval->export = 0; gaaval->template = NULL; gaaval->hash=NULL; gaaval->fix_key = 0; gaaval->quick_random=1; 
        gaaval->privkey_op = 0; gaaval->pkcs_cipher = "3des"; gaaval->crq_extensions=1; gaaval->pkcs11_provider= NULL;
-       gaaval->pkcs11_url = NULL; gaaval->pkcs11_type = PKCS11_TYPE_PK; ;};
+       gaaval->pkcs11_url = NULL; gaaval->pkcs11_type = PKCS11_TYPE_PK; gaaval->pubkey=NULL; ;};
 
     }
     inited = 1;
index ded4286568ec25c647880a955814d694022e7f31..80b022a1bbfe37a77b7fc717ef3b682e7b4d275e 100644 (file)
@@ -8,54 +8,56 @@ typedef struct _gaainfo gaainfo;
 
 struct _gaainfo
 {
-#line 143 "certtool.gaa"
+#line 149 "certtool.gaa"
        int debug;
-#line 137 "certtool.gaa"
+#line 142 "certtool.gaa"
        int pkcs11_type;
-#line 134 "certtool.gaa"
+#line 139 "certtool.gaa"
        char* pkcs11_url;
-#line 131 "certtool.gaa"
+#line 136 "certtool.gaa"
        char* pkcs11_provider;
-#line 128 "certtool.gaa"
+#line 133 "certtool.gaa"
        char *pkcs_cipher;
-#line 125 "certtool.gaa"
+#line 130 "certtool.gaa"
        char *template;
-#line 122 "certtool.gaa"
+#line 127 "certtool.gaa"
        char *infile;
-#line 119 "certtool.gaa"
+#line 124 "certtool.gaa"
        char *outfile;
-#line 116 "certtool.gaa"
+#line 121 "certtool.gaa"
        int quick_random;
-#line 113 "certtool.gaa"
+#line 118 "certtool.gaa"
        int bits;
-#line 109 "certtool.gaa"
+#line 114 "certtool.gaa"
        int outcert_format;
-#line 105 "certtool.gaa"
+#line 110 "certtool.gaa"
        int incert_format;
-#line 102 "certtool.gaa"
+#line 107 "certtool.gaa"
        int export;
-#line 99 "certtool.gaa"
+#line 104 "certtool.gaa"
        char *hash;
-#line 96 "certtool.gaa"
+#line 101 "certtool.gaa"
        int dsa;
-#line 93 "certtool.gaa"
+#line 98 "certtool.gaa"
        int pkcs8;
-#line 85 "certtool.gaa"
+#line 90 "certtool.gaa"
        int v1_cert;
-#line 82 "certtool.gaa"
+#line 87 "certtool.gaa"
        int fix_key;
-#line 67 "certtool.gaa"
+#line 70 "certtool.gaa"
        int crq_extensions;
-#line 54 "certtool.gaa"
+#line 57 "certtool.gaa"
        char *pass;
-#line 51 "certtool.gaa"
+#line 54 "certtool.gaa"
        char *ca;
-#line 48 "certtool.gaa"
+#line 51 "certtool.gaa"
        char *ca_privkey;
-#line 45 "certtool.gaa"
+#line 48 "certtool.gaa"
        char *cert;
-#line 42 "certtool.gaa"
+#line 45 "certtool.gaa"
        char *request;
+#line 42 "certtool.gaa"
+       char *pubkey;
 #line 39 "certtool.gaa"
        char *privkey;
 #line 17 "certtool.gaa"
index bdc8b0c652f8fb1246398af6c1fb0c84a1aa9c95..075f19c8402d97c1abe79a6f6826db28545e65d1 100644 (file)
@@ -26,6 +26,7 @@
 #include <gnutls/openpgp.h>
 #include <gnutls/pkcs12.h>
 #include <gnutls/pkcs11.h>
+#include <gnutls/abstract.h>
 
 #include <gcrypt.h>
 
@@ -60,6 +61,7 @@ void generate_pkcs12 (void);
 void generate_pkcs8 (void);
 void verify_chain (void);
 void verify_crl (void);
+void pubkey_info (void);
 void pgp_privkey_info (void);
 void pgp_ring_info (void);
 gnutls_x509_privkey_t load_private_key (int mand);
@@ -67,6 +69,7 @@ gnutls_x509_crq_t load_request (void);
 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);
+gnutls_pubkey_t load_pubkey (int mand);
 void certificate_info (void);
 void pgp_certificate_info (void);
 void crl_info (void);
@@ -133,8 +136,11 @@ static void
 print_dsa_pkey (gnutls_datum_t * x, gnutls_datum_t * y, gnutls_datum_t * p,
                gnutls_datum_t * q, gnutls_datum_t * g)
 {
-  fprintf (outfile, "private key:");
-  print_hex_datum (x);
+  if (x) 
+    {
+      fprintf (outfile, "private key:");
+      print_hex_datum (x);
+    }
   fprintf (outfile, "public key:");
   print_hex_datum (y);
   fprintf (outfile, "p:");
@@ -153,14 +159,17 @@ print_rsa_pkey (gnutls_datum_t * m, gnutls_datum_t * e, gnutls_datum_t * d,
   print_hex_datum (m);
   fprintf (outfile, "public exponent:");
   print_hex_datum (e);
-  fprintf (outfile, "private exponent:");
-  print_hex_datum (d);
-  fprintf (outfile, "prime1:");
-  print_hex_datum (p);
-  fprintf (outfile, "prime2:");
-  print_hex_datum (q);
-  fprintf (outfile, "coefficient:");
-  print_hex_datum (u);
+  if (d) 
+    {
+      fprintf (outfile, "private exponent:");
+      print_hex_datum (d);
+      fprintf (outfile, "prime1:");
+      print_hex_datum (p);
+      fprintf (outfile, "prime2:");
+      print_hex_datum (q);
+      fprintf (outfile, "coefficient:");
+      print_hex_datum (u);
+    }
 }
 
 static gnutls_x509_privkey_t
@@ -971,6 +980,9 @@ gaa_parser (int argc, char **argv)
     case ACTION_PRIVKEY_INFO:
       privkey_info ();
       break;
+    case ACTION_PUBKEY_INFO:
+      pubkey_info ();
+      break;
     case ACTION_UPDATE_CERTIFICATE:
       update_signed_certificate ();
       break;
@@ -1610,6 +1622,51 @@ privkey_info (void)
   gnutls_x509_privkey_deinit (key);
 }
 
+/* Load a public key.
+ * @mand should be non zero if it is required to read a public key.
+ */
+gnutls_pubkey_t
+load_pubkey (int mand)
+{
+  gnutls_pubkey_t key;
+  int ret;
+  gnutls_datum_t dat;
+  size_t size;
+
+  if (!info.pubkey && !mand)
+    return NULL;
+
+  if (info.pubkey == NULL)
+    error (EXIT_FAILURE, 0, "missing --load-pubkey");
+
+  ret = gnutls_pubkey_init (&key);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));
+
+  dat.data = read_binary_file (info.pubkey, &size);
+  dat.size = size;
+
+  if (!dat.data)
+    error (EXIT_FAILURE, errno, "reading --load-pubkey: %s", info.pubkey);
+
+  ret = gnutls_pubkey_import (key, &dat, info.incert_format);
+
+  free (dat.data);
+
+  if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
+    {
+      error (EXIT_FAILURE, 0,
+            "import error: could not find a valid PEM header; "
+            "check if your key has the PUBLIC KEY header");
+    }
+
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "importing --load-pubkey: %s: %s",
+          info.pubkey, gnutls_strerror (ret));
+
+  return key;
+}
+
 
 /* Load the private key.
  * @mand should be non zero if it is required to read a private key.
@@ -2978,3 +3035,141 @@ certtool_version (void)
   version_etc (stdout, program_name, p, gnutls_check_version (NULL),
               "Nikos Mavrogiannopoulos", "Simon Josefsson", (char *) NULL);
 }
+
+static void print_key_usage(FILE* outfile, unsigned int usage)
+{
+  if (usage & GNUTLS_KEY_DIGITAL_SIGNATURE) {
+    fprintf(outfile, "\tDigital signature.\n");
+  }
+
+  if (usage & GNUTLS_KEY_NON_REPUDIATION) {
+    fprintf(outfile, "\tNon repudiation.\n");
+  }
+
+  if (usage & GNUTLS_KEY_KEY_ENCIPHERMENT) {
+    fprintf(outfile, "\tKey encipherment.\n");
+  }
+
+  if (usage & GNUTLS_KEY_DATA_ENCIPHERMENT) {
+    fprintf(outfile, "\tData encipherment.\n");
+  }
+
+  if (usage & GNUTLS_KEY_KEY_AGREEMENT) {
+    fprintf(outfile, "\tKey agreement.\n");
+  }
+
+  if (usage & GNUTLS_KEY_KEY_CERT_SIGN) {
+    fprintf(outfile, "\tCertificate signing.\n");
+  }
+
+  if (usage & GNUTLS_KEY_NON_REPUDIATION) {
+    fprintf(outfile, "\tCRL signing.\n");  
+  }
+
+  if (usage & GNUTLS_KEY_ENCIPHER_ONLY) {
+    fprintf(outfile, "\tKey encipher only.\n");
+  }
+
+  if (usage & GNUTLS_KEY_DECIPHER_ONLY) {
+    fprintf(outfile, "\tKey decipher only.\n");
+  }
+}
+
+void pubkey_info (void)
+{
+  gnutls_x509_crt_t crt;
+  gnutls_pubkey_t pubkey;
+  unsigned int bits, usage;
+  int ret;
+  size_t size;
+  const char* cprint;
+
+  ret = gnutls_pubkey_init(&pubkey);
+  if (ret < 0) {
+    error (EXIT_FAILURE, 0, "pubkey_init: %s", gnutls_strerror (ret));
+  }
+
+  crt = load_cert(0);
+  
+  if (crt != NULL) {
+    ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
+    if (ret < 0) {
+      error (EXIT_FAILURE, 0, "pubkey_import_x509: %s", gnutls_strerror (ret));
+    }
+  } else {
+    pubkey = load_pubkey(1);
+  }
+
+  fprintf (outfile, "Public Key Info:\n\n");
+  ret = gnutls_pubkey_get_pk_algorithm (pubkey, &bits);
+  fprintf (outfile, "Public Key Algorithm: ");
+
+  cprint = gnutls_pk_algorithm_get_name (ret);
+  fprintf (outfile, "%s (%u bits)\n", cprint ? cprint : "Unknown", bits);
+
+
+  /* Print the raw public and private keys
+   */
+  if (ret == GNUTLS_PK_RSA)
+    {
+      gnutls_datum_t m, e;
+
+      ret = gnutls_pubkey_get_pk_rsa_raw (pubkey, &m, &e);
+      if (ret < 0)
+       fprintf (stderr, "Error in key RSA data export: %s\n",
+                gnutls_strerror (ret));
+      else
+       {
+         print_rsa_pkey (&m, &e, NULL, NULL, NULL, NULL);
+         gnutls_free (m.data);
+         gnutls_free (e.data);
+       }
+    }
+  else if (ret == GNUTLS_PK_DSA)
+    {
+      gnutls_datum_t p, q, g, y;
+
+      ret = gnutls_pubkey_get_pk_dsa_raw (pubkey, &p, &q, &g, &y);
+      if (ret < 0)
+       fprintf (stderr, "Error in key DSA data export: %s\n",
+                gnutls_strerror (ret));
+      else
+       {
+         print_dsa_pkey (NULL, &y, &p, &q, &g);
+         gnutls_free (y.data);
+         gnutls_free (p.data);
+         gnutls_free (q.data);
+         gnutls_free (g.data);
+       }
+    }
+
+  ret = gnutls_pubkey_get_key_usage (pubkey, &usage);
+  if (ret < 0) {
+    error (EXIT_FAILURE, 0, "pubkey_get_key_usage: %s", gnutls_strerror (ret));
+  }
+  
+  fprintf (outfile, "Public Key Usage:\n");
+  print_key_usage(outfile, usage);
+
+  fprintf (outfile, "\n");
+
+  size = sizeof (buffer);
+  if ((ret = gnutls_pubkey_get_key_id (pubkey, 0, buffer, &size)) < 0)
+    {
+      fprintf (stderr, "Error in key id calculation: %s\n",
+              gnutls_strerror (ret));
+    }
+  else
+    {
+      fprintf (outfile, "Public Key ID: %s\n", raw_to_string (buffer, size));
+    }
+
+  size = sizeof (buffer);
+  ret = gnutls_pubkey_export (pubkey, GNUTLS_X509_FMT_PEM, buffer, &size);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret));
+
+  fprintf (outfile, "\n%s\n", buffer);
+
+  gnutls_pubkey_deinit (pubkey);
+}
index 0e9da9e0c06b169e51fd71f3b6a990e7520c86c4..f84b6dbb8da78337a8e97ef4a7002a1f05636095 100644 (file)
@@ -39,6 +39,9 @@ option (get-dh-params) { $action=ACTION_GET_DH; } "Get the included PKCS #3 enco
 #char *privkey;
 option (load-privkey) STR "FILE" { $privkey = $1 } "Private key file to use."
 
+#char *pubkey;
+option (load-pubkey) STR "FILE" { $pubkey = $1 } "Private key file to use."
+
 #char *request;
 option (load-request) STR "FILE" { $request = $1 } "Certificate request file to use."
 
@@ -79,6 +82,8 @@ option (k, key-info) { $privkey_op=1; $action = ACTION_PRIVKEY_INFO; } "Print in
 
 option (pgp-key-info) { $privkey_op=1; $action = ACTION_PGP_PRIVKEY_INFO; } "Print information on a OpenPGP private key."
 
+option (pubkey-info) { $action = ACTION_PUBKEY_INFO; } "Print information on a public key."
+
 #int fix_key;
 option (fix-key) { $privkey_op=1; $fix_key = 1; } "Regenerate the parameters in a private key."
 
@@ -135,8 +140,9 @@ option (pkcs11-provider) STR "Library" { $pkcs11_provider = $1 } "Specify the pk
 option (pkcs11-export-url) STR "URL" { $action = ACTION_PKCS11_EXPORT_URL; $pkcs11_url = $1; } "Export data specified a pkcs11 URL"
 
 #int pkcs11_type;
-option (pkcs11-list) { $action = ACTION_PKCS11_LIST; $pkcs11_type=PKCS11_TYPE_PK; } "List objects specified by a PKCS#11 URL"
-option (pkcs11-list-trusted) { $action = ACTION_PKCS11_LIST; $pkcs11_type=PKCS11_TYPE_TRUSTED; } "List objects marked as trusted, specified by a PKCS#11 URL"
+option (pkcs11-list-certs) { $action = ACTION_PKCS11_LIST; $pkcs11_type=PKCS11_TYPE_PK; } "List certificates specified by a PKCS#11 URL"
+option (pkcs11-list-trusted) { $action = ACTION_PKCS11_LIST; $pkcs11_type=PKCS11_TYPE_TRUSTED; } "List certificates marked as trusted, specified by a PKCS#11 URL"
+option (pkcs11-list-all-certs) { $action = ACTION_PKCS11_LIST; $pkcs11_type=PKCS11_TYPE_CRT_ALL; } "List all certificates specified by a PKCS#11 URL"
 option (pkcs11-list-all) { $action = ACTION_PKCS11_LIST; $pkcs11_type=PKCS11_TYPE_ALL; } "List all objects specified by a PKCS#11 URL"
 option (pkcs11-list-tokens) { $action = ACTION_PKCS11_TOKENS; } "List all available tokens"
 
@@ -152,4 +158,4 @@ init { $bits = 2048; $pkcs8 = 0; $privkey = NULL; $ca=NULL; $ca_privkey = NULL;
        $incert_format = 0; $outcert_format = 0; $action=-1; $pass = NULL; $v1_cert = 0;
        $export = 0; $template = NULL; $hash=NULL; $fix_key = 0; $quick_random=1; 
        $privkey_op = 0; $pkcs_cipher = "3des"; $crq_extensions=1; $pkcs11_provider= NULL;
-       $pkcs11_url = NULL; $pkcs11_type = PKCS11_TYPE_PK; }
+       $pkcs11_url = NULL; $pkcs11_type = PKCS11_TYPE_PK; $pubkey=NULL; }
index b933799378009b389d433c0caab7c565012bf6b6..d2b33018393fdcbc08d5c4bf041b39b24d75305f 100644 (file)
@@ -47,7 +47,7 @@ static void pkcs11_common(void)
  */
 void pkcs11_list( FILE* outfile, const char* url, int type)
 {
-gnutls_pkcs11_crt_t *crt_list;
+gnutls_pkcs11_obj_t *crt_list;
 gnutls_x509_crt_t xcrt;
 unsigned int crt_list_size = 0;
 int ret;
@@ -59,52 +59,66 @@ int i, flags;
        if (url == NULL)
                url = "pkcs11:";
 
-       ret = gnutls_pkcs11_crt_list_import_url( NULL, &crt_list_size, url, GNUTLS_PKCS11_CRT_ATTR_ALL);
+       if (type == PKCS11_TYPE_TRUSTED) {
+               flags = GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED;
+       } else if (type == PKCS11_TYPE_PK) {
+               flags = GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY;
+       } else if (type == PKCS11_TYPE_CRT_ALL) {
+               flags = GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL;
+       } else {
+               flags = GNUTLS_PKCS11_OBJ_ATTR_ALL;
+       }
+               
+       /* give some initial value to avoid asking for the pkcs11 pin twice.
+        */
+       crt_list_size = 128;
+       crt_list = malloc(sizeof(*crt_list)*crt_list_size);
+       if (crt_list == NULL) {
+               fprintf(stderr, "Memory error\n");
+               exit(1);
+       }
+
+       ret = gnutls_pkcs11_obj_list_import_url( crt_list, &crt_list_size, url, flags);
        if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) {
                fprintf(stderr, "Error in crt_list_import (1): %s\n", gnutls_strerror(ret));
                exit(1);
        }
        
        if (crt_list_size == 0) {
-               fprintf(stderr, "No matching certificates found\n");
+               fprintf(stderr, "No matching objects found\n");
                exit(0);
        }
        
-       crt_list = malloc(sizeof(*crt_list)*crt_list_size);
-       if (crt_list == NULL) {
-               fprintf(stderr, "Memory error\n");
-               exit(1);
-       }
-
-       if (type == PKCS11_TYPE_TRUSTED) {
-               flags = GNUTLS_PKCS11_CRT_ATTR_TRUSTED;
-       } else if (type == PKCS11_TYPE_PK) {
-               flags = GNUTLS_PKCS11_CRT_ATTR_WITH_PK;
-       } else {
-               flags = GNUTLS_PKCS11_CRT_ATTR_ALL;
-       }
+       if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
+               crt_list = realloc(crt_list, sizeof(*crt_list)*crt_list_size);
+               if (crt_list == NULL) {
+                       fprintf(stderr, "Memory error\n");
+                       exit(1);
+               }
 
-       ret = gnutls_pkcs11_crt_list_import_url( crt_list, &crt_list_size, url, flags);
-       if (ret < 0) {
-               fprintf(stderr, "Error in crt_list_import: %s\n", gnutls_strerror(ret));
-               exit(1);
+               ret = gnutls_pkcs11_obj_list_import_url( crt_list, &crt_list_size, url, flags);
+               if (ret < 0) {
+                       fprintf(stderr, "Error in crt_list_import: %s\n", gnutls_strerror(ret));
+                       exit(1);
+               }
        }
        
        for (i=0;i<crt_list_size;i++) {
                char buf[128];
                size_t size;
-
-
-               ret = gnutls_pkcs11_crt_export_url(crt_list[i], &output);
+               
+               ret = gnutls_pkcs11_obj_export_url(crt_list[i], &output);
                if (ret < 0) {
                        fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret));
                        exit(1);
                }
 
-               fprintf(outfile, "Certificate %d:\n\tURL: %s\n", i, output);
+               fprintf(outfile, "Object %d:\n\tURL: %s\n", i, output);
 
+               fprintf(outfile, "\tType: %s\n", gnutls_pkcs11_type_get_name(gnutls_pkcs11_obj_get_type( crt_list[i])));
+               
                size = sizeof(buf);
-               ret = gnutls_pkcs11_crt_get_info( crt_list[i], GNUTLS_PKCS11_CRT_LABEL, buf, &size);
+               ret = gnutls_pkcs11_obj_get_info( crt_list[i], GNUTLS_PKCS11_OBJ_LABEL, buf, &size);
                if (ret < 0) {
                        fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret));
                        exit(1);
@@ -112,13 +126,17 @@ int i, flags;
                fprintf(outfile, "\tLabel: %s\n", buf);
 
                size = sizeof(buf);
-               ret = gnutls_pkcs11_crt_get_info( crt_list[i], GNUTLS_PKCS11_CRT_ID_HEX, buf, &size);
+               ret = gnutls_pkcs11_obj_get_info( crt_list[i], GNUTLS_PKCS11_OBJ_ID_HEX, buf, &size);
                if (ret < 0) {
                        fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret));
                        exit(1);
                }
                fprintf(outfile, "\tID: %s\n\n", buf);
+               
+               
 
+               if (flags == GNUTLS_PKCS11_OBJ_ATTR_ALL)
+                       continue;
 
                ret = gnutls_x509_crt_init(&xcrt);
                if (ret < 0) {
@@ -154,7 +172,7 @@ int i, flags;
 
 void pkcs11_export(FILE* outfile, const char* url)
 {
-gnutls_pkcs11_crt_t crt;
+gnutls_pkcs11_obj_t crt;
 gnutls_x509_crt_t xcrt;
 int ret;
 size_t size;
@@ -164,13 +182,13 @@ size_t size;
        if (url == NULL)
                url = "pkcs11:";
 
-       ret = gnutls_pkcs11_crt_init(&crt);
+       ret = gnutls_pkcs11_obj_init(&crt);
        if (ret < 0) {
                fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret));
                exit(1);
        }
 
-       ret = gnutls_pkcs11_crt_import_url( crt, url);
+       ret = gnutls_pkcs11_obj_import_url( crt, url);
        if (ret < 0) {
                fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret));
                exit(1);
@@ -198,7 +216,7 @@ size_t size;
        fputs("\n\n", outfile);
 
        gnutls_x509_crt_deinit(xcrt);
-       gnutls_pkcs11_crt_deinit(crt);
+       gnutls_pkcs11_obj_deinit(crt);
 
        return;