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 source.

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. This function is usually used from within registered PIN callbacks.

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. This function is usually used from within registered PIN callbacks.

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. This function is usually used from within registered PIN callbacks.

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<<0,
    	P11_KIT_PIN_FLAGS_SO_LOGIN = 1<<1,
    	P11_KIT_PIN_FLAGS_CONTEXT_LOGIN = 1<<2,
    	P11_KIT_PIN_FLAGS_RETRY = 1<<3,
    	P11_KIT_PIN_FLAGS_MANY_TRIES = 1<<4,
    	P11_KIT_PIN_FLAGS_FINAL_TRY = 1<<5
    } 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 callback is registered for a 'pin-source'.

### 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.

### 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.

If `pin_flags` contains the `P11_KIT_PIN_FLAGS_RETRY` flag, then this callback will always return `NULL`. This is to prevent endless loops where an application is expecting to interact with a prompter, but instead is interacting with this callback reading a file over and over.

This callback fails on files larger than 4 Kilobytes.

This callback is not registered by default. It may have security implications depending on the source of the PKCS#11 URI and the PKCS#11 in use. 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 file contents, or `NULL` if the file could not be read