|
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 |
}
|