Blame usr/sbin/p11sak/p11sak.c

Packit 8681c6
/*
Packit 8681c6
 * COPYRIGHT (c) International Business Machines Corp. 2001-2020
Packit 8681c6
 *
Packit 8681c6
 * This program is provided under the terms of the Common Public License,
Packit 8681c6
 * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
Packit 8681c6
 * software constitutes recipient's acceptance of CPL-1.0 terms which can be
Packit 8681c6
 * found in the file LICENSE file or at
Packit 8681c6
 * https://opensource.org/licenses/cpl1.0.php
Packit 8681c6
 */
Packit 8681c6
Packit 8681c6
#define _GNU_SOURCE
Packit 8681c6
Packit 8681c6
#include <stdio.h>
Packit 8681c6
#include <stdlib.h>
Packit 8681c6
#include <errno.h>
Packit 8681c6
#include <string.h>
Packit 8681c6
#include <pkcs11types.h>
Packit 8681c6
#include <dlfcn.h>
Packit 8681c6
Packit 8681c6
#include <termios.h>
Packit Service 8aa27d
#include "p11util.h"
Packit 8681c6
#include "p11sak.h"
Packit 8681c6
Packit 8681c6
static const char *default_pkcs11lib = "libopencryptoki.so";
Packit 8681c6
Packit 8681c6
static void *pkcs11lib = NULL;
Packit 8681c6
static CK_FUNCTION_LIST *funcs = NULL;
Packit 8681c6
Packit 8681c6
static void unload_pkcs11lib(void)
Packit 8681c6
{
Packit 8681c6
    if (pkcs11lib)
Packit 8681c6
        dlclose(pkcs11lib);
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
static void load_pkcs11lib(void)
Packit 8681c6
{
Packit 8681c6
    CK_RV rc;
Packit Service 8aa27d
    CK_RV (*pfoo)();
Packit 8681c6
    const char *libname;
Packit 8681c6
Packit 8681c6
    /* check for environment variable PKCSLIB */
Packit Service 8aa27d
    libname = secure_getenv("PKCSLIB");
Packit 8681c6
    if (libname == NULL || strlen(libname) < 1)
Packit 8681c6
        libname = default_pkcs11lib;
Packit 8681c6
Packit 8681c6
    /* try to load the pkcs11 lib */
Packit 8681c6
    pkcs11lib = dlopen(libname, RTLD_NOW);
Packit 8681c6
    if (!pkcs11lib) {
Packit 8681c6
        printf("Error: failed to open pkcs11 lib '%s'\n", libname);
Packit 8681c6
        exit(99);
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    /* get function list */
Packit Service 8aa27d
    *(void**) (&pfoo) = dlsym(pkcs11lib, "C_GetFunctionList");
Packit 8681c6
    if (!pfoo) {
Packit 8681c6
        dlclose(pkcs11lib);
Packit 8681c6
        printf("Error: failed to resolve symbol '%s' from pkcs11 lib '%s'\n",
Packit Service 8aa27d
                "C_GetFunctionList", libname);
Packit 8681c6
        exit(99);
Packit 8681c6
    }
Packit 8681c6
    rc = pfoo(&funcs);
Packit 8681c6
    if (rc != CKR_OK) {
Packit 8681c6
        dlclose(pkcs11lib);
Packit Service 8aa27d
        printf(
Packit Service 8aa27d
                "Error: C_GetFunctionList() on pkcs11 lib '%s' failed with rc = 0x%lX - %s)\n",
Packit Service 8aa27d
                libname, rc, p11_get_ckr(rc));
Packit 8681c6
        exit(99);
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    atexit(unload_pkcs11lib);
Packit 8681c6
}
Packit 8681c6
Packit Service 8aa27d
static CK_RV get_pin(char **pin, size_t *pinlen)
Packit Service 8aa27d
{
Packit 8681c6
    struct termios old, new;
Packit 8681c6
    int nread;
Packit Service 8aa27d
    char *user_input = NULL;
Packit 8681c6
    size_t buflen;
Packit 8681c6
    CK_RV rc = 0;
Packit 8681c6
Packit 8681c6
    /* turn echoing off */
Packit 8681c6
    if (tcgetattr(fileno(stdin), &old) != 0)
Packit 8681c6
        return -1;
Packit 8681c6
Packit 8681c6
    new = old;
Packit 8681c6
    new.c_lflag &= ~ECHO;
Packit 8681c6
    if (tcsetattr(fileno(stdin), TCSAFLUSH, &new) != 0)
Packit 8681c6
        return -1;
Packit 8681c6
Packit 8681c6
    /* read the pin
Packit Service 8aa27d
     * Note: getline will allocate memory for user_input. free it when done.
Packit 8681c6
     */
Packit Service 8aa27d
    nread = getline(&user_input, &buflen, stdin);
Packit 8681c6
    if (nread == -1) {
Packit 8681c6
        rc = -1;
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    /* Restore terminal */
Packit 8681c6
    (void) tcsetattr(fileno(stdin), TCSAFLUSH, &old;;
Packit 8681c6
Packit 8681c6
    /* start a newline */
Packit 8681c6
    printf("\n");
Packit 8681c6
    fflush(stdout);
Packit 8681c6
Packit 8681c6
    /* Allocate  PIN.
Packit 8681c6
     * Note: nread includes carriage return.
Packit 8681c6
     * Replace with terminating NULL.
Packit 8681c6
     */
Packit 8681c6
    *pin = (char*) malloc(nread);
Packit 8681c6
    if (*pin == NULL) {
Packit 8681c6
        rc = -ENOMEM;
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    /* strip the carriage return since not part of pin. */
Packit Service 8aa27d
    user_input[nread - 1] = '\0';
Packit Service 8aa27d
    memcpy(*pin, user_input, nread);
Packit 8681c6
    /* don't include the terminating null in the pinlen */
Packit 8681c6
    *pinlen = nread - 1;
Packit 8681c6
Packit Service 8aa27d
    done: if (user_input)
Packit Service 8aa27d
        free(user_input);
Packit 8681c6
Packit 8681c6
    return rc;
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Translates the given key type to its string representation.
Packit 8681c6
 */
Packit Service 8aa27d
static const char* kt2str(p11sak_kt ktype)
Packit Service 8aa27d
{
Packit 8681c6
    switch (ktype) {
Packit 8681c6
    case kt_DES:
Packit 8681c6
        return "DES";
Packit 8681c6
    case kt_3DES:
Packit 8681c6
        return "3DES";
Packit 8681c6
    case kt_AES:
Packit 8681c6
        return "AES";
Packit 8681c6
    case kt_RSAPKCS:
Packit 8681c6
        return "RSA_PKCS";
Packit 8681c6
    case kt_EC:
Packit 8681c6
        return "EC";
Packit 8681c6
    case kt_GENERIC:
Packit 8681c6
        return "GENERIC";
Packit 8681c6
    case kt_SECRET:
Packit 8681c6
        return "SECRET";
Packit 8681c6
    case kt_PUBLIC:
Packit 8681c6
        return "PUBLIC";
Packit 8681c6
    case kt_PRIVATE:
Packit 8681c6
        return "PRIVATE";
Packit 8681c6
    case no_key_type:
Packit 8681c6
        return "NO_KEYTYPE";
Packit 8681c6
    default:
Packit 8681c6
        return "NO_KEYTYPE";
Packit 8681c6
    }
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Translates the given key type to its CK_KEY_TYPE
Packit 8681c6
 */
Packit Service 8aa27d
static CK_RV kt2CKK(p11sak_kt ktype, CK_KEY_TYPE *a_key_type)
Packit Service 8aa27d
{
Packit 8681c6
    switch (ktype) {
Packit 8681c6
    case kt_DES:
Packit 8681c6
        *a_key_type = CKK_DES;
Packit 8681c6
        break;
Packit 8681c6
    case kt_3DES:
Packit 8681c6
        *a_key_type = CKK_DES3;
Packit 8681c6
        break;
Packit 8681c6
    case kt_AES:
Packit 8681c6
        *a_key_type = CKK_AES;
Packit 8681c6
        break;
Packit 8681c6
    case kt_RSAPKCS:
Packit 8681c6
        *a_key_type = CKK_RSA;
Packit 8681c6
        break;
Packit 8681c6
    case kt_EC:
Packit 8681c6
        *a_key_type = CKK_EC;
Packit 8681c6
        break;
Packit 8681c6
    case kt_GENERIC:
Packit 8681c6
        *a_key_type = CKK_GENERIC_SECRET;
Packit 8681c6
        break;
Packit 8681c6
    default:
Packit 8681c6
        return CKR_ARGUMENTS_BAD;
Packit 8681c6
    }
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Translates the given key type to its CK_OBJECT_CLASS
Packit 8681c6
 */
Packit Service 8aa27d
static CK_RV kt2CKO(p11sak_kt ktype, CK_OBJECT_CLASS *a_cko)
Packit Service 8aa27d
{
Packit 8681c6
    switch (ktype) {
Packit 8681c6
    case kt_SECRET:
Packit 8681c6
        *a_cko = CKO_SECRET_KEY;
Packit 8681c6
        break;
Packit 8681c6
    case kt_PUBLIC:
Packit 8681c6
        *a_cko = CKO_PUBLIC_KEY;
Packit 8681c6
        break;
Packit 8681c6
    case kt_PRIVATE:
Packit 8681c6
        *a_cko = CKO_PRIVATE_KEY;
Packit 8681c6
        break;
Packit 8681c6
    default:
Packit 8681c6
        return CKR_ARGUMENTS_BAD;
Packit 8681c6
    }
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Translates the given p11sak command to its string representation.
Packit 8681c6
 * no_cmd, gen_key, list_key
Packit 8681c6
 */
Packit Service 8aa27d
static const char* cmd2str(p11sak_cmd cmd)
Packit Service 8aa27d
{
Packit 8681c6
    switch (cmd) {
Packit 8681c6
    case no_cmd:
Packit 8681c6
        return "no_cmd";
Packit 8681c6
    case gen_key:
Packit 8681c6
        return "generate-key";
Packit 8681c6
    case list_key:
Packit 8681c6
        return "list-key";
Packit Service 8aa27d
    case remove_key:
Packit Service 8aa27d
        return "remove-key";
Packit 8681c6
    default:
Packit 8681c6
        return "unknown p11sak cmd";
Packit 8681c6
    }
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Translates the given attribute type to its long name.
Packit 8681c6
 */
Packit Service 8aa27d
static const char* CKA2a(CK_ATTRIBUTE_TYPE attr_type)
Packit Service 8aa27d
{
Packit 8681c6
    switch (attr_type) {
Packit 8681c6
    case CKA_TOKEN:
Packit 8681c6
        return "CKA_TOKEN";
Packit 8681c6
    case CKA_PRIVATE:
Packit 8681c6
        return "CKA_PRIVATE";
Packit 8681c6
    case CKA_MODIFIABLE:
Packit 8681c6
        return "CKA_MODIFIABLE";
Packit 8681c6
    case CKA_DERIVE:
Packit 8681c6
        return "CKA_DERIVE";
Packit 8681c6
    case CKA_LOCAL:
Packit 8681c6
        return "CKA_LOCAL";
Packit 8681c6
    case CKA_SENSITIVE:
Packit 8681c6
        return "CKA_SENSITIVE";
Packit 8681c6
    case CKA_ENCRYPT:
Packit 8681c6
        return "CKA_ENCRYPT";
Packit 8681c6
    case CKA_DECRYPT:
Packit 8681c6
        return "CKA_DECRYPT";
Packit 8681c6
    case CKA_SIGN:
Packit 8681c6
        return "CKA_SIGN";
Packit 8681c6
    case CKA_VERIFY:
Packit 8681c6
        return "CKA_VERIFY";
Packit 8681c6
    case CKA_WRAP:
Packit 8681c6
        return "CKA_WRAP";
Packit 8681c6
    case CKA_UNWRAP:
Packit 8681c6
        return "CKA_UNWRAP";
Packit 8681c6
    case CKA_ALWAYS_SENSITIVE:
Packit 8681c6
        return "CKA_ALWAYS_SENSITIVE";
Packit 8681c6
    case CKA_EXTRACTABLE:
Packit 8681c6
        return "CKA_EXTRACTABLE";
Packit 8681c6
    case CKA_NEVER_EXTRACTABLE:
Packit 8681c6
        return "CKA_NEVER_EXTRACTABLE";
Packit 8681c6
    case CKA_TRUSTED:
Packit 8681c6
        return "CKA_TRUSTED";
Packit 8681c6
    default:
Packit 8681c6
        return "unknown attribute";
Packit 8681c6
    }
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Translates the given key type to its related char string.
Packit 8681c6
 */
Packit Service 8aa27d
static const char* CKK2a(CK_KEY_TYPE t)
Packit Service 8aa27d
{
Packit Service 8aa27d
    // if new cases are added, the buffer = malloc()
Packit Service 8aa27d
    // in tok_key_get_key_type() needs to be updated
Packit 8681c6
    switch (t) {
Packit 8681c6
    case CKK_DES:
Packit 8681c6
        return "DES";
Packit 8681c6
    case CKK_DES3:
Packit 8681c6
        return "3DES";
Packit 8681c6
    case CKK_AES:
Packit 8681c6
        return "AES";
Packit 8681c6
    case CKK_EC:
Packit 8681c6
        return "EC";
Packit 8681c6
    case CKK_RSA:
Packit 8681c6
        return "RSA";
Packit 8681c6
    case CKK_DH:
Packit 8681c6
        return "DH";
Packit 8681c6
    case CKK_DSA:
Packit 8681c6
        return "DSA";
Packit 8681c6
    case CKK_GENERIC_SECRET:
Packit 8681c6
        return "generic";
Packit 8681c6
    default:
Packit 8681c6
        return "unknown key type";
Packit 8681c6
    }
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Translates the given bool to its related char string.
Packit 8681c6
 */
Packit Service 8aa27d
static const char* CK_BBOOL2a(CK_BBOOL b)
Packit Service 8aa27d
{
Packit 8681c6
    switch (b) {
Packit 8681c6
    case 0:
Packit 8681c6
        return "CK_FALSE";
Packit 8681c6
    case 1:
Packit 8681c6
        return "CK_TRUE";
Packit 8681c6
    default:
Packit 8681c6
        return "unknown value";
Packit 8681c6
    }
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Translates the given ULONG value to a byte string.
Packit 8681c6
 */
Packit Service 8aa27d
static CK_BYTE* CK_ULONG2bigint(CK_ULONG ul, CK_BYTE *bytes, CK_ULONG *len)
Packit Service 8aa27d
{
Packit 8681c6
    CK_BYTE *ulp;
Packit 8681c6
    CK_ULONG tul = 1;
Packit 8681c6
    CK_BYTE *tulp;
Packit 8681c6
    int i, j, s;
Packit 8681c6
Packit 8681c6
    s = 0;
Packit 8681c6
    ulp = (CK_BYTE*) &ul;
Packit 8681c6
    tulp = (CK_BYTE*) &tu;;
Packit 8681c6
Packit 8681c6
    if (tulp[0] == 1) {
Packit 8681c6
        for (j = sizeof(CK_ULONG) - 1, i = 0; j >= 0; j--, i++) {
Packit 8681c6
            bytes[i] = ulp[j];
Packit 8681c6
            if (s == 0 && bytes[i] != 0)
Packit 8681c6
                s = i;
Packit 8681c6
        }
Packit 8681c6
    } else {
Packit 8681c6
        for (i = 0; i <= (int) sizeof(CK_ULONG) - 1; i++) {
Packit 8681c6
            bytes[i] = ulp[i];
Packit 8681c6
            if (s == 0 && bytes[i] != 0)
Packit 8681c6
                s = i;
Packit 8681c6
        }
Packit 8681c6
    }
Packit 8681c6
    *len = sizeof(CK_ULONG) - s;
Packit 8681c6
Packit 8681c6
    return &bytes[s];
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * print help functions
Packit 8681c6
 */
Packit Service 8aa27d
static void print_cmd_help(void)
Packit Service 8aa27d
{
Packit 8681c6
    printf("\n Usage: p11sak COMMAND [ARGS] [OPTIONS]\n");
Packit 8681c6
    printf("\n Commands:\n");
Packit 8681c6
    printf("      generate-key       Generate a key\n");
Packit 8681c6
    printf("      list-key           List keys in the repository\n");
Packit Service 8aa27d
    printf("      remove-key         Delete keys in the repository\n");
Packit 8681c6
    printf("\n Options:\n");
Packit 8681c6
    printf("      -h, --help         Show this help\n\n");
Packit 8681c6
}
Packit 8681c6
Packit Service 8aa27d
static void print_listkeys_help(void)
Packit Service 8aa27d
{
Packit 8681c6
    printf("\n Usage: p11sak list-key [ARGS] [OPTIONS]\n");
Packit 8681c6
    printf("\n Args:\n");
Packit 8681c6
    printf("      des\n");
Packit 8681c6
    printf("      3des\n");
Packit 8681c6
    printf("      aes\n");
Packit 8681c6
    printf("      rsa\n");
Packit 8681c6
    printf("      ec\n");
Packit 8681c6
    printf("      public\n");
Packit 8681c6
    printf("      private\n");
Packit 8681c6
    printf("      secret\n");
Packit 8681c6
    printf("\n Options:\n");
Packit 8681c6
    printf("      -l, --long           list output with long format\n");
Packit 8681c6
    printf(
Packit 8681c6
            "      --slot SLOTID        openCryptoki repository token SLOTID.\n");
Packit 8681c6
    printf("      --pin PIN            pkcs11 user PIN\n");
Packit 8681c6
    printf("      -h, --help           Show this help\n\n");
Packit 8681c6
}
Packit 8681c6
Packit Service 8aa27d
static void print_gen_help(void)
Packit Service 8aa27d
{
Packit 8681c6
    printf("\n Usage: p11sak generate-key [ARGS] [OPTIONS]\n");
Packit 8681c6
    printf("\n Args:\n");
Packit 8681c6
    printf("      des\n");
Packit 8681c6
    printf("      3des\n");
Packit 8681c6
    printf("      aes [128 | 192 | 256]\n");
Packit 8681c6
    printf("      rsa [1024 | 2048 | 4096]\n");
Packit Service 8aa27d
    printf("      ec [prime256v1 | secp384r1 | secp521r1]\n");
Packit 8681c6
    printf("\n Options:\n");
Packit 8681c6
    printf(
Packit 8681c6
            "      --slot SLOTID                           openCryptoki repository token SLOTID.\n");
Packit 8681c6
    printf("      --pin PIN                               pkcs11 user PIN\n");
Packit 8681c6
    printf(
Packit 8681c6
            "      --label LABEL                           key label LABEL to be listed\n");
Packit 8681c6
    printf(
Packit 8681c6
            "      --exponent EXP                          set RSA exponent EXP\n");
Packit 8681c6
    printf(
Packit 8681c6
            "      --attr [M R L S E D G V W U A X N T]    set key attributes\n");
Packit 8681c6
    printf("      -h, --help                              Show this help\n\n");
Packit 8681c6
}
Packit 8681c6
Packit Service 8aa27d
static void print_removekeys_help(void)
Packit Service 8aa27d
{
Packit Service 8aa27d
    printf("\n Usage: p11sak remove-key [ARGS] [OPTIONS]\n");
Packit Service 8aa27d
    printf("\n Args:\n");
Packit Service 8aa27d
    printf("      des\n");
Packit Service 8aa27d
    printf("      3des\n");
Packit Service 8aa27d
    printf("      aes\n");
Packit Service 8aa27d
    printf("      rsa\n");
Packit Service 8aa27d
    printf("      ec\n");
Packit Service 8aa27d
    printf("\n Options:\n");
Packit Service 8aa27d
    printf(
Packit Service 8aa27d
            "      --slot SLOTID                           openCryptoki repository token SLOTID.\n");
Packit Service 8aa27d
    printf("      --pin PIN                               pkcs11 user PIN\n");
Packit Service 8aa27d
    printf(
Packit Service 8aa27d
            "      --label LABEL                           Key label LABEL to be removed\n");
Packit Service 8aa27d
    printf(
Packit Service 8aa27d
            "      -f, --force                             Force remove all keys of given cipher type\n");
Packit Service 8aa27d
    printf("      -h, --help                              Show this help\n\n");
Packit Service 8aa27d
}
Packit Service 8aa27d
Packit Service 8aa27d
static void print_gen_des_help(void)
Packit Service 8aa27d
{
Packit 8681c6
    printf("\n Options:\n");
Packit 8681c6
    printf(
Packit 8681c6
            "      --slot SLOTID                           openCryptoki repository token SLOTID.\n");
Packit 8681c6
    printf("      --pin PIN                               pkcs11 user PIN\n");
Packit 8681c6
    printf(
Packit 8681c6
            "      --label LABEL                           key label LABEL to be listed\n");
Packit 8681c6
    printf(
Packit 8681c6
            "      --attr [M R L S E D G V W U A X N T]    set key attributes\n");
Packit 8681c6
    printf("      -h, --help                              Show this help\n\n");
Packit 8681c6
}
Packit 8681c6
Packit Service 8aa27d
static void print_gen_aes_help(void)
Packit Service 8aa27d
{
Packit 8681c6
    printf("\n Usage: p11sak generate-key aes [ARGS] [OPTIONS]\n");
Packit 8681c6
    printf("\n Args:\n");
Packit 8681c6
    printf("      128\n");
Packit 8681c6
    printf("      192\n");
Packit 8681c6
    printf("      256\n");
Packit 8681c6
    printf("\n Options:\n");
Packit 8681c6
    printf(
Packit 8681c6
            "      --slot SLOTID                           openCryptoki repository token SLOTID.\n");
Packit 8681c6
    printf("      --pin PIN                               pkcs11 user PIN\n");
Packit 8681c6
    printf(
Packit 8681c6
            "      --label LABEL                           key label LABEL to be listed\n");
Packit 8681c6
    printf(
Packit 8681c6
            "      --attr [M R L S E D G V W U A X N T]    set key attributes\n");
Packit 8681c6
    printf("      -h, --help                              Show this help\n\n");
Packit 8681c6
}
Packit 8681c6
Packit Service 8aa27d
static void print_gen_rsa_help(void)
Packit Service 8aa27d
{
Packit 8681c6
    printf("\n Usage: p11sak generate-key rsa [ARGS] [OPTIONS] [ARGS]\n");
Packit 8681c6
    printf("\n Args:\n");
Packit 8681c6
    printf("      1024\n");
Packit 8681c6
    printf("      2048\n");
Packit 8681c6
    printf("      4096\n");
Packit 8681c6
    printf("\n Options:\n");
Packit 8681c6
    printf(
Packit 8681c6
            "      --slot SLOTID                           openCryptoki repository token SLOTID.\n");
Packit 8681c6
    printf("      --pin PIN                               pkcs11 user PIN\n");
Packit 8681c6
    printf(
Packit 8681c6
            "      --label LABEL                           key label LABEL to be listed\n");
Packit 8681c6
    printf(
Packit 8681c6
            "      --exponent EXP                          set RSA exponent EXP\n");
Packit 8681c6
    printf(
Packit 8681c6
            "      --attr [M R L S E D G V W U A X N T]    set key attributes\n");
Packit 8681c6
    printf("      -h, --help                              Show this help\n\n");
Packit 8681c6
}
Packit 8681c6
Packit Service 8aa27d
static void print_gen_ec_help(void)
Packit Service 8aa27d
{
Packit 8681c6
    printf("\n Usage: p11sak generate-key ec [ARGS] [OPTIONS]\n");
Packit 8681c6
    printf("\n Args:\n");
Packit 8681c6
    printf("      prime256v1\n");
Packit 8681c6
    printf("      secp384r1\n");
Packit Service 8aa27d
    printf("      secp521r1\n");
Packit 8681c6
    printf("\n Options:\n");
Packit 8681c6
    printf(
Packit 8681c6
            "      --slot SLOTID                           openCryptoki repository token SLOTID.\n");
Packit 8681c6
    printf("      --pin PIN                               pkcs11 user PIN\n");
Packit 8681c6
    printf(
Packit 8681c6
            "      --label LABEL                           key label LABEL to be listed\n");
Packit 8681c6
    printf(
Packit 8681c6
            "      --attr [M R L S E D G V W U A X N T]    set key attributes\n");
Packit 8681c6
    printf("      -h, --help                              Show this help\n\n");
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Print help for generate-key command
Packit 8681c6
 */
Packit Service 8aa27d
static CK_RV print_gen_keys_help(p11sak_kt *kt)
Packit Service 8aa27d
{
Packit 8681c6
Packit 8681c6
    switch (*kt) {
Packit 8681c6
    case kt_DES:
Packit 8681c6
        printf("\n Usage: p11sak generate-key des [ARGS] [OPTIONS]\n");
Packit 8681c6
        print_gen_des_help();
Packit 8681c6
        break;
Packit 8681c6
    case kt_3DES:
Packit 8681c6
        printf("\n Usage: p11sak generate-key 3des [ARGS] [OPTIONS]\n");
Packit 8681c6
        print_gen_des_help();
Packit 8681c6
        break;
Packit 8681c6
    case kt_AES:
Packit 8681c6
        print_gen_aes_help();
Packit 8681c6
        break;
Packit 8681c6
    case kt_RSAPKCS:
Packit 8681c6
        print_gen_rsa_help();
Packit 8681c6
        break;
Packit 8681c6
    case kt_EC:
Packit 8681c6
        print_gen_ec_help();
Packit 8681c6
        break;
Packit 8681c6
    case no_key_type:
Packit 8681c6
        print_gen_help();
Packit 8681c6
        break;
Packit 8681c6
    default:
Packit 8681c6
        print_gen_help();
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Print help for attributes
Packit 8681c6
 */
Packit Service 8aa27d
static void print_gen_attr_help(void)
Packit Service 8aa27d
{
Packit 8681c6
    printf("\n");
Packit 8681c6
    printf("      Setting CK_ATTRIBUTE\n");
Packit 8681c6
    printf("\n");
Packit 8681c6
    printf("           'M': CKA_MODIFIABLE\n");
Packit 8681c6
    printf("           'R': CKA_DERIVE\n");
Packit 8681c6
    printf("           'L': CKA_LOCAL\n");
Packit 8681c6
    printf("           'S': CKA_SENSITIVE\n");
Packit 8681c6
    printf("           'E': CKA_ENCRYPT\n");
Packit 8681c6
    printf("           'D': CKA_DECRYPT\n");
Packit 8681c6
    printf("           'G': CKA_SIGN\n");
Packit 8681c6
    printf("           'V': CKA_VERIFY\n");
Packit 8681c6
    printf("           'W': CKA_WRAP\n");
Packit 8681c6
    printf("           'U': CKA_UNWRAP\n");
Packit 8681c6
    printf("           'A': CKA_ALWAYS_SENSITIVE\n");
Packit 8681c6
    printf("           'X': CKA_EXTRACTABLE\n");
Packit 8681c6
    printf("           'N': CKA_NEVER_EXTRACTABLE\n");
Packit 8681c6
    printf("\n");
Packit 8681c6
    printf("           CKA_TOKEN and CKA_PRIVATE are set by default.\n");
Packit 8681c6
    printf(
Packit 8681c6
            "           If an attribute is not set explicitly, the default values are used.\n");
Packit 8681c6
    printf(
Packit 8681c6
            "           For multiple attributes add char without white space, e. g. 'MLD')\n");
Packit 8681c6
    printf("\n");
Packit 8681c6
Packit 8681c6
    printf("\n");
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Builds an attribute from the given modulus bits and exponent.
Packit 8681c6
 * pubattr >= x elements, prvattr >= y elements
Packit 8681c6
 */
Packit 8681c6
static CK_RV read_rsa_args(CK_ULONG modulusbits, CK_ULONG exponent,
Packit Service 8aa27d
                           CK_ATTRIBUTE *pubattr, CK_ULONG *pubcount)
Packit Service 8aa27d
{
Packit 8681c6
    CK_ULONG *mod_bits;
Packit 8681c6
    CK_ULONG ulpubexp;
Packit 8681c6
    CK_BYTE *pubexp;
Packit 8681c6
    CK_BYTE *spubexp;
Packit 8681c6
    CK_ULONG spubexplen;
Packit 8681c6
Packit 8681c6
    if (!(mod_bits = malloc(sizeof(CK_ULONG)))) {
Packit 8681c6
        printf("Error: failed to allocate memory for mod_bits.\n");
Packit 8681c6
        return CKR_HOST_MEMORY;
Packit 8681c6
    }
Packit 8681c6
    *mod_bits = modulusbits;
Packit 8681c6
Packit 8681c6
    pubattr[*pubcount].type = CKA_MODULUS_BITS;
Packit 8681c6
    pubattr[*pubcount].pValue = mod_bits;
Packit 8681c6
    pubattr[*pubcount].ulValueLen = sizeof(CK_ULONG);
Packit 8681c6
    (*pubcount)++;
Packit 8681c6
Packit 8681c6
    if (exponent > 0)
Packit 8681c6
        ulpubexp = exponent;
Packit 8681c6
    else
Packit 8681c6
        ulpubexp = 65537; /* default for RSA_PKCS */
Packit 8681c6
Packit 8681c6
    if (!(pubexp = malloc(sizeof(CK_ULONG)))) {
Packit 8681c6
        printf("Error: failed to allocate memory for public exponent.\n");
Packit 8681c6
        return CKR_HOST_MEMORY;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    spubexp = CK_ULONG2bigint(ulpubexp, pubexp, &spubexplen);
Packit 8681c6
    pubattr[*pubcount].type = CKA_PUBLIC_EXPONENT;
Packit 8681c6
    pubattr[*pubcount].pValue = spubexp;
Packit 8681c6
    pubattr[*pubcount].ulValueLen = spubexplen;
Packit 8681c6
    (*pubcount)++;
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Builds the CKA_EC_PARAMS attribute from the given ECcurve.
Packit 8681c6
 */
Packit 8681c6
static CK_RV read_ec_args(const char *ECcurve, CK_ATTRIBUTE *pubattr,
Packit Service 8aa27d
                          CK_ULONG *pubcount)
Packit Service 8aa27d
{
Packit 8681c6
    pubattr[*pubcount].type = CKA_EC_PARAMS;
Packit 8681c6
    if (strcmp(ECcurve, "prime256v1") == 0) {
Packit 8681c6
        pubattr[*pubcount].pValue = (CK_BYTE*) prime256v1;
Packit 8681c6
        pubattr[*pubcount].ulValueLen = sizeof(prime256v1);
Packit 8681c6
    } else if (strcmp(ECcurve, "prime192") == 0) {
Packit 8681c6
        pubattr[*pubcount].pValue = (CK_BYTE*) prime192;
Packit 8681c6
        pubattr[*pubcount].ulValueLen = sizeof(prime192);
Packit 8681c6
    } else if (strcmp(ECcurve, "secp224") == 0) {
Packit 8681c6
        pubattr[*pubcount].pValue = (CK_BYTE*) secp224;
Packit 8681c6
        pubattr[*pubcount].ulValueLen = sizeof(secp224);
Packit 8681c6
    } else if (strcmp(ECcurve, "secp384r1") == 0) {
Packit 8681c6
        pubattr[*pubcount].pValue = (CK_BYTE*) secp384r1;
Packit 8681c6
        pubattr[*pubcount].ulValueLen = sizeof(secp384r1);
Packit 8681c6
    } else if (strcmp(ECcurve, "secp521r1") == 0) {
Packit 8681c6
        pubattr[*pubcount].pValue = (CK_BYTE*) secp521r1;
Packit 8681c6
        pubattr[*pubcount].ulValueLen = sizeof(secp521r1);
Packit 8681c6
    } else if (strcmp(ECcurve, "secp265k1") == 0) {
Packit 8681c6
        pubattr[*pubcount].pValue = (CK_BYTE*) secp256k1;
Packit 8681c6
        pubattr[*pubcount].ulValueLen = sizeof(secp256k1);
Packit 8681c6
    } else if (strcmp(ECcurve, "brainpoolP160r1") == 0) {
Packit 8681c6
        pubattr[*pubcount].pValue = (CK_BYTE*) brainpoolP160r1;
Packit 8681c6
        pubattr[*pubcount].ulValueLen = sizeof(brainpoolP160r1);
Packit 8681c6
    } else if (strcmp(ECcurve, "brainpoolP160t1") == 0) {
Packit 8681c6
        pubattr[*pubcount].pValue = (CK_BYTE*) brainpoolP160t1;
Packit 8681c6
        pubattr[*pubcount].ulValueLen = sizeof(brainpoolP160t1);
Packit 8681c6
    } else if (strcmp(ECcurve, "brainpoolP192r1") == 0) {
Packit 8681c6
        pubattr[*pubcount].pValue = (CK_BYTE*) brainpoolP192r1;
Packit 8681c6
        pubattr[*pubcount].ulValueLen = sizeof(brainpoolP192r1);
Packit 8681c6
    } else if (strcmp(ECcurve, "brainpoolP192t1") == 0) {
Packit 8681c6
        pubattr[*pubcount].pValue = (CK_BYTE*) brainpoolP192t1;
Packit 8681c6
        pubattr[*pubcount].ulValueLen = sizeof(brainpoolP192t1);
Packit 8681c6
    } else if (strcmp(ECcurve, "brainpoolP224r1") == 0) {
Packit 8681c6
        pubattr[*pubcount].pValue = (CK_BYTE*) brainpoolP224r1;
Packit 8681c6
        pubattr[*pubcount].ulValueLen = sizeof(brainpoolP224r1);
Packit 8681c6
    } else if (strcmp(ECcurve, "brainpoolP224t1") == 0) {
Packit 8681c6
        pubattr[*pubcount].pValue = (CK_BYTE*) brainpoolP224t1;
Packit 8681c6
        pubattr[*pubcount].ulValueLen = sizeof(brainpoolP224t1);
Packit 8681c6
    } else if (strcmp(ECcurve, "brainpoolP256r1") == 0) {
Packit 8681c6
        pubattr[*pubcount].pValue = (CK_BYTE*) brainpoolP256r1;
Packit 8681c6
        pubattr[*pubcount].ulValueLen = sizeof(brainpoolP256r1);
Packit 8681c6
    } else if (strcmp(ECcurve, "brainpoolP256t1") == 0) {
Packit 8681c6
        pubattr[*pubcount].pValue = (CK_BYTE*) brainpoolP256t1;
Packit 8681c6
        pubattr[*pubcount].ulValueLen = sizeof(brainpoolP256t1);
Packit 8681c6
    } else if (strcmp(ECcurve, "brainpoolP320r1") == 0) {
Packit 8681c6
        pubattr[*pubcount].pValue = (CK_BYTE*) brainpoolP320r1;
Packit 8681c6
        pubattr[*pubcount].ulValueLen = sizeof(brainpoolP320r1);
Packit 8681c6
    } else if (strcmp(ECcurve, "brainpoolP320t1") == 0) {
Packit 8681c6
        pubattr[*pubcount].pValue = (CK_BYTE*) brainpoolP320t1;
Packit 8681c6
        pubattr[*pubcount].ulValueLen = sizeof(brainpoolP320t1);
Packit 8681c6
    } else if (strcmp(ECcurve, "brainpoolP384r1") == 0) {
Packit 8681c6
        pubattr[*pubcount].pValue = (CK_BYTE*) brainpoolP384r1;
Packit 8681c6
        pubattr[*pubcount].ulValueLen = sizeof(brainpoolP384r1);
Packit 8681c6
    } else if (strcmp(ECcurve, "brainpoolP384t1") == 0) {
Packit 8681c6
        pubattr[*pubcount].pValue = (CK_BYTE*) brainpoolP384t1;
Packit 8681c6
        pubattr[*pubcount].ulValueLen = sizeof(brainpoolP384t1);
Packit 8681c6
    } else if (strcmp(ECcurve, "brainpoolP512r1") == 0) {
Packit 8681c6
        pubattr[*pubcount].pValue = (CK_BYTE*) brainpoolP512r1;
Packit 8681c6
        pubattr[*pubcount].ulValueLen = sizeof(brainpoolP512r1);
Packit 8681c6
    } else if (strcmp(ECcurve, "brainpoolP512t1") == 0) {
Packit 8681c6
        pubattr[*pubcount].pValue = (CK_BYTE*) brainpoolP512t1;
Packit 8681c6
        pubattr[*pubcount].ulValueLen = sizeof(brainpoolP512t1);
Packit 8681c6
    } else {
Packit 8681c6
        printf("Unexpected case while parsing EC curves.\n");
Packit Service 8aa27d
        printf("Note: not all tokens support all curves.\n");
Packit 8681c6
        return CKR_ARGUMENTS_BAD;
Packit 8681c6
    }
Packit 8681c6
    (*pubcount)++;
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Builds two CKA_LABEL attributes from given label.
Packit 8681c6
 */
Packit 8681c6
static CK_RV set_labelpair_attr(const char *label, CK_ATTRIBUTE *pubattr,
Packit Service 8aa27d
                                CK_ULONG *pubcount, CK_ATTRIBUTE *prvattr,
Packit Service 8aa27d
                                CK_ULONG *prvcount)
Packit Service 8aa27d
{
Packit 8681c6
    char *publabel;
Packit 8681c6
    char *prvlabel;
Packit 8681c6
Packit 8681c6
    if (!(publabel = malloc(strlen(label) + 5))) {
Packit 8681c6
        printf("Error allocating space for publabel\n");
Packit 8681c6
        return CKR_HOST_MEMORY;
Packit 8681c6
    }
Packit 8681c6
    publabel = strcpy(publabel, label);
Packit 8681c6
    publabel = strcat(publabel, ":pub");
Packit 8681c6
Packit 8681c6
    if (!(prvlabel = malloc(strlen(label) + 5))) {
Packit 8681c6
        printf("Error allocating space for prvlabel\n");
Packit 8681c6
        return CKR_HOST_MEMORY;
Packit 8681c6
    }
Packit 8681c6
    prvlabel = strcpy(prvlabel, label);
Packit 8681c6
    prvlabel = strcat(prvlabel, ":prv");
Packit 8681c6
Packit 8681c6
    pubattr[*pubcount].type = CKA_LABEL;
Packit 8681c6
    pubattr[*pubcount].pValue = publabel;
Packit 8681c6
    pubattr[*pubcount].ulValueLen = strlen(publabel) + 1;
Packit 8681c6
    (*pubcount)++;
Packit 8681c6
Packit 8681c6
    prvattr[*prvcount].type = CKA_LABEL;
Packit 8681c6
    prvattr[*prvcount].pValue = prvlabel;
Packit 8681c6
    prvattr[*prvcount].ulValueLen = strlen(prvlabel) + 1;
Packit 8681c6
    (*prvcount)++;
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Set mechanism according to given key type.
Packit 8681c6
 */
Packit Service 8aa27d
static CK_RV key_pair_gen_mech(p11sak_kt kt, CK_MECHANISM *pmech)
Packit Service 8aa27d
{
Packit 8681c6
    pmech->pParameter = NULL_PTR;
Packit 8681c6
    pmech->ulParameterLen = 0;
Packit 8681c6
    switch (kt) {
Packit 8681c6
    case kt_DES:
Packit 8681c6
        pmech->mechanism = CKM_DES_KEY_GEN;
Packit 8681c6
        break;
Packit 8681c6
    case kt_3DES:
Packit 8681c6
        pmech->mechanism = CKM_DES3_KEY_GEN;
Packit 8681c6
        break;
Packit 8681c6
    case kt_AES:
Packit 8681c6
        pmech->mechanism = CKM_AES_KEY_GEN;
Packit 8681c6
        break;
Packit 8681c6
    case kt_RSAPKCS:
Packit 8681c6
        pmech->mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
Packit 8681c6
        break;
Packit 8681c6
    case kt_EC:
Packit 8681c6
        pmech->mechanism = CKM_EC_KEY_PAIR_GEN;
Packit 8681c6
        break;
Packit 8681c6
    default:
Packit 8681c6
        return CKR_MECHANISM_INVALID;
Packit 8681c6
        break;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Set default asymmetric key attributes.
Packit 8681c6
 */
Packit 8681c6
static CK_RV set_battr(const char *attr_string, CK_ATTRIBUTE *pubattr,
Packit Service 8aa27d
                       CK_ULONG *pubcount, CK_ATTRIBUTE *prvattr,
Packit Service 8aa27d
                       CK_ULONG *prvcount)
Packit Service 8aa27d
{
Packit 8681c6
    int i = 0;
Packit 8681c6
Packit 8681c6
    pubattr[*pubcount].type = CKA_TOKEN;
Packit 8681c6
    pubattr[*pubcount].pValue = &ckb_true;
Packit 8681c6
    pubattr[*pubcount].ulValueLen = sizeof(CK_BBOOL);
Packit 8681c6
    (*pubcount)++;
Packit 8681c6
    pubattr[*pubcount].type = CKA_PRIVATE;
Packit 8681c6
    pubattr[*pubcount].pValue = &ckb_true;
Packit 8681c6
    pubattr[*pubcount].ulValueLen = sizeof(CK_BBOOL);
Packit 8681c6
    (*pubcount)++;
Packit 8681c6
Packit 8681c6
    prvattr[*prvcount].type = CKA_TOKEN;
Packit 8681c6
    prvattr[*prvcount].pValue = &ckb_true;
Packit 8681c6
    prvattr[*prvcount].ulValueLen = sizeof(CK_BBOOL);
Packit 8681c6
    (*prvcount)++;
Packit 8681c6
    prvattr[*prvcount].type = CKA_PRIVATE;
Packit 8681c6
    prvattr[*prvcount].pValue = &ckb_true;
Packit 8681c6
    prvattr[*prvcount].ulValueLen = sizeof(CK_BBOOL);
Packit 8681c6
    (*prvcount)++;
Packit 8681c6
Packit 8681c6
    if (attr_string) {
Packit 8681c6
        for (i = 0; i < (int) strlen(attr_string); i++) {
Packit 8681c6
Packit 8681c6
            switch (attr_string[i]) {
Packit 8681c6
            case 'S': /* private sensitive */
Packit 8681c6
                prvattr[*prvcount].type = CKA_SENSITIVE;
Packit 8681c6
                prvattr[*prvcount].pValue = &ckb_true;
Packit 8681c6
                prvattr[*prvcount].ulValueLen = sizeof(CK_BBOOL);
Packit 8681c6
                (*prvcount)++;
Packit 8681c6
                break;
Packit 8681c6
            case 'D': /* private decrypt RSA only*/
Packit 8681c6
                prvattr[*prvcount].type = CKA_DECRYPT;
Packit 8681c6
                prvattr[*prvcount].pValue = &ckb_true;
Packit 8681c6
                prvattr[*prvcount].ulValueLen = sizeof(CK_BBOOL);
Packit 8681c6
                (*prvcount)++;
Packit 8681c6
                pubattr[*pubcount].type = CKA_ENCRYPT;
Packit 8681c6
                pubattr[*pubcount].pValue = &ckb_true;
Packit 8681c6
                pubattr[*pubcount].ulValueLen = sizeof(CK_BBOOL);
Packit 8681c6
                (*pubcount)++;
Packit 8681c6
                break;
Packit 8681c6
            case 'G': /* private sign */
Packit 8681c6
                prvattr[*prvcount].type = CKA_SIGN;
Packit 8681c6
                prvattr[*prvcount].pValue = &ckb_true;
Packit 8681c6
                prvattr[*prvcount].ulValueLen = sizeof(CK_BBOOL);
Packit 8681c6
                (*prvcount)++;
Packit 8681c6
                pubattr[*pubcount].type = CKA_VERIFY;
Packit 8681c6
                pubattr[*pubcount].pValue = &ckb_true;
Packit 8681c6
                pubattr[*pubcount].ulValueLen = sizeof(CK_BBOOL);
Packit 8681c6
                (*pubcount)++;
Packit 8681c6
                break;
Packit 8681c6
            case 'U': /* private unwrap RSA only */
Packit 8681c6
                prvattr[*prvcount].type = CKA_UNWRAP;
Packit 8681c6
                prvattr[*prvcount].pValue = &ckb_true;
Packit 8681c6
                prvattr[*prvcount].ulValueLen = sizeof(CK_BBOOL);
Packit 8681c6
                (*prvcount)++;
Packit 8681c6
                pubattr[*pubcount].type = CKA_WRAP;
Packit 8681c6
                pubattr[*pubcount].pValue = &ckb_true;
Packit 8681c6
                pubattr[*pubcount].ulValueLen = sizeof(CK_BBOOL);
Packit 8681c6
                (*pubcount)++;
Packit 8681c6
                break;
Packit 8681c6
            case 'X': /* private extractable */
Packit 8681c6
                prvattr[*prvcount].type = CKA_EXTRACTABLE;
Packit 8681c6
                prvattr[*prvcount].pValue = &ckb_true;
Packit 8681c6
                prvattr[*prvcount].ulValueLen = sizeof(CK_BBOOL);
Packit 8681c6
                (*prvcount)++;
Packit 8681c6
                break;
Packit 8681c6
            default:
Packit 8681c6
                printf("Unknown argument '%c'\n", attr_string[i]);
Packit 8681c6
            }
Packit 8681c6
        }
Packit 8681c6
    }
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
Packit Service 8aa27d
static CK_ULONG char2attrtype(char c)
Packit Service 8aa27d
{
Packit 8681c6
    switch (c) {
Packit 8681c6
    case 'T':
Packit 8681c6
        return CKA_TOKEN;
Packit 8681c6
    case 'P':
Packit 8681c6
        return CKA_PRIVATE;
Packit 8681c6
    case 'M':
Packit 8681c6
        return CKA_MODIFIABLE;
Packit 8681c6
    case 'R':
Packit 8681c6
        return CKA_DERIVE;
Packit 8681c6
    case 'L':
Packit 8681c6
        return CKA_LOCAL;
Packit 8681c6
    case 'S':
Packit 8681c6
        return CKA_SENSITIVE;
Packit 8681c6
    case 'E':
Packit 8681c6
        return CKA_ENCRYPT;
Packit 8681c6
    case 'D':
Packit 8681c6
        return CKA_DECRYPT;
Packit 8681c6
    case 'G':
Packit 8681c6
        return CKA_SIGN;
Packit 8681c6
    case 'V':
Packit 8681c6
        return CKA_VERIFY;
Packit 8681c6
    case 'W':
Packit 8681c6
        return CKA_WRAP;
Packit 8681c6
    case 'U':
Packit 8681c6
        return CKA_UNWRAP;
Packit 8681c6
    case 'X':
Packit 8681c6
        return CKA_EXTRACTABLE;
Packit 8681c6
    case 'A':
Packit 8681c6
        return CKA_ALWAYS_SENSITIVE;
Packit 8681c6
    case 'N':
Packit 8681c6
        return CKA_NEVER_EXTRACTABLE;
Packit 8681c6
    default:
Packit 8681c6
        return 0;
Packit 8681c6
    }
Packit 8681c6
}
Packit 8681c6
Packit Service 8aa27d
static void set_bool_attr_from_string(CK_ATTRIBUTE *attr, char *attr_string)
Packit Service 8aa27d
{
Packit 8681c6
    int i;
Packit 8681c6
Packit 8681c6
    if (!attr_string)
Packit 8681c6
        return;
Packit 8681c6
Packit 8681c6
    for (i = 0; i < (int) strlen(attr_string); i++) {
Packit 8681c6
        if (char2attrtype(attr_string[i]) == attr->type) {
Packit 8681c6
            attr->pValue = &ckb_true;
Packit 8681c6
        }
Packit 8681c6
    }
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Generation of the symmetric key
Packit 8681c6
 */
Packit 8681c6
static CK_RV tok_key_gen(CK_SESSION_HANDLE session, CK_ULONG keylength,
Packit Service 8aa27d
                         CK_MECHANISM *pmech, char *attr_string,
Packit Service 8aa27d
                         CK_OBJECT_HANDLE *phkey, char *label)
Packit Service 8aa27d
{
Packit Service 8aa27d
    CK_RV rc;
Packit 8681c6
    int i = 0;
Packit 8681c6
Packit 8681c6
    /* Boolean attributes (cannot be specified by user) */
Packit 8681c6
    CK_BBOOL a_token = ckb_true; // always true
Packit 8681c6
    CK_BBOOL a_private = ckb_true; // always true
Packit 8681c6
Packit 8681c6
    /* Boolean attributes from user input */
Packit 8681c6
    CK_BBOOL a_modifiable = ckb_false;
Packit 8681c6
    CK_BBOOL a_derive = ckb_false;
Packit 8681c6
    CK_BBOOL a_sensitive = ckb_false;
Packit 8681c6
    CK_BBOOL a_encrypt = ckb_false;
Packit 8681c6
    CK_BBOOL a_decrypt = ckb_false;
Packit 8681c6
    CK_BBOOL a_sign = ckb_false;
Packit 8681c6
    CK_BBOOL a_verify = ckb_false;
Packit 8681c6
    CK_BBOOL a_wrap = ckb_false;
Packit 8681c6
    CK_BBOOL a_unwrap = ckb_false;
Packit 8681c6
    CK_BBOOL a_extractable = ckb_false;
Packit 8681c6
    CK_ULONG bs = sizeof(CK_BBOOL);
Packit 8681c6
Packit 8681c6
    /* Non-boolean attributes */
Packit 8681c6
    CK_ULONG a_value_len = keylength / 8;
Packit 8681c6
Packit 8681c6
    CK_ATTRIBUTE tmplt[] = {
Packit 8681c6
            // boolean attrs
Packit 8681c6
            { CKA_TOKEN, &a_token, bs }, { CKA_PRIVATE, &a_private, bs }, {
Packit Service 8aa27d
            CKA_MODIFIABLE, &a_modifiable, bs }, { CKA_DERIVE, &a_derive, bs },
Packit Service 8aa27d
            { CKA_SENSITIVE, &a_sensitive, bs }, {
Packit Service 8aa27d
            CKA_ENCRYPT, &a_encrypt, bs }, { CKA_DECRYPT, &a_decrypt, bs }, {
Packit Service 8aa27d
                    CKA_SIGN, &a_sign, bs }, {
Packit Service 8aa27d
            CKA_VERIFY, &a_verify, bs }, { CKA_WRAP, &a_wrap, bs }, {
Packit Service 8aa27d
            CKA_UNWRAP, &a_unwrap, bs },
Packit Service 8aa27d
            { CKA_EXTRACTABLE, &a_extractable, bs },
Packit 8681c6
            // non-boolean attrs
Packit 8681c6
            { CKA_VALUE_LEN, &a_value_len, sizeof(CK_ULONG) }, { CKA_LABEL,
Packit 8681c6
                    label, strlen(label) } };
Packit 8681c6
    CK_ULONG num_attrs = sizeof(tmplt) / sizeof(CK_ATTRIBUTE);
Packit 8681c6
    CK_ULONG num_bools = num_attrs - 2;
Packit 8681c6
Packit 8681c6
    /* set boolean attributes */
Packit 8681c6
    for (i = 0; i < (int) num_bools; i++) {
Packit 8681c6
        set_bool_attr_from_string(&tmplt[i], attr_string);
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    /* generate key */
Packit Service 8aa27d
    rc = funcs->C_GenerateKey(session, pmech, tmplt, num_attrs, phkey);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit 8681c6
        printf("Key generation of key of length %ld bytes failed\n",
Packit 8681c6
                a_value_len);
Packit Service 8aa27d
        printf("in tok_key_gen() (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                p11_get_ckr(rc));
Packit 8681c6
    }
Packit Service 8aa27d
    return rc;
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Generation of the asymmetric key pair
Packit 8681c6
 */
Packit 8681c6
static CK_RV key_pair_gen(CK_SESSION_HANDLE session, p11sak_kt kt,
Packit Service 8aa27d
                          CK_MECHANISM_PTR pmech, CK_ATTRIBUTE *pubattr,
Packit Service 8aa27d
                          CK_ULONG pubcount, CK_ATTRIBUTE *prvattr,
Packit Service 8aa27d
                          CK_ULONG prvcount, CK_OBJECT_HANDLE_PTR phpubkey,
Packit Service 8aa27d
                          CK_OBJECT_HANDLE_PTR phprvkey)
Packit Service 8aa27d
{
Packit 8681c6
Packit Service 8aa27d
    CK_RV rc;
Packit 8681c6
Packit 8681c6
    printf("Generate asymmetric key: %s\n", kt2str(kt));
Packit 8681c6
Packit Service 8aa27d
    rc = funcs->C_GenerateKeyPair(session, pmech, pubattr, pubcount, prvattr,
Packit 8681c6
            prvcount, phpubkey, phprvkey);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Key pair generation failed (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                p11_get_ckr(rc));
Packit Service 8aa27d
        return rc;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    printf("Asymmetric key pair generation successful!\n");
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
/**
Packit Service 8aa27d
 * Initialize key object list
Packit 8681c6
 */
Packit Service 8aa27d
static CK_RV tok_key_list_init(CK_SESSION_HANDLE session, p11sak_kt kt,
Packit Service 8aa27d
                               char *label)
Packit Service 8aa27d
{
Packit 8681c6
    CK_RV rc;
Packit 8681c6
    CK_ULONG count;
Packit 8681c6
Packit 8681c6
    /* Boolean Attributes */
Packit 8681c6
    CK_BBOOL a_token;
Packit 8681c6
    CK_BBOOL a_private;
Packit 8681c6
    CK_ULONG bs = sizeof(CK_BBOOL);
Packit 8681c6
Packit 8681c6
    /* key Type attributes */
Packit 8681c6
    CK_KEY_TYPE a_key_type;
Packit 8681c6
    CK_OBJECT_CLASS a_cko;
Packit 8681c6
Packit 8681c6
    CK_ATTRIBUTE tmplt[4];
Packit 8681c6
Packit 8681c6
    a_token = CK_TRUE;
Packit 8681c6
    tmplt[0].type = CKA_TOKEN;
Packit 8681c6
    tmplt[0].pValue = &a_token;
Packit 8681c6
    tmplt[0].ulValueLen = bs;
Packit 8681c6
    a_private = CK_TRUE;
Packit 8681c6
    tmplt[1].type = CKA_PRIVATE;
Packit 8681c6
    tmplt[1].pValue = &a_private;
Packit 8681c6
    tmplt[1].ulValueLen = bs;
Packit 8681c6
Packit 8681c6
    if (kt < kt_SECRET) {
Packit 8681c6
        rc = kt2CKK(kt, &a_key_type);
Packit 8681c6
        if (rc != CKR_OK) {
Packit Service 8aa27d
            printf("Keytype could not be set (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                    p11_get_ckr(rc));
Packit 8681c6
            return rc;
Packit 8681c6
        }
Packit 8681c6
    } else {
Packit 8681c6
        rc = kt2CKO(kt, &a_cko);
Packit 8681c6
        if (rc != CKR_OK) {
Packit Service 8aa27d
            printf("Keyobject could not be set (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                    p11_get_ckr(rc));
Packit 8681c6
            return rc;
Packit 8681c6
        }
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    /* Set template */
Packit 8681c6
    switch (kt) {
Packit 8681c6
    case kt_DES:
Packit 8681c6
    case kt_3DES:
Packit 8681c6
    case kt_AES:
Packit 8681c6
    case kt_GENERIC:
Packit 8681c6
    case kt_RSAPKCS:
Packit 8681c6
    case kt_EC:
Packit 8681c6
        tmplt[2].type = CKA_KEY_TYPE;
Packit 8681c6
        tmplt[2].pValue = &a_key_type;
Packit 8681c6
        tmplt[2].ulValueLen = sizeof(CK_KEY_TYPE);
Packit 8681c6
        break;
Packit 8681c6
    case kt_SECRET:
Packit 8681c6
    case kt_PUBLIC:
Packit 8681c6
    case kt_PRIVATE:
Packit 8681c6
        tmplt[2].type = CKA_CLASS;
Packit 8681c6
        tmplt[2].pValue = &a_cko;
Packit 8681c6
        tmplt[2].ulValueLen = sizeof(CK_OBJECT_CLASS);
Packit 8681c6
        break;
Packit 8681c6
    default:
Packit 8681c6
        printf("Unknown key type\n");
Packit 8681c6
        return CKR_ARGUMENTS_BAD;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    if (label != NULL_PTR) {
Packit 8681c6
        tmplt[3].type = CKA_LABEL;
Packit 8681c6
        tmplt[3].pValue = label;
Packit 8681c6
        tmplt[3].ulValueLen = strlen(label) + 1;
Packit 8681c6
        count = 4;
Packit 8681c6
    } else
Packit 8681c6
        count = 3;
Packit 8681c6
Packit 8681c6
    rc = funcs->C_FindObjectsInit(session, tmplt, count);
Packit 8681c6
    if (rc != CKR_OK) {
Packit 8681c6
        printf("C_FindObjectInit failed\n");
Packit Service 8aa27d
        printf("in tok_key_list_init() (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                p11_get_ckr(rc));
Packit 8681c6
        return rc;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * returns 1 if the given attribute is not applicable for the
Packit 8681c6
 * given key type, 0 otherwise.
Packit 8681c6
 */
Packit Service 8aa27d
static CK_BBOOL attr_na(const CK_ATTRIBUTE attr, p11sak_kt ktype)
Packit Service 8aa27d
{
Packit 8681c6
    switch (ktype) {
Packit 8681c6
    case kt_DES:
Packit 8681c6
    case kt_3DES:
Packit 8681c6
    case kt_AES:
Packit 8681c6
    case kt_SECRET:
Packit 8681c6
        switch (attr.type) {
Packit 8681c6
        case CKA_TRUSTED:
Packit 8681c6
            return 1;
Packit 8681c6
        default:
Packit 8681c6
            return 0;
Packit 8681c6
        }
Packit 8681c6
        break;
Packit 8681c6
    case kt_PUBLIC:
Packit 8681c6
        switch (attr.type) {
Packit 8681c6
        case CKA_SENSITIVE:
Packit 8681c6
        case CKA_DECRYPT:
Packit 8681c6
        case CKA_SIGN:
Packit 8681c6
        case CKA_UNWRAP:
Packit 8681c6
        case CKA_EXTRACTABLE:
Packit 8681c6
        case CKA_ALWAYS_SENSITIVE:
Packit 8681c6
        case CKA_NEVER_EXTRACTABLE:
Packit 8681c6
            return 1;
Packit 8681c6
        default:
Packit 8681c6
            return 0;
Packit 8681c6
        }
Packit 8681c6
        break;
Packit 8681c6
    case kt_PRIVATE:
Packit 8681c6
        switch (attr.type) {
Packit 8681c6
        case CKA_ENCRYPT:
Packit 8681c6
        case CKA_VERIFY:
Packit 8681c6
        case CKA_WRAP:
Packit 8681c6
            return 1;
Packit 8681c6
        default:
Packit 8681c6
            return 0;
Packit 8681c6
        }
Packit 8681c6
        break;
Packit 8681c6
    default:
Packit 8681c6
        /* key type not handled here */
Packit 8681c6
        return 0;
Packit 8681c6
    }
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Columns: T  P  M  R  L  S  E  D  G  V  W  U  X  A  N
Packit 8681c6
 */
Packit Service 8aa27d
static CK_ATTRIBUTE_TYPE col2type(int col)
Packit Service 8aa27d
{
Packit 8681c6
    switch (col) {
Packit 8681c6
    case 0:
Packit 8681c6
        return CKA_TOKEN;
Packit 8681c6
    case 1:
Packit 8681c6
        return CKA_PRIVATE;
Packit 8681c6
    case 2:
Packit 8681c6
        return CKA_MODIFIABLE;
Packit 8681c6
    case 3:
Packit 8681c6
        return CKA_DERIVE;
Packit 8681c6
    case 4:
Packit 8681c6
        return CKA_LOCAL;
Packit 8681c6
    case 5:
Packit 8681c6
        return CKA_SENSITIVE;
Packit 8681c6
    case 6:
Packit 8681c6
        return CKA_ENCRYPT;
Packit 8681c6
    case 7:
Packit 8681c6
        return CKA_DECRYPT;
Packit 8681c6
    case 8:
Packit 8681c6
        return CKA_SIGN;
Packit 8681c6
    case 9:
Packit 8681c6
        return CKA_VERIFY;
Packit 8681c6
    case 10:
Packit 8681c6
        return CKA_WRAP;
Packit 8681c6
    case 11:
Packit 8681c6
        return CKA_UNWRAP;
Packit 8681c6
    case 12:
Packit 8681c6
        return CKA_EXTRACTABLE;
Packit 8681c6
    case 13:
Packit 8681c6
        return CKA_ALWAYS_SENSITIVE;
Packit 8681c6
    case 14:
Packit 8681c6
        return CKA_NEVER_EXTRACTABLE;
Packit 8681c6
    default:
Packit 8681c6
        return 0;
Packit 8681c6
    }
Packit 8681c6
}
Packit 8681c6
Packit Service 8aa27d
static void short_print(int col, CK_ATTRIBUTE attr[], p11sak_kt ktype)
Packit Service 8aa27d
{
Packit 8681c6
    int j = 0;
Packit 8681c6
    int attr_count = 0;
Packit 8681c6
Packit 8681c6
    switch (ktype) {
Packit 8681c6
    case kt_SECRET:
Packit 8681c6
        attr_count = SEC_KEY_MAX_BOOL_ATTR_COUNT;
Packit 8681c6
        break;
Packit 8681c6
    case kt_PUBLIC:
Packit 8681c6
        attr_count = PUB_KEY_MAX_BOOL_ATTR_COUNT;
Packit 8681c6
        break;
Packit 8681c6
    case kt_PRIVATE:
Packit 8681c6
        attr_count = PRV_KEY_MAX_BOOL_ATTR_COUNT;
Packit 8681c6
        break;
Packit 8681c6
    default:
Packit 8681c6
        attr_count = PUB_KEY_MAX_BOOL_ATTR_COUNT;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    for (j = 0; j < attr_count; j++) {
Packit 8681c6
        if (attr[j].type == col2type(col) && !attr_na(attr[j], ktype)) {
Packit 8681c6
            printf(" %d ", *(CK_BBOOL*) attr[j].pValue);
Packit 8681c6
            return;
Packit 8681c6
        }
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    printf(" - ");
Packit 8681c6
    return;
Packit 8681c6
}
Packit 8681c6
/**
Packit Service 8aa27d
 * Print attributes of secure keys
Packit 8681c6
 */
Packit Service 8aa27d
static CK_RV sec_key_print_attributes(CK_SESSION_HANDLE session,
Packit Service 8aa27d
                                      CK_OBJECT_HANDLE hkey, int long_print)
Packit Service 8aa27d
{
Packit Service 8aa27d
    CK_RV rc;
Packit 8681c6
    int i;
Packit 8681c6
Packit 8681c6
    /* Boolean Attributes */
Packit 8681c6
    CK_BBOOL a_token;
Packit 8681c6
    CK_BBOOL a_private;
Packit 8681c6
    CK_BBOOL a_modifiable;
Packit 8681c6
    CK_BBOOL a_derive;
Packit 8681c6
    CK_BBOOL a_local;
Packit 8681c6
    CK_BBOOL a_sensitive;
Packit 8681c6
    CK_BBOOL a_encrypt;
Packit 8681c6
    CK_BBOOL a_decrypt;
Packit 8681c6
    CK_BBOOL a_sign;
Packit 8681c6
    CK_BBOOL a_verify;
Packit 8681c6
    CK_BBOOL a_wrap;
Packit 8681c6
    CK_BBOOL a_unwrap;
Packit 8681c6
    CK_BBOOL a_extractable;
Packit 8681c6
    CK_BBOOL a_always_sensitive;
Packit 8681c6
    CK_BBOOL a_never_extractable;
Packit 8681c6
    CK_ULONG bs = sizeof(CK_BBOOL);
Packit 8681c6
Packit 8681c6
    CK_ATTRIBUTE bool_tmplt[] = { { CKA_TOKEN, &a_token, bs }, { CKA_PRIVATE,
Packit 8681c6
            &a_private, bs }, { CKA_MODIFIABLE, &a_modifiable, bs }, {
Packit Service 8aa27d
    CKA_DERIVE, &a_derive, bs }, { CKA_LOCAL, &a_local, bs }, {
Packit Service 8aa27d
    CKA_SENSITIVE, &a_sensitive, bs }, { CKA_ENCRYPT, &a_encrypt, bs }, {
Packit Service 8aa27d
            CKA_DECRYPT, &a_decrypt, bs }, { CKA_SIGN, &a_sign, bs }, {
Packit Service 8aa27d
    CKA_VERIFY, &a_verify, bs }, { CKA_WRAP, &a_wrap, bs }, {
Packit Service 8aa27d
    CKA_UNWRAP, &a_unwrap, bs }, { CKA_EXTRACTABLE, &a_extractable, bs }, {
Packit Service 8aa27d
            CKA_ALWAYS_SENSITIVE, &a_always_sensitive, bs }, {
Packit Service 8aa27d
            CKA_NEVER_EXTRACTABLE, &a_never_extractable, bs }, };
Packit 8681c6
    CK_ULONG count = sizeof(bool_tmplt) / sizeof(CK_ATTRIBUTE);
Packit 8681c6
Packit Service 8aa27d
    rc = funcs->C_GetAttributeValue(session, hkey, bool_tmplt, count);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Attribute retrieval failed (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                p11_get_ckr(rc));
Packit Service 8aa27d
        return rc;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    if (long_print) {
Packit 8681c6
        for (i = 0; i < (int) count; i++) {
Packit 8681c6
            if (bool_tmplt[i].ulValueLen != sizeof(CK_BBOOL)) {
Packit 8681c6
                printf(" Error in retrieving Attribute %s\n",
Packit 8681c6
                        CKA2a(bool_tmplt[i].type));
Packit 8681c6
            } else {
Packit 8681c6
                printf("          %s: %s\n", CKA2a(bool_tmplt[i].type),
Packit 8681c6
                        CK_BBOOL2a(*(CK_BBOOL*) bool_tmplt[i].pValue));
Packit 8681c6
            }
Packit 8681c6
        }
Packit 8681c6
        printf("|\n");
Packit 8681c6
    } else {
Packit 8681c6
        printf(" |");
Packit 8681c6
        for (i = 2; i < KEY_MAX_BOOL_ATTR_COUNT; i++)
Packit 8681c6
            short_print(i, bool_tmplt, kt_SECRET);
Packit 8681c6
        printf("|");
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
/**
Packit Service 8aa27d
 * Print attributes of private keys
Packit 8681c6
 */
Packit 8681c6
static CK_RV priv_key_print_attributes(CK_SESSION_HANDLE session,
Packit Service 8aa27d
                                       CK_OBJECT_HANDLE hkey, int long_print)
Packit Service 8aa27d
{
Packit Service 8aa27d
    CK_RV rc;
Packit 8681c6
    int i = 0;
Packit 8681c6
Packit 8681c6
    /* Boolean Attributes */
Packit 8681c6
    CK_BBOOL a_token;
Packit 8681c6
    CK_BBOOL a_private;
Packit 8681c6
    CK_BBOOL a_modifiable;
Packit 8681c6
    CK_BBOOL a_derive;
Packit 8681c6
    CK_BBOOL a_local;
Packit 8681c6
    CK_BBOOL a_sensitive;
Packit 8681c6
    CK_BBOOL a_decrypt;
Packit 8681c6
    CK_BBOOL a_sign;
Packit 8681c6
    CK_BBOOL a_unwrap;
Packit 8681c6
    CK_BBOOL a_extractable;
Packit 8681c6
    CK_BBOOL a_always_sensitive;
Packit 8681c6
    CK_BBOOL a_never_extractable;
Packit 8681c6
    CK_ULONG bs = sizeof(CK_BBOOL);
Packit 8681c6
Packit 8681c6
    CK_ATTRIBUTE bool_tmplt[] = { { CKA_TOKEN, &a_token, bs }, { CKA_PRIVATE,
Packit 8681c6
            &a_private, bs }, { CKA_MODIFIABLE, &a_modifiable, bs }, {
Packit Service 8aa27d
    CKA_DERIVE, &a_derive, bs }, { CKA_LOCAL, &a_local, bs }, {
Packit Service 8aa27d
    CKA_SENSITIVE, &a_sensitive, bs }, { CKA_DECRYPT, &a_decrypt, bs }, {
Packit Service 8aa27d
            CKA_SIGN, &a_sign, bs }, { CKA_UNWRAP, &a_unwrap, bs }, {
Packit Service 8aa27d
    CKA_EXTRACTABLE, &a_extractable, bs }, {
Packit Service 8aa27d
    CKA_ALWAYS_SENSITIVE, &a_always_sensitive, bs }, {
Packit Service 8aa27d
    CKA_NEVER_EXTRACTABLE, &a_never_extractable, bs } };
Packit 8681c6
    CK_ULONG count = sizeof(bool_tmplt) / sizeof(CK_ATTRIBUTE);
Packit 8681c6
Packit Service 8aa27d
    rc = funcs->C_GetAttributeValue(session, hkey, bool_tmplt, count);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Attribute retrieval failed (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                p11_get_ckr(rc));
Packit Service 8aa27d
        return rc;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    /* Long print */
Packit 8681c6
    if (long_print) {
Packit 8681c6
        for (i = 0; i < (int) count; i++) {
Packit 8681c6
            if (bool_tmplt[i].ulValueLen != sizeof(CK_BBOOL)) {
Packit 8681c6
                printf(" Error in retrieving Attribute %s\n",
Packit 8681c6
                        CKA2a(bool_tmplt[i].type));
Packit 8681c6
            } else {
Packit 8681c6
                printf("          %s: %s\n", CKA2a(bool_tmplt[i].type),
Packit 8681c6
                        CK_BBOOL2a(*(CK_BBOOL*) bool_tmplt[i].pValue));
Packit 8681c6
            }
Packit 8681c6
        }
Packit 8681c6
        printf("|\n");
Packit 8681c6
    } else {
Packit 8681c6
        /* Short print */
Packit 8681c6
        printf(" |");
Packit 8681c6
        for (i = 2; i < KEY_MAX_BOOL_ATTR_COUNT; i++)
Packit 8681c6
            short_print(i, bool_tmplt, kt_PRIVATE);
Packit 8681c6
        printf("|");
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
/**
Packit Service 8aa27d
 * Print attributes of public keys
Packit 8681c6
 */
Packit Service 8aa27d
static CK_RV pub_key_print_attributes(CK_SESSION_HANDLE session,
Packit Service 8aa27d
                                      CK_OBJECT_HANDLE hkey, int long_print)
Packit Service 8aa27d
{
Packit Service 8aa27d
    CK_RV rc;
Packit 8681c6
    int i = 0;
Packit 8681c6
Packit 8681c6
    /* Boolean Attributes */
Packit 8681c6
    CK_BBOOL a_token;
Packit 8681c6
    CK_BBOOL a_private;
Packit 8681c6
    CK_BBOOL a_modifiable;
Packit 8681c6
    CK_BBOOL a_derive;
Packit 8681c6
    CK_BBOOL a_local;
Packit 8681c6
    CK_BBOOL a_encrypt;
Packit 8681c6
    CK_BBOOL a_verify;
Packit 8681c6
    CK_BBOOL a_wrap;
Packit 8681c6
    CK_ULONG bs = sizeof(CK_BBOOL);
Packit 8681c6
Packit 8681c6
    CK_ATTRIBUTE bool_tmplt[] = { { CKA_TOKEN, &a_token, bs }, { CKA_PRIVATE,
Packit 8681c6
            &a_private, bs }, { CKA_MODIFIABLE, &a_modifiable, bs }, {
Packit Service 8aa27d
    CKA_DERIVE, &a_derive, bs }, { CKA_LOCAL, &a_local, bs }, {
Packit Service 8aa27d
    CKA_ENCRYPT, &a_encrypt, bs }, { CKA_VERIFY, &a_verify, bs }, {
Packit Service 8aa27d
    CKA_WRAP, &a_wrap, bs } };
Packit 8681c6
    CK_ULONG count = sizeof(bool_tmplt) / sizeof(CK_ATTRIBUTE);
Packit 8681c6
Packit Service 8aa27d
    rc = funcs->C_GetAttributeValue(session, hkey, bool_tmplt, count);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Attribute retrieval failed (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                p11_get_ckr(rc));
Packit Service 8aa27d
        return rc;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    /* Long print */
Packit 8681c6
    if (long_print) {
Packit 8681c6
        for (i = 0; i < (int) count; i++) {
Packit 8681c6
            if (bool_tmplt[i].ulValueLen != sizeof(CK_BBOOL)) {
Packit 8681c6
                printf(" Error in retrieving Attribute %s\n",
Packit 8681c6
                        CKA2a(bool_tmplt[i].type));
Packit 8681c6
            } else {
Packit 8681c6
                printf("          %s: %s\n", CKA2a(bool_tmplt[i].type),
Packit 8681c6
                        CK_BBOOL2a(*(CK_BBOOL*) bool_tmplt[i].pValue));
Packit 8681c6
            }
Packit 8681c6
        }
Packit 8681c6
        printf("|\n");
Packit 8681c6
    } else {
Packit 8681c6
        /* Short print */
Packit 8681c6
        printf(" |");
Packit 8681c6
        for (i = 2; i < KEY_MAX_BOOL_ATTR_COUNT; i++)
Packit 8681c6
            short_print(i, bool_tmplt, kt_PUBLIC);
Packit 8681c6
        printf("|");
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
/**
Packit Service 8aa27d
 * Get label attribute of key
Packit 8681c6
 */
Packit Service 8aa27d
static CK_RV tok_key_get_label_attr(CK_SESSION_HANDLE session,
Packit Service 8aa27d
                                    CK_OBJECT_HANDLE hkey, char **plabel)
Packit Service 8aa27d
{
Packit Service 8aa27d
    CK_RV rc;
Packit 8681c6
    char *label;
Packit 8681c6
    CK_ATTRIBUTE template[1] = { { CKA_LABEL, NULL_PTR, 0 } };
Packit 8681c6
Packit Service 8aa27d
    rc = funcs->C_GetAttributeValue(session, hkey, template, 1);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Key cannot show CKA_LABEL attribute (error code 0x%lX: %s)\n",
Packit Service 8aa27d
                rc, p11_get_ckr(rc));
Packit Service 8aa27d
        return rc;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    label = malloc(template[0].ulValueLen);
Packit 8681c6
    if (!label) {
Packit 8681c6
        printf("Error: cannot malloc storage for label.\n");
Packit 8681c6
        return CKR_HOST_MEMORY;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    template[0].pValue = label;
Packit Service 8aa27d
    rc = funcs->C_GetAttributeValue(session, hkey, template, 1);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Error retrieving CKA_LABEL attribute (error code 0x%lX: %s)\n",
Packit Service 8aa27d
                rc, p11_get_ckr(rc));
Packit Service 8aa27d
        return rc;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    label[template[0].ulValueLen] = 0;
Packit 8681c6
    *plabel = label;
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
/**
Packit Service 8aa27d
 * Get key type
Packit 8681c6
 */
Packit 8681c6
static CK_RV tok_key_get_key_type(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE hkey,
Packit Service 8aa27d
                                  CK_OBJECT_CLASS *keyclass, char **ktype,
Packit Service 8aa27d
                                  CK_ULONG *klength)
Packit Service 8aa27d
{
Packit Service 8aa27d
    CK_RV rc;
Packit 8681c6
    char *buffer;
Packit 8681c6
    CK_OBJECT_CLASS oclass;
Packit 8681c6
    CK_KEY_TYPE kt;
Packit 8681c6
    CK_ULONG vl;
Packit 8681c6
Packit 8681c6
    CK_ATTRIBUTE template[1] =
Packit 8681c6
            { { CKA_CLASS, &oclass, sizeof(CK_OBJECT_CLASS) } };
Packit 8681c6
Packit Service 8aa27d
    rc = funcs->C_GetAttributeValue(session, hkey, template, 1);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf(
Packit Service 8aa27d
                "Object does not have CKA_CLASS attribute (error code 0x%lX: %s)\n",
Packit Service 8aa27d
                rc, p11_get_ckr(rc));
Packit Service 8aa27d
        return rc;
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
    // the buffer holds the following string
Packit Service 8aa27d
    // "public " + CKK2a(kt) with kt = "unknown key type" being the longest kt string
Packit Service 8aa27d
    // or "private  " + CKK2a(kt) with kt = "unknown key type" being the longest kt string
Packit Service 8aa27d
    // Hence, the size of the string is 25 Bytes including the '\0' character
Packit Service 8aa27d
    // Use 32 Bytes as multiple of 8
Packit Service 8aa27d
    buffer = malloc(32);
Packit 8681c6
    if (!buffer) {
Packit 8681c6
        return CKR_HOST_MEMORY;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    switch (oclass) {
Packit 8681c6
    case CKO_SECRET_KEY:
Packit 8681c6
        buffer[0] = 0;
Packit 8681c6
        break;
Packit 8681c6
    case CKO_PUBLIC_KEY:
Packit 8681c6
        strcpy(buffer, "public ");
Packit 8681c6
        break;
Packit 8681c6
    case CKO_PRIVATE_KEY:
Packit 8681c6
        strcpy(buffer, "private ");
Packit 8681c6
        break;
Packit Service 8aa27d
    default:
Packit Service 8aa27d
        // FIXIT - return code to represent object class invalid
Packit Service 8aa27d
        rc = CKR_KEY_HANDLE_INVALID;
Packit Service 8aa27d
        printf("Object handle invalid (error code 0x%lX: %s)\n",
Packit Service 8aa27d
               rc, p11_get_ckr(rc));
Packit Service 8aa27d
        free(buffer);
Packit Service 8aa27d
        return rc;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    template[0].type = CKA_KEY_TYPE;
Packit 8681c6
    template[0].pValue = &kt;
Packit 8681c6
    template[0].ulValueLen = sizeof(CK_KEY_TYPE);
Packit Service 8aa27d
    rc = funcs->C_GetAttributeValue(session, hkey, template, 1);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Object does not have CKA_KEY_TYPE attribute (error code 0x%lX: %s)\n",
Packit Service 8aa27d
               rc, p11_get_ckr(rc));
Packit Service 8aa27d
        free(buffer);
Packit Service 8aa27d
        return rc;
Packit 8681c6
    }
Packit Service 8aa27d
Packit 8681c6
    strcat(buffer, CKK2a(kt));
Packit 8681c6
Packit 8681c6
    *klength = 0;
Packit 8681c6
    switch (kt) {
Packit 8681c6
    case CKK_AES:
Packit 8681c6
    case CKK_GENERIC_SECRET:
Packit 8681c6
        template[0].type = CKA_VALUE_LEN;
Packit 8681c6
        template[0].pValue = &vl;
Packit 8681c6
        template[0].ulValueLen = sizeof(CK_ULONG);
Packit Service 8aa27d
        rc = funcs->C_GetAttributeValue(session, hkey, template, 1);
Packit Service 8aa27d
        if (rc != CKR_OK) {
Packit Service 8aa27d
            printf("Object does not have CKA_VALUE_LEN attribute (error code 0x%lX: %s)\n",
Packit Service 8aa27d
                   rc, p11_get_ckr(rc));
Packit Service 8aa27d
            free(buffer);
Packit Service 8aa27d
            return rc;
Packit 8681c6
        }
Packit 8681c6
        *klength = vl * 8;
Packit 8681c6
        break;
Packit Service 8aa27d
    default:
Packit Service 8aa27d
        // Fall through - template values set above
Packit Service 8aa27d
        break;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    *ktype = buffer;
Packit 8681c6
    *keyclass = oclass;
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
/**
Packit 8681c6
 * Check args for gen_key command.
Packit 8681c6
 */
Packit Service 8aa27d
static CK_RV check_args_gen_key(p11sak_kt *kt, CK_ULONG keylength,
Packit Service 8aa27d
                                char *ECcurve)
Packit Service 8aa27d
{
Packit 8681c6
    switch (*kt) {
Packit 8681c6
    case kt_DES:
Packit 8681c6
    case kt_3DES:
Packit 8681c6
        break;
Packit 8681c6
    case kt_AES:
Packit 8681c6
        if ((keylength == 128) || (keylength == 192) || (keylength == 256)) {
Packit 8681c6
            break;
Packit 8681c6
        } else {
Packit 8681c6
            printf(
Packit 8681c6
                    "Cipher key type [%d] and key bit length %ld is not supported. Try adding argument -bits <128|192|256>\n",
Packit 8681c6
                    *kt, keylength);
Packit 8681c6
            return CKR_ARGUMENTS_BAD;
Packit 8681c6
        }
Packit 8681c6
        break;
Packit 8681c6
    case kt_RSAPKCS:
Packit 8681c6
        if ((keylength == 1024) || (keylength == 2048) || (keylength == 4096)) {
Packit 8681c6
            break;
Packit 8681c6
        } else {
Packit 8681c6
            printf(
Packit 8681c6
                    "[%d] RSA modulus bit length %ld NOT supported. Try adding argument -bits <1024|2048|4096>\n",
Packit 8681c6
                    *kt, keylength);
Packit 8681c6
        }
Packit 8681c6
        break;
Packit 8681c6
    case kt_EC:
Packit 8681c6
        if (ECcurve == NULL) {
Packit 8681c6
            printf(
Packit 8681c6
                    "Cipher key type [%d] supported but EC curve not set in arguments. Try argument -curve <prime256v1|secp384r1|secp521r1> \n",
Packit 8681c6
                    *kt);
Packit 8681c6
            return CKR_ARGUMENTS_BAD;
Packit 8681c6
        }
Packit 8681c6
        break;
Packit 8681c6
    case kt_GENERIC:
Packit 8681c6
    case kt_SECRET:
Packit 8681c6
    case kt_PUBLIC:
Packit 8681c6
    case kt_PRIVATE:
Packit 8681c6
        break;
Packit 8681c6
    default:
Packit 8681c6
        printf("Cipher key type [%d] is not set or not supported\n", *kt);
Packit 8681c6
        print_gen_help();
Packit 8681c6
        return CKR_ARGUMENTS_BAD;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Check args for list_key command.
Packit 8681c6
 */
Packit Service 8aa27d
static CK_RV check_args_list_key(p11sak_kt *kt)
Packit Service 8aa27d
{
Packit 8681c6
    switch (*kt) {
Packit 8681c6
    case kt_AES:
Packit 8681c6
    case kt_RSAPKCS:
Packit 8681c6
    case kt_DES:
Packit 8681c6
    case kt_3DES:
Packit 8681c6
    case kt_EC:
Packit 8681c6
    case kt_GENERIC:
Packit 8681c6
    case kt_SECRET:
Packit 8681c6
    case kt_PUBLIC:
Packit 8681c6
    case kt_PRIVATE:
Packit 8681c6
        break;
Packit 8681c6
    default:
Packit 8681c6
        printf("Cipher key type [%d] is not set or not supported\n", *kt);
Packit 8681c6
        print_listkeys_help();
Packit 8681c6
        return CKR_ARGUMENTS_BAD;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
/**
Packit Service 8aa27d
 * Check args for remove-key command.
Packit Service 8aa27d
 */
Packit Service 8aa27d
static CK_RV check_args_remove_key(p11sak_kt *kt)
Packit Service 8aa27d
{
Packit Service 8aa27d
    switch (*kt) {
Packit Service 8aa27d
    case kt_DES:
Packit Service 8aa27d
    case kt_3DES:
Packit Service 8aa27d
    case kt_AES:
Packit Service 8aa27d
    case kt_RSAPKCS:
Packit Service 8aa27d
    case kt_EC:
Packit Service 8aa27d
    case kt_GENERIC:
Packit Service 8aa27d
    case kt_SECRET:
Packit Service 8aa27d
    case kt_PUBLIC:
Packit Service 8aa27d
    case kt_PRIVATE:
Packit Service 8aa27d
        break;
Packit Service 8aa27d
    default:
Packit Service 8aa27d
        printf("Cipher key type [%d] is not set or not supported\n", *kt);
Packit Service 8aa27d
        print_gen_help();
Packit Service 8aa27d
        return CKR_ARGUMENTS_BAD;
Packit Service 8aa27d
    }
Packit Service 8aa27d
Packit Service 8aa27d
    return CKR_OK;
Packit Service 8aa27d
}
Packit Service 8aa27d
/**
Packit 8681c6
 * Parse p11sak command from argv.
Packit 8681c6
 */
Packit Service 8aa27d
static p11sak_cmd parse_cmd(const char *arg)
Packit Service 8aa27d
{
Packit 8681c6
    p11sak_cmd cmd = no_cmd;
Packit 8681c6
Packit 8681c6
    if ((strcmp(arg, "generate-key") == 0) || (strcmp(arg, "gen-key") == 0)
Packit 8681c6
            || (strcmp(arg, "gen") == 0)) {
Packit 8681c6
        cmd = gen_key;
Packit 8681c6
    } else if ((strcmp(arg, "list-key") == 0) || (strcmp(arg, "ls-key") == 0)
Packit 8681c6
            || (strcmp(arg, "ls") == 0)) {
Packit 8681c6
        cmd = list_key;
Packit Service 8aa27d
    } else if ((strcmp(arg, "remove-key") == 0) || (strcmp(arg, "rm-key") == 0)
Packit Service 8aa27d
            || (strcmp(arg, "rm") == 0)) {
Packit Service 8aa27d
        cmd = remove_key;
Packit 8681c6
    } else {
Packit 8681c6
        printf("Unknown command %s\n", cmd2str(cmd));
Packit 8681c6
        cmd = no_cmd;
Packit 8681c6
    }
Packit 8681c6
    return cmd;
Packit 8681c6
}
Packit 8681c6
Packit Service 8aa27d
static CK_BBOOL last_parm_is_help(char *argv[], int argc)
Packit Service 8aa27d
{
Packit 8681c6
    if (strcmp(argv[argc - 1], "-h") == 0
Packit 8681c6
            || strcmp(argv[argc - 1], "--help") == 0) {
Packit 8681c6
        return 1;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    return 0;
Packit 8681c6
}
Packit 8681c6
Packit Service 8aa27d
static CK_ULONG get_ulong_arg(int pos, char *argv[], int argc)
Packit Service 8aa27d
{
Packit 8681c6
    if (pos < argc)
Packit 8681c6
        return atol(argv[pos]);
Packit 8681c6
    else
Packit 8681c6
        return 0;
Packit 8681c6
}
Packit 8681c6
Packit Service 8aa27d
static char* get_string_arg(int pos, char *argv[], int argc)
Packit Service 8aa27d
{
Packit 8681c6
    if (pos < argc)
Packit 8681c6
        return argv[pos];
Packit 8681c6
    else
Packit 8681c6
        return NULL;
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Parse the list-key args.
Packit 8681c6
 */
Packit 8681c6
static CK_RV parse_list_key_args(char *argv[], int argc, p11sak_kt *kt,
Packit Service 8aa27d
                                 CK_ULONG *keylength, CK_SLOT_ID *slot,
Packit Service 8aa27d
                                 char **pin, int *long_print)
Packit Service 8aa27d
{
Packit Service 8aa27d
    CK_RV rc;
Packit 8681c6
    int i;
Packit 8681c6
Packit 8681c6
    if (last_parm_is_help(argv, argc)) {
Packit 8681c6
        print_listkeys_help();
Packit 8681c6
        return CKR_ARGUMENTS_BAD;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    for (i = 2; i < argc; i++) {
Packit 8681c6
        /* Get arguments */
Packit 8681c6
        if (strcmp(argv[i], "DES") == 0 || strcmp(argv[i], "des") == 0) {
Packit 8681c6
            *kt = kt_DES;
Packit 8681c6
            *keylength = 64;
Packit 8681c6
        } else if (strcmp(argv[i], "3DES") == 0
Packit 8681c6
                || strcmp(argv[i], "3des") == 0) {
Packit 8681c6
            *kt = kt_3DES;
Packit 8681c6
        } else if (strcmp(argv[i], "AES") == 0 || strcmp(argv[i], "aes") == 0) {
Packit 8681c6
            *kt = kt_AES;
Packit 8681c6
        } else if (strcmp(argv[i], "RSA") == 0 || strcmp(argv[i], "rsa") == 0) {
Packit 8681c6
            *kt = kt_RSAPKCS;
Packit 8681c6
        } else if (strcmp(argv[i], "EC") == 0 || strcmp(argv[i], "ec") == 0) {
Packit 8681c6
            *kt = kt_EC;
Packit 8681c6
        } else if (strcmp(argv[i], "GENERIC") == 0
Packit 8681c6
                || strcmp(argv[i], "generic") == 0) {
Packit 8681c6
            *kt = kt_GENERIC;
Packit 8681c6
        } else if (strcmp(argv[i], "SECRET") == 0
Packit 8681c6
                || strcmp(argv[i], "secret") == 0) {
Packit 8681c6
            *kt = kt_SECRET;
Packit 8681c6
        } else if (strcmp(argv[i], "PUBLIC") == 0
Packit 8681c6
                || strcmp(argv[i], "public") == 0) {
Packit 8681c6
            *kt = kt_PUBLIC;
Packit 8681c6
        } else if (strcmp(argv[i], "PRIVATE") == 0
Packit 8681c6
                || strcmp(argv[i], "private") == 0) {
Packit 8681c6
            *kt = kt_PRIVATE;
Packit Service 8aa27d
            /* Get options */
Packit 8681c6
        } else if (strcmp(argv[i], "--slot") == 0) {
Packit Service 8aa27d
            if (i + 1 < argc) {
Packit Service 8aa27d
                *slot = (CK_ULONG) atol(argv[i + 1]);
Packit Service 8aa27d
            } else {
Packit Service 8aa27d
                printf("--slot <SLOT> argument is missing.\n");
Packit Service 8aa27d
                return CKR_ARGUMENTS_BAD;
Packit Service 8aa27d
            }
Packit 8681c6
            i++;
Packit 8681c6
        } else if (strcmp(argv[i], "--pin") == 0) {
Packit Service 8aa27d
            if (i + 1 < argc) {
Packit Service 8aa27d
                *pin = argv[i + 1];
Packit Service 8aa27d
            } else {
Packit Service 8aa27d
                printf("--pin <PIN> argument is missing.\n");
Packit Service 8aa27d
                return CKR_ARGUMENTS_BAD;
Packit Service 8aa27d
            }
Packit 8681c6
            i++;
Packit 8681c6
        } else if ((strcmp(argv[i], "-l") == 0)
Packit 8681c6
                || (strcmp(argv[i], "--long") == 0)) {
Packit 8681c6
            *long_print = 1;
Packit 8681c6
        } else if ((strcmp(argv[i], "-h") == 0)
Packit 8681c6
                || (strcmp(argv[i], "--help") == 0)) {
Packit 8681c6
            print_listkeys_help();
Packit 8681c6
            return CKR_ARGUMENTS_BAD;
Packit 8681c6
        } else {
Packit Service 8aa27d
            printf("Unknown argument or option %s for command list-key\n",
Packit Service 8aa27d
                    argv[i]);
Packit 8681c6
            return CKR_ARGUMENTS_BAD;
Packit 8681c6
        }
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
    rc = check_args_list_key(kt);
Packit 8681c6
Packit 8681c6
    if (*slot == 0) {
Packit 8681c6
        printf("Slot number must be specified.\n");
Packit Service 8aa27d
        rc = CKR_ARGUMENTS_BAD;
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
    return rc;
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Parse the generate-key args.
Packit 8681c6
 */
Packit 8681c6
static CK_RV parse_gen_key_args(char *argv[], int argc, p11sak_kt *kt,
Packit Service 8aa27d
                                CK_ULONG *keylength, char **ECcurve,
Packit Service 8aa27d
                                CK_SLOT_ID *slot, char **pin, CK_ULONG *exponent,
Packit Service 8aa27d
                                char **label, char **attr_string)
Packit Service 8aa27d
{
Packit Service 8aa27d
    CK_RV rc;
Packit 8681c6
    int i;
Packit 8681c6
Packit 8681c6
    for (i = 2; i < argc; i++) {
Packit 8681c6
        /* Get arguments */
Packit 8681c6
        if (strcmp(argv[i], "DES") == 0 || strcmp(argv[i], "des") == 0) {
Packit 8681c6
            *kt = kt_DES;
Packit 8681c6
            *keylength = 64;
Packit 8681c6
        } else if (strcmp(argv[i], "3DES") == 0
Packit 8681c6
                || strcmp(argv[i], "3des") == 0) {
Packit 8681c6
            *kt = kt_3DES;
Packit 8681c6
            *keylength = 192;
Packit 8681c6
        } else if (strcmp(argv[i], "AES") == 0 || strcmp(argv[i], "aes") == 0) {
Packit 8681c6
            *kt = kt_AES;
Packit 8681c6
            *keylength = get_ulong_arg(i + 1, argv, argc);
Packit 8681c6
            i++;
Packit 8681c6
        } else if (strcmp(argv[i], "RSA") == 0 || strcmp(argv[i], "rsa") == 0) {
Packit 8681c6
            *kt = kt_RSAPKCS;
Packit 8681c6
            *keylength = get_ulong_arg(i + 1, argv, argc);
Packit 8681c6
            i++;
Packit 8681c6
        } else if (strcmp(argv[i], "EC") == 0 || strcmp(argv[i], "ec") == 0) {
Packit 8681c6
            *kt = kt_EC;
Packit 8681c6
            *ECcurve = get_string_arg(i + 1, argv, argc);
Packit 8681c6
            i++;
Packit Service 8aa27d
            /* Get options */
Packit 8681c6
        } else if (strcmp(argv[i], "--slot") == 0) {
Packit Service 8aa27d
            if (i + 1 < argc) {
Packit Service 8aa27d
                *slot = (CK_ULONG) atol(argv[i + 1]);
Packit Service 8aa27d
            } else {
Packit Service 8aa27d
                printf("--slot <SLOT> argument is missing.\n");
Packit Service 8aa27d
                return CKR_ARGUMENTS_BAD;
Packit Service 8aa27d
            }
Packit 8681c6
            i++;
Packit 8681c6
        } else if (strcmp(argv[i], "--pin") == 0) {
Packit Service 8aa27d
            if (i + 1 < argc) {
Packit Service 8aa27d
                *pin = argv[i + 1];
Packit Service 8aa27d
            } else {
Packit Service 8aa27d
                printf("--pin <PIN> argument is missing.\n");
Packit Service 8aa27d
                return CKR_ARGUMENTS_BAD;
Packit Service 8aa27d
            }
Packit 8681c6
            i++;
Packit 8681c6
        } else if (strcmp(argv[i], "--label") == 0) {
Packit Service 8aa27d
            if (i + 1 < argc) {
Packit Service 8aa27d
                *label = argv[i + 1];
Packit Service 8aa27d
            } else {
Packit Service 8aa27d
                printf("--label <LABEL> argument is missing.\n");
Packit Service 8aa27d
                return CKR_ARGUMENTS_BAD;
Packit Service 8aa27d
            }
Packit 8681c6
            i++;
Packit 8681c6
        } else if (strcmp(argv[i], "--exponent") == 0) {
Packit Service 8aa27d
            if (i + 1 < argc) {
Packit Service 8aa27d
                *exponent = atol(argv[i + 1]);
Packit Service 8aa27d
            } else {
Packit Service 8aa27d
                printf("--exponent <EXPONENT> argument is missing.\n");
Packit Service 8aa27d
                return CKR_ARGUMENTS_BAD;
Packit Service 8aa27d
            }
Packit 8681c6
            i++;
Packit 8681c6
        } else if ((strcmp(argv[i], "--attr") == 0)) {
Packit Service 8aa27d
            if (i + 1 < argc) {
Packit Service 8aa27d
                *attr_string = argv[i + 1];
Packit Service 8aa27d
            } else {
Packit Service 8aa27d
                printf("--attr <ATTRIBUTES> argument is missing.\n");
Packit Service 8aa27d
                return CKR_ARGUMENTS_BAD;
Packit Service 8aa27d
            }
Packit 8681c6
            i++;
Packit 8681c6
        } else if ((strcmp(argv[i], "-h") == 0)
Packit 8681c6
                || (strcmp(argv[i], "--help") == 0)) {
Packit 8681c6
            print_gen_keys_help(kt);
Packit 8681c6
            return CKR_ARGUMENTS_BAD;
Packit 8681c6
        } else {
Packit Service 8aa27d
            printf("Unknown argument or option %s for command generate-key\n",
Packit Service 8aa27d
                    argv[i]);
Packit 8681c6
            return CKR_ARGUMENTS_BAD;
Packit 8681c6
        }
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    if (last_parm_is_help(argv, argc)) {
Packit 8681c6
        print_gen_keys_help(kt);
Packit 8681c6
        for (i = 2; i < argc; i++) {
Packit 8681c6
            if ((strcmp(argv[i], "--attr") == 0)) {
Packit 8681c6
                print_gen_attr_help();
Packit 8681c6
            }
Packit 8681c6
        }
Packit 8681c6
        return CKR_ARGUMENTS_BAD;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    /* Check args */
Packit Service 8aa27d
    rc = check_args_gen_key(kt, *keylength, *ECcurve);
Packit 8681c6
Packit 8681c6
    /* Check required options */
Packit 8681c6
    if (*label == NULL) {
Packit 8681c6
        printf("Key label must be specified.\n");
Packit Service 8aa27d
        rc = CKR_ARGUMENTS_BAD;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    if (*slot == 0) {
Packit 8681c6
        printf("Slot number must be specified.\n");
Packit Service 8aa27d
        rc = CKR_ARGUMENTS_BAD;
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
    return rc;
Packit 8681c6
}
Packit Service 8aa27d
/**
Packit Service 8aa27d
 * Parse the remove-key args.
Packit Service 8aa27d
 */
Packit Service 8aa27d
static CK_RV parse_remove_key_args(char *argv[], int argc, p11sak_kt *kt,
Packit Service 8aa27d
                                   CK_SLOT_ID *slot, char **pin, char **label,
Packit Service 8aa27d
                                   CK_ULONG *keylength, CK_BBOOL *forceAll)
Packit Service 8aa27d
{
Packit Service 8aa27d
    CK_RV rc;
Packit Service 8aa27d
    int i;
Packit 8681c6
Packit Service 8aa27d
    if (last_parm_is_help(argv, argc)) {
Packit Service 8aa27d
        print_removekeys_help();
Packit Service 8aa27d
        return CKR_ARGUMENTS_BAD;
Packit Service 8aa27d
    }
Packit Service 8aa27d
Packit Service 8aa27d
    for (i = 2; i < argc; i++) {
Packit Service 8aa27d
        /* Get arguments */
Packit Service 8aa27d
        if (strcmp(argv[i], "DES") == 0 || strcmp(argv[i], "des") == 0) {
Packit Service 8aa27d
            *kt = kt_DES;
Packit Service 8aa27d
            *keylength = 64;
Packit Service 8aa27d
        } else if (strcmp(argv[i], "3DES") == 0
Packit Service 8aa27d
                || strcmp(argv[i], "3des") == 0) {
Packit Service 8aa27d
            *kt = kt_3DES;
Packit Service 8aa27d
        } else if (strcmp(argv[i], "AES") == 0 || strcmp(argv[i], "aes") == 0) {
Packit Service 8aa27d
            *kt = kt_AES;
Packit Service 8aa27d
        } else if (strcmp(argv[i], "RSA") == 0 || strcmp(argv[i], "rsa") == 0) {
Packit Service 8aa27d
            *kt = kt_RSAPKCS;
Packit Service 8aa27d
        } else if (strcmp(argv[i], "EC") == 0 || strcmp(argv[i], "ec") == 0) {
Packit Service 8aa27d
            *kt = kt_EC;
Packit Service 8aa27d
            /* Get options */
Packit Service 8aa27d
        } else if (strcmp(argv[i], "--slot") == 0) {
Packit Service 8aa27d
            if (i + 1 < argc) {
Packit Service 8aa27d
                *slot = (CK_ULONG) atol(argv[i + 1]);
Packit Service 8aa27d
            } else {
Packit Service 8aa27d
                printf("--slot <SLOT> argument is missing.\n");
Packit Service 8aa27d
                return CKR_ARGUMENTS_BAD;
Packit Service 8aa27d
            }
Packit Service 8aa27d
            i++;
Packit Service 8aa27d
        } else if (strcmp(argv[i], "--pin") == 0) {
Packit Service 8aa27d
            if (i + 1 < argc) {
Packit Service 8aa27d
                *pin = argv[i + 1];
Packit Service 8aa27d
            } else {
Packit Service 8aa27d
                printf("--pin <PIN> argument is missing.\n");
Packit Service 8aa27d
                return CKR_ARGUMENTS_BAD;
Packit Service 8aa27d
            }
Packit Service 8aa27d
            i++;
Packit Service 8aa27d
        } else if (strcmp(argv[i], "--label") == 0) {
Packit Service 8aa27d
            if (i + 1 < argc) {
Packit Service 8aa27d
                *label = argv[i + 1];
Packit Service 8aa27d
            } else {
Packit Service 8aa27d
                printf("--label <LABEL> argument is missing.\n");
Packit Service 8aa27d
                return CKR_ARGUMENTS_BAD;
Packit Service 8aa27d
            }
Packit Service 8aa27d
            i++;
Packit Service 8aa27d
        } else if ((strcmp(argv[i], "-f") == 0)
Packit Service 8aa27d
                || (strcmp(argv[i], "--force") == 0)) {
Packit Service 8aa27d
            *forceAll = ckb_true;
Packit Service 8aa27d
        } else if ((strcmp(argv[i], "-h") == 0)
Packit Service 8aa27d
                || (strcmp(argv[i], "--help") == 0)) {
Packit Service 8aa27d
Packit Service 8aa27d
            print_removekeys_help();
Packit Service 8aa27d
            return CKR_ARGUMENTS_BAD;
Packit Service 8aa27d
        } else {
Packit Service 8aa27d
            printf("Unknown argument or option %s for command remove-key\n",
Packit Service 8aa27d
                    argv[i]);
Packit Service 8aa27d
            return CKR_ARGUMENTS_BAD;
Packit Service 8aa27d
        }
Packit Service 8aa27d
    }
Packit Service 8aa27d
Packit Service 8aa27d
    rc = check_args_remove_key(kt);
Packit Service 8aa27d
Packit Service 8aa27d
    /* Check required options */
Packit Service 8aa27d
    if (*label == NULL) {
Packit Service 8aa27d
        *label = "";
Packit Service 8aa27d
    }
Packit Service 8aa27d
Packit Service 8aa27d
    if (*slot == 0) {
Packit Service 8aa27d
        printf("Slot number must be specified.\n");
Packit Service 8aa27d
        rc = CKR_ARGUMENTS_BAD;
Packit Service 8aa27d
    }
Packit Service 8aa27d
Packit Service 8aa27d
    return rc;
Packit Service 8aa27d
}
Packit 8681c6
/**
Packit 8681c6
 * Parse the p11sak command args.
Packit 8681c6
 */
Packit Service 8aa27d
static CK_RV parse_cmd_args(p11sak_cmd cmd, char *argv[], int argc,
Packit Service 8aa27d
                            p11sak_kt *kt, CK_ULONG *keylength, char **ECcurve,
Packit Service 8aa27d
                            CK_SLOT_ID *slot, char **pin, CK_ULONG *exponent,
Packit Service 8aa27d
                            char **label, char **attr_string, int *long_print,
Packit Service 8aa27d
                            CK_BBOOL *forceAll)
Packit Service 8aa27d
{
Packit Service 8aa27d
    CK_RV rc;
Packit 8681c6
Packit 8681c6
    switch (cmd) {
Packit 8681c6
    case gen_key:
Packit Service 8aa27d
        rc = parse_gen_key_args(argv, argc, kt, keylength, ECcurve, slot, pin,
Packit Service 8aa27d
                exponent, label, attr_string);
Packit 8681c6
        break;
Packit 8681c6
    case list_key:
Packit Service 8aa27d
        rc = parse_list_key_args(argv, argc, kt, keylength, slot, pin,
Packit Service 8aa27d
                long_print);
Packit Service 8aa27d
        break;
Packit Service 8aa27d
    case remove_key:
Packit Service 8aa27d
        rc = parse_remove_key_args(argv, argc, kt, slot, pin, label, keylength,
Packit Service 8aa27d
                forceAll);
Packit 8681c6
        break;
Packit 8681c6
    default:
Packit 8681c6
        printf("Error: unknown command %d specified.\n", cmd);
Packit Service 8aa27d
        rc = CKR_ARGUMENTS_BAD;
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
    return rc;
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Generate a symmetric key.
Packit 8681c6
 */
Packit Service 8aa27d
static CK_RV generate_symmetric_key(CK_SESSION_HANDLE session, p11sak_kt kt,
Packit Service 8aa27d
                                    CK_ULONG keylength, char *label,
Packit Service 8aa27d
                                    char *attr_string)
Packit Service 8aa27d
{
Packit 8681c6
    CK_OBJECT_HANDLE hkey;
Packit 8681c6
    CK_MECHANISM mech;
Packit Service 8aa27d
    CK_RV rc;
Packit 8681c6
Packit 8681c6
    printf("Generate symmetric key %s with keylen=%ld and label=[%s]\n",
Packit 8681c6
            kt2str(kt), keylength, label);
Packit 8681c6
Packit Service 8aa27d
    rc = key_pair_gen_mech(kt, &mech);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Error setting the mechanism (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                p11_get_ckr(rc));
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
    rc = tok_key_gen(session, keylength, &mech, attr_string, &hkey, label);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Key generation failed (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                p11_get_ckr(rc));
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    printf("Symmetric key generation successful!\n");
Packit 8681c6
Packit 8681c6
    done:
Packit 8681c6
Packit Service 8aa27d
    return rc;
Packit 8681c6
}
Packit 8681c6
/**
Packit 8681c6
 * Generate an asymmetric key.
Packit 8681c6
 */
Packit 8681c6
static CK_RV generate_asymmetric_key(CK_SESSION_HANDLE session, CK_SLOT_ID slot,
Packit Service 8aa27d
                                     p11sak_kt kt, CK_ULONG keylength,
Packit Service 8aa27d
                                     CK_ULONG exponent, char *ECcurve,
Packit Service 8aa27d
                                     char *label, char *attr_string)
Packit Service 8aa27d
{
Packit 8681c6
    CK_OBJECT_HANDLE pub_keyh, prv_keyh;
Packit 8681c6
    CK_ATTRIBUTE pub_attr[KEY_MAX_BOOL_ATTR_COUNT + 2];
Packit 8681c6
    CK_ULONG pub_acount = 0;
Packit 8681c6
    CK_ATTRIBUTE prv_attr[KEY_MAX_BOOL_ATTR_COUNT + 2];
Packit 8681c6
    CK_ULONG prv_acount = 0;
Packit 8681c6
    CK_MECHANISM mech;
Packit Service 8aa27d
    CK_RV rc;
Packit 8681c6
Packit 8681c6
    if (kt == kt_RSAPKCS) {
Packit Service 8aa27d
        rc = read_rsa_args((CK_ULONG) keylength, exponent, pub_attr,
Packit 8681c6
                &pub_acount);
Packit Service 8aa27d
        if (rc) {
Packit 8681c6
            printf("Error setting RSA parameters!\n");
Packit 8681c6
            goto done;
Packit 8681c6
        }
Packit 8681c6
    } else if (kt == kt_EC) {
Packit Service 8aa27d
        rc = read_ec_args(ECcurve, pub_attr, &pub_acount);
Packit Service 8aa27d
        if (rc) {
Packit 8681c6
            printf("Error parsing EC parameters!\n");
Packit 8681c6
            goto done;
Packit 8681c6
        }
Packit 8681c6
    } else {
Packit 8681c6
        printf("The key type %d is not yet supported.\n", kt);
Packit Service 8aa27d
        rc = CKR_KEY_TYPE_INCONSISTENT;
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
    rc = set_labelpair_attr(label, pub_attr, &pub_acount, prv_attr,
Packit 8681c6
            &prv_acount);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Error setting the label attributes (error code 0x%lX: %s)\n",
Packit Service 8aa27d
                rc, p11_get_ckr(rc));
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
    rc = key_pair_gen_mech(kt, &mech);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Error setting the mechanism (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                p11_get_ckr(rc));
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
    rc = set_battr(attr_string, pub_attr, &pub_acount, prv_attr, &prv_acount);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Error setting binary attributes (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                p11_get_ckr(rc));
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
    rc = key_pair_gen(session, kt, &mech, pub_attr, pub_acount, prv_attr,
Packit 8681c6
            prv_acount, &pub_keyh, &prv_keyh);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit 8681c6
        printf(
Packit Service 8aa27d
                "Generating a key pair in the token in slot %ld failed (error code 0x%lX: %s)\n",
Packit Service 8aa27d
                slot, rc, p11_get_ckr(rc));
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
done:
Packit 8681c6
Packit Service 8aa27d
    return rc;
Packit 8681c6
}
Packit 8681c6
/**
Packit Service 8aa27d
 * Generate a new key.
Packit 8681c6
 */
Packit Service 8aa27d
static CK_RV generate_ckey(CK_SESSION_HANDLE session, CK_SLOT_ID slot,
Packit Service 8aa27d
                           p11sak_kt kt, CK_ULONG keylength, char *ECcurve,
Packit Service 8aa27d
                           CK_ULONG exponent, char *label, char *attr_string)
Packit Service 8aa27d
{
Packit 8681c6
    switch (kt) {
Packit 8681c6
    case kt_DES:
Packit 8681c6
    case kt_3DES:
Packit 8681c6
    case kt_AES:
Packit 8681c6
        return generate_symmetric_key(session, kt, keylength, label,
Packit 8681c6
                attr_string);
Packit 8681c6
    case kt_RSAPKCS:
Packit 8681c6
    case kt_EC:
Packit 8681c6
        return generate_asymmetric_key(session, slot, kt, keylength, exponent,
Packit 8681c6
                ECcurve, label, attr_string);
Packit 8681c6
    default:
Packit 8681c6
        printf("Error: cannot create a key of type %i (%s)\n", kt, kt2str(kt));
Packit 8681c6
        return CKR_ARGUMENTS_BAD;
Packit 8681c6
    }
Packit 8681c6
}
Packit 8681c6
/**
Packit Service 8aa27d
 * List the given key.
Packit 8681c6
 */
Packit Service 8aa27d
static CK_RV list_ckey(CK_SESSION_HANDLE session, p11sak_kt kt, int long_print)
Packit Service 8aa27d
{
Packit 8681c6
    CK_ULONG keylength, count;
Packit 8681c6
    CK_OBJECT_CLASS keyclass;
Packit 8681c6
    CK_OBJECT_HANDLE hkey;
Packit 8681c6
    char *keytype = NULL;
Packit 8681c6
    char *label = NULL;
Packit Service 8aa27d
    CK_RV rc;
Packit 8681c6
    int CELL_SIZE = 11;
Packit 8681c6
Packit Service 8aa27d
    rc = tok_key_list_init(session, kt, label);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Init token key list failed (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                p11_get_ckr(rc));
Packit Service 8aa27d
        return rc;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    if (long_print == 0) {
Packit 8681c6
        printf("\n");
Packit 8681c6
        printf(
Packit 8681c6
                " | M  R  L  S  E  D  G  V  W  U  X  A  N |    KEY TYPE | LABEL\n");
Packit 8681c6
        printf(
Packit 8681c6
                " |---------------------------------------+-------------+-------------\n");
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    while (1) {
Packit Service 8aa27d
        rc = funcs->C_FindObjects(session, &hkey, 1, &count);
Packit Service 8aa27d
        if (rc != CKR_OK) {
Packit Service 8aa27d
            printf("C_FindObjects failed (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                    p11_get_ckr(rc));
Packit Service 8aa27d
            return rc;
Packit 8681c6
        }
Packit 8681c6
        if (count == 0)
Packit 8681c6
            break;
Packit 8681c6
Packit Service 8aa27d
        rc = tok_key_get_key_type(session, hkey, &keyclass, &keytype,
Packit 8681c6
                &keylength);
Packit Service 8aa27d
        if (rc != CKR_OK) {
Packit Service 8aa27d
            printf("Invalid key type (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                    p11_get_ckr(rc));
Packit 8681c6
            continue;
Packit 8681c6
        }
Packit 8681c6
Packit Service 8aa27d
        rc = tok_key_get_label_attr(session, hkey, &label);
Packit Service 8aa27d
        if (rc != CKR_OK) {
Packit Service 8aa27d
            printf("Retrieval of label failed (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                    p11_get_ckr(rc));
Packit 8681c6
        } else if (long_print) {
Packit 8681c6
            printf("Label: %s\t\t", label);
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
        if (long_print) {
Packit 8681c6
            printf("\n      Key: ");
Packit 8681c6
            if (keylength > 0)
Packit 8681c6
                printf("%s %ld\t\t", keytype, keylength);
Packit 8681c6
            else
Packit 8681c6
                printf("%s\t\t", keytype);
Packit 8681c6
Packit 8681c6
            printf("\n      Attributes:\n");
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
        switch (keyclass) {
Packit 8681c6
        case CKO_SECRET_KEY:
Packit Service 8aa27d
            rc = sec_key_print_attributes(session, hkey, long_print);
Packit Service 8aa27d
            if (rc != CKR_OK) {
Packit 8681c6
                printf(
Packit Service 8aa27d
                        "Secret key attribute printing failed (error code 0x%lX: %s)\n",
Packit Service 8aa27d
                        rc, p11_get_ckr(rc));
Packit 8681c6
                goto done;
Packit 8681c6
            }
Packit 8681c6
            break;
Packit 8681c6
        case CKO_PRIVATE_KEY:
Packit Service 8aa27d
            rc = priv_key_print_attributes(session, hkey, long_print);
Packit Service 8aa27d
            if (rc != CKR_OK) {
Packit 8681c6
                printf(
Packit Service 8aa27d
                        "Private key attribute printing failed (error code 0x%lX: %s)\n",
Packit Service 8aa27d
                        rc, p11_get_ckr(rc));
Packit 8681c6
                goto done;
Packit 8681c6
            }
Packit 8681c6
            break;
Packit 8681c6
        case CKO_PUBLIC_KEY:
Packit Service 8aa27d
            rc = pub_key_print_attributes(session, hkey, long_print);
Packit Service 8aa27d
            if (rc != CKR_OK) {
Packit 8681c6
                printf(
Packit Service 8aa27d
                        "Public key attribute printing failed (error code 0x%lX: %s)\n",
Packit Service 8aa27d
                        rc, p11_get_ckr(rc));
Packit 8681c6
                goto done;
Packit 8681c6
            }
Packit 8681c6
            break;
Packit 8681c6
        default:
Packit Service 8aa27d
            printf("Unhandled keyclass in list_ckey!\n");
Packit 8681c6
            break;
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
        if (long_print == 0) {
Packit 8681c6
            if (keylength > 0) {
Packit 8681c6
                char tmp[16];
Packit 8681c6
                snprintf(tmp, sizeof(tmp), "%s %ld", keytype, keylength);
Packit 8681c6
                printf(" %*s | ", CELL_SIZE, tmp);
Packit 8681c6
            } else
Packit 8681c6
                printf(" %*s | ", CELL_SIZE, keytype);
Packit 8681c6
            printf("%s\n", label);
Packit 8681c6
        }
Packit Service 8aa27d
        free(label);
Packit Service 8aa27d
        free(keytype);
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
    rc = funcs->C_FindObjectsFinal(session);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("C_FindObjectsFinal failed (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                p11_get_ckr(rc));
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
    rc = CKR_OK;
Packit 8681c6
Packit Service 8aa27d
done:
Packit Service 8aa27d
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        free(label);
Packit Service 8aa27d
        free(keytype);
Packit Service 8aa27d
    }
Packit Service 8aa27d
    return rc;
Packit 8681c6
}
Packit 8681c6
Packit Service 8aa27d
static CK_BBOOL user_input_ok(char *input)
Packit Service 8aa27d
{
Packit Service 8aa27d
    if (strlen(input) != 2)
Packit Service 8aa27d
        return CK_FALSE;
Packit 8681c6
Packit Service 8aa27d
    if ((strncmp(input, "y", 1) == 0) ||
Packit Service 8aa27d
        (strncmp(input, "n", 1) == 0))
Packit Service 8aa27d
        return CK_TRUE;
Packit Service 8aa27d
    else
Packit Service 8aa27d
        return CK_FALSE;
Packit Service 8aa27d
}
Packit Service 8aa27d
Packit Service 8aa27d
static CK_RV confirm_destroy(char **user_input, char* label)
Packit Service 8aa27d
{
Packit Service 8aa27d
    int nread;
Packit Service 8aa27d
    size_t buflen;
Packit Service 8aa27d
    CK_RV rc = CKR_OK;
Packit Service 8aa27d
Packit Service 8aa27d
    printf("Are you sure you want to destroy object %s [y/n]? ", label);
Packit Service 8aa27d
    while (1){
Packit Service 8aa27d
        nread = getline(user_input, &buflen, stdin);
Packit Service 8aa27d
        if (nread == -1) {
Packit Service 8aa27d
            printf("User input failed (error code 0x%lX: %s)\n",
Packit Service 8aa27d
                    rc, p11_get_ckr(rc));
Packit Service 8aa27d
            rc = -1;
Packit Service 8aa27d
            return rc;
Packit Service 8aa27d
        }
Packit Service 8aa27d
Packit Service 8aa27d
        if (user_input_ok(*user_input)) {
Packit Service 8aa27d
            break;
Packit Service 8aa27d
        } else {
Packit Service 8aa27d
            free(*user_input);
Packit Service 8aa27d
            *user_input = NULL;
Packit Service 8aa27d
            printf("Please just enter 'y' or 'n': ");
Packit Service 8aa27d
        }
Packit Service 8aa27d
    }
Packit Service 8aa27d
Packit Service 8aa27d
    return rc;
Packit Service 8aa27d
}
Packit Service 8aa27d
Packit Service 8aa27d
Packit Service 8aa27d
static CK_RV finalize_destroy_object(char *label, CK_SESSION_HANDLE *session,
Packit Service 8aa27d
                                   CK_OBJECT_HANDLE *hkey)
Packit Service 8aa27d
{
Packit Service 8aa27d
    char *user_input = NULL;
Packit Service 8aa27d
    CK_RV rc = CKR_OK;
Packit Service 8aa27d
Packit Service 8aa27d
    rc = confirm_destroy(&user_input, label);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("User input failed (error code 0x%lX: %s)\n",
Packit Service 8aa27d
                rc, p11_get_ckr(rc));
Packit Service 8aa27d
        goto done;
Packit Service 8aa27d
    }
Packit Service 8aa27d
Packit Service 8aa27d
    if (strncmp(user_input, "y", 1) == 0) {
Packit Service 8aa27d
        printf("Destroy Object with Label: %s\n", label);
Packit Service 8aa27d
        rc = funcs->C_DestroyObject(*session, *hkey);
Packit Service 8aa27d
        if (rc != CKR_OK) {
Packit Service 8aa27d
            printf("Key with label %s could not be destroyed (error code 0x%lX: %s)\n",
Packit Service 8aa27d
                   label, rc, p11_get_ckr(rc));
Packit Service 8aa27d
            goto done;
Packit Service 8aa27d
        }
Packit Service 8aa27d
        printf("DONE - Destroy Object with Label: %s\n", label);
Packit Service 8aa27d
    } else if (strncmp(user_input, "n", 1) == 0) {
Packit Service 8aa27d
        printf("Skip deleting Key\n");
Packit Service 8aa27d
    } else {
Packit Service 8aa27d
        printf("Please just enter (y) for yes or (n) for no.\n");
Packit Service 8aa27d
    }
Packit Service 8aa27d
Packit Service 8aa27d
done:
Packit Service 8aa27d
    free(user_input);
Packit Service 8aa27d
    return rc;
Packit Service 8aa27d
}
Packit Service 8aa27d
/**
Packit Service 8aa27d
 * Delete objects
Packit Service 8aa27d
 */
Packit Service 8aa27d
static CK_RV delete_key(CK_SESSION_HANDLE session, p11sak_kt kt, char *rm_label,
Packit Service 8aa27d
                       CK_BBOOL *forceAll)
Packit Service 8aa27d
{
Packit Service 8aa27d
    CK_ULONG keylength, count;
Packit Service 8aa27d
    CK_OBJECT_CLASS keyclass;
Packit Service 8aa27d
    CK_OBJECT_HANDLE hkey;
Packit Service 8aa27d
    char *keytype = NULL;
Packit Service 8aa27d
    char *label = NULL;
Packit Service 8aa27d
    CK_RV rc = CKR_OK;
Packit Service 8aa27d
Packit Service 8aa27d
    rc = tok_key_list_init(session, kt, label);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Init token key list failed (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                p11_get_ckr(rc));
Packit Service 8aa27d
        return rc;
Packit Service 8aa27d
    }
Packit Service 8aa27d
Packit Service 8aa27d
    while (1) {
Packit Service 8aa27d
        rc = funcs->C_FindObjects(session, &hkey, 1, &count);
Packit Service 8aa27d
        if (rc != CKR_OK) {
Packit Service 8aa27d
            printf("C_FindObjects failed (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                    p11_get_ckr(rc));
Packit Service 8aa27d
            goto done;
Packit Service 8aa27d
        }
Packit Service 8aa27d
        if (count == 0)
Packit Service 8aa27d
            break;
Packit Service 8aa27d
Packit Service 8aa27d
        rc = tok_key_get_key_type(session, hkey, &keyclass, &keytype,
Packit Service 8aa27d
                &keylength);
Packit Service 8aa27d
        if (rc != CKR_OK) {
Packit Service 8aa27d
            printf("Invalid key type (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                    p11_get_ckr(rc));
Packit Service 8aa27d
            continue;
Packit Service 8aa27d
        }
Packit Service 8aa27d
Packit Service 8aa27d
        rc = tok_key_get_label_attr(session, hkey, &label);
Packit Service 8aa27d
        if (rc != CKR_OK) {
Packit Service 8aa27d
            printf("Retrieval of label failed (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                    p11_get_ckr(rc));
Packit Service 8aa27d
        }
Packit Service 8aa27d
Packit Service 8aa27d
        if (*forceAll) {
Packit Service 8aa27d
            if ((strcmp(rm_label, "") == 0) || (strcmp(rm_label, label) == 0)) {
Packit Service 8aa27d
                printf("Destroy Object with Label: %s\n", label);
Packit Service 8aa27d
                rc = funcs->C_DestroyObject(session, hkey);
Packit Service 8aa27d
                if (rc != CKR_OK) {
Packit Service 8aa27d
                    printf(
Packit Service 8aa27d
                            "Key with label %s could not be destroyed (error code 0x%lX: %s)\n",
Packit Service 8aa27d
                            label, rc, p11_get_ckr(rc));
Packit Service 8aa27d
                    goto done;
Packit Service 8aa27d
                }
Packit Service 8aa27d
                printf("DONE - Destroy Object with Label: %s\n", label);
Packit Service 8aa27d
            }
Packit Service 8aa27d
        } else {
Packit Service 8aa27d
            if ((strcmp(rm_label, "") == 0) || (strcmp(rm_label, label) == 0)) {
Packit Service 8aa27d
                rc = finalize_destroy_object(label, &session, &hkey);
Packit Service 8aa27d
                if (rc != CKR_OK) {
Packit Service 8aa27d
                    goto done;
Packit Service 8aa27d
                }
Packit Service 8aa27d
            }
Packit Service 8aa27d
        }
Packit Service 8aa27d
Packit Service 8aa27d
        free(label);
Packit Service 8aa27d
        free(keytype);
Packit Service 8aa27d
    }
Packit Service 8aa27d
Packit Service 8aa27d
    rc = funcs->C_FindObjectsFinal(session);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("C_FindObjectsFinal failed (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                p11_get_ckr(rc));
Packit Service 8aa27d
        goto done;
Packit Service 8aa27d
    }
Packit Service 8aa27d
Packit Service 8aa27d
done:
Packit Service 8aa27d
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        free(label);
Packit Service 8aa27d
        free(keytype);
Packit Service 8aa27d
    }
Packit Service 8aa27d
    return rc;
Packit Service 8aa27d
}
Packit Service 8aa27d
Packit Service 8aa27d
static CK_RV execute_cmd(CK_SESSION_HANDLE session, CK_SLOT_ID slot,
Packit Service 8aa27d
                         p11sak_cmd cmd, p11sak_kt kt, CK_ULONG keylength,
Packit Service 8aa27d
                         CK_ULONG exponent, char *ECcurve, char *label,
Packit Service 8aa27d
                         char *attr_string, int long_print, CK_BBOOL *forceAll)
Packit Service 8aa27d
{
Packit Service 8aa27d
    CK_RV rc;
Packit 8681c6
    switch (cmd) {
Packit 8681c6
    case gen_key:
Packit Service 8aa27d
        rc = generate_ckey(session, slot, kt, keylength, ECcurve, exponent,
Packit 8681c6
                label, attr_string);
Packit 8681c6
        break;
Packit 8681c6
    case list_key:
Packit Service 8aa27d
        rc = list_ckey(session, kt, long_print);
Packit Service 8aa27d
        break;
Packit Service 8aa27d
    case remove_key:
Packit Service 8aa27d
        rc = delete_key(session, kt, label, forceAll);
Packit 8681c6
        break;
Packit 8681c6
    default:
Packit 8681c6
        printf("   Unknown COMMAND %c\n", cmd);
Packit 8681c6
        print_cmd_help();
Packit Service 8aa27d
        rc = CKR_ARGUMENTS_BAD;
Packit 8681c6
        break;
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
    return rc;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
static CK_RV start_session(CK_SESSION_HANDLE *session, CK_SLOT_ID slot,
Packit Service 8aa27d
                           CK_CHAR_PTR pin, CK_ULONG pinlen)
Packit Service 8aa27d
{
Packit 8681c6
    CK_SESSION_HANDLE tmp_sess;
Packit 8681c6
    CK_TOKEN_INFO tokeninfo;
Packit 8681c6
    CK_SLOT_INFO slotinfo;
Packit Service 8aa27d
    CK_RV rc;
Packit 8681c6
Packit Service 8aa27d
    rc = funcs->C_Initialize(NULL_PTR);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Error in C_Initialize (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                p11_get_ckr(rc));
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
    rc = funcs->C_GetSlotInfo(slot, &slotinfo);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Slot %ld not available (error code 0x%lX: %s)\n", slot, rc,
Packit Service 8aa27d
                p11_get_ckr(rc));
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
    rc = funcs->C_GetTokenInfo(slot, &tokeninfo);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Token at slot %ld not available (error code 0x%lX: %s)\n", slot,
Packit Service 8aa27d
                rc, p11_get_ckr(rc));
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
    rc = funcs->C_OpenSession(slot, CKF_SERIAL_SESSION | CKF_RW_SESSION,
Packit Service 8aa27d
            NULL_PTR,
Packit 8681c6
            NULL_PTR, &tmp_sess);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Opening a session failed (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                p11_get_ckr(rc));
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
    rc = funcs->C_Login(tmp_sess, CKU_USER, pin, pinlen);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Login failed (error code 0x%lX: %s)\n", rc, p11_get_ckr(rc));
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    *session = tmp_sess;
Packit Service 8aa27d
    rc = CKR_OK;
Packit 8681c6
Packit 8681c6
    done:
Packit 8681c6
Packit Service 8aa27d
    return rc;
Packit 8681c6
}
Packit 8681c6
Packit Service 8aa27d
static CK_RV close_session(CK_SESSION_HANDLE session)
Packit Service 8aa27d
{
Packit Service 8aa27d
    CK_RV rc;
Packit 8681c6
Packit Service 8aa27d
    rc = funcs->C_Logout(session);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Logout failed (error code 0x%lX: %s)\n", rc, p11_get_ckr(rc));
Packit Service 8aa27d
        return rc;
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
    rc = funcs->C_Finalize(NULL_PTR);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Error in C_Finalize: (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                p11_get_ckr(rc));
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
    return rc;
Packit 8681c6
}
Packit 8681c6
Packit Service 8aa27d
int main(int argc, char *argv[])
Packit Service 8aa27d
{
Packit 8681c6
    int long_print = 0;
Packit 8681c6
    p11sak_kt kt = no_key_type;
Packit 8681c6
    p11sak_cmd cmd = no_cmd;
Packit 8681c6
    CK_ULONG exponent = 0;
Packit 8681c6
    CK_SLOT_ID slot = 0;
Packit 8681c6
    char *label = NULL;
Packit 8681c6
    char *ECcurve = NULL;
Packit 8681c6
    char *attr_string = NULL;
Packit 8681c6
    CK_ULONG keylength = 0;
Packit Service 8aa27d
    CK_RV rc = CKR_OK;
Packit 8681c6
    CK_SESSION_HANDLE session;
Packit 8681c6
    char *pin = NULL;
Packit 8681c6
    size_t pinlen;
Packit Service 8aa27d
    CK_BBOOL forceAll = ckb_false;
Packit 8681c6
Packit 8681c6
    /* Check if just help requested */
Packit 8681c6
    if (argc < 3) {
Packit 8681c6
        print_cmd_help();
Packit Service 8aa27d
        rc = CKR_OK;
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    /* Parse command */
Packit 8681c6
    cmd = parse_cmd(argv[1]);
Packit 8681c6
    if (cmd == no_cmd) {
Packit Service 8aa27d
        rc = CKR_ARGUMENTS_BAD;
Packit 8681c6
        print_cmd_help();
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    /* Parse command args */
Packit Service 8aa27d
    rc = parse_cmd_args(cmd, argv, argc, &kt, &keylength, &ECcurve, &slot, &pin,
Packit Service 8aa27d
            &exponent, &label, &attr_string, &long_print, &forceAll);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    /* now try to load the pkcs11 lib (will exit(99) on failure) */
Packit 8681c6
    load_pkcs11lib();
Packit 8681c6
Packit 8681c6
    /* Prompt for PIN if not already set via option */
Packit 8681c6
    if (!pin) {
Packit 8681c6
        printf("Please enter user PIN:");
Packit Service 8aa27d
        rc = get_pin(&pin, &pinlen);
Packit 8681c6
Packit 8681c6
        if (strlen(pin) == 0) {
Packit 8681c6
            char *s = getenv("PKCS11_USER_PIN");
Packit 8681c6
            if (s) {
Packit 8681c6
                strcpy((char*) pin, s);
Packit 8681c6
            } else {
Packit 8681c6
                goto done;
Packit 8681c6
            }
Packit 8681c6
        }
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    /* Open PKCS#11 session */
Packit Service 8aa27d
    rc = start_session(&session, slot, (CK_CHAR_PTR) pin, strlen(pin));
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Failed to open session (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                p11_get_ckr(rc));
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    /* Execute command */
Packit Service 8aa27d
    rc = execute_cmd(session, slot, cmd, kt, keylength, exponent, ECcurve,
Packit Service 8aa27d
            label, attr_string, long_print, &forceAll);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Failed to execute p11sak command (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                p11_get_ckr(rc));
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    /* Close PKCS#11 session */
Packit Service 8aa27d
    rc = close_session(session);
Packit Service 8aa27d
    if (rc != CKR_OK) {
Packit Service 8aa27d
        printf("Failed to close session (error code 0x%lX: %s)\n", rc,
Packit Service 8aa27d
                p11_get_ckr(rc));
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
    rc = CKR_OK;
Packit 8681c6
Packit 8681c6
    done:
Packit 8681c6
Packit Service 8aa27d
    return rc;
Packit 8681c6
}