]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added gnutls_pkcs11_token_set_pin() and gnutls_pkcs11_token_init() to enable
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 7 Nov 2010 10:08:51 +0000 (11:08 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 7 Nov 2010 10:08:51 +0000 (11:08 +0100)
manipulating tokens purely from PKCS #11.

NEWS
lib/Makefile.am
lib/includes/gnutls/pkcs11.h
lib/libgnutls.map
lib/pkcs11.c
lib/pkcs11_int.h
lib/pkcs11_secret.c [new file with mode: 0644]
lib/pkcs11_write.c
src/pkcs11.c

diff --git a/NEWS b/NEWS
index 6887cef58cd526da0e7f3ddfd07f32262259adce..65e721eee1fac62716c8b18bdabba8a0fc082d8c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,12 +5,15 @@ See the end for copying conditions.
 
 * Version 2.11.5 (unreleased)
 
+** p11tool: Introduced. It allows manipulating pkcs 11 tokens.
+
 ** gnutls-cli: Print channel binding only in verbose mode.
 Before it printed it after the 'Compression:' output, thus breaking
 Emacs starttls.el string searches.
 
 ** API and ABI modifications:
-No changes since last version.
+gnutls_pkcs11_token_init: New function
+gnutls_pkcs11_token_set_pin: New function
 
 * Version 2.11.4 (released 2010-10-15)
 
index 13531d985735214a66fac1c0bf3586d9ac47bf3a..d17725336356e23ce8a26a5340e4580c7e6d4a28 100644 (file)
@@ -80,7 +80,8 @@ COBJECTS = gnutls_record.c gnutls_compress.c debug.c gnutls_cipher.c  \
        auth_dh_common.c gnutls_helper.c gnutls_supplemental.c          \
        crypto.c random.c  ext_signature.c cryptodev.c system.c \
        crypto-api.c ext_safe_renegotiation.c gnutls_privkey.c \
-       pkcs11.c pkcs11_privkey.c gnutls_pubkey.c pkcs11_write.c locks.c
+       pkcs11.c pkcs11_privkey.c gnutls_pubkey.c pkcs11_write.c locks.c \
+       pkcs11_secret.c
 
 
 if ENABLE_NETTLE
index 95c74d62d0eb18b663e93cd0bc69cfa98b39d6e1..d801f0a6c50d19cd0b71d1c55275a6dd87d5642c 100644 (file)
@@ -20,13 +20,19 @@ typedef int (*gnutls_pkcs11_token_callback_t) (void *const global_data,
                                               const unsigned retry);
 
 /* flags */
-#define GNUTLS_PKCS11_PIN_FINAL_TRY (1<<0)
-#define GNUTLS_PKCS11_PIN_COUNT_LOW (1<<1)
+typedef enum
+{
+  GNUTLS_PKCS11_PIN_USER = (1<<0),
+  GNUTLS_PKCS11_PIN_SO = (1<<1),
+  GNUTLS_PKCS11_PIN_FINAL_TRY = (1<<2),
+  GNUTLS_PKCS11_PIN_COUNT_LOW = (1<<3)
+} gnutls_pkcs11_pin_flag_t;
 
 typedef int (*gnutls_pkcs11_pin_callback_t) (void *userdata, int attempt,
                                             const char *token_url,
                                             const char *token_label,
-                                            unsigned int flags, char *pin,
+                                            unsigned int flags /*gnutls_pkcs11_pin_flag_t*/, 
+                                            char *pin,
                                             size_t pin_max);
 
 struct gnutls_pkcs11_obj_st;
@@ -82,6 +88,12 @@ int gnutls_pkcs11_copy_x509_privkey (const char *token_url, gnutls_x509_privkey_
 int gnutls_pkcs11_delete_url (const char *object_url, unsigned int flags
                              /* GNUTLS_PKCS11_OBJ_FLAG_* */ );
 
+int gnutls_pkcs11_copy_secret_key (const char *token_url, gnutls_datum_t* key,
+                                const char *label, 
+                                unsigned int key_usage /* GNUTLS_KEY_* */,
+                                unsigned int flags
+                                /* GNUTLS_PKCS11_OBJ_FLAG_* */ );
+
 typedef enum
 {
   GNUTLS_PKCS11_OBJ_ID_HEX = 1,
@@ -130,6 +142,15 @@ typedef enum
   GNUTLS_PKCS11_OBJ_DATA
 } gnutls_pkcs11_obj_type_t;
 
+int
+gnutls_pkcs11_token_init (const char *token_url,
+                                const char* so_pin,
+                                const char *label);
+
+int
+gnutls_pkcs11_token_set_pin (const char *token_url,
+  const char* oldpin, const char* newpin, unsigned int flags/*gnutls_pkcs11_pin_flag_t*/);
+
 int gnutls_pkcs11_token_get_url (unsigned int seq,
                                 gnutls_pkcs11_url_type_t detailed,
                                 char **url);
index 18981a1485f2e8643e69503fb31486046999929d..c9474f3eecc1de1cd79492707e933b2dd9c046bc 100644 (file)
@@ -689,8 +689,10 @@ GNUTLS_2_12
        gnutls_cipher_decrypt2;
        gnutls_openpgp_privkey_sec_param;
        gnutls_x509_privkey_sec_param;
-
        gnutls_session_channel_binding;
+       gnutls_pkcs11_copy_secret_key;
+       gnutls_pkcs11_token_init;
+       gnutls_pkcs11_token_set_pin;
 } GNUTLS_2_10;
 
 GNUTLS_PRIVATE {
index c825fb42a5dc5442c9752ee0f40eaba757051046..170835fb73413eafca55e6ad73513c482de98f3e 100644 (file)
@@ -1088,12 +1088,10 @@ fix_strings (struct token_info *info)
 }
 
 int
-pkcs11_open_session (pakchois_session_t ** _pks,
-                    struct pkcs11_url_info *info, unsigned int flags)
+pkcs11_find_slot (pakchois_module_t** module, ck_slot_id_t *slot,
+                    struct pkcs11_url_info *info, struct token_info* _tinfo)
 {
-  ck_rv_t rv;
-  int x, z, ret;
-  pakchois_session_t *pks = NULL;
+  int x, z;
 
   for (x = 0; x < active_providers; x++)
     {
@@ -1101,21 +1099,11 @@ pkcs11_open_session (pakchois_session_t ** _pks,
        {
          struct token_info tinfo;
 
-         rv = pakchois_open_session (providers[x].module,
-                                     providers[x].slots[z],
-                                     ((flags & SESSION_WRITE)
-                                      ? CKF_RW_SESSION : 0) |
-                                     CKF_SERIAL_SESSION, NULL, NULL, &pks);
-         if (rv != CKR_OK)
-           {
-             continue;
-           }
-
          if (pakchois_get_token_info
              (providers[x].module, providers[x].slots[z],
               &tinfo.tinfo) != CKR_OK)
            {
-             goto next;
+             continue;
            }
          tinfo.sid = providers[x].slots[z];
          tinfo.prov = &providers[x];
@@ -1124,7 +1112,7 @@ pkcs11_open_session (pakchois_session_t ** _pks,
              (providers[x].module, providers[x].slots[z],
               &tinfo.sinfo) != CKR_OK)
            {
-             goto next;
+             continue;
            }
 
          /* XXX make wrapper for token_info? */
@@ -1133,30 +1121,67 @@ pkcs11_open_session (pakchois_session_t ** _pks,
          if (pkcs11_token_matches_info (info, &tinfo.tinfo,
                                         &providers[x].info) < 0)
            {
-             goto next;
-           }
-
-         if (flags & SESSION_LOGIN)
-           {
-             ret = pkcs11_login (pks, &tinfo);
-             if (ret < 0)
-               {
-                 gnutls_assert ();
-                 pakchois_close_session (pks);
-                 return ret;
-               }
+             continue;
            }
 
          /* ok found */
-         *_pks = pks;
+         *module = providers[x].module;
+         *slot = providers[x].slots[z];
+         
+         if (_tinfo != NULL)
+           memcpy(_tinfo, &tinfo, sizeof(tinfo));
+
          return 0;
+       }
+    }
 
-       next:
+  gnutls_assert();
+  return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+}
+
+int
+pkcs11_open_session (pakchois_session_t ** _pks,
+                    struct pkcs11_url_info *info, unsigned int flags)
+{
+  ck_rv_t rv;
+  int ret;
+  pakchois_session_t *pks = NULL;
+  pakchois_module_t *module;
+  ck_slot_id_t slot;
+  struct token_info tinfo;
+
+  ret = pkcs11_find_slot(&module, &slot, info, &tinfo);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+
+  rv = pakchois_open_session (module,
+                             slot,
+                             ((flags & SESSION_WRITE)
+                              ? CKF_RW_SESSION : 0) |
+                             CKF_SERIAL_SESSION, NULL, NULL, &pks);
+  if (rv != CKR_OK)
+    {
+      gnutls_assert();
+      return pkcs11_rv_to_err (rv);
+    }
+
+  if (flags & SESSION_LOGIN)
+    {
+      ret = pkcs11_login (pks, &tinfo, (flags & SESSION_SO)?1:0);
+      if (ret < 0)
+       {
+         gnutls_assert ();
          pakchois_close_session (pks);
+         return ret;
        }
     }
 
-  return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+  /* ok found */
+  *_pks = pks;
+  return 0;
 }
 
 
@@ -1176,21 +1201,11 @@ _pkcs11_traverse_tokens (find_func_t find_func, void *input,
 
          ret = GNUTLS_E_PKCS11_ERROR;
 
-         rv = pakchois_open_session (providers[x].module,
-                                     providers[x].slots[z],
-                                     ((flags & SESSION_WRITE)
-                                      ? CKF_RW_SESSION : 0) |
-                                     CKF_SERIAL_SESSION, NULL, NULL, &pks);
-         if (rv != CKR_OK)
-           {
-             continue;
-           }
-
          if (pakchois_get_token_info
              (providers[x].module, providers[x].slots[z],
               &info.tinfo) != CKR_OK)
            {
-             goto next;
+             continue;
            }
          info.sid = providers[x].slots[z];
          info.prov = &providers[x];
@@ -1199,15 +1214,25 @@ _pkcs11_traverse_tokens (find_func_t find_func, void *input,
              (providers[x].module, providers[x].slots[z],
               &info.sinfo) != CKR_OK)
            {
-             goto next;
+             continue;
            }
 
          /* XXX make wrapper for token_info? */
          fix_strings (&info);
 
+         rv = pakchois_open_session (providers[x].module,
+                                     providers[x].slots[z],
+                                     ((flags & SESSION_WRITE)
+                                      ? CKF_RW_SESSION : 0) |
+                                     CKF_SERIAL_SESSION, NULL, NULL, &pks);
+         if (rv != CKR_OK)
+           {
+             continue;
+           }
+
          if (flags & SESSION_LOGIN)
            {
-             ret = pkcs11_login (pks, &info);
+             ret = pkcs11_login (pks, &info, (flags & SESSION_SO)?1:0);
              if (ret < 0)
                {
                  gnutls_assert ();
@@ -1217,8 +1242,6 @@ _pkcs11_traverse_tokens (find_func_t find_func, void *input,
 
          ret = find_func (pks, &info, &providers[x].info, input);
 
-       next:
-
          if (ret == 0)
            {
              found = 1;
@@ -2005,8 +2028,8 @@ struct pkey_list
   size_t key_ids_size;
 };
 
-int
-pkcs11_login (pakchois_session_t * pks, const struct token_info *info)
+int pkcs11_login (pakchois_session_t * pks, 
+  const struct token_info *info, int so)
 {
   int attempt = 0, ret;
   ck_rv_t rv;
@@ -2015,7 +2038,7 @@ pkcs11_login (pakchois_session_t * pks, const struct token_info *info)
   struct pkcs11_url_info uinfo;
 
 
-  if ((info->tinfo.flags & CKF_LOGIN_REQUIRED) == 0)
+  if (so == 0 && (info->tinfo.flags & CKF_LOGIN_REQUIRED) == 0)
     {
       gnutls_assert ();
       _gnutls_debug_log ("pk11: No login required.\n");
@@ -2039,7 +2062,7 @@ pkcs11_login (pakchois_session_t * pks, const struct token_info *info)
    * required. */
   if (info->tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
     {
-      if (pakchois_login (pks, CKU_USER, NULL, 0) == CKR_OK)
+      if (pakchois_login (pks, (so==0)?CKU_USER:CKU_SO, NULL, 0) == CKR_OK)
        {
          return 0;
        }
@@ -2083,10 +2106,22 @@ pkcs11_login (pakchois_session_t * pks, const struct token_info *info)
        }
 
       flags = 0;
-      if (tinfo.flags & CKF_USER_PIN_COUNT_LOW)
-       flags |= GNUTLS_PKCS11_PIN_COUNT_LOW;
-      if (tinfo.flags & CKF_USER_PIN_FINAL_TRY)
-       flags |= GNUTLS_PKCS11_PIN_FINAL_TRY;
+      if (so == 0)
+        {
+         flags |= GNUTLS_PKCS11_PIN_USER;
+         if (tinfo.flags & CKF_USER_PIN_COUNT_LOW)
+           flags |= GNUTLS_PKCS11_PIN_COUNT_LOW;
+         if (tinfo.flags & CKF_USER_PIN_FINAL_TRY)
+           flags |= GNUTLS_PKCS11_PIN_FINAL_TRY;
+       }
+      else
+        {
+         flags |= GNUTLS_PKCS11_PIN_SO;
+         if (tinfo.flags & CKF_SO_PIN_COUNT_LOW)
+           flags |= GNUTLS_PKCS11_PIN_COUNT_LOW;
+         if (tinfo.flags & CKF_SO_PIN_FINAL_TRY)
+           flags |= GNUTLS_PKCS11_PIN_FINAL_TRY;
+       }
 
       ret = pin_func (pin_data, attempt++,
                      (char *) token_url,
@@ -2099,7 +2134,8 @@ pkcs11_login (pakchois_session_t * pks, const struct token_info *info)
        }
       pin_len = strlen (pin);
 
-      rv = pakchois_login (pks, CKU_USER, (unsigned char *) pin, pin_len);
+      rv = pakchois_login (pks, (so==0)?CKU_USER:CKU_SO, 
+       (unsigned char *) pin, pin_len);
 
       /* Try to scrub the pin off the stack.  Clever compilers will
        * probably optimize this away, oh well. */
index 354bba3be7e83ebc0eba87f94a3228df5ed607be..11306e0dee5a33217b534ee4fe53ccaa01610adb 100644 (file)
@@ -60,11 +60,15 @@ typedef int (*find_func_t) (pakchois_session_t * pks,
 
 int pkcs11_rv_to_err (ck_rv_t rv);
 int pkcs11_url_to_info (const char *url, struct pkcs11_url_info *info);
+int
+pkcs11_find_slot (pakchois_module_t** module, ck_slot_id_t *slot,
+                    struct pkcs11_url_info *info, struct token_info* _tinfo);
 
 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, const struct token_info *info);
+int pkcs11_login (pakchois_session_t * pks, 
+  const struct token_info *info, int admin);
 
 extern gnutls_pkcs11_token_callback_t token_func;
 extern void *token_data;
@@ -73,8 +77,9 @@ void pkcs11_rescan_slots (void);
 int pkcs11_info_to_url (const struct pkcs11_url_info *info,
                        gnutls_pkcs11_url_type_t detailed, char **url);
 
-#define SESSION_WRITE 1
-#define SESSION_LOGIN 2
+#define SESSION_WRITE (1<<0)
+#define SESSION_LOGIN (1<<1)
+#define SESSION_SO (1<<2) /* security officer session */
 int pkcs11_open_session (pakchois_session_t ** _pks,
                         struct pkcs11_url_info *info, unsigned int flags);
 int _pkcs11_traverse_tokens (find_func_t find_func, void *input,
diff --git a/lib/pkcs11_secret.c b/lib/pkcs11_secret.c
new file mode 100644 (file)
index 0000000..554359e
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * 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 <gnutls/pkcs11.h>
+#include <stdio.h>
+#include <string.h>
+#include <gnutls_errors.h>
+#include <gnutls_datum.h>
+#include <pkcs11_int.h>
+
+/**
+ * gnutls_pkcs11_copy_x509_crt:
+ * @token_url: A PKCS #11 URL specifying a token
+ * @key: The raw key
+ * @key_size: the size of the key
+ * @label: A name to be used for the stored data
+ * @key_usage: One of GNUTLS_KEY_*
+ * @flags: One of GNUTLS_PKCS11_OBJ_FLAG_*
+ *
+ * This function will copy a raw secret (symmetric) key into a PKCS #11 
+ * token specified by a URL. The key can be marked as sensitive or not.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
+ *   negative error value.
+ **/
+int gnutls_pkcs11_copy_secret_key (const char *token_url, gnutls_datum_t* key,
+                                const char *label, 
+                                unsigned int key_usage,
+                                unsigned int flags
+                                /* GNUTLS_PKCS11_OBJ_FLAG_* */ )
+{
+  int ret;
+  pakchois_session_t *pks;
+  struct pkcs11_url_info info;
+  ck_rv_t rv;
+  struct ck_attribute a[8];
+  ck_object_class_t class = CKO_SECRET_KEY;
+  ck_object_handle_t obj;
+  unsigned int tval = 1;
+  int a_val;
+
+  ret = pkcs11_url_to_info (token_url, &info);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  ret =
+    pkcs11_open_session (&pks, &info,
+                        SESSION_WRITE | pkcs11_obj_flags_to_int (flags));
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  /* FIXME: copy key usage flags */
+
+  a[0].type = CKA_CLASS;
+  a[0].value = &class;
+  a[0].value_len = sizeof (class);
+  a[1].type = CKA_VALUE;
+  a[1].value = key->data;
+  a[1].value_len = key->size;
+  a[2].type = CKA_TOKEN;
+  a[2].value = &tval;
+  a[2].value_len = sizeof (tval);
+  a[3].type = CKA_PRIVATE;
+  a[3].value = &tval;
+  a[3].value_len = sizeof (tval);
+
+  a_val = 4;
+
+  if (label)
+    {
+      a[a_val].type = CKA_LABEL;
+      a[a_val].value = (void *) label;
+      a[a_val].value_len = strlen (label);
+      a_val++;
+    }
+
+  if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE)
+    tval = 1;
+  else
+    tval = 0;
+
+  a[a_val].type = CKA_SENSITIVE;
+  a[a_val].value = &tval;
+  a[a_val].value_len = sizeof (tval);
+  a_val++;
+
+  rv = pakchois_create_object (pks, a, a_val, &obj);
+  if (rv != CKR_OK)
+    {
+      gnutls_assert ();
+      _gnutls_debug_log ("pkcs11: %s\n", pakchois_error (rv));
+      ret = pkcs11_rv_to_err (rv);
+      goto cleanup;
+    }
+
+  /* generated! 
+   */
+
+  ret = 0;
+
+cleanup:
+  pakchois_close_session (pks);
+
+  return ret;
+
+}
+
index 15fd10c59963ef401bf275cb909d2ab06b72a890..34fb921acea3b47bf301196eb95feb9c7bf15f1b 100644 (file)
@@ -243,6 +243,16 @@ gnutls_pkcs11_copy_x509_privkey (const char *token_url,
   a[a_val].value_len = sizeof (type);
   a_val++;
 
+  a[a_val].type = CKA_TOKEN;
+  a[a_val].value = &tval;
+  a[a_val].value_len = sizeof (tval);
+  a_val++;
+
+  a[a_val].type = CKA_PRIVATE;
+  a[a_val].value = &tval;
+  a[a_val].value_len = sizeof (tval);
+  a_val++;
+
   if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE)
     tval = 1;
   else
@@ -567,3 +577,138 @@ gnutls_pkcs11_delete_url (const char *object_url, unsigned int flags)
   return find_data.deleted;
 
 }
+
+/**
+ * gnutls_pkcs11_token_init:
+ * @token_url: A PKCS #11 URL specifying a token
+ * @so_pin: Security Officer's PIN
+ * @label: A name to be used for the token
+ *
+ * This function will initialize (format) a token. If the token is
+ * at a factory defaults state the security officer's PIN given will be
+ * set to be the default. Otherwise it should match the officer's PIN.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_pkcs11_token_init (const char *token_url,
+                                const char* so_pin,
+                                const char *label)
+{
+  int ret;
+  struct pkcs11_url_info info;
+  ck_rv_t rv;
+  pakchois_module_t *module;
+  ck_slot_id_t slot;
+  char flabel[32];
+
+  ret = pkcs11_url_to_info (token_url, &info);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  ret = pkcs11_find_slot(&module, &slot, &info, NULL);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+
+  /* so it seems memset has other uses than zeroing! */
+  memset(flabel, ' ', sizeof(flabel));
+  if (label != NULL)
+    memcpy(flabel, label, strlen(label));
+
+  rv = pakchois_init_token(module, slot, (char*)so_pin, strlen(so_pin), flabel);
+  if (rv != CKR_OK)
+    {
+      gnutls_assert ();
+      _gnutls_debug_log ("pkcs11: %s\n", pakchois_error (rv));
+      return pkcs11_rv_to_err (rv);
+    }
+
+  return 0;
+
+}
+
+/**
+ * gnutls_pkcs11_token_set_pin:
+ * @token_url: A PKCS #11 URL specifying a token
+ * @oldpin: old user's PIN
+ * @newpin: new user's PIN
+ * @flags: one of gnutls_pkcs11_pin_flag_t
+ *
+ * This function will modify or set a user's PIN for the given token. 
+ * If it is called to set a user pin for first time the oldpin must
+ * be NULL.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_pkcs11_token_set_pin (const char *token_url,
+                            const char* oldpin,
+                            const char* newpin,
+                            unsigned int flags)
+{
+  int ret;
+  pakchois_session_t *pks;
+  struct pkcs11_url_info info;
+  ck_rv_t rv;
+  unsigned int ses_flags;
+
+  ret = pkcs11_url_to_info (token_url, &info);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  if (((flags & GNUTLS_PKCS11_PIN_USER) && oldpin == NULL) || 
+    (flags & GNUTLS_PKCS11_PIN_SO))
+    ses_flags = SESSION_WRITE|SESSION_LOGIN|SESSION_SO;
+  else 
+    ses_flags = SESSION_WRITE|SESSION_LOGIN;
+
+  ret = pkcs11_open_session (&pks, &info, ses_flags);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+
+  if (oldpin == NULL)
+    {
+      rv = pakchois_init_pin(pks, (char*)newpin, strlen(newpin));
+      if (rv != CKR_OK)
+       {
+         gnutls_assert ();
+         _gnutls_debug_log ("pkcs11: %s\n", pakchois_error (rv));
+         ret = pkcs11_rv_to_err (rv);
+         goto finish;
+       }
+    }
+  else
+    {
+      rv = pakchois_set_pin(pks, 
+       (char*)oldpin, strlen(oldpin),
+       (char*)newpin, strlen(newpin));
+      if (rv != CKR_OK)
+       {
+         gnutls_assert ();
+         _gnutls_debug_log ("pkcs11: %s\n", pakchois_error (rv));
+         ret = pkcs11_rv_to_err (rv);
+         goto finish;
+       }
+    }
+
+  ret = 0;
+
+finish:
+  pakchois_close_session (pks);
+  return ret;
+
+}
index 9a5de9fd0b84526ea16e7f27468eb4c0657a05c2..6dad19beedae8fe274808e6c1d1cb66a753c4964 100644 (file)
@@ -614,7 +614,16 @@ pkcs11_init (FILE * outfile, const char *url, const char *label, common_info_st*
     exit(0);
   
   ret =
-    gnutls_pkcs11_token_init (url, so_pin, pin, label);
+    gnutls_pkcs11_token_init (url, so_pin, label);
+  if (ret < 0)
+    {
+      fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
+                  gnutls_strerror (ret));
+      exit (1);
+    }
+
+  ret =
+    gnutls_pkcs11_token_set_pin (url, NULL, pin, GNUTLS_PKCS11_PIN_USER);
   if (ret < 0)
     {
       fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,