## Create PSKC data

To create PSKC data you should first get a handle to a container using pskc_init. Add one or more keypackages to the container using pskc_add_keypackage. For each keypackage, set the relevant values you want using the "pskc_set_*" functions, for example pskc_set_device_serialno.

The XML output is created as usual with pskc_build_xml.

Here follows an example that would generate PSKC data that could be used to personalize an imaginary HOTP token.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    #include <stdio.h>
    #include <pskc/pskc.h>

    /*
     * $ cc -o pskccreate pskccreate.c $(pkg-config --cflags --libs libpskc)
     * $ ./pskccreate
     */

    #define PSKC_CHECK_RC					   \
      if (rc != PSKC_OK) {					   \
        printf ("%s (%d): %s\n", pskc_strerror_name (rc),	   \
    	    rc, pskc_strerror (rc));			   \
        return 1;						   \
      }

    int
    main (void)
    {
      size_t len;
      pskc_t *container;
      pskc_key_t *keypackage;
      char *out;
      int rc;

      rc = pskc_global_init ();
      PSKC_CHECK_RC;
      rc = pskc_init (&container);
      PSKC_CHECK_RC;

      rc = pskc_add_keypackage (container, &keypackage);
      PSKC_CHECK_RC;

      pskc_set_device_manufacturer (keypackage, "Acme");
      pskc_set_device_serialno (keypackage, "42");

      pskc_set_key_id (keypackage, "4711");
      pskc_set_key_algorithm (keypackage,
    			  "urn:ietf:params:xml:ns:keyprov:pskc:hotp");

      pskc_set_key_algparm_resp_encoding (keypackage, PSKC_VALUEFORMAT_DECIMAL);
      pskc_set_key_algparm_resp_length (keypackage, 8);

      pskc_set_key_data_counter (keypackage, 42);

      rc = pskc_set_key_data_b64secret (keypackage, "Zm9v");
      PSKC_CHECK_RC;

      rc = pskc_build_xml (container, &out, &len);
      PSKC_CHECK_RC;
      fwrite (out, 1, len, stdout);
      pskc_free (out);

      pskc_done (container);
      pskc_global_done ();

      return 0;
    }

You would compile and use the example like this.

    1
    2
    3
    4
    5
    jas@latte:~$ cc -o pskccreate pskccreate.c $(pkg-config --cflags --libs libpskc)
    jas@latte:~$ ./pskccreate
    <?xml version="1.0"?>
    <KeyContainer xmlns="urn:ietf:params:xml:ns:keyprov:pskc" Version="1.0"><KeyPackage><DeviceInfo><Manufacturer>Acme</Manufacturer><SerialNo>42</SerialNo></DeviceInfo><Key Id="4711" Algorithm="urn:ietf:params:xml:ns:keyprov:pskc:hotp"><AlgorithmParameters><ResponseFormat Encoding="DECIMAL" Length="8"/></AlgorithmParameters><Data><Secret><PlainValue>Zm9v</PlainValue></Secret><Counter><PlainValue>42</PlainValue></Counter></Data></Key></KeyPackage></KeyContainer>
    jas@latte:~$

For more background and information what each field mean and which ones are required, you should read the PSKC specification (RFC 6030). You may pretty print the XML generate using "xmllint --pretty 1" which may simplify reading it. You may use "pskctool --info" to print a human summary of some PSKC data and validate the XML syntax using "pskctool --validate".