Blame testcases/pkcs11/generate_keypair.c

Packit 8681c6
/*
Packit 8681c6
 * COPYRIGHT (c) International Business Machines Corp. 2015-2017
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
#include <stdio.h>
Packit 8681c6
#include <stdlib.h>
Packit 8681c6
#include <unistd.h>
Packit 8681c6
#include <string.h>
Packit 8681c6
#include <memory.h>
Packit 8681c6
Packit 8681c6
#include "pkcs11types.h"
Packit 8681c6
#include "regress.h"
Packit 8681c6
#include "common.c"
Packit 8681c6
Packit 8681c6
/* API Routines exercised:
Packit 8681c6
 * C_GenerateKeyPair
Packit 8681c6
 */
Packit 8681c6
CK_RV do_GenerateKeyPairRSA(void)
Packit 8681c6
{
Packit 8681c6
    CK_FLAGS flags;
Packit 8681c6
    CK_SESSION_HANDLE session;
Packit 8681c6
    CK_RV rc = 0;
Packit 8681c6
    CK_BYTE user_pin[PKCS11_MAX_PIN_LEN];
Packit 8681c6
    CK_ULONG user_pin_len;
Packit 8681c6
Packit 8681c6
    CK_OBJECT_HANDLE priv_key = CK_INVALID_HANDLE;
Packit 8681c6
    CK_OBJECT_HANDLE publ_key = CK_INVALID_HANDLE;
Packit 8681c6
    CK_MECHANISM mech;
Packit 8681c6
Packit 8681c6
    CK_KEY_TYPE keytype = CKK_RSA;
Packit 8681c6
    CK_ULONG modbits = 2048;
Packit 8681c6
    unsigned int modbytes = modbits / 8;
Packit 8681c6
    CK_BYTE pubExp[3] = { 0x01, 0x00, 0x01 };
Packit 8681c6
    CK_ATTRIBUTE publ_tmpl[] = {
Packit 8681c6
        {CKA_KEY_TYPE, &keytype, sizeof(keytype)},
Packit 8681c6
        {CKA_MODULUS_BITS, &modbits, sizeof(modbits)},
Packit 8681c6
        {CKA_PUBLIC_EXPONENT, pubExp, sizeof(pubExp)}
Packit 8681c6
    };
Packit 8681c6
Packit 8681c6
    CK_OBJECT_CLASS class;
Packit 8681c6
    CK_BYTE publicExponent[4];
Packit 8681c6
    CK_BYTE modulus[512];
Packit 8681c6
    CK_BYTE subject[20], id[20];;
Packit 8681c6
    CK_BYTE start_date[20], end_date[20];
Packit 8681c6
    CK_BBOOL encrypt, decrypt, sign, sign_recover, verify, verify_recover;
Packit 8681c6
    CK_BBOOL wrap, unwrap, derive, local, extractable, never;
Packit 8681c6
    CK_BBOOL sensitive, always;
Packit 8681c6
Packit 8681c6
    CK_ATTRIBUTE publ_def[] = {
Packit 8681c6
        {CKA_KEY_TYPE, &keytype, sizeof(keytype)},
Packit 8681c6
        {CKA_CLASS, &class, sizeof(class)},
Packit 8681c6
        {CKA_PUBLIC_EXPONENT, publicExponent, sizeof(publicExponent)},
Packit 8681c6
        {CKA_MODULUS, modulus, sizeof(modulus)},
Packit 8681c6
        {CKA_SUBJECT, subject, sizeof(subject)},
Packit 8681c6
        {CKA_ENCRYPT, &encrypt, sizeof(encrypt)},
Packit 8681c6
        {CKA_VERIFY, &verify, sizeof(verify)},
Packit 8681c6
        {CKA_VERIFY_RECOVER, &verify_recover, sizeof(verify_recover)},
Packit 8681c6
        {CKA_WRAP, &wrap, sizeof(wrap)},
Packit 8681c6
        {CKA_ID, &id, sizeof(id)},
Packit 8681c6
        {CKA_START_DATE, &start_date, sizeof(start_date)},
Packit 8681c6
        {CKA_END_DATE, &end_date, sizeof(end_date)},
Packit 8681c6
        {CKA_DERIVE, &derive, sizeof(derive)},
Packit 8681c6
        {CKA_LOCAL, &local, sizeof(local)}
Packit 8681c6
    };
Packit 8681c6
Packit 8681c6
    /* According to pkcs#11v2.20, Section 12.1.4, the implementation
Packit 8681c6
     * MAY contribute some of the CRT attributes. So, dont look for these.
Packit 8681c6
     * Only check for the common defaults for the private key.
Packit 8681c6
     */
Packit 8681c6
    CK_ATTRIBUTE priv_def[] = {
Packit 8681c6
        {CKA_KEY_TYPE, &keytype, sizeof(keytype)},
Packit 8681c6
        {CKA_CLASS, &class, sizeof(class)},
Packit 8681c6
        {CKA_SUBJECT, subject, sizeof(subject)},
Packit 8681c6
        {CKA_SENSITIVE, &sensitive, sizeof(sensitive)},
Packit 8681c6
        {CKA_DECRYPT, &decrypt, sizeof(decrypt)},
Packit 8681c6
        {CKA_SIGN, &sign, sizeof(sign)},
Packit 8681c6
        {CKA_SIGN_RECOVER, &sign_recover, sizeof(sign_recover)},
Packit 8681c6
        {CKA_UNWRAP, &unwrap, sizeof(unwrap)},
Packit 8681c6
        {CKA_EXTRACTABLE, &extractable, sizeof(extractable)},
Packit 8681c6
        {CKA_ALWAYS_SENSITIVE, &always, sizeof(always)},
Packit 8681c6
        {CKA_NEVER_EXTRACTABLE, &never, sizeof(never)},
Packit 8681c6
        {CKA_ID, &id, sizeof(id)},
Packit 8681c6
        {CKA_START_DATE, start_date, sizeof(start_date)},
Packit 8681c6
        {CKA_END_DATE, end_date, sizeof(end_date)},
Packit 8681c6
        {CKA_DERIVE, &derive, sizeof(derive)},
Packit 8681c6
        {CKA_LOCAL, &local, sizeof(local)}
Packit 8681c6
    };
Packit 8681c6
Packit 8681c6
    /* Do some setup and login to the token */
Packit 8681c6
    testcase_begin("starting...");
Packit 8681c6
    testcase_rw_session();
Packit 8681c6
    testcase_user_login();
Packit 8681c6
Packit 8681c6
    mech.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
Packit 8681c6
    mech.ulParameterLen = 0;
Packit 8681c6
    mech.pParameter = NULL;
Packit 8681c6
Packit 8681c6
    /* Assertion #1: generate an RSA key pair. */
Packit 8681c6
    testcase_new_assertion();
Packit 8681c6
Packit 8681c6
    rc = funcs->C_GenerateKeyPair(session, &mech, publ_tmpl, 3, NULL,
Packit 8681c6
                                  0, &publ_key, &priv_key);
Packit 8681c6
    if (rc != CKR_OK) {
Packit 8681c6
        testcase_fail("C_GenerateKeyPair() rc = %s", p11_get_ckr(rc));
Packit 8681c6
        goto testcase_cleanup;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    testcase_pass("C_GenerateKeypair was successful\n");
Packit 8681c6
Packit 8681c6
    /* Assertion #2: Ensure public key contains the default attributes
Packit 8681c6
     * and those the implementation should have contributed for RSA PKCS#1
Packit 8681c6
     * key pairs. (Section 12.1.4 of pkcs#11v2.20)
Packit 8681c6
     */
Packit 8681c6
    testcase_new_assertion();
Packit 8681c6
Packit 8681c6
    rc = funcs->C_GetAttributeValue(session, publ_key, publ_def, 14);
Packit 8681c6
    if (rc == CKR_ATTRIBUTE_TYPE_INVALID) {
Packit 8681c6
        testcase_fail("Some of the default attributes were missing.\n");
Packit 8681c6
        goto testcase_cleanup;
Packit 8681c6
    }
Packit 8681c6
    if (rc != CKR_OK) {
Packit 8681c6
        testcase_error("C_GetAttributeValue: rc = %s", p11_get_ckr(rc));
Packit 8681c6
        goto testcase_cleanup;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    if (*(CK_ULONG *) publ_def[0].pValue != CKK_RSA) {
Packit 8681c6
        testcase_fail("Public RSA key was not generated correctly"
Packit 8681c6
                      " (wrong CKA_KEY_TYPE).\n");
Packit 8681c6
    }
Packit 8681c6
    if (*(CK_ULONG *) publ_def[1].pValue != CKO_PUBLIC_KEY) {
Packit 8681c6
        testcase_fail("Public RSA key was not generated correctly"
Packit 8681c6
                      " (wrong CKA_CLASS).\n");
Packit 8681c6
    }
Packit 8681c6
    if (publ_def[2].ulValueLen != sizeof(pubExp)) {
Packit 8681c6
        /* some tokens add an leading 0x00 to the exponent value */
Packit 8681c6
        unsigned char *pv = (unsigned char *) publ_def[2].pValue;
Packit 8681c6
        if (publ_def[2].ulValueLen == sizeof(pubExp) + 1
Packit 8681c6
            && pv[0] == 0x00 && memcmp(pv + 1, pubExp, sizeof(pubExp)) == 0) {
Packit 8681c6
            /* len is just +1, first byte is 0, rest matches to pubExp */
Packit 8681c6
        } else {
Packit 8681c6
            testcase_fail("Public RSA key was not generated correctly"
Packit 8681c6
                          " (pub exp mismatch).\n");
Packit 8681c6
        }
Packit 8681c6
    } else {
Packit 8681c6
        /* same length, check value */
Packit 8681c6
        if (memcmp(publ_def[2].pValue, pubExp, sizeof(pubExp)) != 0) {
Packit 8681c6
            testcase_fail("Public RSA key was not generated correctly"
Packit 8681c6
                          " (pub exp mismatch).\n");
Packit 8681c6
        }
Packit 8681c6
    }
Packit 8681c6
    if (publ_def[3].ulValueLen != modbytes) {
Packit 8681c6
        /* some tokens add an leading 0x00 to the modulus value */
Packit 8681c6
        unsigned char *pv = (unsigned char *) publ_def[3].pValue;
Packit 8681c6
        if (publ_def[3].ulValueLen == modbytes + 1 && pv[0] == 0x00) {
Packit 8681c6
            /* len is just +1, first byte is 0, all fine */
Packit 8681c6
        } else {
Packit 8681c6
            testcase_fail("Public RSA key was not generated correctly"
Packit 8681c6
                          " (modulus length mismatch).\n");
Packit 8681c6
        }
Packit 8681c6
    }
Packit 8681c6
    testcase_pass("Public RSA key generated correctly.\n");
Packit 8681c6
Packit 8681c6
    testcase_new_assertion();
Packit 8681c6
Packit 8681c6
    rc = funcs->C_GetAttributeValue(session, priv_key, priv_def, 16);
Packit 8681c6
    if (rc != CKR_OK) {
Packit 8681c6
        testcase_error("C_GetAttributeValue: rc = %s", p11_get_ckr(rc));
Packit 8681c6
        goto testcase_cleanup;
Packit 8681c6
    }
Packit 8681c6
    if (rc == CKR_ATTRIBUTE_TYPE_INVALID) {
Packit 8681c6
        testcase_fail("Some of the default attributes were missing.\n");
Packit 8681c6
        goto testcase_cleanup;
Packit 8681c6
    }
Packit 8681c6
    if (rc != CKR_OK) {
Packit 8681c6
        testcase_error("C_GetAttributeValue: rc = %s", p11_get_ckr(rc));
Packit 8681c6
        goto testcase_cleanup;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    /* Assertion #3: Ensure private key contains the default attributes
Packit 8681c6
     * and those the implementation should have contributed for RSA PKCS#1
Packit 8681c6
     * key pairs. (Section 12.1.4 of pkcs#11v2.20)
Packit 8681c6
     */
Packit 8681c6
    if (*(CK_ULONG *) priv_def[0].pValue != CKK_RSA) {
Packit 8681c6
        testcase_fail("Private RSA key was not generated correctly"
Packit 8681c6
                      " (wrong CKA_KEY_TYPE).\n");
Packit 8681c6
    }
Packit 8681c6
    if (*(CK_ULONG *) priv_def[1].pValue != CKO_PRIVATE_KEY) {
Packit 8681c6
        testcase_fail("Private RSA key was not generated correctly"
Packit 8681c6
                      " (wrong CKA_CLASS).\n");
Packit 8681c6
    }
Packit 8681c6
    testcase_pass("Private RSA key generated correctly.\n");
Packit 8681c6
Packit 8681c6
testcase_cleanup:
Packit 8681c6
    funcs->C_DestroyObject(session, priv_key);
Packit 8681c6
    funcs->C_DestroyObject(session, publ_key);
Packit 8681c6
Packit 8681c6
    testcase_user_logout();
Packit 8681c6
    rc = funcs->C_CloseSession(session);
Packit 8681c6
    if (rc != CKR_OK) {
Packit 8681c6
        testcase_error("C_CloseSessions rc=%s", p11_get_ckr(rc));
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    return rc;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
int main(int argc, char **argv)
Packit 8681c6
{
Packit 8681c6
    int rc;
Packit 8681c6
    CK_C_INITIALIZE_ARGS cinit_args;
Packit 8681c6
    CK_RV rv = 0;
Packit 8681c6
Packit 8681c6
    rc = do_ParseArgs(argc, argv);
Packit 8681c6
    if (rc != 1)
Packit 8681c6
        return rc;
Packit 8681c6
Packit 8681c6
    printf("Using slot #%lu...\n\n", SLOT_ID);
Packit 8681c6
    printf("With option: nostop: %d\n", no_stop);
Packit 8681c6
Packit 8681c6
    rc = do_GetFunctionList();
Packit 8681c6
    if (!rc) {
Packit 8681c6
        testcase_error("do_getFunctionList(), rc=%s", p11_get_ckr(rc));
Packit 8681c6
        return rc;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    memset(&cinit_args, 0x0, sizeof(cinit_args));
Packit 8681c6
    cinit_args.flags = CKF_OS_LOCKING_OK;
Packit 8681c6
Packit 8681c6
    funcs->C_Initialize(&cinit_args);
Packit 8681c6
Packit 8681c6
    {
Packit 8681c6
        CK_SESSION_HANDLE hsess = 0;
Packit 8681c6
Packit 8681c6
        rc = funcs->C_GetFunctionStatus(hsess);
Packit 8681c6
        if (rc != CKR_FUNCTION_NOT_PARALLEL)
Packit 8681c6
            return rc;
Packit 8681c6
Packit 8681c6
        rc = funcs->C_CancelFunction(hsess);
Packit 8681c6
        if (rc != CKR_FUNCTION_NOT_PARALLEL)
Packit 8681c6
            return rc;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    testcase_setup(0);
Packit 8681c6
    rc = do_GenerateKeyPairRSA();
Packit 8681c6
    testcase_print_result();
Packit 8681c6
Packit 8681c6
    /* make sure we return non-zero if rv is non-zero */
Packit 8681c6
    return ((rv == 0) || (rv % 256) ? (int)rv : -1);
Packit 8681c6
}