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_from_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*
ref_pin_callback(void * pointer)153 ref_pin_callback (void *pointer)
154 {
155 PinCallback *cb = pointer;
156 cb->refs++;
157 return pointer;
158 }
159
160 static void
unref_pin_callback(void * pointer)161 unref_pin_callback (void *pointer)
162 {
163 PinCallback *cb = pointer;
164 assert (cb->refs >= 1);
165
166 cb->refs--;
167 if (cb->refs == 0) {
168 if (cb->destroy)
169 (cb->destroy) (cb->user_data);
170 free (cb);
171 }
172 }
173
174 static bool
register_callback_unlocked(const char * pin_source,PinCallback * cb)175 register_callback_unlocked (const char *pin_source,
176 PinCallback *cb)
177 {
178 p11_array *callbacks = NULL;
179 char *name;
180
181 name = strdup (pin_source);
182 return_val_if_fail (name != NULL, false);
183
184 if (gl.pin_sources == NULL) {
185 gl.pin_sources = p11_dict_new (p11_dict_str_hash, p11_dict_str_equal,
186 free, (p11_destroyer)p11_array_free);
187 return_val_if_fail (gl.pin_sources != NULL, false);
188 }
189
190 if (gl.pin_sources != NULL)
191 callbacks = p11_dict_get (gl.pin_sources, name);
192
193 if (callbacks == NULL) {
194 callbacks = p11_array_new (unref_pin_callback);
195 return_val_if_fail (callbacks != NULL, false);
196 if (!p11_dict_set (gl.pin_sources, name, callbacks))
197 return_val_if_reached (false);
198 name = NULL;
199 }
200
201 if (!p11_array_push (callbacks, cb))
202 return_val_if_reached (false);
203
204 free (name);
205 return true;
206 }
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
p11_kit_pin_register_callback(const char * pin_source,p11_kit_pin_callback callback,void * callback_data,p11_kit_pin_destroy_func callback_destroy)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 {
232 PinCallback *cb;
233 bool ret;
234
235 return_val_if_fail (pin_source != NULL, -1);
236 return_val_if_fail (callback != NULL, -1);
237
238 cb = calloc (1, sizeof (PinCallback));
239 return_val_if_fail (cb != NULL, -1);
240
241 cb->refs = 1;
242 cb->func = callback;
243 cb->user_data = callback_data;
244 cb->destroy = callback_destroy;
245
246 p11_lock ();
247
248 ret = register_callback_unlocked (pin_source, cb);
249
250 p11_unlock ();
251
252 return ret ? 0 : -1;
253 }
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
p11_kit_pin_unregister_callback(const char * pin_source,p11_kit_pin_callback callback,void * callback_data)267 p11_kit_pin_unregister_callback (const char *pin_source,
268 p11_kit_pin_callback callback,
269 void *callback_data)
270 {
271 PinCallback *cb;
272 p11_array *callbacks;
273 unsigned int i;
274
275 return_if_fail (pin_source != NULL);
276 return_if_fail (callback != NULL);
277
278 p11_lock ();
279
280 if (gl.pin_sources) {
281 callbacks = p11_dict_get (gl.pin_sources, pin_source);
282 if (callbacks) {
283 for (i = 0; i < callbacks->num; i++) {
284 cb = callbacks->elem[i];
285 if (cb->func == callback && cb->user_data == callback_data) {
286 p11_array_remove (callbacks, i);
287 break;
288 }
289 }
290
291 if (callbacks->num == 0)
292 p11_dict_remove (gl.pin_sources, pin_source);
293 }
294
295 /* When there are no more pin sources, get rid of the hash table */
296 if (p11_dict_size (gl.pin_sources) == 0) {
297 p11_dict_free (gl.pin_sources);
298 gl.pin_sources = NULL;
299 }
300 }
301
302 p11_unlock ();
303 }
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 *
p11_kit_pin_request(const char * pin_source,P11KitUri * pin_uri,const char * pin_description,P11KitPinFlags pin_flags)337 p11_kit_pin_request (const char *pin_source,
338 P11KitUri *pin_uri,
339 const char *pin_description,
340 P11KitPinFlags pin_flags)
341 {
342 PinCallback **snapshot = NULL;
343 unsigned int snapshot_count = 0;
344 p11_array *callbacks;
345 P11KitPin *pin;
346 unsigned int i;
347
348 return_val_if_fail (pin_source != NULL, NULL);
349
350 p11_lock ();
351
352 /* Find and ref the pin source data */
353 if (gl.pin_sources) {
354 callbacks = p11_dict_get (gl.pin_sources, pin_source);
355
356 /* If we didn't find any snapshots try the global ones */
357 if (callbacks == NULL)
358 callbacks = p11_dict_get (gl.pin_sources, P11_KIT_PIN_FALLBACK);
359
360 if (callbacks != NULL && callbacks->num) {
361 snapshot = memdup (callbacks->elem, sizeof (void *) * callbacks->num);
362 snapshot_count = callbacks->num;
363 for (i = 0; snapshot && i < snapshot_count; i++)
364 ref_pin_callback (snapshot[i]);
365 }
366 }
367
368 p11_unlock ();
369
370 if (snapshot == NULL)
371 return NULL;
372
373 for (pin = NULL, i = snapshot_count; pin == NULL && i > 0; i--) {
374 pin = (snapshot[i - 1]->func) (pin_source, pin_uri, pin_description, pin_flags,
375 snapshot[i - 1]->user_data);
376 }
377
378 p11_lock ();
379 for (i = 0; i < snapshot_count; i++)
380 unref_pin_callback (snapshot[i]);
381 free (snapshot);
382 p11_unlock ();
383
384 return pin;
385 }
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 *
p11_kit_pin_file_callback(const char * pin_source,P11KitUri * pin_uri,const char * pin_description,P11KitPinFlags pin_flags,void * callback_data)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 {
455 const size_t block = 1024;
456 unsigned char *buffer;
457 unsigned char *memory;
458 size_t used, allocated;
459 int error = 0;
460 int fd;
461 int res;
462
463 return_val_if_fail (pin_source != NULL, NULL);
464
465 /* We don't support retries */
466 if (pin_flags & P11_KIT_PIN_FLAGS_RETRY)
467 return NULL;
468
469 fd = open (pin_source, O_BINARY | O_RDONLY | O_CLOEXEC);
470 if (fd == -1)
471 return NULL;
472
473 buffer = NULL;
474 used = 0;
475 allocated = 0;
476
477 for (;;) {
478 if (used + block > 4096) {
479 error = EFBIG;
480 break;
481 }
482 if (used + block > allocated) {
483 memory = realloc (buffer, used + block);
484 if (memory == NULL) {
485 error = ENOMEM;
486 break;
487 }
488 buffer = memory;
489 allocated = used + block;
490 }
491
492 res = read (fd, buffer + used, allocated - used);
493 if (res < 0) {
494 if (errno == EAGAIN)
495 continue;
496 error = errno;
497 break;
498 } else if (res == 0) {
499 break;
500 } else {
501 used += res;
502 }
503 }
504
505 close (fd);
506
507 if (error != 0) {
508 free (buffer);
509 errno = error;
510 return NULL;
511 }
512
513 return p11_kit_pin_new_for_buffer (buffer, used, free);
514 }
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 *
p11_kit_pin_new(const unsigned char * value,size_t length)544 p11_kit_pin_new (const unsigned char *value, size_t length)
545 {
546 unsigned char *copy;
547 P11KitPin *pin;
548
549 copy = malloc (length);
550 return_val_if_fail (copy != NULL, NULL);
551
552 memcpy (copy, value, length);
553 pin = p11_kit_pin_new_for_buffer (copy, length, free);
554 return_val_if_fail (pin != NULL, NULL);
555
556 return pin;
557 }
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 *
p11_kit_pin_new_for_string(const char * value)574 p11_kit_pin_new_for_string (const char *value)
575 {
576 return p11_kit_pin_new ((const unsigned char *)value, strlen (value));
577 }
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 *
p11_kit_pin_new_for_buffer(unsigned char * buffer,size_t length,p11_kit_pin_destroy_func destroy)606 p11_kit_pin_new_for_buffer (unsigned char *buffer, size_t length,
607 p11_kit_pin_destroy_func destroy)
608 {
609 P11KitPin *pin;
610
611 pin = calloc (1, sizeof (P11KitPin));
612 return_val_if_fail (pin != NULL, NULL);
613
614 pin->ref_count = 1;
615 pin->buffer = buffer;
616 pin->length = length;
617 pin->destroy = destroy;
618
619 return pin;
620 }
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 *
p11_kit_pin_get_value(P11KitPin * pin,size_t * length)637 p11_kit_pin_get_value (P11KitPin *pin, size_t *length)
638 {
639 if (length)
640 *length = pin->length;
641 return pin->buffer;
642 }
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
p11_kit_pin_get_length(P11KitPin * pin)653 p11_kit_pin_get_length (P11KitPin *pin)
654 {
655 return pin->length;
656 }
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 *
p11_kit_pin_ref(P11KitPin * pin)669 p11_kit_pin_ref (P11KitPin *pin)
670 {
671 p11_lock ();
672
673 pin->ref_count++;
674
675 p11_unlock ();
676
677 return pin;
678 }
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
p11_kit_pin_unref(P11KitPin * pin)688 p11_kit_pin_unref (P11KitPin *pin)
689 {
690 bool last = false;
691
692 p11_lock ();
693
694 last = (pin->ref_count == 1);
695 pin->ref_count--;
696
697 p11_unlock ();
698
699 if (last) {
700 if (pin->destroy)
701 (pin->destroy) (pin->buffer);
702 free (pin);
703 }
704 }
705