Coverage Report

Created: 2025-07-12 06:14

/src/p11-kit/p11-kit/pin.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2011 Collabora Ltd.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 *
8
 *     * Redistributions of source code must retain the above
9
 *       copyright notice, this list of conditions and the
10
 *       following disclaimer.
11
 *     * Redistributions in binary form must reproduce the
12
 *       above copyright notice, this list of conditions and
13
 *       the following disclaimer in the documentation and/or
14
 *       other materials provided with the distribution.
15
 *     * The names of contributors to this software may not be
16
 *       used to endorse or promote products derived from this
17
 *       software without specific prior written permission.
18
 *
19
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
29
 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
30
 * DAMAGE.
31
 *
32
 * Author: Stef Walter <stefw@collabora.co.uk>
33
 */
34
35
#include "config.h"
36
37
#define P11_DEBUG_FLAG P11_DEBUG_PIN
38
#include "debug.h"
39
#include "dict.h"
40
#include "library.h"
41
#include "message.h"
42
#include "pkcs11.h"
43
#include "p11-kit.h"
44
#include "pin.h"
45
#include "private.h"
46
#include "array.h"
47
48
#include <assert.h>
49
#include <errno.h>
50
#include <fcntl.h>
51
#include <stdlib.h>
52
#include <string.h>
53
#include <unistd.h>
54
55
/**
56
 * SECTION:p11-kit-pin
57
 * @title: PIN Callbacks
58
 * @short_description: PIN Callbacks
59
 *
60
 * Applications can register a callback which will be called to provide a
61
 * password associated with a given pin source.
62
 *
63
 * PKCS\#11 URIs can contain a 'pin-source' attribute. The value of this attribute
64
 * is application dependent, but often references a file containing a PIN to
65
 * use.
66
 *
67
 * Using these functions, an applications or libraries can register a
68
 * callback with p11_kit_pin_register_callback() to be called when a given
69
 * 'pin-source' attribute value is requested. The application can then prompt
70
 * the user or retrieve a PIN for the given context. These registered
71
 * callbacks are only relevant and valid within the current process.
72
 *
73
 * A fallback callback can be registered by passing the %P11_KIT_PIN_FALLBACK
74
 * value to p11_kit_pin_register_callback(). This fallback callback will be
75
 * called for every 'pin-source' attribute request for which no callback has been
76
 * directly registered.
77
 *
78
 * To request a PIN for a given 'pin-source' attribute, use the
79
 * p11_kit_pin_request() function. If this function returns %NULL then either
80
 * no callbacks were registered or none of them could handle the request.
81
 *
82
 * If multiple callbacks are registered for the same PIN source, then they are
83
 * called in last-registered-first-called order. They are called in turn until
84
 * one of them can handle the request. Fallback callbacks are not called if
85
 * a callback was registered specifically for a requested 'pin-source' attribute.
86
 *
87
 * PINs themselves are handled inside of P11KitPin structures. These are thread
88
 * safe and allow the callback to specify how the PIN is stored in memory
89
 * and freed. A callback can use p11_kit_pin_new_for_string() or related
90
 * functions to create a PIN to be returned.
91
 *
92
 * For example in order to handle the following PKCS\#11 URI with a 'pin-source'
93
 * attribute
94
 *
95
 * <code><literallayout>
96
 *      pkcs11:id=\%69\%95\%3e\%5c\%f4\%bd\%ec\%91;pin-source=my-application
97
 * </literallayout></code>
98
 *
99
 * an application could register a callback like this:
100
 *
101
 * <informalexample><programlisting>
102
 * static P11KitPin*
103
 * my_application_pin_callback (const char *pin_source, P11KitUri *pin_uri,
104
 *                              const char *pin_description, P11KitPinFlags pin_flags,
105
 *                              void *callback_data)
106
 * {
107
 *     return p11_kit_pin_new_for_string ("pin-value");
108
 * }
109
 *
110
 * p11_kit_pin_register_callback ("my-application", my_application_pin_callback,
111
 *                                NULL, NULL);
112
 * </programlisting></informalexample>
113
 */
114
115
/**
116
 * P11KitPinFlags:
117
 * @P11_KIT_PIN_FLAGS_USER_LOGIN: The PIN is for a PKCS\#11 user type login.
118
 * @P11_KIT_PIN_FLAGS_SO_LOGIN: The PIN is for a PKCS\#11 security officer type login.
119
 * @P11_KIT_PIN_FLAGS_CONTEXT_LOGIN: The PIN is for a PKCS\#11 contect specific type login.
120
 * @P11_KIT_PIN_FLAGS_RETRY: The PIN is being requested again, due to an invalid previous PIN.
121
 * @P11_KIT_PIN_FLAGS_MANY_TRIES: The PIN has failed too many times, and few tries are left.
122
 * @P11_KIT_PIN_FLAGS_FINAL_TRY: The PIN has failed too many times, and this is the last try.
123
 *
124
 * Flags that are passed to p11_kit_pin_request() and registered callbacks.
125
 */
126
127
/**
128
 * P11_KIT_PIN_FALLBACK:
129
 *
130
 * Used with p11_kit_pin_register_callback() to register a fallback callback.
131
 * This callback will be called if no other callback is registered for a 'pin-source'.
132
 */
133
134
typedef struct _PinCallback {
135
  /* Only used/modified within the lock */
136
  int refs;
137
138
  /* Readonly after construct */
139
  p11_kit_pin_callback func;
140
  void *user_data;
141
  p11_kit_pin_destroy_func destroy;
142
} PinCallback;
143
144
/*
145
 * Shared data between threads, protected by the mutex, a structure so
146
 * we can audit thread safety easier.
147
 */
148
static struct _Shared {
149
  p11_dict *pin_sources;
150
} gl = { NULL };
151
152
static void*
153
ref_pin_callback (void *pointer)
154
0
{
155
0
  PinCallback *cb = pointer;
156
0
  cb->refs++;
157
0
  return pointer;
158
0
}
159
160
static void
161
unref_pin_callback (void *pointer)
162
0
{
163
0
  PinCallback *cb = pointer;
164
0
  assert (cb->refs >= 1);
165
166
0
  cb->refs--;
167
0
  if (cb->refs == 0) {
168
0
    if (cb->destroy)
169
0
      (cb->destroy) (cb->user_data);
170
0
    free (cb);
171
0
  }
172
0
}
173
174
static bool
175
register_callback_unlocked (const char *pin_source,
176
                            PinCallback *cb)
177
0
{
178
0
  p11_array *callbacks = NULL;
179
0
  char *name;
180
181
0
  name = strdup (pin_source);
182
0
  return_val_if_fail (name != NULL, false);
183
184
0
  if (gl.pin_sources == NULL) {
185
0
    gl.pin_sources = p11_dict_new (p11_dict_str_hash, p11_dict_str_equal,
186
0
                                   free, (p11_destroyer)p11_array_free);
187
0
    return_val_if_fail (gl.pin_sources != NULL, false);
188
0
  }
189
190
0
  if (gl.pin_sources != NULL)
191
0
    callbacks = p11_dict_get (gl.pin_sources, name);
192
193
0
  if (callbacks == NULL) {
194
0
    callbacks = p11_array_new (unref_pin_callback);
195
0
    return_val_if_fail (callbacks != NULL, false);
196
0
    if (!p11_dict_set (gl.pin_sources, name, callbacks))
197
0
      return_val_if_reached (false);
198
0
    name = NULL;
199
0
  }
200
201
0
  if (!p11_array_push (callbacks, cb))
202
0
    return_val_if_reached (false);
203
204
0
  free (name);
205
0
  return true;
206
0
}
207
208
/**
209
 * p11_kit_pin_register_callback:
210
 * @pin_source: the 'pin-source' attribute this this callback is for
211
 * @callback: the callback function
212
 * @callback_data: data that will be passed to the callback
213
 * @callback_destroy: a function that will be called with @callback_data when
214
 *     the callback is unregistered.
215
 *
216
 * Register a callback to handle PIN requests for a given 'pin-source' attribute.
217
 * If @pin_source is set to P11_KIT_PIN_FALLBACK then this will be a fallback
218
 * callback and will be called for requests for which no other callback has
219
 * been specifically registered.
220
 *
221
 * If multiple callbacks are registered for the same @pin_source value, then
222
 * the last registered callback will be the first to be called.
223
 *
224
 * Returns: Returns negative if registering fails.
225
 */
226
int
227
p11_kit_pin_register_callback (const char *pin_source,
228
                               p11_kit_pin_callback callback,
229
                               void *callback_data,
230
                               p11_kit_pin_destroy_func callback_destroy)
231
0
{
232
0
  PinCallback *cb;
233
0
  bool ret;
234
235
0
  return_val_if_fail (pin_source != NULL, -1);
236
0
  return_val_if_fail (callback != NULL, -1);
237
238
0
  cb = calloc (1, sizeof (PinCallback));
239
0
  return_val_if_fail (cb != NULL, -1);
240
241
0
  cb->refs = 1;
242
0
  cb->func = callback;
243
0
  cb->user_data = callback_data;
244
0
  cb->destroy = callback_destroy;
245
246
0
  p11_lock ();
247
248
0
  ret = register_callback_unlocked (pin_source, cb);
249
250
0
  p11_unlock ();
251
252
0
  return ret ? 0 : -1;
253
0
}
254
255
/**
256
 * p11_kit_pin_unregister_callback:
257
 * @pin_source: the 'pin-source' attribute the callback was registered for
258
 * @callback: the callback function that was registered
259
 * @callback_data: data that was registered for the callback
260
 *
261
 * Unregister a callback that was previously registered with the
262
 * p11_kit_pin_register_callback() function. If more than one registered
263
 * callback matches the given arguments, then only one of those will be
264
 * removed.
265
 */
266
void
267
p11_kit_pin_unregister_callback (const char *pin_source,
268
                                 p11_kit_pin_callback callback,
269
                                 void *callback_data)
270
0
{
271
0
  PinCallback *cb;
272
0
  p11_array *callbacks;
273
0
  unsigned int i;
274
275
0
  return_if_fail (pin_source != NULL);
276
0
  return_if_fail (callback != NULL);
277
278
0
  p11_lock ();
279
280
0
    if (gl.pin_sources) {
281
0
      callbacks = p11_dict_get (gl.pin_sources, pin_source);
282
0
      if (callbacks) {
283
0
        for (i = 0; i < callbacks->num; i++) {
284
0
          cb = callbacks->elem[i];
285
0
          if (cb->func == callback && cb->user_data == callback_data) {
286
0
            p11_array_remove (callbacks, i);
287
0
            break;
288
0
          }
289
0
        }
290
291
0
        if (callbacks->num == 0)
292
0
          p11_dict_remove (gl.pin_sources, pin_source);
293
0
      }
294
295
      /* When there are no more pin sources, get rid of the hash table */
296
0
      if (p11_dict_size (gl.pin_sources) == 0) {
297
0
        p11_dict_free (gl.pin_sources);
298
0
        gl.pin_sources = NULL;
299
0
      }
300
0
    }
301
302
0
  p11_unlock ();
303
0
}
304
305
/**
306
 * p11_kit_pin_request:
307
 * @pin_source: the 'pin-source' attribute that is being requested
308
 * @pin_uri: a PKCS\#11 URI that the PIN is being requested for, optionally %NULL.
309
 * @pin_description: a description of what the PIN is for, must not be %NULL.
310
 * @pin_flags: various flags for this request
311
 *
312
 * Request a PIN for a given 'pin-source' attribute. The result depends on the
313
 * registered callbacks.
314
 *
315
 * If not %NULL, then the @pin_uri attribute should point to the thing that the
316
 * PIN is being requested for. In most use cases this should be a PKCS\#11 URI
317
 * pointing to a token.
318
 *
319
 * The @pin_description should always be specified. It is a string describing
320
 * what the PIN is for. For example this would be the token label, if the PIN
321
 * is for a token.
322
 *
323
 * If more than one callback is registered for the @pin_source, then the latest
324
 * registered one will be called first. If that callback does not return a
325
 * PIN, then the next will be called in turn.
326
 *
327
 * If no callback is registered for @pin_source, then the fallback callbacks will
328
 * be invoked in the same way. The fallback callbacks will not be called if any
329
 * callback has been registered specifically for @pin_source.
330
 *
331
 * The PIN returned should be released with p11_kit_pin_unref().
332
 *
333
 * Returns: the PIN which should be released with p11_kit_pin_unref(), or %NULL
334
 *     if no callback was registered or could proivde a PIN
335
 */
336
P11KitPin *
337
p11_kit_pin_request (const char *pin_source,
338
                     P11KitUri *pin_uri,
339
                     const char *pin_description,
340
                     P11KitPinFlags pin_flags)
341
0
{
342
0
  PinCallback **snapshot = NULL;
343
0
  unsigned int snapshot_count = 0;
344
0
  p11_array *callbacks;
345
0
  P11KitPin *pin;
346
0
  unsigned int i;
347
348
0
  return_val_if_fail (pin_source != NULL, NULL);
349
350
0
  p11_lock ();
351
352
    /* Find and ref the pin source data */
353
0
    if (gl.pin_sources) {
354
0
      callbacks = p11_dict_get (gl.pin_sources, pin_source);
355
356
      /* If we didn't find any snapshots try the global ones */
357
0
      if (callbacks == NULL)
358
0
        callbacks = p11_dict_get (gl.pin_sources, P11_KIT_PIN_FALLBACK);
359
360
0
      if (callbacks != NULL && callbacks->num) {
361
0
        snapshot = memdup (callbacks->elem, sizeof (void *) * callbacks->num);
362
0
        snapshot_count = callbacks->num;
363
0
        for (i = 0; snapshot && i < snapshot_count; i++)
364
0
          ref_pin_callback (snapshot[i]);
365
0
      }
366
0
    }
367
368
0
  p11_unlock ();
369
370
0
  if (snapshot == NULL)
371
0
    return NULL;
372
373
0
  for (pin = NULL, i = snapshot_count; pin == NULL && i > 0; i--) {
374
0
    pin = (snapshot[i - 1]->func) (pin_source, pin_uri, pin_description, pin_flags,
375
0
                                   snapshot[i - 1]->user_data);
376
0
  }
377
378
0
  p11_lock ();
379
0
    for (i = 0; i < snapshot_count; i++)
380
0
      unref_pin_callback (snapshot[i]);
381
0
    free (snapshot);
382
0
  p11_unlock ();
383
384
0
  return pin;
385
0
}
386
387
/**
388
 * p11_kit_pin_callback:
389
 * @pin_source: a 'pin-source' attribute string
390
 * @pin_uri: a PKCS\#11 URI that the PIN is for, or %NULL
391
 * @pin_description: a descrption of what the PIN is for
392
 * @pin_flags: flags describing the PIN request
393
 * @callback_data: data that was provided when registering this callback
394
 *
395
 * Represents a PIN callback function.
396
 *
397
 * The various arguments are the same as the ones passed to
398
 * p11_kit_pin_request(). The @callback_data argument was the one passed to
399
 * p11_kit_pin_register_callback() when registering this callback.
400
 *
401
 * The function should return %NULL if it could not provide a PIN, either
402
 * because of an error or a user cancellation.
403
 *
404
 * If a PIN is returned, it will be unreferenced by the caller. So it should be
405
 * either newly allocated, or referenced before returning.
406
 *
407
 * Returns: A PIN or %NULL
408
 */
409
410
/**
411
 * p11_kit_pin_destroy_func:
412
 * @data: the data to destroy
413
 *
414
 * A function called to free or cleanup @data.
415
 */
416
417
/**
418
 * p11_kit_pin_file_callback:
419
 * @pin_source: a 'pin-source' attribute string
420
 * @pin_uri: a PKCS\#11 URI that the PIN is for, or %NULL
421
 * @pin_description: a descrption of what the PIN is for
422
 * @pin_flags: flags describing the PIN request
423
 * @callback_data: unused, should be %NULL
424
 *
425
 * This is a PIN callback function that looks up the 'pin-source' attribute in
426
 * a file with that name. This can be used to enable the normal PKCS\#11 URI
427
 * behavior described in the RFC.
428
 *
429
 * If @pin_flags contains the %P11_KIT_PIN_FLAGS_RETRY flag, then this
430
 * callback will always return %NULL. This is to prevent endless loops
431
 * where an application is expecting to interact with a prompter, but
432
 * instead is interacting with this callback reading a file over and over.
433
 *
434
 * This callback fails on files larger than 4 Kilobytes.
435
 *
436
 * This callback is not registered by default. It may have security
437
 * implications depending on the source of the PKCS\#11 URI and the PKCS\#11
438
 * in use. To register it, use code like the following:
439
 *
440
 * <informalexample><programlisting>
441
 * p11_kit_pin_register_callback (P11_KIT_PIN_FALLBACK, p11_kit_pin_file_callback,
442
 *                                NULL, NULL);
443
 * </programlisting></informalexample>
444
 *
445
 * Returns: a referenced PIN with the file contents, or %NULL if the file
446
 *          could not be read
447
 */
448
P11KitPin *
449
p11_kit_pin_file_callback (const char *pin_source,
450
                           P11KitUri *pin_uri,
451
                           const char *pin_description,
452
                           P11KitPinFlags pin_flags,
453
                           void *callback_data)
454
0
{
455
0
  const size_t block = 1024;
456
0
  unsigned char *buffer;
457
0
  unsigned char *memory;
458
0
  size_t used, allocated;
459
0
  int error = 0;
460
0
  int fd;
461
0
  int res;
462
463
0
  return_val_if_fail (pin_source != NULL, NULL);
464
465
  /* We don't support retries */
466
0
  if (pin_flags & P11_KIT_PIN_FLAGS_RETRY)
467
0
    return NULL;
468
469
0
  fd = open (pin_source, O_BINARY | O_RDONLY | O_CLOEXEC);
470
0
  if (fd == -1)
471
0
    return NULL;
472
473
0
  buffer = NULL;
474
0
  used = 0;
475
0
  allocated = 0;
476
477
0
  for (;;) {
478
0
    if (used + block > 4096) {
479
0
      error = EFBIG;
480
0
      break;
481
0
    }
482
0
    if (used + block > allocated) {
483
0
      memory = realloc (buffer, used + block);
484
0
      if (memory == NULL) {
485
0
        error = ENOMEM;
486
0
        break;
487
0
      }
488
0
      buffer = memory;
489
0
      allocated = used + block;
490
0
    }
491
492
0
    res = read (fd, buffer + used, allocated - used);
493
0
    if (res < 0) {
494
0
      if (errno == EAGAIN)
495
0
        continue;
496
0
      error = errno;
497
0
      break;
498
0
    } else if (res == 0) {
499
0
      break;
500
0
    } else {
501
0
      used += res;
502
0
    }
503
0
  }
504
505
0
  close (fd);
506
507
0
  if (error != 0) {
508
0
    free (buffer);
509
0
    errno = error;
510
0
    return NULL;
511
0
  }
512
513
0
  return p11_kit_pin_new_for_buffer (buffer, used, free);
514
0
}
515
516
/**
517
 * P11KitPin:
518
 *
519
 * A structure representing a PKCS\#11 PIN. There are no public fields
520
 * visible in this structure. Use the various accessor functions.
521
 */
522
struct p11_kit_pin {
523
  int ref_count;
524
  unsigned char *buffer;
525
  size_t length;
526
  p11_kit_pin_destroy_func destroy;
527
};
528
529
/**
530
 * p11_kit_pin_new:
531
 * @value: the value of the PIN
532
 * @length: the length of @value
533
 *
534
 * Create a new P11KitPin with the given PIN value. This function is
535
 * usually used from within registered PIN callbacks.
536
 *
537
 * Exactly @length bytes from @value are used. Null terminated strings,
538
 * or encodings are not considered. A copy of the @value will be made.
539
 *
540
 * Returns: The newly allocated P11KitPin, which should be freed with
541
 *          p11_kit_pin_unref() when no longer needed.
542
 */
543
P11KitPin *
544
p11_kit_pin_new (const unsigned char *value, size_t length)
545
0
{
546
0
  unsigned char *copy;
547
0
  P11KitPin *pin;
548
549
0
  copy = malloc (length);
550
0
  return_val_if_fail (copy != NULL, NULL);
551
552
0
  memcpy (copy, value, length);
553
0
  pin = p11_kit_pin_new_for_buffer (copy, length, free);
554
0
  return_val_if_fail (pin != NULL, NULL);
555
556
0
  return pin;
557
0
}
558
559
/**
560
 * p11_kit_pin_new_for_string:
561
 * @value: the value of the PIN
562
 *
563
 * Create a new P11KitPin for the given null-terminated string, such as a
564
 * password. This function is usually used from within registered
565
 * PIN callbacks.
566
 *
567
 * The PIN will consist of the string not including the null terminator.
568
 * String encoding is not considered. A copy of the @value will be made.
569
 *
570
 * Returns: The newly allocated P11KitPin, which should be freed with
571
 *     p11_kit_pin_unref() when no longer needed.
572
 */
573
P11KitPin *
574
p11_kit_pin_new_for_string (const char *value)
575
0
{
576
0
  return p11_kit_pin_new ((const unsigned char *)value, strlen (value));
577
0
}
578
579
/**
580
 * p11_kit_pin_new_for_buffer:
581
 * @buffer: the value of the PIN
582
 * @length: the length of @buffer
583
 * @destroy: if not %NULL, then called when PIN is destroyed.
584
 *
585
 * Create a new P11KitPin which will use @buffer for the PIN value.
586
 * This function is usually used from within registered PIN callbacks.
587
 *
588
 * The buffer will not be copied. String encodings and null characters
589
 * are not considered.
590
 *
591
 * When the last reference to this PIN is lost, then the @destroy callback
592
 * function will be called passing @buffer as an argument. This allows the
593
 * caller to use a buffer as a PIN without copying it.
594
 *
595
 * <informalexample><programlisting>
596
 * char *buffer = malloc (128);
597
 * P11KitPin *pin;
598
 *  ....
599
 * pin = p11_kit_pin_new_for_buffer (buffer, 128, free);
600
 * </programlisting></informalexample>
601
 *
602
 * Returns: The newly allocated P11KitPin, which should be freed with
603
 *          p11_kit_pin_unref() when no longer needed.
604
 */
605
P11KitPin *
606
p11_kit_pin_new_for_buffer (unsigned char *buffer, size_t length,
607
                            p11_kit_pin_destroy_func destroy)
608
0
{
609
0
  P11KitPin *pin;
610
611
0
  pin = calloc (1, sizeof (P11KitPin));
612
0
  return_val_if_fail (pin != NULL, NULL);
613
614
0
  pin->ref_count = 1;
615
0
  pin->buffer = buffer;
616
0
  pin->length = length;
617
0
  pin->destroy = destroy;
618
619
0
  return pin;
620
0
}
621
622
/**
623
 * p11_kit_pin_get_value:
624
 * @pin: the P11KitPin
625
 * @length: a location to return the value length
626
 *
627
 * Get the PIN value from a P11KitPin. @length will be set to the
628
 * length of the value.
629
 *
630
 * The value returned is owned by the P11KitPin and should not be modified.
631
 * It remains valid as long as a reference to the PIN is held. The PIN value
632
 * will not contain an extra null-terminator character.
633
 *
634
 * Returns: the value for the PIN.
635
 */
636
const unsigned char *
637
p11_kit_pin_get_value (P11KitPin *pin, size_t *length)
638
0
{
639
0
  if (length)
640
0
    *length = pin->length;
641
0
  return pin->buffer;
642
0
}
643
644
/**
645
 * p11_kit_pin_get_length
646
 * @pin: the P11KitPin
647
 *
648
 * Get the length of the PIN value from a P11KitPin.
649
 *
650
 * Returns: the length of the PIN value.
651
 */
652
size_t
653
p11_kit_pin_get_length (P11KitPin *pin)
654
0
{
655
0
  return pin->length;
656
0
}
657
658
/**
659
 * p11_kit_pin_ref:
660
 * @pin: the P11KitPin
661
 *
662
 * Add a reference to a P11KitPin. This should be matched with a later call
663
 * to p11_kit_pin_unref(). As long as at least one reference is held, the PIN
664
 * will remain valid and in memory.
665
 *
666
 * Returns: the @pin pointer, for convenience sake.
667
 */
668
P11KitPin *
669
p11_kit_pin_ref (P11KitPin *pin)
670
0
{
671
0
  p11_lock ();
672
673
0
    pin->ref_count++;
674
675
0
  p11_unlock ();
676
677
0
  return pin;
678
0
}
679
680
/**
681
 * p11_kit_pin_unref:
682
 * @pin: the P11KitPin
683
 *
684
 * Remove a reference from a P11KitPin. When all references have been removed
685
 * then the PIN will be freed and will no longer be in memory.
686
 */
687
void
688
p11_kit_pin_unref (P11KitPin *pin)
689
0
{
690
0
  bool last = false;
691
692
0
  p11_lock ();
693
694
0
    last = (pin->ref_count == 1);
695
0
    pin->ref_count--;
696
697
0
  p11_unlock ();
698
699
0
  if (last) {
700
0
    if (pin->destroy)
701
0
      (pin->destroy) (pin->buffer);
702
0
    free (pin);
703
0
  }
704
0
}