Ejemplo n.º 1
0
/* API Routines exercised that take /var/lock/LCK..opencryptoki spinlock.
 * C_OpenSession
 * C_CloseSession
 *
 * API routines exercised that result in stdll taking
 * /var/lock/opencryptoki_stdll spinlock.
 *    C_CreateObject
 *    C_GetAttributeValue
 *    C_SetAttributeValue
 *
 * 1) create a certificate object with no CKA_SERIAL_NUMBER or CKA_ISSUER
 * 2) add CKA_SERIAL_NUMBER and CKA_ISSUER and modify CKA_ID.
 *    verify this works.
 * 3) try to modify CKA_VALUE and CKA_ID in a single call to
 *    C_SetAttributeValue.  verify that this fails correctly and that
 *    the object is not modified.
 */
CK_RV do_SetAttributeValues(void)
{
	CK_SLOT_ID        slot_id;
	CK_FLAGS          flags;
	CK_SESSION_HANDLE h_session;
	CK_RV             rc = 0, loc_rc = 0;
	CK_BYTE           user_pin[PKCS11_MAX_PIN_LEN];
	CK_ULONG          user_pin_len;

	CK_BYTE           true = TRUE;

	CK_OBJECT_HANDLE    h_cert;
	CK_OBJECT_CLASS     cert_class         = CKO_CERTIFICATE;
	CK_CERTIFICATE_TYPE cert_type          = CKC_X_509;
	CK_BYTE             cert_subject[]     = "Certificate subject";
	CK_BYTE             cert_id[]          = "Certificate ID";
	CK_BYTE             cert_value[]       = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz";

	CK_ATTRIBUTE        cert_attribs[] =
	{
		{CKA_CLASS,            &cert_class,       sizeof(cert_class)   },
		{CKA_TOKEN,            &true,             sizeof(true)         },
		{CKA_CERTIFICATE_TYPE, &cert_type,        sizeof(cert_type)    },
		{CKA_SUBJECT,          &cert_subject,     sizeof(cert_subject) },
		{CKA_ID,               &cert_id,          sizeof(cert_id)      },
		{CKA_VALUE,            &cert_value,       sizeof(cert_value)   }
	};

	CK_BYTE       cert_id2[]    = "New ID";
	CK_BYTE       cert_issuer[] = "Certificate Issuer";
	CK_BYTE       cert_ser_no[] = "Serial Number: 12345";
	CK_ATTRIBUTE  update_attr[] =
	{
		{CKA_SERIAL_NUMBER, &cert_ser_no,  sizeof(cert_ser_no) },
		{CKA_ISSUER,        &cert_issuer,  sizeof(cert_issuer) },
		{CKA_ID,            &cert_id2,     sizeof(cert_id2)    }
	};

	CK_BYTE       cert_value2[] = "Invalid Value";
	CK_BYTE       cert_id3[]    = "ID #3";
	CK_ATTRIBUTE  invalid_attr[] =
	{
		{CKA_VALUE, &cert_value2,  sizeof(cert_value2) },
		{CKA_ID,    &cert_id3,     sizeof(cert_id3)    }
	};

	testcase_begin("starting...");

	if (get_user_pin(user_pin))
		return CKR_FUNCTION_FAILED;
	user_pin_len = (CK_ULONG)strlen((char *)user_pin);

	slot_id = SLOT_ID;


	/*  create a USER R/W session */
	flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
	rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &h_session);
	if (rc != CKR_OK) {
                testcase_fail("C_OpenSession() rc = %s", p11_get_ckr(rc));
		return rc;
	}

	rc = funcs->C_Login(h_session, CKU_USER, user_pin, user_pin_len);
	if (rc != CKR_OK) {
                testcase_fail("C_Login() rc = %s", p11_get_ckr(rc));
		return rc;
	}


	/* create the object */
	rc = funcs->C_CreateObject(h_session, cert_attribs, 6, &h_cert);
	if (rc != CKR_OK) {
                testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc));
		return rc;
	}

	/* Add CKA_SERIAL_NUMBER and CKA_ISSUER and change the
	 *  existing CKA_ID
	 */
	rc = funcs->C_SetAttributeValue(h_session, h_cert, update_attr, 3);
	if (rc != CKR_OK) {
                testcase_fail("C_SetAttributeValue() rc = %s", p11_get_ckr(rc));
		goto done;
	}
	else {
		CK_BYTE       buf1[100];
		CK_BYTE       buf2[100];
		CK_BYTE       buf3[100];
		CK_ATTRIBUTE  check1[] =
		{
			{CKA_ISSUER,        &buf1, sizeof(buf1)},
			{CKA_SERIAL_NUMBER, &buf2, sizeof(buf2)},
			{CKA_ID,            &buf3, sizeof(buf3)}
		};

		rc = funcs->C_GetAttributeValue(h_session, h_cert, (CK_ATTRIBUTE *)&check1, 3);
		if (rc != CKR_OK) {
                        testcase_fail("C_GetAttributeValue() rc = %s", p11_get_ckr(rc));
			goto done;
		}

		if (memcmp(check1[0].pValue, cert_issuer, check1[0].ulValueLen) != 0) {
                        testcase_fail("CKA_ISSUER mismatch");
			rc = -1;
			goto done;
		}

		if (memcmp(check1[1].pValue, cert_ser_no, check1[1].ulValueLen) != 0) {
                        testcase_fail("CKA_SERIAL_NUMBER mismatch");
			return -1;
		}

		if (memcmp(check1[2].pValue, cert_id2, check1[2].ulValueLen) != 0) {
                        testcase_fail("CKA_ID mismatch");
			rc = -1;
			goto done;
		}
	}

	/* the next template tries to update a CK_ID (valid) and
	 * CKA_VALUE (read-only). the entire operation should fail -- no
	 * attributes should get modified
	 */
	rc = funcs->C_SetAttributeValue(h_session, h_cert, invalid_attr, 2);
	if (rc != CKR_ATTRIBUTE_READ_ONLY) {
                testcase_fail("C_SetAttributeValue() rc = %s (expected CKR_ATTRIBUTE_READ_ONLY)", p11_get_ckr(rc));
		goto done;
	}
	else {
		CK_BYTE       buf1[100];
		CK_ATTRIBUTE  check1[] =
		{
			{CKA_ID, &buf1, sizeof(buf1)}
		};

		rc = funcs->C_GetAttributeValue(h_session, h_cert, check1, 1);
		if (rc != CKR_OK) {
                        testcase_fail("C_GetAttributeValue() rc = %s", p11_get_ckr(rc));
			goto done;
		}

		if (memcmp(check1[0].pValue, cert_id2, check1[0].ulValueLen) != 0) {
                        testcase_fail("CKA_ID mismatch");
			rc = -1;
			goto done;
		}
	}

	testcase_pass("Looks okay...");

done:
	/* now destroy the objects but don't clobber rc */
	loc_rc = funcs->C_DestroyObject(h_session, h_cert);
	if (loc_rc != CKR_OK)
                testcase_error("C_DestroyObject() loc_rc = %s", p11_get_ckr(loc_rc));


	/* done...close the session */
	loc_rc = funcs->C_CloseAllSessions(slot_id);
	if (loc_rc != CKR_OK)
                testcase_error("C_CloseAllSessions() loc_rc = %s", p11_get_ckr(loc_rc));

	return rc;
}
Ejemplo n.º 2
0
/* API Routines exercised that take /var/lock/LCK..opencryptoki spinlock.
 * C_OpenSession
 * C_CloseSession
 *
 * API routines exercised that result in stdll taking
 * /var/lock/opencryptoki_stdll spinlock.
 *    C_CreateObject
 *    C_CopyObject
 *    C_DestroyObject
 *    C_GetAttributeValue
 *    C_GetObjectSize
 *
 * 1) create a data object with no CKA_APPLICATION attribute
 * 2) create a copy of the object specifying the CKA_APPLICATION attribute
 * 3) extract the CK_VALUE attribute from the copy. Ensure matches the original
 * 4) extract the CKA_APPLICATION attribute from the original. ensure empty.
 * 5) extract the CKA_APPLICATION attribute from the copy. ensure is correct.
 * 6) attempt to extract CK_PRIME from the original. ensure fails correctly.
 * 7) attempt to extract CK_PRIME from a non-existant object. ensure fails
 *    correctly.
 * 8) get the size of the original object and copied objects
 * 9) destroy the original object.  ensure this succeeds.
 * A) destroy a non-existant object.  ensure this fails correctly.
 * B) get the size of the original object.  ensure this fails correctly.
 */
CK_RV do_CopyObject(void)
{
	CK_SLOT_ID        slot_id;
	CK_FLAGS          flags;
	CK_SESSION_HANDLE h_session;
	CK_RV             rc = 0, loc_rc = 0;
	CK_BYTE           user_pin[PKCS11_MAX_PIN_LEN];
	CK_ULONG          user_pin_len;
	CK_ULONG          obj_size;

	CK_BYTE           true = TRUE;

	CK_OBJECT_HANDLE  h_data;
	CK_OBJECT_CLASS   data_class         = CKO_DATA;
	CK_BYTE           data_application[] = "Test Application";
	CK_BYTE           data_value[]       = "1234567890abcedfghijklmnopqrstuvwxyz";
	CK_ATTRIBUTE      data_attribs[] =
	{
		{CKA_CLASS,       &data_class,       sizeof(data_class)       },
		{CKA_TOKEN,       &true,             sizeof(true)             },
		{CKA_VALUE,       &data_value,       sizeof(data_value)       }
	};

	CK_OBJECT_HANDLE  h_copy;
	CK_ATTRIBUTE      copy_attribs[] =
	{
		{CKA_APPLICATION, &data_application, sizeof(data_application) }
	};

	CK_BYTE           buf1[100];
	CK_ATTRIBUTE      verify_attribs[] =
	{
		{CKA_APPLICATION, &buf1, sizeof(buf1) }
	};

	CK_BYTE           buf2[100];
	CK_ATTRIBUTE      prime_attribs[] =
	{
		{CKA_PRIME, &buf2, sizeof(buf2) }
	};

	testcase_begin("starting...");

	if (get_user_pin(user_pin))
		return CKR_FUNCTION_FAILED;
	user_pin_len = (CK_ULONG)strlen((char *)user_pin);

	slot_id = SLOT_ID;


	/* create a USER R/W session */
	flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
	rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &h_session);
	if (rc != CKR_OK) {
		testcase_fail("C_OpenSession() rc = %s", p11_get_ckr(rc));
		return rc;
	}

	rc = funcs->C_Login(h_session, CKU_USER, user_pin, user_pin_len);
	if (rc != CKR_OK) {
		testcase_fail("C_Login() rc = %s", p11_get_ckr(rc));
		return rc;
	}


	/* create the object */
	rc = funcs->C_CreateObject(h_session, data_attribs, 3, &h_data);
	if (rc != CKR_OK) {
		testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc));
		return rc;
	}

	/* create the copy */
	rc = funcs->C_CopyObject(h_session, h_data, copy_attribs, 1, &h_copy);
	if (rc != CKR_OK) {
                testcase_fail("C_CopyObject() rc = %s", p11_get_ckr(rc));
		goto destroy_1;
	}

	/* now, try to extract the CKA_APPLICATION attribute from the original
	 * this will pull in the token's default value for CKA_APPLICATION which
	 */
	verify_attribs[0].ulValueLen = sizeof(buf1);
	rc = funcs->C_GetAttributeValue(h_session, h_data, verify_attribs, 1);
	if (rc != CKR_OK) {
		testcase_fail("C_GetAttributeValue() rc=%s", p11_get_ckr(rc));
		goto destroy;
	}

	/* now, try to extract the CKA_APPLICATION attribute from the copy */
	verify_attribs[0].ulValueLen = sizeof(buf1);
	rc = funcs->C_GetAttributeValue(h_session, h_copy, verify_attribs, 1);
	if (rc != CKR_OK) {
		testcase_fail("C_GetAttributeValue() rc=%s", p11_get_ckr(rc));
		goto destroy;
	}

	if (memcmp(&data_application, verify_attribs[0].pValue, sizeof(data_application)) != 0) {
		testcase_fail("extracted attribute doesn't match");
		rc = -1;
		goto destroy;
	}

	/* now, try to extract CKA_PRIME from the original.
	 * this should not exist
	 */
	prime_attribs[0].ulValueLen = sizeof(buf2);
	rc = funcs->C_GetAttributeValue(h_session, h_data, prime_attribs, 1);
	if (rc != CKR_ATTRIBUTE_TYPE_INVALID) {
                testcase_fail("C_GetAttributeValue() rc = %s (expected CKR_ATTRIBUTE_TYPE_INVALID)", p11_get_ckr(rc));
		goto destroy;
	}

	/* now, try to extract CKA_PRIME from a bogus object handle.
	 * this should not exist
	 */
	rc = funcs->C_GetAttributeValue(h_session, 98765, prime_attribs, 1);
	if (rc != CKR_OBJECT_HANDLE_INVALID) {
                testcase_fail("C_GetAttributeValue() rc = %s (expected CKR_OBJECT_HANDLE_INVALID)", p11_get_ckr(rc));
		goto destroy;
	}

	/* now, get the size of the original object */
	rc = funcs->C_GetObjectSize(h_session, h_data, &obj_size);
	if (rc != CKR_OK) {
                testcase_fail("C_GetObjectSize() rc = %s", p11_get_ckr(rc));
		goto destroy;
	}

	testcase_pass("Looks okay...");

destroy:
	/* now, destroy the original object and the copy */
	loc_rc = funcs->C_DestroyObject(h_session, h_copy);
	if (loc_rc != CKR_OK)
                testcase_error("C_DestroyObject() loc_rc = %s", p11_get_ckr(loc_rc));

destroy_1:
	loc_rc = funcs->C_DestroyObject(h_session, h_data);
	if (loc_rc != CKR_OK)
                testcase_error("C_DestroyObject() loc_rc = %s", p11_get_ckr(loc_rc));

	loc_rc = funcs->C_CloseAllSessions(slot_id);
	if (loc_rc != CKR_OK)
                testcase_error("C_CloseAllSessions() loc_rc=%s", p11_get_ckr(loc_rc));

	return rc;
}
Ejemplo n.º 3
0
/* API Routines exercised that take /var/lock/LCK..opencryptoki spinlock.
 * C_OpenSession
 * C_CloseSession
 *
 * API Routines exercised that cause stdll to take /var/lock/opencryptoki_stdll
 * spinlock.
 * C_CreateObject
 * C_Login
 *
 * 1) create a data object
 * 2) create a certificate
 * 3) create a key object
 */
CK_RV do_CreateSessionObject(void)
{
	CK_SLOT_ID        slot_id;
	CK_FLAGS          flags;
	CK_SESSION_HANDLE h_session;
	CK_RV             rc = 0;
	CK_BYTE           user_pin[PKCS11_MAX_PIN_LEN];
	CK_ULONG          user_pin_len;

	CK_BYTE           true  = TRUE;
	CK_BYTE           false = FALSE;

	CK_OBJECT_HANDLE  h_data;
	CK_OBJECT_CLASS   data_class         = CKO_DATA;
	CK_BYTE           data_application[] = "Test Application";
	CK_BYTE           data_value[]       = "1234567890abcedfghijklmnopqrstuvwxyz";
	CK_ATTRIBUTE      data_attribs[] =
	{
		{CKA_CLASS,       &data_class,       sizeof(data_class)       },
		{CKA_TOKEN,       &false,            sizeof(false)            },
		{CKA_APPLICATION, &data_application, sizeof(data_application) },
		{CKA_VALUE,       &data_value,       sizeof(data_value)       }
	};

	CK_OBJECT_HANDLE    h_cert;
	CK_OBJECT_CLASS     cert_class         = CKO_CERTIFICATE;
	CK_CERTIFICATE_TYPE cert_type          = CKC_X_509;
	CK_BYTE             cert_subject[]     = "Certificate subject";
	CK_BYTE             cert_id[]          = "Certificate ID";
	CK_BYTE             cert_value[]       = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz";
	CK_ATTRIBUTE        cert_attribs[] =
	{
		{CKA_CLASS,            &cert_class,       sizeof(cert_class)   },
		{CKA_TOKEN,            &false,            sizeof(false)        },
		{CKA_CERTIFICATE_TYPE, &cert_type,        sizeof(cert_type)    },
		{CKA_SUBJECT,          &cert_subject,     sizeof(cert_subject) },
		{CKA_ID,               &cert_id,          sizeof(cert_id)      },
		{CKA_VALUE,            &cert_value,       sizeof(cert_value)   }
	};

	CK_OBJECT_HANDLE  h_key;
	CK_OBJECT_CLASS   key_class          = CKO_PUBLIC_KEY;
	CK_KEY_TYPE       key_type           = CKK_RSA;
	CK_BYTE           key_modulus[]      = "1234567890987654321";
	CK_BYTE           key_exponent[]     = "123";
	CK_ATTRIBUTE      key_attribs[] =
	{
		{CKA_CLASS,           &key_class,    sizeof(key_class)    },
		{CKA_KEY_TYPE,        &key_type,     sizeof(key_type)     },
		{CKA_WRAP,            &true,         sizeof(true)         },
		{CKA_MODULUS,         &key_modulus,  sizeof(key_modulus)  },
		{CKA_PUBLIC_EXPONENT, &key_exponent, sizeof(key_exponent) }
	};

	testcase_begin("starting...");

	if (get_user_pin(user_pin))
		return CKR_FUNCTION_FAILED;
	user_pin_len = (CK_ULONG)strlen((char *)user_pin);

	slot_id = SLOT_ID;


	// create a USER R/W session
	//
	flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
	rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &h_session);
	if (rc != CKR_OK) {
		testcase_fail("C_OpenSession() rc = %s", p11_get_ckr(rc));
		return rc;
	}

	rc = funcs->C_Login(h_session, CKU_USER, user_pin, user_pin_len);
	if (rc != CKR_OK) {
		testcase_fail("C_Login() rc = %s", p11_get_ckr(rc));
		return rc;
	}

	//
	// now, create the objects
	//

	rc = funcs->C_CreateObject(h_session, data_attribs, 4, &h_data);
	if (rc != CKR_OK) {
		testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc));
		return rc;
	}

	rc = funcs->C_CreateObject(h_session, cert_attribs, 6, &h_cert);
	if (rc != CKR_OK) {
		testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc));
		return rc;
	}

	rc = funcs->C_CreateObject(h_session, key_attribs, 5, &h_key);
	if (rc != CKR_OK) {
		testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc));
		return rc;
	}

	// done...close the session and verify the object is deleted
	//
	rc = funcs->C_CloseAllSessions(slot_id);
	if (rc != CKR_OK) {
		testcase_fail("C_CloseAllSessions() rc=%s", p11_get_ckr(rc));
		return rc;
	}

	testcase_pass("looks okay...");
	return rc;
}
Ejemplo n.º 4
0
/* This function should test:
 * C_Sign, mechanism chosen by caller
 *
 * 1. Get message from test vector
 * 2. Get expected signature from test vector
 * 3. Sign message
 * 4. Compare expected signature with actual signature
 *
 */
CK_RV do_SignRSA(struct PUBLISHED_TEST_SUITE_INFO *tsuite)
{
	int 			i;
	CK_BYTE			message[MAX_MESSAGE_SIZE];
	CK_BYTE			actual[MAX_SIGNATURE_SIZE];
	CK_BYTE			expected[MAX_SIGNATURE_SIZE];
	CK_ULONG		message_len, actual_len, expected_len;

	CK_MECHANISM		mech;
	CK_OBJECT_HANDLE	priv_key;

	CK_SLOT_ID		slot_id = SLOT_ID;
	CK_SESSION_HANDLE	session;
	CK_FLAGS		flags;
	CK_BYTE			user_pin[PKCS11_MAX_PIN_LEN];
	CK_ULONG		user_pin_len;
	CK_RV			rc, loc_rc;

	// begin testsuite
	testsuite_begin("%s Sign. ", tsuite->name);
	testcase_rw_session();
	testcase_user_login();

	// skip tests if the slot doesn't support this mechanism **/
        if (! mech_supported(slot_id, tsuite->mech.mechanism)){
                testsuite_skip(tsuite->tvcount,
                           "Slot %u doesn't support %u",
                           (unsigned int) slot_id,
                           (unsigned int) tsuite->mech.mechanism );
                goto testcase_cleanup;
        }

	// iterate over test vectors
	for (i = 0; i < tsuite->tvcount; i++){
		testcase_begin("%s Sign with test vector %d.",
				tsuite->name, i);

		rc = CKR_OK; // set return value

		// special case for ica
		// prime1, prime2, exp1, exp2, coef
		// must be size mod_len/2 or smaller
		// skip test if prime1, or prime2, or exp1,
		// or exp2 or coef are too long
		if (is_ica_token(slot_id)) {
			// check sizes
			if ((tsuite->tv[i].prime1_len >
				(tsuite->tv[i].mod_len/2)) ||
				(tsuite->tv[i].prime2_len >
				(tsuite->tv[i].mod_len/2)) ||
				(tsuite->tv[i].exp1_len >
				(tsuite->tv[i].mod_len/2)) ||
				(tsuite->tv[i].exp2_len >
				(tsuite->tv[i].mod_len/2)) ||
				(tsuite->tv[i].coef_len >
				(tsuite->tv[i].mod_len/2))) {
				testcase_skip("ICA Token cannot be used with "
					"this test vector.");
				continue;
			}

		}

		// clear buffers
		memset(message, 0, MAX_MESSAGE_SIZE);
		memset(actual, 0, MAX_SIGNATURE_SIZE);
		memset(expected, 0, MAX_SIGNATURE_SIZE);

		actual_len = MAX_SIGNATURE_SIZE; // set buffer size

		// get message
		message_len = tsuite->tv[i].msg_len;
		memcpy(message, tsuite->tv[i].msg, message_len);

		// get (expected) signature
		expected_len = tsuite->tv[i].sig_len;
		memcpy(expected, tsuite->tv[i].sig, expected_len);

		// create (private) key handle
		rc = create_RSAPrivateKey(session,
                                        tsuite->tv[i].mod,
                                        tsuite->tv[i].pub_exp,
                                        tsuite->tv[i].priv_exp,
                                        tsuite->tv[i].prime1,
                                        tsuite->tv[i].prime2,
                                        tsuite->tv[i].exp1,
                                        tsuite->tv[i].exp2,
                                        tsuite->tv[i].coef,
					tsuite->tv[i].mod_len,
					tsuite->tv[i].pubexp_len,
					tsuite->tv[i].privexp_len,
					tsuite->tv[i].prime1_len,
					tsuite->tv[i].prime2_len,
					tsuite->tv[i].exp1_len,
					tsuite->tv[i].exp2_len,
					tsuite->tv[i].coef_len,
                                        &priv_key);
                if (rc != CKR_OK) {
                        testcase_error("create_RSAPrivateKey(), rc=%s",
                                p11_get_ckr(rc));
                        goto error;
                }

		// set mechanism
		mech = tsuite->mech;

		// initialize signing
		rc = funcs->C_SignInit(session, &mech, priv_key);
		if (rc != CKR_OK) {
			testcase_error("C_SignInit(), rc=%s.", p11_get_ckr(rc));
			goto error;
		}

		// do signing
		rc = funcs->C_Sign(session,
				message,
				message_len,
				actual,
				&actual_len);

		if (rc != CKR_OK) {
			testcase_error("C_Sign(), rc=%s.", p11_get_ckr(rc));
			goto error;
		}

		// check results
		testcase_new_assertion();

		if (actual_len != expected_len) {
			testcase_fail("%s Sign with test vector %d failed. "
				"Expected len=%ld, found len=%ld.",
				tsuite->name, i, expected_len, actual_len);
		}

		else if (memcmp(actual, expected, expected_len)) {
			testcase_fail("%s Sign with test vector %d failed. "
				"Signature data does not match test vector "
				"signature.", tsuite->name, i);

		}

		else {
			testcase_pass("C_Sign.");
		}

		// clean up
		rc = funcs->C_DestroyObject(session, priv_key);
		if (rc != CKR_OK) {
			testcase_error("C_DestroyObject(), rc=%s.",
				p11_get_ckr(rc));
			goto testcase_cleanup;
		}
	}
	goto testcase_cleanup;
error:
	loc_rc = funcs->C_DestroyObject(session, priv_key);
	if (loc_rc != CKR_OK) {
		testcase_error("C_DestroyObject, rc=%s.", p11_get_ckr(loc_rc));
	}
testcase_cleanup:
	testcase_user_logout();
	loc_rc = funcs->C_CloseAllSessions(slot_id);
	if (loc_rc != CKR_OK) {
		testcase_error("C_CloseAllSessions, rc=%s.", p11_get_ckr(rc));
	}
	return rc;
}
Ejemplo n.º 5
0
CK_RV do_HWFeatureSearch(void)
{
	unsigned int            i, got_it = 0;
	CK_RV 			rc, loc_rc;
	CK_ULONG		find_count;
	CK_SLOT_ID		slot_id;
	CK_BBOOL		false = FALSE;
	CK_BBOOL                true = TRUE;

	CK_SESSION_HANDLE 	h_session;
	CK_BYTE           	user_pin[PKCS11_MAX_PIN_LEN];
	CK_ULONG          	user_pin_len;

	/* A counter object */
	CK_OBJECT_CLASS         counter1_class = CKO_HW_FEATURE;
	CK_HW_FEATURE_TYPE      feature1_type = CKH_MONOTONIC_COUNTER;
	CK_UTF8CHAR             counter1_label[] = "Monotonic counter";
	CK_CHAR			counter1_value[16];
	CK_ATTRIBUTE            counter1_template[] = {
		{CKA_CLASS,		&counter1_class, sizeof(counter1_class)},
		{CKA_HW_FEATURE_TYPE,	&feature1_type,  sizeof(feature1_type)},
		{CKA_LABEL,		counter1_label,  sizeof(counter1_label)-1},
		{CKA_VALUE,		counter1_value,	sizeof(counter1_value)},
		{CKA_RESET_ON_INIT,	&true,		sizeof(true)},
		{CKA_HAS_RESET,		&false,		sizeof(false)}
	};
	/* A clock object */
	CK_OBJECT_CLASS         clock_class = CKO_HW_FEATURE;
	CK_HW_FEATURE_TYPE      clock_type = CKH_CLOCK;
	CK_UTF8CHAR             clock_label[] = "Clock";
	CK_CHAR			clock_value[16];
	CK_ATTRIBUTE            clock_template[] = {
		{CKA_CLASS,		&clock_class, sizeof(clock_class)},
		{CKA_HW_FEATURE_TYPE,	&clock_type,  sizeof(clock_type)},
		{CKA_LABEL,		clock_label,  sizeof(clock_label)-1},
		{CKA_VALUE,		clock_value,	sizeof(clock_value)}
	};
	/* A data object */
	CK_OBJECT_CLASS		obj1_class = CKO_DATA;
	CK_UTF8CHAR             obj1_label[] = "Object 1";
	CK_BYTE			obj1_data[] = "Object 1's data";
	CK_ATTRIBUTE            obj1_template[] = {
		{CKA_CLASS,		&obj1_class,    sizeof(obj1_class)},
		{CKA_TOKEN,		&true,          sizeof(true)},
		{CKA_LABEL,		obj1_label,     sizeof(obj1_label)-1},
		{CKA_VALUE,		obj1_data,	sizeof(obj1_data)}
	};
	/* A secret key object */
	CK_OBJECT_CLASS		obj2_class = CKO_SECRET_KEY;
	CK_KEY_TYPE		obj2_type = CKK_AES;
	CK_UTF8CHAR             obj2_label[] = "Object 2";
	CK_BYTE			obj2_data[AES_KEY_SIZE_128];
	CK_ATTRIBUTE            obj2_template[] = {
		{CKA_CLASS,		&obj2_class,    sizeof(obj2_class)},
		{CKA_TOKEN,		&true,          sizeof(true)},
		{CKA_KEY_TYPE,		&obj2_type,	sizeof(obj2_type)},
		{CKA_LABEL,		obj2_label,     sizeof(obj2_label)-1},
		{CKA_VALUE,		obj2_data,	sizeof(obj2_data)}
	};

	CK_OBJECT_HANDLE        h_counter1,
				h_clock,
				h_obj1,
				h_obj2,
				obj_list[10];
	CK_ATTRIBUTE		find_tmpl[] = {
		{CKA_CLASS,	&counter1_class, sizeof(counter1_class)}
	};

	slot_id = SLOT_ID;

        testcase_begin("starting...");

	if (get_user_pin(user_pin))
		return CKR_FUNCTION_FAILED;
	user_pin_len = (CK_ULONG)strlen((char *)user_pin);

	/* Open a session with the token */
	if( (rc = funcs->C_OpenSession(slot_id,
					(CKF_SERIAL_SESSION|CKF_RW_SESSION),
					NULL_PTR,
					NULL_PTR,
					&h_session)) != CKR_OK ) {
                testcase_fail("C_OpenSession() rc = %s", p11_get_ckr(rc));
		return rc;
	}

	// Login correctly
	rc = funcs->C_Login(h_session, CKU_USER, user_pin, user_pin_len);
	if( rc != CKR_OK ) {
                testcase_fail("C_Login() rc = %s", p11_get_ckr(rc));
		goto session_close;
	}

	/* Create the 3 test objects */
	if( (rc = funcs->C_CreateObject(h_session, obj1_template, 4, &h_obj1)) != CKR_OK) {
                testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc));
		goto session_close;
	}

	if( (rc = funcs->C_CreateObject(h_session, obj2_template, 5, &h_obj2)) != CKR_OK) {
                testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc));
		goto destroy_1;
	}

	/* try and create a monotonic object. This should fail
	 * since it is a read only feature.
	 */
	if( (rc = funcs->C_CreateObject(h_session, counter1_template, 6, &h_counter1)) != CKR_ATTRIBUTE_READ_ONLY) {
                testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc));
		goto destroy_2;
	}

	if( (rc = funcs->C_CreateObject(h_session, clock_template, 4, &h_clock)) != CKR_OK) {
                testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc));
		goto destroy_2;
	}

	/* Now find the hardware feature objects */
	rc = funcs->C_FindObjectsInit(h_session, find_tmpl, 1 );
	if (rc != CKR_OK) {
                testcase_fail("C_FindObjectsInit() rc = %s", p11_get_ckr(rc));
		goto destroy;
	}

	rc = funcs->C_FindObjects(h_session, obj_list, 10, &find_count );
	if (rc != CKR_OK) {
                testcase_fail("C_FindObjects() rc = %s", p11_get_ckr(rc));
		goto destroy;
	}

	got_it = 0;
	/* Make sure we got the right ones */
	for(i=0; i < find_count; i++) {
		if(obj_list[i] == h_clock) {
			got_it++;
		}
	}

	if (got_it != 1) {
		testcase_fail("could not find the corect object handle");
		rc = -1;
		goto destroy;
	}

	rc = funcs->C_FindObjectsFinal(h_session );
	if (rc != CKR_OK) {
                testcase_fail("C_FindObjectsFinal() rc = %s", p11_get_ckr(rc));
	}

        testcase_pass("Looks okay...");

destroy:
	/* Destroy the created objects, don't clobber the rc */
	loc_rc = funcs->C_DestroyObject(h_session, h_clock);
	if( loc_rc != CKR_OK )
                testcase_error("C_DestroyObject() rc = %s", p11_get_ckr(loc_rc));
destroy_2:
	loc_rc = funcs->C_DestroyObject(h_session, h_obj2);
	if( loc_rc != CKR_OK )
                testcase_error("C_DestroyObject() rc = %s", p11_get_ckr(loc_rc));
destroy_1:
	loc_rc = funcs->C_DestroyObject(h_session, h_obj1);
	if( loc_rc != CKR_OK )
                testcase_error("C_DestroyObject() rc = %s", p11_get_ckr(loc_rc));

	loc_rc = funcs->C_Logout(h_session);
	if( loc_rc != CKR_OK )
                testcase_error("C_Logout() rc = %s", p11_get_ckr(loc_rc));

session_close:
	/* Close the session */
	if( (loc_rc = funcs->C_CloseSession(h_session)) != CKR_OK )
                testcase_error("C_CloseSession() rc = %s", p11_get_ckr(loc_rc));

	return rc;
}
Ejemplo n.º 6
0
/* This function should test:
 * RSA Key Generation, CKM_RSA_PKCS_KEY_PAIR_GEN
 * RSA Encryption, mechanism chosen by caller
 * RSA Decryption, mechanism chosen by caller
 *
 * 1. Generate RSA Key Pair
 * 2. Generate plaintext
 * 3. Encrypt plaintext
 * 4. Decrypt encrypted data
 * 5. Compare plaintext with decrypted data
 *
 */
CK_RV do_EncryptDecryptRSA(struct GENERATED_TEST_SUITE_INFO *tsuite)
{
	int 			i, j;
	CK_BYTE			original[BIG_REQUEST];
	CK_ULONG		original_len;
	CK_BYTE			crypt[BIG_REQUEST];
	CK_ULONG		crypt_len;
	CK_BYTE			decrypt[BIG_REQUEST];
	CK_ULONG		decrypt_len;
	CK_MECHANISM		mech;
	CK_OBJECT_HANDLE	publ_key, priv_key;
	CK_SLOT_ID		slot_id = SLOT_ID;
	CK_SESSION_HANDLE	session;
	CK_FLAGS		flags;
	CK_BYTE			user_pin[PKCS11_MAX_PIN_LEN];
	CK_ULONG		user_pin_len;
	CK_RV			rc, loc_rc;

	char 			*s;

	// begin testsuite
	testsuite_begin("%s Encrypt Decrypt.", tsuite->name);
	testcase_rw_session();
	testcase_user_login();

	// skip tests if the slot doesn't support this mechanism
        if (! mech_supported(slot_id, tsuite->mech.mechanism)) {
                testsuite_skip(tsuite->tvcount,
                        "Slot %u doesn't support %u",
                        (unsigned int) slot_id,
                        (unsigned int) tsuite->mech.mechanism );
                goto testcase_cleanup;
        }

	// iterate over test vectors
	for (i = 0; i < tsuite->tvcount; i++) {

		// get public exponent from test vector
                if ( p11_ahex_dump(&s, tsuite->tv[i].publ_exp,
                                tsuite->tv[i].publ_exp_len) == NULL) {
                        testcase_error("p11_ahex_dump() failed");
                        rc = -1;
                        goto testcase_cleanup;
                }

		// begin testcase
		testcase_begin("%s Encrypt and Decrypt with test vector %d."
			"\npubl_exp='%s', modbits=%ld, publ_exp_len=%ld, "
			"inputlen=%ld.", tsuite->name, i, s,
			tsuite->tv[i].modbits,
			tsuite->tv[i].publ_exp_len,
			tsuite->tv[i].inputlen);

		rc = CKR_OK; // set rc

		if (!keysize_supported(slot_id, tsuite->mech.mechanism,
					tsuite->tv[i].modbits)) {
			testcase_skip("Token in slot %ld cannot be used with "
					"modbits.='%ld'",
					SLOT_ID,tsuite->tv[i].modbits);
			continue;
		}

		if (is_ep11_token(slot_id)) {
			if (! is_valid_ep11_pubexp(tsuite->tv[i].publ_exp,
						  tsuite->tv[i].publ_exp_len)) {
				testcase_skip("EP11 Token cannot "
					       "be used with publ_exp.='%s'",s);
				continue;
			}
		}

		// cca special cases:
		// cca token can only use the following public exponents
		// 0x03 or 0x010001 (65537)
		// so skip test if invalid public exponent is used
		if (is_cca_token(slot_id)) {
			if (! is_valid_cca_pubexp(tsuite->tv[i].publ_exp,
				tsuite->tv[i].publ_exp_len) ) {
				testcase_skip("CCA Token cannot "
					"be used with publ_exp.='%s'",s);
				continue;
			}
		}

		// tpm special cases:
		// tpm token can only use public exponent 0x010001 (65537)
		// so skip test if invalid public exponent is used
		if (is_tpm_token(slot_id)) {
			if ((! is_valid_tpm_pubexp(tsuite->tv[i].publ_exp,
				tsuite->tv[i].publ_exp_len) ) || (! is_valid_tpm_modbits(tsuite->tv[i].modbits))) {
				testcase_skip("TPM Token cannot "
					"be used with publ_exp.='%s'",s);
				continue;
			}
		}

		free(s);

		// clear buffers
                memset(original, 0, BIG_REQUEST);
                memset(crypt, 0, BIG_REQUEST);
                memset(decrypt, 0, BIG_REQUEST);

                // get test vector parameters
                original_len = tsuite->tv[i].inputlen;

		// generate key pair
		rc = generate_RSA_PKCS_KeyPair(session,
					tsuite->tv[i].modbits,
					tsuite->tv[i].publ_exp,
					tsuite->tv[i].publ_exp_len,
					&publ_key,
					&priv_key);

		if (rc != CKR_OK) {
			testcase_error("generate_RSA_PKCS_KeyPair(), "
				       "rc=%s", p11_get_ckr(rc));
                        goto error;
		}

		// generate plaintext
		for (j = 0; j < original_len; j++) {
			original[j] = (j + 1) % 255;
		}

		// set cipher buffer length
		crypt_len = BIG_REQUEST;
		decrypt_len = BIG_REQUEST;

		// get mech
		mech = tsuite->mech;

		// initialize (public key) encryption
		rc = funcs->C_EncryptInit(session, &mech, publ_key);
		if (rc != CKR_OK) {
			testcase_error("C_EncryptInit, rc=%s", p11_get_ckr(rc));
		}

		// do (public key) encryption
		rc = funcs->C_Encrypt(session,
				original,
				original_len,
				crypt,
				&crypt_len);
		if (rc != CKR_OK) {
			testcase_error("C_Encrypt, rc=%s", p11_get_ckr(rc));
			goto error;
		}

		// initialize (private key) decryption
		rc = funcs->C_DecryptInit(session, &mech, priv_key);
		if (rc != CKR_OK) {
			testcase_error("C_DecryptInit, rc=%s", p11_get_ckr(rc));
			goto error;
		}

		// do (private key) decryption
		rc = funcs->C_Decrypt(session,
				crypt,
				crypt_len,
				decrypt,
				&decrypt_len);
		if (rc != CKR_OK) {
			testcase_error("C_Decrypt, rc=%s", p11_get_ckr(rc));
			goto error;
		}

		// FIXME: there shouldn't be any padding here
		// remove padding if mech is CKM_RSA_X_509
		if (mech.mechanism == CKM_RSA_X_509) {
			memmove(decrypt,
				decrypt + decrypt_len - original_len,
				original_len);
			decrypt_len = original_len;
		}

		// check results
		testcase_new_assertion();

		if (decrypt_len != original_len) {
			testcase_fail("decrypted length does not match"
				"original data length.\n expected length = %ld,"
				"but found length=%ld.\n",
				original_len, decrypt_len);
		}

		else if (memcmp(decrypt, original, original_len)) {
			testcase_fail("decrypted data does not match "
				"original data.");
		}

		else {
			testcase_pass("C_Encrypt and C_Decrypt.");
		}

		// clean up
		rc = funcs->C_DestroyObject(session, publ_key);
		if (rc != CKR_OK) {
			testcase_error("C_DestroyObject(), rc=%s.",
				p11_get_ckr(rc));
			goto error;
		}

		rc = funcs->C_DestroyObject(session, priv_key);
		if (rc != CKR_OK) {
			testcase_error("C_DestroyObject(), rc=%s.",
				p11_get_ckr(rc));
			goto error;
		}

	}
	goto testcase_cleanup;
error:
	loc_rc = funcs->C_DestroyObject(session, publ_key);
	if (loc_rc != CKR_OK) {
		testcase_error("C_DestroyObject(), rc=%s.",
			p11_get_ckr(loc_rc));
	}

	loc_rc = funcs->C_DestroyObject(session, priv_key);
	if (loc_rc != CKR_OK) {
		testcase_error("C_DestroyObject(), rc=%s.",
			p11_get_ckr(loc_rc));
	}

testcase_cleanup:
	testcase_user_logout();
	loc_rc = funcs->C_CloseAllSessions(slot_id);
	if (loc_rc != CKR_OK) {
		testcase_error("C_CloseAllSessions, rc=%s",
			p11_get_ckr(loc_rc));
	}
	return rc;

}
Ejemplo n.º 7
0
/* This function should test:
 * RSA Key Generation, using CKM_PKCS_KEY_PAIR_GEN
 * RSA Public-Key Wrap
 * RSA Private-Key Unwrap
 *
 */
CK_RV do_WrapUnwrapRSA(struct GENERATED_TEST_SUITE_INFO *tsuite)
{
	int			i = 0, j = 0;
	CK_OBJECT_HANDLE        publ_key, priv_key, secret_key, unwrapped_key;
	CK_BYTE_PTR		wrapped_key = NULL;
	CK_ULONG		wrapped_keylen, unwrapped_keylen;
	CK_MECHANISM		wrap_mech, keygen_mech, mech;
	CK_BYTE			clear[32];
	CK_BYTE			cipher[32];
	CK_BYTE			re_cipher[32];
	CK_ULONG		cipher_len = 32;
	CK_ULONG		re_cipher_len = 32;

	char 			*s;

	CK_SESSION_HANDLE	session;
	CK_FLAGS		flags;
	CK_SLOT_ID		slot_id = SLOT_ID;
	CK_BYTE			user_pin[PKCS11_MAX_PIN_LEN];
	CK_ULONG		user_pin_len;
	CK_RV			rc, loc_rc;


	// begin test suite
	testsuite_begin("%s Wrap Unwrap.", tsuite->name);
	testcase_rw_session();
	testcase_user_login();

	// skip all tests if the slot doesn't support this mechanism
        if (! mech_supported(slot_id, tsuite->mech.mechanism)){
                testsuite_skip(tsuite->tvcount,
                           "Slot %u doesn't support %u",
                           (unsigned int) slot_id,
                           (unsigned int) tsuite->mech.mechanism );
                goto testcase_cleanup;
        }

	// skip all tests if the slot doesn't support wrapping
	else if (! wrap_supported(slot_id, tsuite->mech)) {
		testsuite_skip(tsuite->tvcount,
			"Slot %u doesn't support key wrapping",
			(unsigned int) slot_id);
		goto testcase_cleanup;

	}

	// skip all tests if the slot doesn't support unwrapping
	else if (! unwrap_supported(slot_id, tsuite->mech)) {
		testsuite_skip(tsuite->tvcount,
			"Slot %u doesn't support key unwrapping",
			(unsigned int) slot_id);
		goto testcase_cleanup;
	}

	for (i = 0; i < tsuite->tvcount; i++) {

		// wrap templates & unwrap templates
		CK_ATTRIBUTE            unwrap_tmpl[] = {
						{CKA_CLASS, NULL, 0},
						{CKA_KEY_TYPE, NULL, 0},
						{CKA_VALUE_LEN, NULL, 0}
					};
		CK_ULONG                unwrap_tmpl_len;

		// get public exponent from test vector
		if ( p11_ahex_dump(&s, tsuite->tv[i].publ_exp,
				tsuite->tv[i].publ_exp_len) == NULL) {
				testcase_error("p11_ahex_dump() failed");
			rc = -1;
			goto testcase_cleanup;
		}

		// begin test
		testcase_begin("%s Wrap Unwrap with test vector %d, "
			"\npubl_exp='%s', mod_bits='%lu', keylen='%lu', "
			"keytype='%s'", tsuite->name, i, s,
			tsuite->tv[i].modbits,
			tsuite->tv[i].keylen,
			p11_get_ckm(tsuite->tv[i].keytype.mechanism));

		// free memory
		free(s);

		// get key gen mechanism
		keygen_mech = tsuite->tv[i].keytype;

		// get wrapping mechanism
		wrap_mech = tsuite->mech;

		// skip this test if the slot doesn't support this
		// keygen mechanism
		if (! mech_supported(slot_id,
			keygen_mech.mechanism)) {
			testcase_skip();
			continue;
		}

		if (!keysize_supported(slot_id, tsuite->mech.mechanism,
					tsuite->tv[i].modbits)) {
			testcase_skip("Token in slot %ld cannot be used with "
					"modbits.='%ld'",
					SLOT_ID,tsuite->tv[i].modbits);
			continue;
		}

		if (is_ep11_token(slot_id)) {
			if (! is_valid_ep11_pubexp(tsuite->tv[i].publ_exp,
						  tsuite->tv[i].publ_exp_len)) {
				testcase_skip("EP11 Token cannot "
					       "be used with publ_exp.='%s'",s);
				continue;
			}
		}

		// initialize buffer lengths
		wrapped_keylen = PKCS11_MAX_PIN_LEN;

		// generate RSA key pair
		rc = generate_RSA_PKCS_KeyPair(session,
				tsuite->tv[i].modbits,
				tsuite->tv[i].publ_exp,
				tsuite->tv[i].publ_exp_len,
				&publ_key,
				&priv_key);
		if (rc != CKR_OK) {
                        testcase_error("C_GenerateKeyPair() rc = %s",
					p11_get_ckr(rc));
                        goto testcase_cleanup;
		}

		// generate secret key
		rc = generate_SecretKey(session,
				tsuite->tv[i].keylen,
				&keygen_mech,
				&secret_key);
		if (rc != CKR_OK) {
			testcase_error("generate_SecretKey(), rc=%s",
				p11_get_ckr(rc));
			goto error;
		}

		// extract CKA_CLASS and CKA_KEY_TYPE from generated key
		// we will use this for unwrapping

		// extract sizes first
		rc = funcs->C_GetAttributeValue(session,
						secret_key,
						unwrap_tmpl,
						2);
		if (rc != CKR_OK) {
			testcase_error("C_GetAttributeValue(), rc=%s",
					p11_get_ckr(rc));
			goto error;
		}

		// allocate memory for extraction
		unwrap_tmpl[0].pValue = calloc(sizeof(CK_BYTE),
						unwrap_tmpl[0].ulValueLen);
		unwrap_tmpl[1].pValue = calloc(sizeof(CK_BYTE),
						unwrap_tmpl[1].ulValueLen);

		if ( (unwrap_tmpl[0].pValue == NULL) ||
			(unwrap_tmpl[1].pValue == NULL) ) {
			testcase_error("Error allocating %lu bytes"
				"for unwrap template attributes",
				unwrap_tmpl[0].ulValueLen +
				unwrap_tmpl[1].ulValueLen);
			rc = -1;
			goto error;
		}

		// now extract values
		rc = funcs->C_GetAttributeValue(session,
						secret_key,
						unwrap_tmpl,
						2);
		if (rc != CKR_OK) {
			testcase_error("C_GetAttributeValue(), rc=%s",
					p11_get_ckr(rc));
			goto error;
		}

		// wrap key (length only)
		rc = funcs->C_WrapKey(session,
				&wrap_mech,
				publ_key,
				secret_key,
				NULL,
				&wrapped_keylen);
		if (rc != CKR_OK) {
			testcase_error("C_WrapKey(), rc=%s.",
				p11_get_ckr(rc));
			goto error;
		}

		// allocate memory for wrapped_key
		wrapped_key = calloc(sizeof(CK_BYTE), wrapped_keylen);
		if (wrapped_key == NULL) {
			testcase_error("Can't allocate memory "
				"for %lu bytes.",
				sizeof(CK_BYTE) * wrapped_keylen);
			rc = -1;
			goto error;
		}

		// wrap key
		rc = funcs->C_WrapKey(session,
				&wrap_mech,
				publ_key,
				secret_key,
				wrapped_key,
				&wrapped_keylen);
		if (rc != CKR_OK) {
			testcase_error("C_WrapKey, rc=%s", p11_get_ckr(rc));
			goto error;
		}

		unwrapped_keylen = tsuite->tv[i].keylen;

		// variable key length specific case:
		// According to PKCS#11 v2.2 section 12.1.12
		// CKM_RSA_X_509 does not wrap the key type, key length,
		// or any other information about the key; the application
		// must convey these separately, and supply them when
		// unwrapping the key.
		if (((keygen_mech.mechanism == CKM_AES_KEY_GEN) ||
		    (keygen_mech.mechanism == CKM_GENERIC_SECRET_KEY_GEN)) && 
		    (wrap_mech.mechanism == CKM_RSA_X_509)) {
			unwrapped_keylen = tsuite->tv[i].keylen;
			unwrap_tmpl[2].type = CKA_VALUE_LEN;
			unwrap_tmpl[2].ulValueLen = sizeof(unwrapped_keylen);
			unwrap_tmpl[2].pValue = &unwrapped_keylen;
			unwrap_tmpl_len = 3;
		}
		else {
			unwrap_tmpl_len = 2;
		}

		// unwrap key
		rc = funcs->C_UnwrapKey(session,
				&wrap_mech,
				priv_key,
				wrapped_key,
				wrapped_keylen,
				unwrap_tmpl,
				unwrap_tmpl_len,
				&unwrapped_key);
		if (rc != CKR_OK) {
			testcase_error("C_UnwrapKey, rc=%s",
				p11_get_ckr(rc));
			goto error;
		}

		testcase_new_assertion();

		// encode/decode with secrect key and peer secret key
		for (j = 0; j < 32; j++)
			clear[j] = j;

		switch (keygen_mech.mechanism) {
		case CKM_AES_KEY_GEN:
			mech.mechanism = CKM_AES_ECB;
			break;
		case CKM_GENERIC_SECRET_KEY_GEN:
		case CKM_DES3_KEY_GEN:
			mech.mechanism = CKM_DES3_ECB;
			break;
		case CKM_DES_KEY_GEN:
			mech.mechanism = CKM_DES_ECB;
			break;
		case CKM_CDMF_KEY_GEN:
			mech.mechanism = CKM_CDMF_ECB;
			break;
		default:
			testcase_error("unknowm mech");
			goto error;
		}
		
		mech.ulParameterLen = 0;
		mech.pParameter = NULL;

		rc = funcs->C_EncryptInit(session, &mech, secret_key);
		if (rc != CKR_OK) {
			testcase_error("C_EncryptInit secret_key: rc = %s",
					p11_get_ckr(rc));
			goto error;
		}

		rc = funcs->C_Encrypt(session, clear, 32, cipher, &cipher_len);
		if (rc != CKR_OK) {
			testcase_error("C_Encrypt secret_key: rc = %s",
					p11_get_ckr(rc));
			goto error;
		}

		rc = funcs->C_DecryptInit(session,&mech,unwrapped_key);
		if (rc != CKR_OK) {
			testcase_error("C_DecryptInit unwrapped_key: rc = %s",
					p11_get_ckr(rc));
			goto error;
		}

		rc = funcs->C_Decrypt(session, cipher, cipher_len, re_cipher,
					&re_cipher_len);
		if (rc != CKR_OK) {
		testcase_error("C_Decrypt unwrapped_key: rc = %s",
				p11_get_ckr(rc));
			testcase_fail("Unwrapped key differs in CKA_VALUE.");
			goto error;
		}

		if (memcmp(clear, re_cipher, 32) != 0) {
			testcase_fail("ERROR:data mismatch\n");
			goto error;
		} else
			testcase_pass("C_Wrap and C_Unwrap.");

		// clean up
		if (wrapped_key)
			free(wrapped_key);

		rc = funcs->C_DestroyObject(session, secret_key);
		if (rc != CKR_OK) {
			testcase_error("C_DestroyObject(), rc=%s.",
					p11_get_ckr(rc));
			goto testcase_cleanup;
		}

		rc = funcs->C_DestroyObject(session, publ_key);
		if (rc != CKR_OK) {
			testcase_error("C_DestroyObject(), rc=%s.",
					p11_get_ckr(rc));
			goto testcase_cleanup;
		}

		rc = funcs->C_DestroyObject(session, priv_key);
		if (rc != CKR_OK) {
			testcase_error("C_DestroyObject(), rc=%s.",
					p11_get_ckr(rc));
			goto testcase_cleanup;
		}
	}
	goto testcase_cleanup;

error:
	if (wrapped_key)
		free(wrapped_key);

	funcs->C_DestroyObject(session, secret_key);
	funcs->C_DestroyObject(session, publ_key);
	funcs->C_DestroyObject(session, priv_key);

testcase_cleanup:
	testcase_user_logout();
	loc_rc = funcs->C_CloseAllSessions(slot_id);
	if (loc_rc != CKR_OK) {
		testcase_error("C_CloseAllSessions(), rc=%s.",
			p11_get_ckr(rc));
	}
	return rc;
}
Ejemplo n.º 8
0
/* This function should test:
 * C_Verify, mechanism chosen by caller
 *
 * 1. Get message from test vector
 * 2. Get signature from test vector
 * 3. Verify signature
 *
 */
CK_RV do_VerifyRSA(struct PUBLISHED_TEST_SUITE_INFO *tsuite)
{
	int			i;
	CK_BYTE			actual[MAX_SIGNATURE_SIZE];
	CK_BYTE			message[MAX_MESSAGE_SIZE];
	CK_ULONG		message_len;
	CK_BYTE			signature[MAX_SIGNATURE_SIZE];
	CK_ULONG		signature_len;

	CK_MECHANISM		mech;
	CK_OBJECT_HANDLE	publ_key;

	CK_SLOT_ID		slot_id = SLOT_ID;
	CK_SESSION_HANDLE	session;
	CK_FLAGS		flags;
	CK_BYTE			user_pin[PKCS11_MAX_PIN_LEN];
	CK_ULONG		user_pin_len;
	CK_RV			rc, loc_rc;

	// begin testsuite
	testsuite_begin("%s Verify.", tsuite->name);
	testcase_rw_session();
	testcase_user_login();

	// skip tests if the slot doesn't support this mechanism
        if (! mech_supported(slot_id, tsuite->mech.mechanism)){
                testsuite_skip(tsuite->tvcount,
                           "Slot %u doesn't support %u",
                           (unsigned int) slot_id,
                           (unsigned int) tsuite->mech.mechanism );
                goto testcase_cleanup;
        }

	// iterate over test vectors
	for (i = 0; i < tsuite->tvcount; i++){

		testcase_begin("%s Verify with test vector %d.",
				tsuite->name, i);

		rc = CKR_OK; // set return value

		// clear buffers
		memset(message, 0, MAX_MESSAGE_SIZE);
		memset(signature, 0, MAX_SIGNATURE_SIZE);
		memset(actual, 0, MAX_SIGNATURE_SIZE);

		// get message
		message_len = tsuite->tv[i].msg_len;
		memcpy(message, tsuite->tv[i].msg, message_len);

		// get signature
		signature_len = tsuite->tv[i].sig_len;
		memcpy(signature, tsuite->tv[i].sig, signature_len);

		// create (public) key handle
		rc = create_RSAPublicKey(session,
				tsuite->tv[i].mod,
				tsuite->tv[i].pub_exp,
				tsuite->tv[i].mod_len,
				tsuite->tv[i].pubexp_len,
				&publ_key);

		if (rc != CKR_OK) {
			testcase_error("create_RSAPublicKey(), rc=%s",
				p11_get_ckr(rc));
			goto error;
		}

		// set mechanism
		mech = tsuite->mech;

		// initialize verify
		rc = funcs->C_VerifyInit(session, &mech, publ_key);
		if (rc != CKR_OK) {
			testcase_error("C_VerifyInit(), rc=%s",
				p11_get_ckr(rc));
			goto error;
		}

		// do verify
		rc = funcs->C_Verify(session,
			message,
			message_len,
			signature,
			signature_len);

		// check result
		testcase_new_assertion();

		if (rc == CKR_OK){
			testcase_pass("C_Verify.");
		}

		else {
			testcase_fail("%s Sign Verify with test vector %d "
				"failed.", tsuite->name, i);
		}

		// clean up
		rc = funcs->C_DestroyObject(session, publ_key);
		if (rc != CKR_OK) {
			testcase_error("C_DestroyObject(), rc=%s.",
				p11_get_ckr(rc));
			goto testcase_cleanup;
		}

	}
	goto testcase_cleanup;
error:
	loc_rc = funcs->C_DestroyObject(session, publ_key);
	if (loc_rc != CKR_OK) {
		testcase_error("C_DestroyObject(), rc=%s.",
			p11_get_ckr(loc_rc));
	}

testcase_cleanup:
        testcase_user_logout();
        rc = funcs->C_CloseAllSessions(slot_id);
        if (rc != CKR_OK) {
                testcase_error("C_CloseAllSessions rc=%s", p11_get_ckr(rc));
        }
        return rc;
}
Ejemplo n.º 9
0
/* This function should test:
 * RSA Key Generation, usign CKM_RSA_PKCS_KEY_PAIR_GEN
 * RSA Sign, mechanism chosen by caller
 * RSA Verify, mechanism chosen by caller
 *
 * 1. Generate RSA Key Pair
 * 2. Generate message
 * 3. Sign message
 * 4. Verify signature
 *
 */
CK_RV do_SignVerifyRSA(struct GENERATED_TEST_SUITE_INFO *tsuite)
{
	int 			i; // test vector index
	int			j; // message byte index
	CK_BYTE			message[MAX_MESSAGE_SIZE];
	CK_ULONG		message_len;
	CK_BYTE			signature[MAX_SIGNATURE_SIZE];
	CK_ULONG		signature_len;

	CK_MECHANISM		mech;
	CK_OBJECT_HANDLE	publ_key, priv_key;

	CK_SLOT_ID		slot_id = SLOT_ID;
	CK_SESSION_HANDLE	session;
	CK_FLAGS		flags;
	CK_BYTE			user_pin[PKCS11_MAX_PIN_LEN];
	CK_ULONG		user_pin_len;
	CK_RV			rc, loc_rc;

	char 			*s;

	// begin testsuite
	testsuite_begin("%s Sign Verify.", tsuite->name);
	testcase_rw_session();
	testcase_user_login();

	// skip tests if the slot doesn't support this mechanism
	if (! mech_supported(slot_id, tsuite->mech.mechanism)){
		testsuite_skip(tsuite->tvcount,
			"Slot %u doesn't support %u",
			(unsigned int) slot_id,
                        (unsigned int) tsuite->mech.mechanism );
                goto testcase_cleanup;
	}


	// iterate over test vectors
	for (i = 0; i < tsuite->tvcount; i++){

                // get public exponent from test vector
                if ( p11_ahex_dump(&s, tsuite->tv[i].publ_exp,
                                tsuite->tv[i].publ_exp_len) == NULL) {
                        testcase_error("p11_ahex_dump() failed");
                        rc = -1;
                        goto testcase_cleanup;
                }

                // begin test
                testcase_begin("%s Sign and Verify with test vector %d, "
                        "\npubl_exp='%s', mod_bits='%lu', keylen='%lu'.",
			tsuite->name, i, s,
                        tsuite->tv[i].modbits,
                        tsuite->tv[i].keylen);

		if (!keysize_supported(slot_id, tsuite->mech.mechanism,
					tsuite->tv[i].modbits)) {
			testcase_skip("Token in slot %ld cannot be used with "
					"modbits.='%ld'",
					SLOT_ID,tsuite->tv[i].modbits);
			continue;
		}

		if (is_ep11_token(slot_id)) {
			if (! is_valid_ep11_pubexp(tsuite->tv[i].publ_exp,
						  tsuite->tv[i].publ_exp_len)) {
				testcase_skip("EP11 Token cannot "
					       "be used with publ_exp.='%s'",s);
				continue;
			}
		}

		if (is_cca_token(slot_id)) {
                        if (! is_valid_cca_pubexp(tsuite->tv[i].publ_exp,
                                tsuite->tv[i].publ_exp_len)) {
                                testcase_skip("CCA Token cannot "
                                        "be used with publ_exp='%s'.",s);
                                continue;
                        }
                }

		if (is_tpm_token(slot_id)) {
                        if ((! is_valid_tpm_pubexp(tsuite->tv[i].publ_exp,
                                tsuite->tv[i].publ_exp_len)) || (!is_valid_tpm_modbits(tsuite->tv[i].modbits))) {
                                testcase_skip("TPM Token cannot "
                                        "be used with publ_exp='%s'.",s);
                                continue;
                        }
                }


                // free memory
                free(s);

		rc = CKR_OK; // set rc

		// clear buffers
                memset(message, 0, MAX_MESSAGE_SIZE);
                memset(signature, 0, MAX_SIGNATURE_SIZE);

		// get test vector parameters
		message_len = tsuite->tv[i].inputlen;

		// generate key pair
                rc = generate_RSA_PKCS_KeyPair(session,
                                        tsuite->tv[i].modbits,
                                        tsuite->tv[i].publ_exp,
                                        tsuite->tv[i].publ_exp_len,
                                        &publ_key,
                                        &priv_key);
                if (rc != CKR_OK) {
                        testcase_error("generate_RSA_PKCS_KeyPair(), "
					"rc=%s", p11_get_ckr(rc));
                        goto error;
                }

		// generate message
		for (j = 0; j < message_len; j++) {
			message[j] = (j + 1) % 255;
		}

		// get  mech
		mech = tsuite->mech;

		// initialize Sign (length only)
		rc = funcs->C_SignInit(session,
				&mech,
				priv_key);
		if (rc != CKR_OK){
			testcase_error("C_SignInit(), rc=%s", p11_get_ckr(rc));
			goto error;
		}

		// set buffer size
		signature_len = MAX_SIGNATURE_SIZE;

		// do Sign
		rc = funcs->C_Sign(session,
				message,
				message_len,
				signature,
				&signature_len);
		if (rc != CKR_OK) {
			testcase_error("C_Sign(), rc=%s signature len=%ld",
				p11_get_ckr(rc), signature_len);
			goto error;
		}


		// initialize Verify
		rc = funcs->C_VerifyInit(session,
				&mech,
				publ_key);
		if (rc != CKR_OK) {
			testcase_error("C_VerifyInit(), rc=%s",
				p11_get_ckr(rc));
		}

		// do Verify
		rc = funcs->C_Verify(session,
				message,
				message_len,
				signature,
				signature_len);

		// check results
		testcase_new_assertion();
		if (rc == CKR_OK) {
			testcase_pass("C_Verify.");
		}
		else {
			testcase_fail("C_Verify(), rc=%s", p11_get_ckr(rc));
		}

		// clean up
		rc = funcs->C_DestroyObject(session, publ_key);
		if (rc != CKR_OK) {
			testcase_error("C_DestroyObject(), rc=%s.",
				p11_get_ckr(rc));
		}

		rc = funcs->C_DestroyObject(session, priv_key);
		if (rc != CKR_OK) {
			testcase_error("C_DestroyObject(), rc=%s.",
				p11_get_ckr(rc));
		}
        }
	goto testcase_cleanup;
error:
	loc_rc = funcs->C_DestroyObject(session, publ_key);
	if (loc_rc != CKR_OK) {
		testcase_error("C_DestroyObject, rc=%s.", p11_get_ckr(loc_rc));
	}
	loc_rc = funcs->C_DestroyObject(session, priv_key);
	if (loc_rc != CKR_OK) {
		testcase_error("C_DestroyObject, rc=%s.", p11_get_ckr(loc_rc));
	}

testcase_cleanup:
	testcase_user_logout();
	rc = funcs->C_CloseAllSessions(slot_id);
	if (rc != CKR_OK) {
		testcase_error("C_CloesAllSessions, rc=%s", p11_get_ckr(rc));
	}
	return rc;
}
Ejemplo n.º 10
0
/* This function should test:
 * RSA Key Generation, using CKM_PKCS_KEY_PAIR_GEN
 * RSA Public-Key Wrap
 * RSA Private-Key Unwrap
 *
 */
CK_RV do_WrapUnwrapRSA(struct GENERATED_TEST_SUITE_INFO *tsuite)
{
	int			i;
	CK_OBJECT_HANDLE        publ_key, priv_key, secret_key, unwrapped_key;
	CK_BYTE_PTR		wrapped_key;
	CK_ULONG		wrapped_keylen, unwrapped_keylen;
	CK_MECHANISM		wrap_mech, keygen_mech;

	char 			*s;

	CK_SESSION_HANDLE	session;
	CK_FLAGS		flags;
	CK_SLOT_ID		slot_id = SLOT_ID;
	CK_BYTE			user_pin[PKCS11_MAX_PIN_LEN];
	CK_ULONG		user_pin_len;
	CK_RV			rc, loc_rc;


	// begin test suite
	testsuite_begin("%s Wrap Unwrap.", tsuite->name);
	testcase_rw_session();
	testcase_user_login();

	// skip all tests if the slot doesn't support this mechanism
        if (! mech_supported(slot_id, tsuite->mech.mechanism)){
                testsuite_skip(tsuite->tvcount,
                           "Slot %u doesn't support %u",
                           (unsigned int) slot_id,
                           (unsigned int) tsuite->mech.mechanism );
                goto testcase_cleanup;
        }

	// skip all tests if the slot doesn't support wrapping
	else if (! wrap_supported(slot_id, tsuite->mech)) {
		testsuite_skip(tsuite->tvcount,
			"Slot %u doesn't support key wrapping",
			(unsigned int) slot_id);
		goto testcase_cleanup;

	}

	// skip all tests if the slot doesn't support unwrapping
	else if (! unwrap_supported(slot_id, tsuite->mech)) {
		testsuite_skip(tsuite->tvcount,
			"Slot %u doesn't support key unwrapping",
			(unsigned int) slot_id);
		goto testcase_cleanup;
	}

	for (i = 0; i < tsuite->tvcount; i++) {

		// wrap templates & unwrap templates
		CK_ATTRIBUTE		secret_value[] = {
						{CKA_VALUE, NULL, 0}
					};
		CK_ATTRIBUTE		unwrapped_value[] = {
						{CKA_VALUE, NULL, 0}
					};
		CK_ULONG		s_valuelen = 0;
		CK_ATTRIBUTE		secret_value_len[] = {
						{CKA_VALUE_LEN,
						&s_valuelen,
						sizeof(s_valuelen)}
					};
		CK_ULONG		u_valuelen = 0;
		CK_ATTRIBUTE		unwrapped_value_len[] = {
						{CKA_VALUE_LEN,
						&u_valuelen,
						sizeof(u_valuelen)}
					};
		CK_ATTRIBUTE            unwrap_tmpl[] = {
						{CKA_CLASS, NULL, 0},
						{CKA_KEY_TYPE, NULL, 0},
						{CKA_VALUE_LEN, NULL, 0}
					};
		CK_ULONG                unwrap_tmpl_len;

		// get public exponent from test vector
		if ( p11_ahex_dump(&s, tsuite->tv[i].publ_exp,
				tsuite->tv[i].publ_exp_len) == NULL) {
				testcase_error("p11_ahex_dump() failed");
			rc = -1;
			goto testcase_cleanup;
		}

		// begin test
		testcase_begin("%s Wrap Unwrap with test vector %d, "
			"\npubl_exp='%s', mod_bits='%lu', keylen='%lu', "
			"keytype='%s'", tsuite->name, i, s,
			tsuite->tv[i].modbits,
			tsuite->tv[i].keylen,
			p11_get_ckm(tsuite->tv[i].keytype.mechanism));

		// free memory
		free(s);

		// get key gen mechanism
		keygen_mech = tsuite->tv[i].keytype;

		// get wrapping mechanism
		wrap_mech = tsuite->mech;

		// skip this test if the slot doesn't support this
		// keygen mechanism
		if (! mech_supported(slot_id,
			keygen_mech.mechanism)) {
			testcase_skip();
			continue;
		}

		// initialize buffer lengths
		wrapped_keylen = PKCS11_MAX_PIN_LEN;

		// generate RSA key pair
		rc = generate_RSA_PKCS_KeyPair(session,
				tsuite->tv[i].modbits,
				tsuite->tv[i].publ_exp,
				tsuite->tv[i].publ_exp_len,
				&publ_key,
				&priv_key);
		if (rc != CKR_OK) {
                        testcase_error("C_GenerateKeyPair() rc = %s",
					p11_get_ckr(rc));
                        goto testcase_cleanup;
		}

		// generate secret key
		rc = generate_SecretKey(session,
				tsuite->tv[i].keylen,
				&keygen_mech,
				&secret_key);
		if (rc != CKR_OK) {
			testcase_error("generate_SecretKey(), rc=%s",
				p11_get_ckr(rc));
			goto error;
		}

		// extract CKA_CLASS and CKA_KEY_TYPE from generated key
		// we will use this for unwrapping

		// extract sizes first
		rc = funcs->C_GetAttributeValue(session,
						secret_key,
						unwrap_tmpl,
						2);
		if (rc != CKR_OK) {
			testcase_error("C_GetAttributeValue(), rc=%s",
					p11_get_ckr(rc));
			goto error;
		}

		// allocate memory for extraction
		unwrap_tmpl[0].pValue = calloc(sizeof(CK_BYTE),
						unwrap_tmpl[0].ulValueLen);
		unwrap_tmpl[1].pValue = calloc(sizeof(CK_BYTE),
						unwrap_tmpl[1].ulValueLen);

		if ( (unwrap_tmpl[0].pValue == NULL) ||
			(unwrap_tmpl[1].pValue == NULL) ) {
			testcase_error("Error allocating %lu bytes"
				"for unwrap template attributes",
				unwrap_tmpl[0].ulValueLen +
				unwrap_tmpl[1].ulValueLen);
			rc = -1;
			goto error;
		}

		// now extract values
		rc = funcs->C_GetAttributeValue(session,
						secret_key,
						unwrap_tmpl,
						2);
		if (rc != CKR_OK) {
			testcase_error("C_GetAttributeValue(), rc=%s",
					p11_get_ckr(rc));
			goto error;
		}

		// wrap key (length only)
		rc = funcs->C_WrapKey(session,
				&wrap_mech,
				publ_key,
				secret_key,
				NULL,
				&wrapped_keylen);
		if (rc != CKR_OK) {
			testcase_error("C_WrapKey(), rc=%s.",
				p11_get_ckr(rc));
			goto error;
		}

		// allocate memory for wrapped_key
		wrapped_key = calloc(sizeof(CK_BYTE), wrapped_keylen);
		if (wrapped_key == NULL) {
			testcase_error("Can't allocate memory "
				"for %lu bytes.",
				sizeof(CK_BYTE) * wrapped_keylen);
			rc = -1;
			goto error;
		}

		// wrap key
		rc = funcs->C_WrapKey(session,
				&wrap_mech,
				publ_key,
				secret_key,
				wrapped_key,
				&wrapped_keylen);
		if (rc != CKR_OK) {
			testcase_error("C_WrapKey, rc=%s", p11_get_ckr(rc));
			goto error;
		}

		unwrapped_keylen = tsuite->tv[i].keylen;

		// variable key length specific case:
		// According to PKCS#11 v2.2 section 12.1.12
		// CKM_RSA_X_509 does not wrap the key type, key length,
		// or any other information about the key; the application
		// must convey these separately, and supply them when
		// unwrapping the key.
		if (keygen_mech.mechanism == CKM_AES_KEY_GEN) {
			unwrapped_keylen = tsuite->tv[i].keylen;
			unwrap_tmpl[2].type = CKA_VALUE_LEN;
			unwrap_tmpl[2].ulValueLen = sizeof(unwrapped_keylen);
			unwrap_tmpl[2].pValue = &unwrapped_keylen;
			unwrap_tmpl_len = 3;
		}
		else {
			unwrap_tmpl_len = 2;
		}

		// unwrap key
		rc = funcs->C_UnwrapKey(session,
				&wrap_mech,
				priv_key,
				wrapped_key,
				wrapped_keylen,
				unwrap_tmpl,
				unwrap_tmpl_len,
				&unwrapped_key);
		if (rc != CKR_OK) {
			testcase_error("C_UnwrapKey, rc=%s",
				p11_get_ckr(rc));
			goto error;
		}

		testcase_new_assertion();

		// get secret CKA_VALUE_LEN (if applicable)
		// then compare to expected value
		if (keygen_mech.mechanism == CKM_GENERIC_SECRET_KEY_GEN
			|| keygen_mech.mechanism == CKM_RC4_KEY_GEN
			|| keygen_mech.mechanism == CKM_RC5_KEY_GEN
			|| keygen_mech.mechanism == CKM_AES_KEY_GEN) {

			rc = funcs->C_GetAttributeValue(session,
						secret_key,
						secret_value_len,
						1);

			if (rc != CKR_OK) {
				testcase_error("C_GetAttributeValue(), rc=%s",
					p11_get_ckr(rc));
				goto error;
			}

			rc = funcs->C_GetAttributeValue(session,
						unwrapped_key,
						unwrapped_value_len,
						1);

			if (rc != CKR_OK) {
				testcase_error("C_GetAttributeValue(), rc=%s",
					p11_get_ckr(rc));
				goto error;
			}

			// check results

			if ( * ((CK_ULONG_PTR) secret_value_len[0].pValue) !=
			     * ((CK_ULONG_PTR) unwrapped_value_len[0].pValue)) {

				testcase_fail("CKA_VALUE_LEN value differs "
					"(original %lu, unwrapped %lu)",
					*((CK_ULONG_PTR) secret_value_len),
					*((CK_ULONG_PTR) unwrapped_value_len));
				goto error;
			}
		}

		// get size of secret key's CKA_VALUE
		rc = funcs->C_GetAttributeValue(session, secret_key,
					secret_value, 1);
		if (rc != CKR_OK) {
			testcase_error("C_GetAttributeValue(), rc=%s.",
				p11_get_ckr(rc));
			goto error;
		}

		// get size of unwrapped key's CKA_VALUE
		rc = funcs->C_GetAttributeValue(session, unwrapped_key,
					unwrapped_value, 1);
		if (rc != CKR_OK) {
			testcase_error("C_GetAttributeValue(), rc=%s.",
				p11_get_ckr(rc));
			goto error;
		}

		// allocate memory for extraction
                secret_value[0].pValue = calloc(sizeof(CK_BYTE),
                                                secret_value[0].ulValueLen);
                if (secret_value[0].pValue == NULL) {
                        testcase_error("Error allocating %lu bytes "
                                        "for Secret Key Value.",
                                        secret_value[0].ulValueLen);
                        goto error;
                }

                unwrapped_value[0].pValue = calloc(sizeof(CK_BYTE),
                                                unwrapped_value[0].ulValueLen);
                if (unwrapped_value[0].pValue == NULL) {
                        testcase_error("Error allocating %lu bytes "
                                        "for Unwrapped Key Value.",
                                        unwrapped_value[0].ulValueLen);
                        goto error;
                }

		// get secret CKA_VALUE
		rc = funcs->C_GetAttributeValue(session,
					secret_key,
					secret_value,
					1);
		if (rc != CKR_OK) {
			testcase_error("C_GetAttributeValue(), rc=%s.",
				p11_get_ckr(rc));
			goto error;
		}

		// get unwrapped CKA_VALUE
		rc = funcs->C_GetAttributeValue(session,
					unwrapped_key,
					unwrapped_value,
					1);
		if (rc != CKR_OK) {
			testcase_error("C_GetAttributeValue(), rc=%s.",
				p11_get_ckr(rc));
			goto error;
		}

		// compare secret and unwrapped CKA_VALUE
		if (memcmp(secret_value[0].pValue,
				unwrapped_value[0].pValue,
				secret_value[0].ulValueLen)) {

			testcase_fail("Unwrapped key differs in CKA_VALUE.");
		}

		else {
			testcase_pass("C_Wrap and C_Unwrap.");
		}

		// free memory
		if (unwrap_tmpl[0].pValue) {
			free(unwrap_tmpl[0].pValue);
		}
		if (unwrap_tmpl[1].pValue) {
			free(unwrap_tmpl[1].pValue);
		}
		if (secret_value[0].pValue) {
			free(secret_value[0].pValue);
		}
		if (unwrapped_value[0].pValue) {
			free(unwrapped_value[0].pValue);
		}
		if (wrapped_key) {
			free(wrapped_key);
		}

		// clean up
		rc = funcs->C_DestroyObject(session, secret_key);
		if (rc != CKR_OK) {
			testcase_error("C_DestroyObject(), rc=%s.",
					p11_get_ckr(rc));
			goto testcase_cleanup;
		}

		rc = funcs->C_DestroyObject(session, publ_key);
		if (rc != CKR_OK) {
			testcase_error("C_DestroyObject(), rc=%s.",
					p11_get_ckr(rc));
			goto testcase_cleanup;
		}

		rc = funcs->C_DestroyObject(session, priv_key);
		if (rc != CKR_OK) {
			testcase_error("C_DestroyObject(), rc=%s.",
					p11_get_ckr(rc));
			goto testcase_cleanup;
		}
	}
	goto testcase_cleanup;

error:
	loc_rc = funcs->C_DestroyObject(session, secret_key);
	if (loc_rc != CKR_OK) {
		testcase_error("C_DestroyObject(), rc=%s.",
				p11_get_ckr(loc_rc));
	}

	loc_rc = funcs->C_DestroyObject(session, publ_key);
	if (loc_rc != CKR_OK) {
		testcase_error("C_DestroyObject(), rc=%s.",
				p11_get_ckr(loc_rc));
	}

	loc_rc = funcs->C_DestroyObject(session, priv_key);
	if (loc_rc != CKR_OK) {
		testcase_error("C_DestroyObject(), rc=%s.",
				p11_get_ckr(loc_rc));
	}

testcase_cleanup:
	testcase_user_logout();
	loc_rc = funcs->C_CloseAllSessions(slot_id);
	if (loc_rc != CKR_OK) {
		testcase_error("C_CloseAllSessions(), rc=%s.",
			p11_get_ckr(rc));
	}
	return rc;
}
Ejemplo n.º 11
0
CK_RV do_DestroyObjects(void)
{
	CK_FLAGS          flags;
	CK_SESSION_HANDLE session;
	CK_RV             rc = 0;
	CK_BYTE           user_pin[PKCS11_MAX_PIN_LEN];
	CK_ULONG          user_pin_len;
	CK_OBJECT_HANDLE  keyobj[8];
	CK_OBJECT_HANDLE  obj_list[10];
	CK_ULONG	  i, num_objs=0, find_count, found=0;
	CK_MECHANISM	  mech;

	CK_BBOOL true = TRUE;
	CK_KEY_TYPE aes_type = CKK_AES;
	CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
	CK_CHAR aes_value[] = "This is a fake aes key.";
	CK_CHAR test_id[5] = "abcde";
	CK_ULONG aesgen_keylen = 32;

	CK_ATTRIBUTE aes_tmpl[] = {
		{CKA_CLASS, &key_class, sizeof(key_class)},
		{CKA_KEY_TYPE, &aes_type, sizeof(aes_type)},
		{CKA_ID, &test_id, sizeof(test_id)},
		{CKA_VALUE, &aes_value, sizeof(aes_value)}
	};

	CK_ATTRIBUTE aesgen_tmpl[] = {
		{CKA_CLASS, &key_class, sizeof(key_class)},
		{CKA_KEY_TYPE, &aes_type, sizeof(aes_type)},
		{CKA_ID, &test_id, sizeof(test_id)},
		{CKA_VALUE_LEN, &aesgen_keylen, sizeof(aesgen_keylen)},
		{CKA_TOKEN, &true, sizeof(true)}
	};

	CK_ATTRIBUTE find_tmpl[] = {
		{CKA_KEY_TYPE, &aes_type, sizeof(aes_type)},
		{CKA_ID, &test_id, sizeof(test_id)}
	};

	testcase_begin("starting...");
	testcase_rw_session();
	testcase_user_login();

	/* Create a few  session key objects */
	for (i = 0; i < 4; i++) {
		rc = funcs->C_CreateObject(session, aes_tmpl, 4, &keyobj[num_objs]);
		if (rc != CKR_OK) {
			testcase_error("C_CreateObject() rc = %s", p11_get_ckr(rc));
			goto testcase_cleanup;
		}
		num_objs++;
	}

	/* Generate a few token key objects */
	mech.mechanism = CKM_AES_KEY_GEN;
	mech.ulParameterLen = 0;
	mech.pParameter = NULL;

	for (i = 4; i < 8; i++) {
		rc = funcs->C_GenerateKey(session, &mech, aesgen_tmpl, 5, &keyobj[num_objs]);
		if (rc != CKR_OK) {
			testcase_error("C_GenerateObject() rc = %s", p11_get_ckr(rc));
			goto testcase_cleanup;
		}
		num_objs++;
	}

	/* Now delete 2 session key objects */
	rc = funcs->C_DestroyObject(session, keyobj[7]);
	if (rc != CKR_OK) {
		testcase_fail("C_FindObjects() rc = %s", p11_get_ckr(rc));
		goto testcase_cleanup;
	}
	num_objs--;

	rc = funcs->C_DestroyObject(session, keyobj[6]);
	if (rc != CKR_OK) {
		testcase_fail("C_FindObjects() rc = %s", p11_get_ckr(rc));
		goto testcase_cleanup;
	}
	num_objs--;

	/* Now see if only 2 session key objects were destroyed */
	rc = funcs->C_FindObjectsInit(session, find_tmpl, 2);
	if (rc != CKR_OK) {
		testcase_error("C_FindObjectsInit() rc = %s", p11_get_ckr(rc));
		goto testcase_cleanup;
	}

	rc = funcs->C_FindObjects(session, obj_list, 10, &find_count);
	if (rc != CKR_OK) {
		testcase_error("C_FindObjects() rc = %s", p11_get_ckr(rc));
		goto testcase_cleanup;
	}

	rc = funcs->C_FindObjectsFinal(session);
	if (rc != CKR_OK) {
		testcase_error("C_FindObjectsFinal() rc = %s", p11_get_ckr(rc));
		goto testcase_cleanup;
	}

	/* Testcase 1: step thru and see if objects were deleted. */
	if (find_count != 6) {
		testcase_fail("Did not find 6 objects!");
		goto testcase_cleanup;
	}

	for (i = 0; i < find_count; i++) {
		if ((obj_list[i] == keyobj[6]) || (obj_list[i] == keyobj[7]))
			found++;
	}

	if (found) {
		testcase_fail("Objects were not deleted.");
		goto testcase_cleanup;
	} else
		testcase_pass("The 2 objects were successfully deleted.");

	/* Testcase 2: Now make sure the other objects are still there */

	for (i = 0; i < find_count; i++) {
		if ((obj_list[i] == keyobj[0]) || (obj_list[i] == keyobj[1]) ||
		   (obj_list[i] == keyobj[2]) || (obj_list[i] == keyobj[3]) ||
		   (obj_list[i] == keyobj[4]) || (obj_list[i] == keyobj[5]))
			found++;
	}

	if (found != 6) {
		testcase_fail("Some Objects were not found!");
		goto testcase_cleanup;
	} else
		testcase_pass("The other objects are intact.");

	/* Testcase 3: Remove all the objects */
	find_count = 0;

	/* Now delete the rest of the objects */
	for (i = 0; i < num_objs; i++)
		funcs->C_DestroyObject(session, keyobj[i]);

	/* Now see if all the objects were deleted. */
	rc = funcs->C_FindObjectsInit(session, find_tmpl, 2);
	if (rc != CKR_OK) {
		testcase_fail("C_FindObjectsInit() rc = %s", p11_get_ckr(rc));
		goto testcase_cleanup;
	}

	rc = funcs->C_FindObjects(session, obj_list, 10, &find_count);
	if (rc != CKR_OK) {
		testcase_fail("C_FindObjects() rc = %s", p11_get_ckr(rc));
		goto testcase_cleanup;
	}

	rc = funcs->C_FindObjectsFinal(session);
	if (rc != CKR_OK) {
		testcase_fail("C_FindObjectsFinal() rc = %s", p11_get_ckr(rc));
		goto testcase_cleanup;
	}

	if (find_count) {
		testcase_fail("The remaining objects were not deleted.");
		goto testcase_cleanup;
	} else
		testcase_pass("All objects were deleted.");

testcase_cleanup:

	if (num_objs) {
		for (i = 0; i < num_objs; i++)
			funcs->C_DestroyObject(session, keyobj[i]);
	}

        testcase_user_logout();
        rc = funcs->C_CloseSession(session);
        if (rc != CKR_OK) {
                testcase_error("C_CloseSession rc=%s", p11_get_ckr(rc));
        }
        return rc;
}
Ejemplo n.º 12
0
CK_RV do_SetPIN(void)
{
	CK_SLOT_ID slot_id;
	CK_FLAGS flags;
	CK_SESSION_HANDLE session;
	CK_CHAR old_pin[PKCS11_MAX_PIN_LEN];
	CK_CHAR new_pin[PKCS11_MAX_PIN_LEN];
	CK_ULONG old_len;
	CK_ULONG new_len;
	CK_RV rc;

	testcase_begin("Testing C_SetPIN");

	// first, try to get the user PIN
	if (get_user_pin(old_pin))
		return CKR_FUNCTION_FAILED;
	old_len = (CK_ULONG)strlen((char *)old_pin);

	memcpy(new_pin, "ABCDEF", 6);
	new_len = 6;

	slot_id = SLOT_ID;

	/* try to call C_SetPIN from a R/O public session, it should fail.
	 */
	flags = CKF_SERIAL_SESSION;
	testcase_new_assertion();
	rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &session);
	if (rc != CKR_OK) {
		testcase_error("C_OpenSession #1 rc=%s", p11_get_ckr(rc));
		return rc;
	}

	rc = funcs->C_SetPIN(session, old_pin, old_len, new_pin, new_len);
	if (rc != CKR_SESSION_READ_ONLY) {
		testcase_fail("C_SetPIN #1 returned %s instead of "
			      "CKR_SESSION_READ_ONLY.", p11_get_ckr(rc));
		rc = CKR_FUNCTION_FAILED;
		goto testcase_cleanup;
	} else
		testcase_pass("C_SetPIN successful in pubic session.");

	if (funcs->C_CloseSession(session) != CKR_OK) {
		testcase_error("C_CloseSession #1 failed.");
		goto testcase_cleanup;
	}

	/* try to call C_SetPIN from a R/W public session, it should work.
	 */
	flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
	rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &session);
	if (rc != CKR_OK) {
		testcase_error("C_OpenSession #1 rc=%s", p11_get_ckr(rc));
		return rc;
	}

	rc = funcs->C_SetPIN(session, old_pin, old_len, new_pin, new_len);
	if (rc != CKR_OK) {
		testcase_fail("C_SetPIN failed: rc = %s", p11_get_ckr(rc));
	} else
		testcase_pass("C_SetPIN successful in r/w pubic session.");

	if (funcs->C_CloseSession(session) != CKR_OK) {
		testcase_error("C_CloseSession #1 failed.");
		goto testcase_cleanup;
	}
	if (rc != CKR_OK) 	// above C_SetPIN failed so leave
		goto testcase_cleanup;

	/* open a new session and try logging in with new pin */

	flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
	rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &session);
	if (rc != CKR_OK) {
		testcase_error("C_OpenSession #1 rc=%s", p11_get_ckr(rc));
		return rc;
	}

	testcase_new_assertion();

	rc = funcs->C_Login(session, CKU_USER, new_pin, new_len);
	if (rc != CKR_OK) {
		testcase_fail("C_Login #1 failed: rc=%s", p11_get_ckr(rc));
		goto testcase_cleanup;
	} else
		testcase_pass("Successfully logged in with new pin.");

	/* try to call C_SetPIN from a normal user session, r/w user.
	 * set back to original user pin. this should work.
	 */
	testcase_new_assertion();

	rc = funcs->C_SetPIN(session, new_pin, new_len, old_pin, old_len);
	if (rc != CKR_OK)
		testcase_fail("C_SetPIN #2 rc=%s", p11_get_ckr(rc));
	else
		testcase_pass("C_SetPIN successful.");

	if ((funcs->C_Logout(session)) != CKR_OK) {
		testcase_error("C_Logout #1 falied: rc=%s", p11_get_ckr(rc));
		goto testcase_cleanup;
	}
	if (rc != CKR_OK)	// above C_SetPIN failed.
		goto testcase_cleanup;

	/*
	 *  done with user tests...now try with the SO
	 */

	if (get_so_pin(old_pin))
		return CKR_FUNCTION_FAILED;

	/* try to call C_SetPIN from a normal user session */
	testcase_new_assertion();

	rc = funcs->C_Login(session, CKU_SO, old_pin, old_len);
	if (rc != CKR_OK) {
		testcase_error("C_Login #3failed: rc=%s", p11_get_ckr(rc));
		goto testcase_cleanup;
	}

	rc = funcs->C_SetPIN(session, old_pin, old_len, new_pin, new_len);
	if (rc != CKR_OK)
		testcase_fail("C_SetPIN #4 failed: rc=%s",  p11_get_ckr(rc));
	else
		testcase_pass("C_SetPIN successfully set SO PIN.");

	if ((funcs->C_Logout(session)) != CKR_OK) {
		testcase_error("C_Logout #3 failed.");
		goto testcase_cleanup;
	}

	if (rc != CKR_OK)	// above C_SetPIN failed
		goto testcase_cleanup;

	/* now login with new pin. should work. */
	testcase_new_assertion();

	rc = funcs->C_Login(session, CKU_SO, new_pin, new_len);
	if (rc != CKR_OK) {
		testcase_fail("C_Login #5 failed: rc=%s",  p11_get_ckr(rc));
	} else
		testcase_pass("C_Login #5 was successful.");

	/* change the PIN back to the original so the rest of this program
	 * doesn't break
	 */
	if (funcs->C_SetPIN(session, new_pin, new_len, old_pin, old_len) != CKR_OK)
		testcase_error("C_SetPIN #5 failed to set back to the original "
				"SO PIN, rc=%s", p11_get_ckr(rc));

	if ((funcs->C_Logout(session)) != CKR_OK)
		testcase_error("C_Logout #4 failed.");

testcase_cleanup:
	if (funcs->C_CloseSession(session) != CKR_OK)
		testcase_error("C_CloseSession #1 failed.");

	return rc;
}
Ejemplo n.º 13
0
CK_RV do_GetSlotList(void)
{
	CK_FLAGS flags;
	CK_SESSION_HANDLE session;
	CK_RV rc = 0;
	CK_BYTE user_pin[PKCS11_MAX_PIN_LEN];
	CK_ULONG user_pin_len;

	CK_BBOOL tokenPresent;
	CK_SLOT_ID_PTR pSlotList = NULL;
	CK_ULONG ulCount = 0;

	tokenPresent = TRUE;

	testcase_begin("testing C_GetSlotList");
	testcase_rw_session();
	testcase_user_login();

	testcase_new_assertion();

	/* pkcs#11v2.20, Section 11.5
	 * If pSlotList is NULL_PTR, then all that C_GetSlotList does is
	 * return (in *pulCount) the number of slots, without actually
	 * returning a list of slots.
	 */
	rc = funcs->C_GetSlotList(tokenPresent, NULL, &ulCount);
	if (rc != CKR_OK) {
		testcase_fail("C_GetSlotList rc=%s", p11_get_ckr(rc));
		goto testcase_cleanup;
	}

	if (ulCount)
		testcase_pass("C_GetSlotList received slot count.");
	else
		testcase_fail("C_GetSlotList did not receive slot count.");

	pSlotList = (CK_SLOT_ID *)malloc(ulCount * sizeof(CK_SLOT_ID));
	if (!pSlotList) {
		testcase_error("malloc failed to allocate memory for list\n");
		rc = CKR_HOST_MEMORY;
		goto testcase_cleanup;
	}

	testcase_new_assertion();

	/* Get the slots */
	rc = funcs->C_GetSlotList(tokenPresent, pSlotList, &ulCount);
	if (rc != CKR_OK) {
		testcase_fail("C_GetSlotList rc=%s", p11_get_ckr(rc));
		goto testcase_cleanup;
	}

	testcase_pass("Slot list returned successfully");

testcase_cleanup:
	if (pSlotList)
		free(pSlotList);

	testcase_user_logout();
        if ((funcs->C_CloseSession(session)) != CKR_OK)
                testcase_error("C_CloseSession failed.");
	return rc;

}
Ejemplo n.º 14
0
CK_RV do_InitPIN(void)
{
	CK_SLOT_ID slot_id;
	CK_FLAGS flags;
	CK_SESSION_HANDLE session;
	CK_CHAR so_pin[PKCS11_MAX_PIN_LEN];
	CK_CHAR user_pin[PKCS11_MAX_PIN_LEN];
	CK_ULONG so_pin_len;
	CK_ULONG user_pin_len;
	CK_RV rc;

	testcase_begin("Testing C_InitPIN");

	if (get_user_pin(user_pin))
		return CKR_FUNCTION_FAILED;
	user_pin_len = (CK_ULONG)strlen((char *)user_pin);

	if (get_so_pin(so_pin))
		return CKR_FUNCTION_FAILED;
	so_pin_len = (CK_ULONG)strlen((char *)so_pin);

	slot_id = SLOT_ID;
	flags   = CKF_SERIAL_SESSION | CKF_RW_SESSION;

	// try to call C_InitPIN from a public session
	testcase_new_assertion();
	rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &session);
	if (rc != CKR_OK) {
		testcase_error("C_OpenSession rc=%s", p11_get_ckr(rc));
		return rc;
	}

	rc = funcs->C_InitPIN(session, user_pin, user_pin_len);
	if (rc != CKR_USER_NOT_LOGGED_IN) {
		testcase_fail("C_InitPIN returned %s instead of "
			      "CKR_USER_NOT_LOGGED_IN", p11_get_ckr(rc));
		goto testcase_cleanup;
	} else
		testcase_pass("C_InitPin correctly returned CKR_USER_NOT_LOGGED_IN.");

	// try to call C_InitPIN from an SO session
	testcase_new_assertion();
	rc = funcs->C_Login(session, CKU_SO, so_pin, so_pin_len);
	if (rc != CKR_OK) {
		testcase_error("C_Login #1 failed: rc=%s", p11_get_ckr(rc));
		goto testcase_cleanup;
	}

	rc = funcs->C_InitPIN(session, user_pin, user_pin_len);
	if (rc != CKR_OK)
		testcase_fail("C_InitPIN failed: rc=%s", p11_get_ckr(rc));
	else
		testcase_pass("C_InitPIN #1 was successful.");

	if ((funcs->C_Logout(session)) != CKR_OK) {
		testcase_error("C_Logout #1 failed.");
		if (rc != CKR_OK)
			goto testcase_cleanup;
	}

	// try to call C_InitPIN from a normal user session
	testcase_new_assertion();
	rc = funcs->C_Login( session, CKU_USER, user_pin, user_pin_len );
	if (rc != CKR_OK) {
		testcase_error("C_Login failed: rc=%s", p11_get_ckr(rc));
		goto testcase_cleanup;
	}

	rc = funcs->C_InitPIN(session, user_pin, user_pin_len);
	if (rc != CKR_USER_NOT_LOGGED_IN) {
		testcase_fail("C_InitPIN returned %s instead of "
			      "CKR_USER_NOT_LOGGED_IN.", p11_get_ckr(rc));
		rc = CKR_FUNCTION_FAILED;
	} else {
		testcase_pass("C_InitPIN #2 was successful.");
		rc = CKR_OK;
	}

	if  ((funcs->C_Logout(session)) != CKR_OK)
		testcase_error("C_Logout #2 rc=%s", p11_get_ckr(rc));

testcase_cleanup:
	if (funcs->C_CloseAllSessions(slot_id) != CKR_OK)
		testcase_error("C_CloseAllSessions #1 rc=%s", p11_get_ckr(rc));

	return rc;
}
Ejemplo n.º 15
0
CK_RV do_GetMechanismList(void)
{
	CK_FLAGS flags;
	CK_SESSION_HANDLE session;
	CK_RV rc = 0;
	CK_BYTE user_pin[PKCS11_MAX_PIN_LEN];
	CK_ULONG user_pin_len;
	CK_SLOT_ID slot_id = SLOT_ID;
	CK_ULONG count;
	CK_MECHANISM_TYPE *mech_list = NULL;

	testcase_begin("testing C_GetMechanismList");
	testcase_rw_session();
	testcase_user_login();

	/* pkcs11v2.20, page 111
	 * If pMechanismList is NULL_PTR, then all that C_GetMechanismList
	 * does is return (in *pulCount) the number of mechanisms, without
	 * actually returning a list of mechanisms. The contents of
	 * *pulCount on entry to C_GetMechanismList has no meaning in this
	 * case, and the call returns the value CKR_OK.
	 */
	testcase_new_assertion();

	rc = funcs->C_GetMechanismList(slot_id, NULL, &count);
	if (rc != CKR_OK) {
		testcase_fail("C_GetMechanismList 1 rc=%s",p11_get_ckr(rc));
		return rc;
	}

	if (count)
		testcase_pass("C_GetMechanismList returned mechanism count.");
	else
		testcase_fail("C_GetMechanismList did not not return "
			      "mechanism count.");

	mech_list = (CK_MECHANISM_TYPE *)malloc( count * sizeof(CK_MECHANISM_TYPE) );
	if (!mech_list) {
		testcase_fail();
		rc = CKR_HOST_MEMORY;
		goto testcase_cleanup;
	}

	testcase_new_assertion();
	rc = funcs->C_GetMechanismList(slot_id, mech_list, &count);
	if (rc != CKR_OK) {
		testcase_fail("C_GetMechanismList 2 rc=%s", p11_get_ckr(rc));
		goto testcase_cleanup;
	} else
		testcase_pass("Mechanism listing from current slot");

	/* Test for invalid slot */
	testcase_new_assertion();

	rc = funcs->C_GetMechanismList(999, NULL, &count);

	if (rc != CKR_SLOT_ID_INVALID) {
		testcase_fail("C_GetMechanismList() returned %s instead of"
			      " CKR_SLOT_ID_INVALID.", p11_get_ckr(rc));
		rc = CKR_FUNCTION_FAILED;
		goto testcase_cleanup;
	} else {
		testcase_pass("C_GetMechanismList correctly returned "
			      "CKR_SLOT_ID_INVALID.");
		rc = CKR_OK;
	}

testcase_cleanup:
	if (mech_list)
		free(mech_list);

        testcase_user_logout();
        if ((funcs->C_CloseSession(session)) != CKR_OK)
                testcase_error("C_CloseSessions failed.");

        return rc;
}
Ejemplo n.º 16
0
/* This function should test:
 * RSA Key Generation, using CKM_PKCS_KEY_PAIR_GEN
 * RSA Public-Key Wrap
 * RSA Private-Key Unwrap
 *
 */
CK_RV do_WrapUnwrapRSA(struct GENERATED_TEST_SUITE_INFO *tsuite)
{
	int i = 0, j = 0;
	char *s = NULL;
	CK_OBJECT_HANDLE publ_key, priv_key, secret_key, unwrapped_key;
	CK_BYTE_PTR wrapped_key = NULL;
	CK_ULONG wrapped_keylen, unwrapped_keylen = 0;
	CK_MECHANISM wrap_mech, keygen_mech, mech;
	CK_BYTE	clear[32], cipher[32], re_cipher[32];
	CK_ULONG cipher_len = 32, re_cipher_len = 32;
	CK_RSA_PKCS_OAEP_PARAMS oaep_params;

	CK_SESSION_HANDLE	session;
	CK_FLAGS		flags;
	CK_SLOT_ID		slot_id = SLOT_ID;
	CK_BYTE			user_pin[PKCS11_MAX_PIN_LEN];
	CK_ULONG		user_pin_len;
	CK_RV			rc, loc_rc;

	CK_OBJECT_CLASS	key_class = CKO_SECRET_KEY;
	CK_KEY_TYPE key_type;
	CK_ATTRIBUTE unwrap_tmpl[] = {
		{CKA_CLASS, &key_class, sizeof(CK_OBJECT_CLASS)},
		{CKA_KEY_TYPE, &key_type, sizeof(CK_KEY_TYPE)},
		{CKA_VALUE_LEN, &unwrapped_keylen, sizeof(CK_ULONG)}
	};
	CK_ULONG                unwrap_tmpl_len;

	// begin test suite
	testsuite_begin("%s Wrap Unwrap.", tsuite->name);
	testcase_rw_session();
	testcase_user_login();

	/* create some data */
	for (j = 0; j < 32; j++)
		clear[j] = j;

	// skip all tests if the slot doesn't support this mechanism
        if (! mech_supported(slot_id, tsuite->mech.mechanism)){
                testsuite_skip(tsuite->tvcount,
                           "Slot %u doesn't support %u",
                           (unsigned int) slot_id,
                           (unsigned int) tsuite->mech.mechanism );
                goto testcase_cleanup;
        }

	// skip all tests if the slot doesn't support wrapping
	else if (! wrap_supported(slot_id, tsuite->mech)) {
		testsuite_skip(tsuite->tvcount,
			"Slot %u doesn't support key wrapping",
			(unsigned int) slot_id);
		goto testcase_cleanup;

	}

	for (i = 0; i < tsuite->tvcount; i++) {

		// skip if the slot doesn't support the keygen mechanism
		if (!mech_supported(slot_id, tsuite->tv[i].keytype.mechanism)) {
			testcase_skip("Slot %u doesn't support %u",
				      (unsigned int)slot_id,
				      (unsigned int)tsuite->tv[i].keytype.mechanism);
			continue;
		}

		if (!keysize_supported(slot_id, tsuite->mech.mechanism,
					tsuite->tv[i].modbits)) {
			testcase_skip("Token in slot %ld cannot be used with "
					"modbits.='%ld'",
					SLOT_ID,tsuite->tv[i].modbits);
			continue;
		}

		// get public exponent from test vector
		if ( p11_ahex_dump(&s, tsuite->tv[i].publ_exp,
				tsuite->tv[i].publ_exp_len) == NULL) {
				testcase_error("p11_ahex_dump() failed");
			rc = -1;
			goto testcase_cleanup;
		}

		if (is_ep11_token(slot_id)) {
			if (! is_valid_ep11_pubexp(tsuite->tv[i].publ_exp,
						  tsuite->tv[i].publ_exp_len)) {
				testcase_skip("EP11 Token cannot "
					       "be used with publ_exp.='%s'",s);
				continue;
			}
		}

		// begin test
		testcase_begin("%s Wrap Unwrap with test vector %d, "
			"\npubl_exp='%s', mod_bits='%lu', keylen='%lu', "
			"keytype='%s'", tsuite->name, i, s,
			tsuite->tv[i].modbits, tsuite->tv[i].keylen,
			p11_get_ckm(tsuite->tv[i].keytype.mechanism));

		// free memory
		if (s)
			free(s);

		// get key gen mechanism
		keygen_mech = tsuite->tv[i].keytype;

		// get wrapping mechanism
		wrap_mech = tsuite->mech;
		if (wrap_mech.mechanism == CKM_RSA_PKCS_OAEP) {
			oaep_params = tsuite->tv[i].oaep_params;
			wrap_mech.pParameter = &oaep_params;
			wrap_mech.ulParameterLen = sizeof(CK_RSA_PKCS_OAEP_PARAMS);
		}

		// clear out buffers
		memset (cipher, 0, sizeof(cipher));
		memset (re_cipher, 0, sizeof(re_cipher));

		// initialize buffer lengths
		wrapped_keylen = PKCS11_MAX_PIN_LEN;

		// generate RSA key pair
		rc = generate_RSA_PKCS_KeyPair(session, tsuite->tv[i].modbits,
					       tsuite->tv[i].publ_exp,
					       tsuite->tv[i].publ_exp_len,
					       &publ_key, &priv_key);
		if (rc != CKR_OK) {
                        testcase_error("C_GenerateKeyPair() rc = %s",
					p11_get_ckr(rc));
                        goto testcase_cleanup;
		}

		// generate secret key
		rc = generate_SecretKey(session, tsuite->tv[i].keylen,
					&keygen_mech, &secret_key);
		if (rc != CKR_OK) {
			testcase_error("generate_SecretKey(), rc=%s",
				p11_get_ckr(rc));
			goto error;
		}

		/* Testcase Goals:
		 * 1. Encrypt data.
		 * 2. Use RSA to wrap the secret key we just used to encrypt.
		 * 3. Use RSA to unwrap the secret key.
		 * 4. Decrypt with the newly unwrapped key to get original data.
		 *
		 * The first assertion will be the success of RSA to wrap and
		 * unwrap the secret key.
		 * The second assertion will be the success of the unwrapped
		 * key to decrypt the original text.
		 * Note: Generic secret keys are not used for encrypt/decrypt
		 *       by default. So they will not be included in second
		 *	 assertion.
		 */
		if (keygen_mech.mechanism != CKM_GENERIC_SECRET_KEY_GEN) {

			switch (keygen_mech.mechanism) {
			case CKM_AES_KEY_GEN:
				mech.mechanism = CKM_AES_ECB;
				key_type = CKK_AES;
				break;
			case CKM_DES3_KEY_GEN:
				mech.mechanism = CKM_DES3_ECB;
				key_type = CKK_DES3;
				break;
			case CKM_DES_KEY_GEN:
				mech.mechanism = CKM_DES_ECB;
				key_type = CKK_DES;
				break;
			case CKM_CDMF_KEY_GEN:
				mech.mechanism = CKM_CDMF_ECB;
				key_type = CKK_CDMF;
				break;
			default:
				testcase_error("unknown mech");
				goto error;
			}

			mech.ulParameterLen = 0;
			mech.pParameter = NULL;

			rc = funcs->C_EncryptInit(session, &mech, secret_key);
			if (rc != CKR_OK) {
				testcase_error("C_EncryptInit secret_key "
					       ": rc = %s", p11_get_ckr(rc));
				goto error;
			}

			rc = funcs->C_Encrypt(session, clear, 32, cipher,
					      &cipher_len);
			if (rc != CKR_OK) {
				testcase_error("C_Encrypt secret_key: rc = %s",
						p11_get_ckr(rc));
				goto error;
			}
		} else
			key_type = CKK_GENERIC_SECRET;

		testcase_new_assertion();	/* assertion #1 */
		// wrap key (length only)
		rc = funcs->C_WrapKey(session, &wrap_mech, publ_key, secret_key,
				      NULL, &wrapped_keylen);
		if (rc != CKR_OK) {
			testcase_error("C_WrapKey(), rc=%s.", p11_get_ckr(rc));
			goto error;
		}

		// allocate memory for wrapped_key
		wrapped_key = calloc(sizeof(CK_BYTE), wrapped_keylen);
		if (wrapped_key == NULL) {
			testcase_error("Can't allocate memory for %lu bytes.",
					sizeof(CK_BYTE) * wrapped_keylen);
			rc = CKR_HOST_MEMORY;
			goto error;
		}

		// wrap key
		rc = funcs->C_WrapKey(session, &wrap_mech, publ_key, secret_key,
				      wrapped_key, &wrapped_keylen);
		if (rc != CKR_OK) {
			testcase_fail("C_WrapKey, rc=%s", p11_get_ckr(rc));
			goto error;
		}

		/* variable key length specific case:
		 * According to PKCS#11 v2.2 section 12.1.12
		 * CKM_RSA_X_509 does not wrap the key type, key length,
		 * or any other information about the key; the application
		 * must convey these separately, and supply them when
		 * unwrapping the key.
		 */
		if (((keygen_mech.mechanism == CKM_AES_KEY_GEN) ||
		    (keygen_mech.mechanism == CKM_GENERIC_SECRET_KEY_GEN)) && 
		    (wrap_mech.mechanism == CKM_RSA_X_509)) {
			unwrapped_keylen = tsuite->tv[i].keylen;
			unwrap_tmpl_len = 3;
		}
		else {
			unwrap_tmpl_len = 2;
		}

		// unwrap key
		rc = funcs->C_UnwrapKey(session, &wrap_mech, priv_key,
					wrapped_key, wrapped_keylen,
					unwrap_tmpl, unwrap_tmpl_len,
					&unwrapped_key);
		if (rc != CKR_OK) {
			testcase_fail("C_UnwrapKey, rc=%s",
				p11_get_ckr(rc));
			goto error;
		} else
			testcase_pass("wrapped and unwrapped key successful.");

		/* now decrypt the message with the unwrapped key */

		if (keygen_mech.mechanism != CKM_GENERIC_SECRET_KEY_GEN) {
			rc = funcs->C_DecryptInit(session,&mech,unwrapped_key);
			if (rc != CKR_OK) {
				testcase_error("C_DecryptInit unwrapped_key: "
					       " rc = %s", p11_get_ckr(rc));
				goto error;
			}

			rc = funcs->C_Decrypt(session, cipher, cipher_len,
					      re_cipher, &re_cipher_len);
			if (rc != CKR_OK) {
				testcase_error("C_Decrypt unwrapped_key: "
					       "rc = %s", p11_get_ckr(rc));
				goto error;
			}

			testcase_new_assertion();

			if (memcmp(clear, re_cipher, 32) != 0) {
				testcase_fail("ERROR:data mismatch\n");
				goto error;
			} else
				testcase_pass("Decrypted data is correct.");
		}

		// clean up
		if (wrapped_key) {
			free(wrapped_key);
			wrapped_key = NULL;
		}

		rc = funcs->C_DestroyObject(session, secret_key);
		if (rc != CKR_OK)
			testcase_error("C_DestroyObject(), rc=%s.",
					p11_get_ckr(rc));

		rc = funcs->C_DestroyObject(session, publ_key);
		if (rc != CKR_OK)
			testcase_error("C_DestroyObject(), rc=%s.",
					p11_get_ckr(rc));

		rc = funcs->C_DestroyObject(session, priv_key);
		if (rc != CKR_OK)
			testcase_error("C_DestroyObject(), rc=%s.",
					p11_get_ckr(rc));
	}
	goto testcase_cleanup;

error:
	if (wrapped_key) {
		free(wrapped_key);
		wrapped_key = NULL;
	}

	funcs->C_DestroyObject(session, secret_key);
	funcs->C_DestroyObject(session, publ_key);
	funcs->C_DestroyObject(session, priv_key);

testcase_cleanup:
	testcase_user_logout();
	loc_rc = funcs->C_CloseAllSessions(slot_id);
	if (loc_rc != CKR_OK) {
		testcase_error("C_CloseAllSessions(), rc=%s.",
			p11_get_ckr(rc));
	}
	return rc;
}