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