PIN Callbacks

## PIN Callbacks PIN Callbacks — PIN Callbacks |

## Synopsis

    typedef             P11KitPin;
    P11KitPin *         p11_kit_pin_new                     (const unsigned char *value,
                                                             size_t length);
    P11KitPin *         p11_kit_pin_new_for_buffer          (unsigned char *buffer,
                                                             size_t length,
                                                             p11_kit_pin_destroy_func destroy);
    P11KitPin *         p11_kit_pin_new_for_string          (const char *value);
    const unsigned char * p11_kit_pin_get_value             (P11KitPin *pin,
                                                             size_t *length);
    size_t              p11_kit_pin_get_length              (P11KitPin *pin);
    P11KitPin *         p11_kit_pin_ref                     (P11KitPin *pin);
    void                p11_kit_pin_unref                   (P11KitPin *pin);
    enum                P11KitPinFlags;
    #define             P11_KIT_PIN_FALLBACK
    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);
    void                p11_kit_pin_unregister_callback     (const char *pin_source,
                                                             p11_kit_pin_callback callback,
                                                             void *callback_data);
    P11KitPin *         (*p11_kit_pin_callback)             (const char *pin_source,
                                                             P11KitUri *pin_uri,
                                                             const char *pin_description,
                                                             P11KitPinFlags pin_flags,
                                                             void *callback_data);
    P11KitPin *         p11_kit_pin_request                 (const char *pin_source,
                                                             P11KitUri *pin_uri,
                                                             const char *pin_description,
                                                             P11KitPinFlags pin_flags);
    void                (*p11_kit_pin_destroy_func)         (void *data);
    P11KitPin *         p11_kit_pin_file_callback           (const char *pin_source,
                                                             P11KitUri *pin_uri,
                                                             const char *pin_description,
                                                             P11KitPinFlags pin_flags,
                                                             void *callback_data);

## Description

Applications can register a callback which will be called to provide a password associated with a given pin file.

PKCS#11 URIs can contain a 'pin-source' attribute. The value of this attribute is application dependent, but often references a file containing a PIN to use.

Using these functions, an applications or libraries can register a callback with `p11_kit_pin_register_callback()` to be called when a given 'pin-source' attribute value is requested. The application can then prompt the user or retrieve a PIN for the given context. These registered callbacks are only relevant and valid within the current process.

A fallback callback can be registered by passing the `P11_KIT_PIN_FALLBACK` value to `p11_kit_pin_register_callback()`. This fallback callback will be called for every 'pin-source' attribute request for which no callback has been directly registered.

To request a PIN for a given 'pin-source' attribute, use the `p11_kit_pin_request()` function. If this function returns `NULL` then either no callbacks were registered or none of them could handle the request.

If multiple callbacks are registered for the same PIN source, then they are called in last-registered-first-called order. They are called in turn until one of them can handle the request. Fallback callbacks are not called if a callback was registered specifically for a requested 'pin-source' attribute.

PINs themselves are handled inside of P11KitPin structures. These are thread safe and allow the callback to specify how the PIN is stored in memory and freed. A callback can use `p11_kit_pin_new_for_string()` or related functions to create a PIN to be returned.

For example in order to handle the following PKCS#11 URI with a 'pin-source' attribute

``

pkcs11:id=%69%95%3e%5c%f4%bd%ec%91;pin-source=my-application

an application could register a callback like this:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    static P11KitPin*
    my_application_pin_callback (const char *pin_source, P11KitUri *pin_uri,
                                 const char *pin_description, P11KitPinFlags pin_flags,
                                 void *callback_data)
    {
        return p11_kit_pin_new_from_string ("pin-value");
    }

    p11_kit_pin_register_callback ("my-application", my_application_pin_callback,
                                   NULL, NULL);

## Details

### P11KitPin

    typedef struct p11_kit_pin P11KitPin;

A structure representing a PKCS#11 PIN. There are no public fields visible in this structure. Use the various accessor functions.

### p11_kit_pin_new ()

    P11KitPin *         p11_kit_pin_new                     (const unsigned char *value,
                                                             size_t length);

Create a new P11KitPin with the given PIN value. The exactly `length` bytes from `value` are used. Null terminated strings, or encodings are not considered.

A copy of the `value` will be made.

`value` : | the value of the PIN
`length` : | the length of `value`
Returns : | The newly allocated P11KitPin, which should be freed with `p11_kit_pin_unref()` when no longer needed.

### p11_kit_pin_new_for_buffer ()

    P11KitPin *         p11_kit_pin_new_for_buffer          (unsigned char *buffer,
                                                             size_t length,
                                                             p11_kit_pin_destroy_func destroy);

Create a new P11KitPin which will use `buffer` for the PIN value. The buffer will not be copied. String encodings and null characters are not considered.

When the last reference to this PIN is lost, then the `destroy` callback function will be called passing `buffer` as an argument. This allows the caller to use a buffer as a PIN without copying it.

    1
    2
    3
    4
    char *buffer = malloc (128);
    P11KitPin *pin;
     ....
    pin = p11_kit_pin_new_for_buffer (buffer, 128, free);

`buffer` : | the value of the PIN
`length` : | the length of `buffer`
`destroy` : | if not `NULL`, then called when PIN is destroyed.
Returns : | The newly allocated P11KitPin, which should be freed with `p11_kit_pin_unref()` when no longer needed.

### p11_kit_pin_new_for_string ()

    P11KitPin *         p11_kit_pin_new_for_string          (const char *value);

Create a new P11KitPin for the given null-terminated string, such as a password. The PIN will consist of the string not including the null terminator. String encoding is not considered.

A copy of the `value` will be made.

`value` : | the value of the PIN
Returns : | The newly allocated P11KitPin, which should be freed with `p11_kit_pin_unref()` when no longer needed.

### p11_kit_pin_get_value ()

    const unsigned char * p11_kit_pin_get_value             (P11KitPin *pin,
                                                             size_t *length);

Get the PIN value from a P11KitPin. `length` will be set to the length of the value.

The value returned is owned by the P11KitPin and should not be modified. It remains valid as long as a reference to the PIN is held. The PIN value will not contain an extra null-terminator character.

`pin` : | the P11KitPin
`length` : | a location to return the value length
Returns : | the value for the PIN.

### p11_kit_pin_get_length ()

    size_t              p11_kit_pin_get_length              (P11KitPin *pin);

Get the length of the PIN value from a P11KitPin.

`pin` : | the P11KitPin
Returns : | the length of the PIN value.

### p11_kit_pin_ref ()

    P11KitPin *         p11_kit_pin_ref                     (P11KitPin *pin);

Add a reference to a P11KitPin. This should be matched with a later call to `p11_kit_pin_unref()`. As long as at least one reference is held, the PIN will remain valid and in memory.

`pin` : | the P11KitPin
Returns : | the `pin` pointer, for convenience sake.

### p11_kit_pin_unref ()

    void                p11_kit_pin_unref                   (P11KitPin *pin);

Remove a reference from a P11KitPin. When all references have been removed then the PIN will be freed and will no longer be in memory.

`pin` : | the P11KitPin

### enum P11KitPinFlags

    typedef enum {
    	P11_KIT_PIN_FLAGS_USER_LOGIN = 1,
    	P11_KIT_PIN_FLAGS_SO_LOGIN = 2,
    	P11_KIT_PIN_FLAGS_CONTEXT_LOGIN = 4,
    	P11_KIT_PIN_FLAGS_RETRY = 10,
    	P11_KIT_PIN_FLAGS_MANY_TRIES = 20,
    	P11_KIT_PIN_FLAGS_FINAL_TRY = 40
    } P11KitPinFlags;

Flags that are passed to `p11_kit_pin_request()` and registered callbacks.

`P11_KIT_PIN_FLAGS_USER_LOGIN` | The PIN is for a PKCS#11 user type login.
`P11_KIT_PIN_FLAGS_SO_LOGIN` | The PIN is for a PKCS#11 security officer type login.
`P11_KIT_PIN_FLAGS_CONTEXT_LOGIN` | The PIN is for a PKCS#11 contect specific type login.
`P11_KIT_PIN_FLAGS_RETRY` | The PIN is being requested again, due to an invalid previous PIN.
`P11_KIT_PIN_FLAGS_MANY_TRIES` | The PIN has failed too many times, and few tries are left.
`P11_KIT_PIN_FLAGS_FINAL_TRY` | The PIN has failed too many times, and this is the last try.

### P11_KIT_PIN_FALLBACK

    #define P11_KIT_PIN_FALLBACK ""

Used with `p11_kit_pin_register_callback()` to register a fallback callback. This callback will be called if no other String of URI scheme for PKCS#11 URIs.

### p11_kit_pin_register_callback ()

    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);

Register a callback to handle PIN requests for a given 'pin-source' attribute. If `pin_source` is set to P11_KIT_PIN_FALLBACK then this will be a fallback callback and will be called for requests for which no other callback has been specifically registered.

If multiple callbacks are registered for the same `pin_source` value, then the last registered callback will be the first to be called.

`pin_source` : | the 'pin-source' attribute this this callback is for
`callback` : | the callback function
`callback_data` : | data that will be passed to the callback
`callback_destroy` : | a function that will be called with `callback_data` when the callback is unregistered.
Returns : | Returns negative if registering fails. This can only happen if memory cannot be allocated.

### p11_kit_pin_unregister_callback ()

    void                p11_kit_pin_unregister_callback     (const char *pin_source,
                                                             p11_kit_pin_callback callback,
                                                             void *callback_data);

Unregister a callback that was previously registered with the `p11_kit_pin_register_callback()` function. If more than one registered callback matches the given arguments, then only one of those will be removed.

`pin_source` : | the 'pin-source' attribute the callback was registered for
`callback` : | the callback function that was registered
`callback_data` : | data that was registered for the callback

### p11_kit_pin_callback ()

    P11KitPin *         (*p11_kit_pin_callback)             (const char *pin_source,
                                                             P11KitUri *pin_uri,
                                                             const char *pin_description,
                                                             P11KitPinFlags pin_flags,
                                                             void *callback_data);

Represents a PIN callback function.

The various arguments are the same as the ones passed to `p11_kit_pin_request()`. The `callback_data` argument was the one passed to `p11_kit_pin_register_callback()` when registering this callback.

The function should return `NULL` if it could not provide a PIN, either because of an error or a user cancellation.

If a PIN is returned, it will be unreferenced by the caller. So it should be either newly allocated, or referenced before returning.

`pin_source` : | a 'pin-source' attribute string
`pin_uri` : | a PKCS#11 URI that the PIN is for, or `NULL`
`pin_description` : | a descrption of what the PIN is for
`pin_flags` : | flags describing the PIN request
`callback_data` : | data that was provided when registering this callback
Returns : | A PIN or `NULL`

### p11_kit_pin_request ()

    P11KitPin *         p11_kit_pin_request                 (const char *pin_source,
                                                             P11KitUri *pin_uri,
                                                             const char *pin_description,
                                                             P11KitPinFlags pin_flags);

Request a PIN for a given 'pin-source' attribute. The result depends on the registered callbacks.

If not `NULL`, then the `pin_uri` attribute should point to the thing that the PIN is being requested for. In most use cases this should be a PKCS#11 URI pointing to a token.

The `pin_description` should always be specified. It is a string describing what the PIN is for. For example this would be the token label, if the PIN is for a token.

If more than one callback is registered for the `pin_source`, then the latest registered one will be called first. If that callback does not return a PIN, then the next will be called in turn.

If no callback is registered for `pin_source`, then the fallback callbacks will be invoked in the same way. The fallback callbacks will not be called if any callback has been registered specifically for `pin_source`.

The PIN returned should be released with `p11_kit_pin_unref()`.

`pin_source` : | the 'pin-source' attribute that is being requested
`pin_uri` : | a PKCS#11 URI that the PIN is being requested for, optionally `NULL`.
`pin_description` : | a description of what the PIN is for, must not be `NULL`.
`pin_flags` : | various flags for this request
Returns : | the PIN which should be released with `p11_kit_pin_unref()`, or `NULL` if no callback was registered or could proivde a PIN

### p11_kit_pin_destroy_func ()

    void                (*p11_kit_pin_destroy_func)         (void *data);

A function called to free or cleanup `data`.

`data` : | the data to destroy

### p11_kit_pin_file_callback ()

    P11KitPin *         p11_kit_pin_file_callback           (const char *pin_source,
                                                             P11KitUri *pin_uri,
                                                             const char *pin_description,
                                                             P11KitPinFlags pin_flags,
                                                             void *callback_data);

This is a PIN callback function that looks up the 'pin-source' attribute in a file with that name. This can be used to enable the normal PKCS#11 URI behavior described in the RFC.

This callback is not registered by default. To register it use code like the following:

    1
    2
    p11_kit_pin_register_callback (P11_KIT_PIN_FALLBACK, p11_kit_pin_file_callback,
                                   NULL, NULL);

`pin_source` : | a 'pin-source' attribute string
`pin_uri` : | a PKCS#11 URI that the PIN is for, or `NULL`
`pin_description` : | a descrption of what the PIN is for
`pin_flags` : | flags describing the PIN request
`callback_data` : | unused, should be `NULL`
Returns : | A referenced PIN with the pinfile contents, or `NULL` if the file could not be read.