Exemplo n.º 1
0
void CPKCSDemoDlg::OnOK() 
{
	CK_RV rv;

	if(m_bKeyGen)
	{
		StartOP();
		BOOL bRet = TRUE;
		ShowMsg(NEWLINE"Clear Key Pair which was generated!"NEWLINE);
		UpdateWindow();
		::SetCursor(::LoadCursor(NULL, IDC_WAIT));

		rv = C_DestroyObject(m_hSession, m_hPubKey);
		if(CKR_OK != rv)
		{
			bRet = FALSE;
			ShowErr(NEWLINE"Can't delete public key ,Error code 0x%08X."NEWLINE, rv);
		}
		rv = C_DestroyObject(m_hSession, m_hPriKey);
		if(CKR_OK != rv)
		{
			bRet = FALSE;
			ShowErr(NEWLINE"Can't delete private key ,Error code 0x%08X."NEWLINE, rv);
		}
		if(bRet)
			ShowMsg(NEWLINE"Clear Key Pair that was generated successfully!"NEWLINE);
	}

	CDialog::OnOK();
}
Exemplo n.º 2
0
/*
 * PKCS_AcquirePublicKeyHandle
 *
 *   Given an assymetric key keyblob, attempts to find the appropriate
 *    public key.
 *
 *  Methods of finding the public key:
 *  - Public Key with data present:
 *    Parses the key and creates a temporary session object.
 *  - Public Key with handle:
 *    The handle is type converted and returned. Validity of the handle is
 *    not checked.
 *  - Public Key with label:
 *    Attempts to find a public key with the corresponding label.
 */
static KMF_RETURN
PKCS_AcquirePublicKeyHandle(CK_SESSION_HANDLE ckSession,
	const KMF_X509_SPKI *pKey,
	CK_KEY_TYPE ckRequestedKeyType,
	CK_OBJECT_HANDLE *pckKeyHandle)
{
	KMF_RETURN mrReturn = KMF_OK;

	/* Key searching variables */
	CK_OBJECT_HANDLE ckKeyHandle = 0;
	CK_OBJECT_CLASS ckObjClass;
	CK_KEY_TYPE ckKeyType;
	CK_ATTRIBUTE ckTemplate[3];
	CK_ULONG ckNumTemplates;
	static const CK_ULONG ckMaxTemplates = (sizeof (ckTemplate) /
	    sizeof (CK_ATTRIBUTE));
	CK_RV ckRv;

	/* Extract the data from the SPKI into individual fields */
	mrReturn = PKCS_CreatePublicKey(pKey, ckSession, &ckKeyHandle);
	if (mrReturn != KMF_OK)
		return (mrReturn);

	/* Fetch the key class and algorithm from the object */
	ckNumTemplates = 0;
	if (!PKCS_AddTemplate(ckTemplate, &ckNumTemplates,
	    ckMaxTemplates, CKA_CLASS, (CK_BYTE *)&ckObjClass,
	    sizeof (ckObjClass)) ||
	    !PKCS_AddTemplate(ckTemplate, &ckNumTemplates,
	    ckMaxTemplates, CKA_KEY_TYPE, (CK_BYTE *)&ckKeyType,
	    sizeof (ckKeyType))) {
		(void) C_DestroyObject(ckSession, ckKeyHandle);
		return (KMF_ERR_INTERNAL);
	}
	ckRv = C_GetAttributeValue(ckSession, ckKeyHandle,
	    ckTemplate,	ckNumTemplates);
	if (ckRv != CKR_OK) {
		(void) C_DestroyObject(ckSession, ckKeyHandle);
		return (ckRv);
	}

	/* Make sure the results match the expected values */
	if ((ckKeyType != ckRequestedKeyType) ||
	    (ckObjClass != CKO_PUBLIC_KEY)) {
		(void) C_DestroyObject(ckSession, ckKeyHandle);
		return (KMF_ERR_BAD_KEY_FORMAT);
	}

	/* Set the return values */
	*pckKeyHandle = ckKeyHandle;

	return (KMF_OK);
}
void SymmetricAlgorithmTests::testNullTemplate()
{
	CK_RV rv;
	CK_UTF8CHAR pin[] = SLOT_0_USER1_PIN;
	CK_ULONG pinLength = sizeof(pin) - 1;
	CK_SESSION_HANDLE hSession;
	CK_MECHANISM mechanism1 = { CKM_DES3_KEY_GEN, NULL_PTR, 0 };
	CK_MECHANISM mechanism2 = { CKM_AES_KEY_GEN, NULL_PTR, 0 };
	CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;

	// Just make sure that we finalize any previous tests
	C_Finalize(NULL_PTR);

	// Initialize the library and start the test.
	rv = C_Initialize(NULL_PTR);
	CPPUNIT_ASSERT(rv == CKR_OK);

	// Open read-write session
	rv = C_OpenSession(SLOT_INIT_TOKEN, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession);
	CPPUNIT_ASSERT(rv == CKR_OK);

	// Login USER into the sessions so we can create a private objects
	rv = C_Login(hSession, CKU_USER, pin, pinLength);
	CPPUNIT_ASSERT(rv==CKR_OK);

	rv = C_GenerateKey(hSession, &mechanism1, NULL_PTR, 0, &hKey);
	CPPUNIT_ASSERT(rv == CKR_OK);

	rv = C_DestroyObject(hSession, hKey);
	CPPUNIT_ASSERT(rv == CKR_OK);

	rv = C_GenerateKey(hSession, &mechanism2, NULL_PTR, 0, &hKey);
	CPPUNIT_ASSERT(rv == CKR_TEMPLATE_INCOMPLETE);
}
Exemplo n.º 4
0
krb5_error_code
krb5_free_ef_handle(krb5_context ctx)
{
	/* 
	 * fork safety: Don't free any PKCS state if we've forked since
	 * allocating the pkcs handles.
	 */
	if (ctx->cryptoki_initialized == TRUE &&
	    ctx->pid == __krb5_current_pid) {
		/* 
		 * It is safe for this function to access ctx->hSession
		 * directly.  Do NOT use the krb_ctx_hSession() here.
		 */
		if (ctx->hSession) {
			C_CloseSession(ctx->hSession);
			ctx->hSession = 0;
		}
		if (ctx->arcfour_ctx.dKey) {
			C_DestroyObject(ctx->arcfour_ctx.dSession,
				ctx->arcfour_ctx.dKey);
			ctx->arcfour_ctx.dKey = 0;
		}
		if (ctx->arcfour_ctx.eKey) {
			C_DestroyObject(ctx->arcfour_ctx.eSession,
				ctx->arcfour_ctx.eKey);
			ctx->arcfour_ctx.eKey = 0;
		}
		if (ctx->arcfour_ctx.eSession) {
			C_CloseSession(ctx->arcfour_ctx.eSession);
			ctx->arcfour_ctx.eSession = 0;
		}
		if (ctx->arcfour_ctx.dSession) {
			C_CloseSession(ctx->arcfour_ctx.dSession);
			ctx->arcfour_ctx.eSession = 0;
		}
		ctx->arcfour_ctx.initialized = 0;

		ctx->cryptoki_initialized = FALSE;
	}
	return(0);
}
CK_RV SymmetricAlgorithmTests::generateRsaPrivateKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
{
	CK_MECHANISM mechanism = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 };
	CK_ULONG bits = 1536;
	CK_BYTE pubExp[] = {0x01, 0x00, 0x01};
	CK_BYTE subject[] = { 0x12, 0x34 }; // dummy
	CK_BYTE id[] = { 123 } ; // dummy
	CK_BBOOL bFalse = CK_FALSE;
	CK_BBOOL bTrue = CK_TRUE;
	CK_ATTRIBUTE pubAttribs[] = {
		{ CKA_TOKEN, &bToken, sizeof(bToken) },
		{ CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
		{ CKA_ENCRYPT, &bFalse, sizeof(bFalse) },
		{ CKA_VERIFY, &bTrue, sizeof(bTrue) },
		{ CKA_WRAP, &bFalse, sizeof(bFalse) },
		{ CKA_MODULUS_BITS, &bits, sizeof(bits) },
		{ CKA_PUBLIC_EXPONENT, &pubExp[0], sizeof(pubExp) }
	};
	CK_ATTRIBUTE privAttribs[] = {
		{ CKA_TOKEN, &bToken, sizeof(bToken) },
		{ CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
		{ CKA_SUBJECT, &subject[0], sizeof(subject) },
		{ CKA_ID, &id[0], sizeof(id) },
		{ CKA_SENSITIVE, &bTrue, sizeof(bTrue) },
		{ CKA_DECRYPT, &bFalse, sizeof(bFalse) },
		{ CKA_SIGN, &bTrue, sizeof(bTrue) },
		{ CKA_UNWRAP, &bFalse, sizeof(bFalse) },
		{ CKA_SENSITIVE, &bFalse, sizeof(bFalse) },
		{ CKA_EXTRACTABLE, &bTrue, sizeof(bTrue) }
	};

	CK_OBJECT_HANDLE hPub = CK_INVALID_HANDLE;
	hKey = CK_INVALID_HANDLE;
	CK_RV rv;
	rv = C_GenerateKeyPair(hSession, &mechanism,
			       pubAttribs, sizeof(pubAttribs)/sizeof(CK_ATTRIBUTE),
			       privAttribs, sizeof(privAttribs)/sizeof(CK_ATTRIBUTE),
			       &hPub, &hKey);
	if (hPub != CK_INVALID_HANDLE)
	{
		C_DestroyObject(hSession, hPub);
	}
	return rv;
}
void SymmetricAlgorithmTests::testNonModifiableDesKeyGeneration()
{
	CK_RV rv;
	CK_UTF8CHAR pin[] = SLOT_0_USER1_PIN;
	CK_ULONG pinLength = sizeof(pin) - 1;
	CK_SESSION_HANDLE hSession;
	CK_MECHANISM mechanism = { CKM_DES3_KEY_GEN, NULL_PTR, 0 };
	CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
	CK_BBOOL bFalse = CK_FALSE;
	CK_BBOOL bTrue = CK_TRUE;
	CK_BBOOL bToken = IN_SESSION;

	CK_ATTRIBUTE keyAttribs[] =
		{
		{ CKA_TOKEN, &bToken, sizeof(bToken) },
		{ CKA_PRIVATE, &bTrue, sizeof(bTrue) },
		{ CKA_MODIFIABLE, &bTrue, sizeof(bTrue) },
		{ CKA_ENCRYPT, &bTrue, sizeof(bTrue) },
		{ CKA_DECRYPT, &bTrue, sizeof(bTrue) },
		{ CKA_WRAP, &bTrue, sizeof(bTrue) }
	};

	// Just make sure that we finalize any previous tests
	C_Finalize(NULL_PTR);

	// Initialize the library and start the test.
	rv = C_Initialize(NULL_PTR);
	CPPUNIT_ASSERT(rv == CKR_OK);

	// Open read-write session
	rv = C_OpenSession(SLOT_INIT_TOKEN, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession);
	CPPUNIT_ASSERT(rv == CKR_OK);

	// Login USER into the sessions so we can create a private objects
	rv = C_Login(hSession, CKU_USER, pin, pinLength);
	CPPUNIT_ASSERT(rv==CKR_OK);

	rv = C_GenerateKey(hSession, &mechanism,
		keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
		&hKey);
	CPPUNIT_ASSERT(rv == CKR_OK);

	rv = C_DestroyObject(hSession, hKey);
	CPPUNIT_ASSERT(rv == CKR_OK);

	// The C_GenerateKey call failed if CKA_MODIFIABLE was bFalse
	// This was a bug in the SoftHSM implementation
	keyAttribs[2].pValue = &bFalse;
	keyAttribs[2].ulValueLen = sizeof(bFalse);

	rv = C_GenerateKey(hSession, &mechanism,
		keyAttribs, sizeof(keyAttribs) / sizeof(CK_ATTRIBUTE),
		&hKey);
	// The call would fail with CKR_ATTRIBUTE_READ_ONLY
	CPPUNIT_ASSERT(rv == CKR_OK);

	// Now create a template where the CKA_MODIFIABLE attribute is last in the list
	CK_ATTRIBUTE keyAttribs1[] =
	{
		{ CKA_TOKEN, &bToken, sizeof(bToken) },
		{ CKA_PRIVATE, &bTrue, sizeof(bTrue) },
		{ CKA_ENCRYPT, &bTrue, sizeof(bTrue) },
		{ CKA_DECRYPT, &bTrue, sizeof(bTrue) },
		{ CKA_WRAP, &bTrue, sizeof(bTrue) },
		{ CKA_MODIFIABLE, &bTrue, sizeof(bTrue) }
	};

	rv = C_GenerateKey(hSession, &mechanism,
		keyAttribs1, sizeof(keyAttribs1) / sizeof(CK_ATTRIBUTE),
		&hKey);
	CPPUNIT_ASSERT(rv == CKR_OK);

	// Now when CKA_MODIFIABLE is bFalse the key generation succeeds
	keyAttribs1[2].pValue = &bFalse;
	keyAttribs1[2].ulValueLen = sizeof(bFalse);

	rv = C_GenerateKey(hSession, &mechanism,
		keyAttribs1, sizeof(keyAttribs1) / sizeof(CK_ATTRIBUTE),
		&hKey);
	CPPUNIT_ASSERT(rv == CKR_OK);
}
void SymmetricAlgorithmTests::aesWrapUnwrap(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
{
	CK_MECHANISM mechanism = { mechanismType, NULL_PTR, 0 };
	CK_BBOOL bFalse = CK_FALSE;
	CK_BBOOL bTrue = CK_TRUE;
	CK_OBJECT_CLASS secretClass = CKO_SECRET_KEY;
	CK_KEY_TYPE genKeyType = CKK_GENERIC_SECRET;
	CK_BYTE keyPtr[128];
	CK_ULONG keyLen =
		mechanismType == CKM_AES_KEY_WRAP_PAD ? 125UL : 128UL;
	CK_ATTRIBUTE attribs[] = {
		{ CKA_EXTRACTABLE, &bFalse, sizeof(bFalse) },
		{ CKA_CLASS, &secretClass, sizeof(secretClass) },
		{ CKA_KEY_TYPE, &genKeyType, sizeof(genKeyType) },
		{ CKA_TOKEN, &bFalse, sizeof(bFalse) },
		{ CKA_PRIVATE, &bTrue, sizeof(bTrue) },
		{ CKA_SENSITIVE, &bTrue, sizeof(bTrue) }, // Wrapping is allowed even on sensitive objects
		{ CKA_VALUE, keyPtr, keyLen }
	};
	CK_OBJECT_HANDLE hSecret;
	CK_RV rv;

	rv = C_GenerateRandom(hSession, keyPtr, keyLen);
	CPPUNIT_ASSERT(rv == CKR_OK);

	hSecret = CK_INVALID_HANDLE;
	rv = C_CreateObject(hSession, attribs, sizeof(attribs)/sizeof(CK_ATTRIBUTE), &hSecret);
	CPPUNIT_ASSERT(rv == CKR_OK);
	CPPUNIT_ASSERT(hSecret != CK_INVALID_HANDLE);

	CK_BYTE_PTR wrappedPtr = NULL_PTR;
	CK_ULONG wrappedLen = 0UL;
	CK_ULONG zero = 0UL;
	CK_ULONG rndKeyLen = keyLen;
	if (mechanismType == CKM_AES_KEY_WRAP_PAD)
		rndKeyLen =  (keyLen + 7) & ~7;
	rv = C_WrapKey(hSession, &mechanism, hKey, hSecret, wrappedPtr, &wrappedLen);
	CPPUNIT_ASSERT(rv == CKR_KEY_UNEXTRACTABLE);
	rv = C_DestroyObject(hSession, hSecret);
	CPPUNIT_ASSERT(rv == CKR_OK);

	attribs[0].pValue = &bTrue;

	hSecret = CK_INVALID_HANDLE;
	rv = C_CreateObject(hSession, attribs, sizeof(attribs)/sizeof(CK_ATTRIBUTE), &hSecret);
	CPPUNIT_ASSERT(rv == CKR_OK);
	CPPUNIT_ASSERT(hSecret != CK_INVALID_HANDLE);

	// Estimate wrapped length
	rv = C_WrapKey(hSession, &mechanism, hKey, hSecret, wrappedPtr, &wrappedLen);
	CPPUNIT_ASSERT(rv == CKR_OK);
	CPPUNIT_ASSERT(wrappedLen == rndKeyLen + 8);

	wrappedPtr = (CK_BYTE_PTR) malloc(wrappedLen);
	CPPUNIT_ASSERT(wrappedPtr != NULL_PTR);
	rv = C_WrapKey(hSession, &mechanism, hKey, hSecret, wrappedPtr, &wrappedLen);
	CPPUNIT_ASSERT(rv == CKR_OK);
	CPPUNIT_ASSERT(wrappedLen == rndKeyLen + 8);

	// This should always fail because wrapped data have to be longer than 0 bytes
	zero = 0;
	rv = C_WrapKey(hSession, &mechanism, hKey, hSecret, wrappedPtr, &zero);
	CPPUNIT_ASSERT(rv == CKR_BUFFER_TOO_SMALL);

	CK_ATTRIBUTE nattribs[] = {
		{ CKA_CLASS, &secretClass, sizeof(secretClass) },
		{ CKA_KEY_TYPE, &genKeyType, sizeof(genKeyType) },
		{ CKA_TOKEN, &bFalse, sizeof(bFalse) },
		{ CKA_PRIVATE, &bTrue, sizeof(bTrue) },
		{ CKA_ENCRYPT, &bFalse, sizeof(bFalse) },
		{ CKA_DECRYPT, &bTrue, sizeof(bTrue) },
		{ CKA_SIGN, &bFalse,sizeof(bFalse) },
		{ CKA_VERIFY, &bTrue, sizeof(bTrue) }
	};
	CK_OBJECT_HANDLE hNew;

	hNew = CK_INVALID_HANDLE;
	rv = C_UnwrapKey(hSession, &mechanism, hKey, wrappedPtr, wrappedLen, nattribs, sizeof(nattribs)/sizeof(CK_ATTRIBUTE), &hNew);
	CPPUNIT_ASSERT(rv == CKR_OK);
	CPPUNIT_ASSERT(hNew != CK_INVALID_HANDLE);

	free(wrappedPtr);
	wrappedPtr = NULL_PTR;
	rv = C_DestroyObject(hSession, hSecret);
	CPPUNIT_ASSERT(rv == CKR_OK);

#ifdef HAVE_AES_KEY_WRAP_PAD
	if (mechanismType != CKM_AES_KEY_WRAP_PAD) return;

	CK_OBJECT_HANDLE hRsa;
	hRsa = CK_INVALID_HANDLE;
	rv = generateRsaPrivateKey(hSession, CK_TRUE, CK_TRUE, hRsa);
	CPPUNIT_ASSERT(rv == CKR_OK);
	CPPUNIT_ASSERT(hRsa != CK_INVALID_HANDLE);

	CK_OBJECT_CLASS privateClass = CKO_PRIVATE_KEY;
	CK_KEY_TYPE rsaKeyType = CKK_RSA;
	CK_BYTE_PTR p2Ptr = NULL_PTR;
	CK_ULONG p2Len = 0UL;
	CK_ATTRIBUTE rsaAttribs[] = {
		{ CKA_CLASS, &privateClass, sizeof(privateClass) },
		{ CKA_KEY_TYPE, &rsaKeyType, sizeof(rsaKeyType) },
		{ CKA_PRIME_2, NULL_PTR, 0UL }
	};

	rv = C_GetAttributeValue(hSession, hRsa, rsaAttribs, sizeof(rsaAttribs)/sizeof(CK_ATTRIBUTE));
	CPPUNIT_ASSERT(rv == CKR_OK);

	CPPUNIT_ASSERT(rsaAttribs[0].ulValueLen == sizeof(CK_OBJECT_CLASS));
	CPPUNIT_ASSERT(*(CK_OBJECT_CLASS*)rsaAttribs[0].pValue == CKO_PRIVATE_KEY);
	CPPUNIT_ASSERT(rsaAttribs[1].ulValueLen == sizeof(CK_KEY_TYPE));
	CPPUNIT_ASSERT(*(CK_KEY_TYPE*)rsaAttribs[1].pValue == CKK_RSA);

	p2Len = rsaAttribs[2].ulValueLen;
	p2Ptr = (CK_BYTE_PTR) malloc(2 * p2Len);
	CPPUNIT_ASSERT(p2Ptr != NULL_PTR);
	rsaAttribs[2].pValue = p2Ptr;
	rsaAttribs[2].ulValueLen = p2Len;

	rv = C_GetAttributeValue(hSession, hRsa, rsaAttribs, sizeof(rsaAttribs)/sizeof(CK_ATTRIBUTE));
	CPPUNIT_ASSERT(rv == CKR_OK);
	CPPUNIT_ASSERT(rsaAttribs[2].ulValueLen == p2Len);

	rv = C_WrapKey(hSession, &mechanism, hKey, hRsa, wrappedPtr, &wrappedLen);
	CPPUNIT_ASSERT(rv == CKR_OK);
	wrappedPtr = (CK_BYTE_PTR) malloc(wrappedLen);
	CPPUNIT_ASSERT(wrappedPtr != NULL_PTR);
	rv = C_WrapKey(hSession, &mechanism, hKey, hRsa, wrappedPtr, &wrappedLen);
	CPPUNIT_ASSERT(rv == CKR_OK);

	rv = C_DestroyObject(hSession, hRsa);
	CPPUNIT_ASSERT(rv == CKR_OK);

	CK_ATTRIBUTE nRsaAttribs[] = {
		{ CKA_CLASS, &privateClass, sizeof(privateClass) },
		{ CKA_KEY_TYPE, &rsaKeyType, sizeof(rsaKeyType) },
		{ CKA_TOKEN, &bFalse, sizeof(bFalse) },
		{ CKA_PRIVATE, &bTrue, sizeof(bTrue) },
		{ CKA_DECRYPT, &bTrue, sizeof(bTrue) },
		{ CKA_SIGN, &bFalse,sizeof(bFalse) },
		{ CKA_UNWRAP, &bTrue, sizeof(bTrue) },
		{ CKA_SENSITIVE, &bFalse, sizeof(bFalse) },
		{ CKA_EXTRACTABLE, &bTrue, sizeof(bTrue) }
	};

	hRsa = CK_INVALID_HANDLE;
	rv = C_UnwrapKey(hSession, &mechanism, hKey, wrappedPtr, wrappedLen, nRsaAttribs, sizeof(nRsaAttribs)/sizeof(CK_ATTRIBUTE), &hRsa);
	CPPUNIT_ASSERT(rv == CKR_OK);
	CPPUNIT_ASSERT(hRsa != CK_INVALID_HANDLE);

	rsaAttribs[2].pValue = p2Ptr + p2Len;
	rv = C_GetAttributeValue(hSession, hRsa, rsaAttribs, sizeof(rsaAttribs)/sizeof(CK_ATTRIBUTE));
	CPPUNIT_ASSERT(rv == CKR_OK);

	CPPUNIT_ASSERT(rsaAttribs[0].ulValueLen == sizeof(CK_OBJECT_CLASS));
	CPPUNIT_ASSERT(*(CK_OBJECT_CLASS*)rsaAttribs[0].pValue == CKO_PRIVATE_KEY);
	CPPUNIT_ASSERT(rsaAttribs[1].ulValueLen == sizeof(CK_KEY_TYPE));
	CPPUNIT_ASSERT(*(CK_KEY_TYPE*)rsaAttribs[1].pValue == CKK_RSA);
	CPPUNIT_ASSERT(rsaAttribs[2].ulValueLen == p2Len);
	CPPUNIT_ASSERT(memcmp(p2Ptr, p2Ptr + p2Len, p2Len) == 0);

	free(wrappedPtr);
	free(p2Ptr);
	rv = C_DestroyObject(hSession, hRsa);
	CPPUNIT_ASSERT(rv == CKR_OK);
#endif
}
Exemplo n.º 8
0
FLAG ECCTest_out()
{
	CK_RV rv = 0;
	CK_SLOT_ID SlotId = 0;
	CK_SESSION_HANDLE hSession = 0;
	CK_OBJECT_HANDLE hECCPubKey = 0;
	CK_OBJECT_HANDLE hECCPriKey = 0;
	CK_BBOOL isTrue = TRUE;
	CK_ULONG ECCPubKeyClass = CKO_PUBLIC_KEY;
	CK_ULONG ECCPriKeyClass = CKO_PRIVATE_KEY;
	CK_BYTE Id[] = "MY_ECC_KEY";

	CK_ATTRIBUTE ECCPubKey[] = {
		{CKA_CLASS, &ECCPubKeyClass, sizeof(ECCPubKeyClass)},
		{CKA_ID, &Id, strlen(Id)},
		{CKA_TOKEN, &isTrue, sizeof(isTrue)}
								};

	CK_ATTRIBUTE ECCPriKey[] = {
		{CKA_CLASS, &ECCPriKeyClass, sizeof(ECCPriKeyClass)},
		{CKA_ID, &Id, strlen(Id)},
		{CKA_TOKEN, &isTrue, sizeof(isTrue)}
								};

	CK_ATTRIBUTE CreateECCPubKey[] = {
		{CKA_CLASS, NULL_PTR, 0},
		{CKA_MODULUS_BITS, NULL_PTR, 0},
		{CKA_ID, NULL_PTR, 0},
		{CKA_EC_POINT, NULL_PTR, 0}
								};

	CK_ATTRIBUTE CreateECCPriKey[] = {
		{CKA_CLASS, NULL_PTR, 0},
		{CKA_ID, NULL_PTR, 0},
		{CKA_MODULUS_BITS, NULL_PTR, 0},
		{CKA_VALUE, NULL_PTR, 0}
								};
	
	CK_MECHANISM ECCGenKey = {CKM_ECDSA_KEY_PAIR_GEN, NULL_PTR, 0};
	CK_MECHANISM mECCEncrypt = {CKM_ECDSA_PKCS, NULL_PTR, 0};
	CK_BYTE indata[160] = {0x00};
	CK_BYTE outdata[300] = {0x00};
	CK_BYTE temp[300] = {0x00};
	CK_ULONG outlength = 0;
	CK_ULONG templength = 0;

	printf("ECC Outside Encrypt and Decrypt!\n");
	rv = C_OpenSession(SlotId, CKF_SERIAL_SESSION|CKF_RW_SESSION, NULL_PTR, NULL, &hSession);
#ifdef DEVICE_KEY
	C_Login(hSession, CKU_SO, "11111111", 8);
#endif
	rv = C_GenerateKeyPair(hSession, &ECCGenKey, ECCPubKey, 3, ECCPriKey, 3, &hECCPubKey, &hECCPriKey);
	rv = C_CloseSession(hSession);

	rv = C_OpenSession(SlotId, CKF_SERIAL_SESSION|CKF_RW_SESSION, NULL_PTR, NULL, &hSession);
#ifdef DEVICE_KEY
	C_Login(hSession, CKU_SO, "11111111", 8);
#endif
	rv = C_GetAttributeValue(hSession, hECCPubKey, CreateECCPubKey, 4);
	if (rv == 0)
	{
		CreateECCPubKey[0].pValue = malloc(CreateECCPubKey[0].ulValueLen);
		if (CreateECCPubKey[0].pValue == NULL)
		{
			printf("ECCTest_out->malloc ERROR!\n");
			return -1;
		}
		CreateECCPubKey[1].pValue = malloc(CreateECCPubKey[1].ulValueLen);
		if (CreateECCPubKey[1].pValue == NULL)
		{
			printf("ECCTest_out->malloc ERROR!\n");
			FreeAttribute(CreateECCPubKey, 1);
			return -1;
		}
		CreateECCPubKey[2].pValue = malloc(CreateECCPubKey[2].ulValueLen);
		if (CreateECCPubKey[2].pValue == NULL)
		{
			printf("ECCTest_out->malloc ERROR!\n");
			FreeAttribute(CreateECCPubKey, 2);
			return -1;
		}
		CreateECCPubKey[3].pValue = malloc(CreateECCPubKey[3].ulValueLen);
		if (CreateECCPubKey[3].pValue == NULL)
		{
			printf("ECCTest_out->malloc ERROR!\n");
			FreeAttribute(CreateECCPubKey, 3);
			return -1;
		}
		rv = C_GetAttributeValue(hSession, hECCPubKey, CreateECCPubKey, 4);
		rv = C_DestroyObject(hSession, hECCPubKey);
		rv = C_CreateObject(hSession, CreateECCPubKey, 4, &hECCPubKey);
	}
	FreeAttribute(CreateECCPubKey, 4);

	memset(indata, 0x33, 110);
	memset(outdata, 0x00, 300);
	memset(temp, 0x00, 300);
	
	rv = C_EncryptInit(hSession, &mECCEncrypt, hECCPubKey);
	rv = C_Encrypt(hSession, indata, 110, outdata, &outlength);

	rv = C_GetAttributeValue(hSession, hECCPriKey, CreateECCPriKey, 4);
	if (rv == 0)
	{
		CreateECCPriKey[0].pValue = malloc(CreateECCPriKey[0].ulValueLen);
		if (CreateECCPriKey[0].pValue == NULL)
		{
			printf("ECCTest_out->malloc ERROR!\n");
			return -1;
		}
		CreateECCPriKey[1].pValue = malloc(CreateECCPriKey[1].ulValueLen);
		if (CreateECCPriKey[1].pValue == NULL)
		{
			printf("ECCTest_out->malloc ERROR!\n");
			FreeAttribute(CreateECCPriKey, 1);
			return -1;
		}
	
		CreateECCPriKey[2].pValue = malloc(CreateECCPriKey[2].ulValueLen);
		if (CreateECCPriKey[2].pValue == NULL)
		{
			printf("ECCTest_out->malloc ERROR!\n");
			FreeAttribute(CreateECCPriKey, 2);
			return -1;
		}
		CreateECCPriKey[3].pValue = malloc(CreateECCPriKey[3].ulValueLen);
		if (CreateECCPriKey[3].pValue == NULL)
		{
			printf("ECCTest_out->malloc ERROR!\n");
			FreeAttribute(CreateECCPriKey, 3);
			return -1;
		}
		rv = C_GetAttributeValue(hSession, hECCPriKey, CreateECCPriKey, 4);
		rv = C_DestroyObject(hSession, hECCPriKey);
		rv = C_CreateObject(hSession, CreateECCPriKey, 4, &hECCPriKey);
	}
	FreeAttribute(CreateECCPriKey, 4);

	rv = C_DecryptInit(hSession, &mECCEncrypt, hECCPriKey);
	rv = C_Decrypt(hSession, outdata, outlength, temp, &templength);
#ifdef DEVICE_KEY
	C_Logout(hSession);
#endif
	rv = C_CloseSession(hSession);

	if (memcmp(indata, temp, 110) == 0 && templength == 110)
	{
		printf("OK ECC OUT!\n");
	}
	else
	{
		printf("ERROR ECC OUT!\n");
	}
	return 0;
}
Exemplo n.º 9
0
int main(int argc, char const *argv[]){
	CK_RV rv = CKR_OK;
	CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
	CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
	CK_SLOT_ID slotId = 0;
	FILE *file;
	FILE *file_out;
	
	char * key_name;
	char command;

	if (argc !=3) {
		printf("Wrong arguments\n");
		printf("Usage:\n");
		printf("\t%s <command> <key name>\n", argv[0]);
		printf("\t\te - encode\n\t\td - decode\n\n");
		return 1;
	}

	/* read the command and key name arguments from the command line */
	command = argv[1][0];
	key_name = argv[2];

	/* Initialise the cryptoki API */
	printf( "Initializing Cryptoki API ... " );
    rv = C_Initialize(NULL);
    CHECK_CK_RV_GOTO(rv, "C_Initialize", end);
	printf( "OK\n" );

	/* Obtain a session so we can perform cryptoki operations */
	printf( "Obtaining a session ... " );
    rv = C_OpenSession(slotId, CKF_RW_SESSION, NULL, NULL, &hSession);
    CHECK_CK_RV_GOTO(rv, "C_OpenSession", end);
	printf( "OK\n" );

	printf("Using key: %s\n", key_name);

    /* Login as a user with a PIN */
	printf( "Logining as a user with a PIN ... " );
	rv = C_Login(hSession, CKU_USER, (CK_CHAR_PTR)USERPIN, (CK_SIZE) strlen((char*)USERPIN));
	CHECK_CK_RV_GOTO(rv, "C_Login as User", end);
	printf( "OK\n" );

	printf("Creating 3DES secret key ... ");
	rv = CreateSecretKeyObject(hSession, &hKey, key_name);
	CHECK_CK_RV_GOTO(rv, "CreateSecretKeyObject", end);
	printf("OK\n");

	printf("Finding 3DES key ... ");
	rv = findObject(hSession, CKO_SECRET_KEY, key_name, &hKey);
	CHECK_CK_RV_GOTO(rv, "findObject", end);
	printf("OK\n");
		
	switch(command) {
		
		case 'e':
			printf("Opening file... ");
			file = fopen("input.txt", "rb");
			if (!file) {
				printf("file not found\n");
				return 1;
			} else {
				file_out = fopen("output.txt", "wb");
				printf("ok\n");
			}
			
			printf("Encrypting file with 3DES ... ");
			rv = encryptDataLoop(file, file_out, hSession, hKey);
			CHECK_CK_RV_GOTO(rv, "encryptDataLoop", end);
			printf("OK\n");

			fclose(file);
			fclose(file_out);
			break;
		
		case 'd':
			printf("Opening file... ");
			file = fopen("output.txt", "rb");
			if (!file) {
				printf("file not found\n");
				return 1;
			} else {
				file_out = fopen("output2.txt", "wb");
				printf("ok\n");
			}

			printf("Decrypting file with 3DES ... ");
			rv = decryptDataLoop(file, file_out, hSession, hKey);
			CHECK_CK_RV_GOTO(rv, "decryptDataLoop", end);
			printf("OK\n");

			fclose(file);
			fclose(file_out);
			break;

		default:
			printf("Unknown command: %s\n", argv[1]);
	}

	/** Destroying the 3DES key */
	printf("Destrying the 3DES key ... ");
	rv = C_DestroyObject(hSession, hKey);
	CHECK_CK_RV_GOTO(rv, "DestroyObject", end);
	printf("OK\n");

	/* We've finished our work, close the session */
	printf( "Closing the session ... " );
    rv = C_CloseSession(hSession);
    CHECK_CK_RV_GOTO(rv, "C_CloseSession", end);
	printf("OK\n");

    /* We no longer need the cryptoki API ... */
	printf( "Finilizing the cryptoki ... " );
    rv = C_Finalize(NULL);
    CHECK_CK_RV_GOTO(rv, "C_Finalize", end);
	printf("OK\n");

	end:
    if (rv != CKR_OK)
    {
        fprintf(stderr,
                "Error performing create key operation : 0x%lx\n",
                rv);
        /* Clean up... we don't care if there are any errors.
         */
        if (hSession != CK_INVALID_HANDLE) C_CloseSession(hSession);
        C_Finalize(NULL);
    }
    return rv;
}
Exemplo n.º 10
0
/* initial code will only support what is needed for pkcs11_ec_ckey
 * i.e. CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE
 * and CK_EC_KDF_TYPE  supported by token
 * The secret key object is deleted
 *
 * In future CKM_ECMQV_DERIVE with CK_ECMQV_DERIVE_PARAMS
 * could also be supported, and the secret key object could be returned.
 */
static int pkcs11_ecdh_derive(unsigned char **out, size_t *outlen,
		const unsigned long ecdh_mechanism,
		const void * ec_params,
		void *outnewkey,
		PKCS11_KEY * key)
{
	PKCS11_SLOT *slot = KEY2SLOT(key);
	PKCS11_CTX *ctx = KEY2CTX(key);
	PKCS11_TOKEN *token = KEY2TOKEN(key);
	PKCS11_KEY_private *kpriv = PRIVKEY(key);
	PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
	CK_MECHANISM mechanism;
	int rv;

	CK_BBOOL true = TRUE;
	CK_BBOOL false = FALSE;
	CK_OBJECT_HANDLE newkey = CK_INVALID_HANDLE;
	CK_OBJECT_CLASS newkey_class= CKO_SECRET_KEY;
	CK_KEY_TYPE newkey_type = CKK_GENERIC_SECRET;
	CK_OBJECT_HANDLE * tmpnewkey = (CK_OBJECT_HANDLE *)outnewkey;
	CK_ATTRIBUTE newkey_template[] = {
		{CKA_TOKEN, &false, sizeof(false)}, /* session only object */
		{CKA_CLASS, &newkey_class, sizeof(newkey_class)},
		{CKA_KEY_TYPE, &newkey_type, sizeof(newkey_type)},
		{CKA_ENCRYPT, &true, sizeof(true)},
		{CKA_DECRYPT, &true, sizeof(true)}
	};

	memset(&mechanism, 0, sizeof(mechanism));
	mechanism.mechanism  = ecdh_mechanism;
	mechanism.pParameter =  (void*)ec_params;
	switch (ecdh_mechanism) {
		case CKM_ECDH1_DERIVE:
		case CKM_ECDH1_COFACTOR_DERIVE:
			mechanism.ulParameterLen  = sizeof(CK_ECDH1_DERIVE_PARAMS);
			break;
#if 0
		/* TODO */
		case CK_ECMQV_DERIVE_PARAMS:
			mechanism.ulParameterLen  = sizeof(CK_ECMQV_DERIVE_PARAMS);
			break;
#endif
		default:
			PKCS11err(PKCS11_F_PKCS11_EC_KEY_COMPUTE_KEY, pkcs11_map_err(PKCS11_NOT_SUPPORTED));
			return -1;
	}

	rv = CRYPTOKI_call(ctx, C_DeriveKey(spriv->session, &mechanism, kpriv->object, newkey_template, 5, &newkey));
	CRYPTOKI_checkerr(PKCS11_F_PKCS11_EC_KEY_COMPUTE_KEY, rv);

	/* Return the value of the secret key and/or the object handle of the secret key */
	if (out && outlen) { /* pkcs11_ec_ckey only asks for the value */
		if (pkcs11_getattr_alloc(token, newkey, CKA_VALUE, out, outlen)) {
			PKCS11err(PKCS11_F_PKCS11_EC_KEY_COMPUTE_KEY,
				pkcs11_map_err(CKR_ATTRIBUTE_VALUE_INVALID));
			CRYPTOKI_call(ctx, C_DestroyObject(spriv->session, newkey));
			return -1;
		}
	}
	if (tmpnewkey) /* For future use (not used by pkcs11_ec_ckey) */
		*tmpnewkey = newkey;
	else /* Destroy the temporary key */
		CRYPTOKI_call(ctx, C_DestroyObject(spriv->session, newkey));

	return 0;
}
BOOL UpdateValidationX509::ValidateUpdate( MFUpdate* pUpdate, UINT8* pValidation, INT32 validationLen )
{
    CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS };
    CK_SLOT_ID slotID;
    CK_SESSION_HANDLE session;
    CK_OBJECT_CLASS ckoCert = CKO_CERTIFICATE;
    CK_OBJECT_HANDLE hCACert;
    CK_MECHANISM_TYPE sha1Mech = CKM_SHA_1;
    CK_MECHANISM mech = { CKM_RSA_PKCS, &sha1Mech, sizeof(sha1Mech) };
    BOOL retVal = FALSE;
    UINT8* caCert;
    UINT32 certLen = 0;

    if(g_DebuggerPortSslConfig.GetCertificateAuthority == NULL)
    {
        return FALSE;
    }
    
    g_DebuggerPortSslConfig.GetCertificateAuthority( &caCert, &certLen );

    CK_ATTRIBUTE attribs[] =
    {
        { CKA_CLASS   , &ckoCert, sizeof(ckoCert) },
        { CKA_VALUE   , caCert  , certLen         }
    };

    if(pUpdate->Providers->Storage == NULL) return FALSE;
    if(certLen == 0 || caCert == NULL     ) return FALSE;
    if(pValidation == NULL                ) return FALSE;

    C_Initialize(NULL);

    slotID = Cryptoki_FindSlot(NULL, mechs, ARRAYSIZE(mechs));  if(CK_SLOT_ID_INVALID == slotID) return FALSE;
    
    if(CKR_OK == C_OpenSession(slotID, CKF_SERIAL_SESSION, NULL, NULL, &session) && (CK_SESSION_HANDLE_INVALID != session))
    {
        if(CKR_OK == C_CreateObject(session, attribs, ARRAYSIZE(attribs), &hCACert) && hCACert != CK_OBJECT_HANDLE_INVALID)
        {
            if(CKR_OK == C_VerifyInit(session, &mech, hCACert)) 
            {
                UINT8 buff[512];
                INT32 len = sizeof(buff);
                INT32 updateSize = pUpdate->Header.UpdateSize;
                INT32 offset = 0;

                while(offset < updateSize)
                {
                    if((offset + len) > updateSize)
                    {
                        len = updateSize - offset;
                    }
                    
                    if(!pUpdate->Providers->Storage->Read(pUpdate->StorageHandle, offset, buff, len)) break;

                    C_VerifyUpdate(session, buff, len);

                    offset += len;
                }
                retVal = CKR_OK == C_VerifyFinal(session, pValidation, (CK_ULONG)validationLen);
            }

            C_DestroyObject(session, hCACert);
        }
        
        C_CloseSession(session);
    }

    return retVal;    
}
Exemplo n.º 12
0
/* initial code will only support what is needed for pkcs11_ec_ckey
 * i.e. CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE
 * and CK_EC_KDF_TYPE  supported by token
 * The secret key object is deleted
 *
 * In future CKM_ECMQV_DERIVE with CK_ECMQV_DERIVE_PARAMS
 * could also be supported, and the secret key object could be returned. 
 */
int pkcs11_ecdh_derive_internal(unsigned char **out, size_t *outlen,
		const unsigned long ecdh_mechanism,
		const void * ec_params,
		void *outnewkey,
		PKCS11_KEY * key)
{
	int rv;
	int ret = -1;
	unsigned char * buf = NULL;
	size_t buflen;
	PKCS11_KEY_private *priv;
	PKCS11_SLOT *slot;
	PKCS11_CTX *ctx;
	PKCS11_TOKEN *token;
	CK_SESSION_HANDLE session;
	CK_MECHANISM mechanism;

	CK_BBOOL true = TRUE;
	CK_BBOOL false = FALSE;
	CK_OBJECT_HANDLE newkey = CK_INVALID_HANDLE;
	CK_OBJECT_CLASS newkey_class= CKO_SECRET_KEY;
	CK_KEY_TYPE newkey_type = CKK_GENERIC_SECRET;
	CK_OBJECT_HANDLE * tmpnewkey = (CK_OBJECT_HANDLE *)outnewkey;
	CK_ATTRIBUTE newkey_template[] = {
		{CKA_TOKEN, &false, sizeof(false)}, /* session only object */
		{CKA_CLASS, &newkey_class, sizeof(newkey_class)},
		{CKA_KEY_TYPE, &newkey_type, sizeof(newkey_type)},
		{CKA_ENCRYPT, &true, sizeof(true)},
		{CKA_DECRYPT, &true, sizeof(true)}
	};

	ctx = KEY2CTX(key);
	priv = PRIVKEY(key);
	token = KEY2TOKEN(key);
	slot = KEY2SLOT(key);

	CHECK_KEY_FORK(key);

	session = PRIVSLOT(slot)->session;

	memset(&mechanism, 0, sizeof(mechanism));
	mechanism.mechanism  = ecdh_mechanism;
	mechanism.pParameter =  (void*)ec_params;
	switch (ecdh_mechanism) {
		case CKM_ECDH1_DERIVE:
		case CKM_ECDH1_COFACTOR_DERIVE:
			mechanism.ulParameterLen  = sizeof(CK_ECDH1_DERIVE_PARAMS);
			break;
//		case CK_ECMQV_DERIVE_PARAMS:
//			mechanism.ulParameterLen  = sizeof(CK_ECMQV_DERIVE_PARAMS);
//			break;
		default:
		    PKCS11err(PKCS11_F_PKCS11_EC_KEY_COMPUTE_KEY, PKCS11_NOT_SUPPORTED);
		    goto err;
	}

	CRYPTO_w_lock(PRIVSLOT(slot)->lockid);
	rv = CRYPTOKI_call(ctx, C_DeriveKey(session, &mechanism, priv->object, newkey_template, 5, &newkey));
	if (rv) {
	    PKCS11err(PKCS11_F_PKCS11_EC_KEY_COMPUTE_KEY, pkcs11_map_err(rv));
	    goto err;
	}

	/* Return the value of the secret key and/or the object handle of the secret key */
	
	/* pkcs11_ec_ckey only asks for the value */

	if (out && outlen) {
		/* get size of secret key value */
		if (!pkcs11_getattr_var(token, newkey, CKA_VALUE, NULL, &buflen)
			&& buflen > 0) {
			buf = OPENSSL_malloc(buflen);
			if (buf == NULL) {
				PKCS11err(PKCS11_F_PKCS11_EC_KEY_COMPUTE_KEY,
					pkcs11_map_err(CKR_HOST_MEMORY));
				goto err;
			}
		} else {
			PKCS11err(PKCS11_F_PKCS11_EC_KEY_COMPUTE_KEY,
				pkcs11_map_err(CKR_ATTRIBUTE_VALUE_INVALID));
			goto err;
		}

		pkcs11_getattr_var(token, newkey, CKA_VALUE, buf, &buflen);
		*out = buf;
		*outlen = buflen;
		buf = NULL;
	}

	/* not used by pkcs11_ec_ckey for future use */
	if (tmpnewkey) {
	    *tmpnewkey = newkey;
	    newkey = CK_INVALID_HANDLE;
	}

	ret = 1;
err:
	if (buf)
	    OPENSSL_free(buf);
	if (newkey != CK_INVALID_HANDLE && session != CK_INVALID_HANDLE)
		CRYPTOKI_call(ctx, C_DestroyObject(session, newkey));
	
	return ret;
}
Exemplo n.º 13
0
KMF_RETURN
PKCS_EncryptData(KMF_HANDLE_T kmfh,
		KMF_ALGORITHM_INDEX AlgorithmId,
		KMF_X509_SPKI *keyp,
		KMF_DATA *plaintext,
		KMF_DATA *ciphertext)
{
	KMF_RETURN rv = KMF_OK;
	CK_RV ckRv;
	CK_MECHANISM ckMechanism;
	CK_MECHANISM_TYPE mechtype;
	CK_KEY_TYPE keytype;
	CK_OBJECT_HANDLE ckKeyHandle = 0;
	CK_SESSION_HANDLE ckSession = NULL;
	CK_ULONG out_len = 0, in_len = 0, total_encrypted = 0;
	uint8_t *in_data, *out_data;
	int i, blocks, block_size;
	CK_ATTRIBUTE ckTemplate[2];
	CK_ULONG ckNumTemplates;
	CK_ULONG ckMaxTemplates = (sizeof (ckTemplate) /
	    sizeof (CK_ATTRIBUTE));

	if (get_pk11_data(AlgorithmId, &keytype, &mechtype, NULL, 0))
		return (KMF_ERR_BAD_ALGORITHM);

	rv = kmf_create_pk11_session(&ckSession, mechtype, CKF_ENCRYPT);
	if (rv != KMF_OK)
		return (rv);

	/* Get the public key used in encryption */
	rv = PKCS_AcquirePublicKeyHandle(ckSession, keyp,
	    keytype, &ckKeyHandle);

	if (rv != KMF_OK) {
		(void) C_CloseSession(ckSession);
		return (rv);
	}

	/* Get the modulus length */
	ckNumTemplates = 0;
	if (!PKCS_AddTemplate(ckTemplate, &ckNumTemplates, ckMaxTemplates,
	    CKA_MODULUS, (CK_BYTE *)NULL, sizeof (CK_ULONG))) {
		if (ckKeyHandle != 0)
			(void) C_DestroyObject(ckSession, ckKeyHandle);
		(void) C_CloseSession(ckSession);
		return (KMF_ERR_INTERNAL);
	}

	ckRv = C_GetAttributeValue(ckSession, ckKeyHandle,
	    ckTemplate, ckNumTemplates);

	if (ckRv != CKR_OK) {
		if (ckKeyHandle != 0)
			(void) C_DestroyObject(ckSession, ckKeyHandle);
		kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
		kmfh->lasterr.errcode = ckRv;
		(void) C_CloseSession(ckSession);
		return (KMF_ERR_INTERNAL);
	}
	out_len = ckTemplate[0].ulValueLen;

	if (out_len > ciphertext->Length) {
		if (ckKeyHandle != 0)
			(void) C_DestroyObject(ckSession, ckKeyHandle);
		(void) C_CloseSession(ckSession);
		return (KMF_ERR_BUFFER_SIZE);
	}

	ckMechanism.mechanism = mechtype;
	ckMechanism.pParameter = NULL_PTR;
	ckMechanism.ulParameterLen = 0;

	/* Compute the fixed input data length for single-part encryption */
	block_size = out_len - 11;

	in_data = plaintext->Data;
	out_data = ciphertext->Data;

	blocks = plaintext->Length/block_size;

	for (i = 0; i < blocks; i++) {
		ckRv = C_EncryptInit(ckSession, &ckMechanism, ckKeyHandle);
		if (ckRv != CKR_OK) {
			if (ckKeyHandle != 0)
				(void) C_DestroyObject(ckSession, ckKeyHandle);
			kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
			kmfh->lasterr.errcode = ckRv;
			(void) C_CloseSession(ckSession);
			return (KMF_ERR_INTERNAL);
		}
		ckRv = C_Encrypt(ckSession, (CK_BYTE_PTR)in_data, block_size,
		    (CK_BYTE_PTR)out_data, &out_len);

		if (ckRv != CKR_OK) {
			if (ckKeyHandle != 0)
				(void) C_DestroyObject(ckSession, ckKeyHandle);
			kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
			kmfh->lasterr.errcode = ckRv;
			(void) C_CloseSession(ckSession);
			return (KMF_ERR_INTERNAL);
		}

		out_data += out_len;
		total_encrypted += out_len;
		in_data += block_size;
	}

	if (plaintext->Length % block_size) {
		/* Encrypt the remaining data */
		ckRv = C_EncryptInit(ckSession, &ckMechanism, ckKeyHandle);
		if (ckRv != CKR_OK) {
			if (ckKeyHandle != 0)
				(void) C_DestroyObject(ckSession, ckKeyHandle);
			kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
			kmfh->lasterr.errcode = ckRv;
			(void) C_CloseSession(ckSession);
			return (KMF_ERR_INTERNAL);
		}

		in_len = plaintext->Length % block_size;
		ckRv = C_Encrypt(ckSession, (CK_BYTE_PTR)in_data, in_len,
		    (CK_BYTE_PTR)out_data, &out_len);

		if (ckRv != CKR_OK) {
			if (ckKeyHandle != 0)
				(void) C_DestroyObject(ckSession, ckKeyHandle);
			kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
			kmfh->lasterr.errcode = ckRv;
			(void) C_CloseSession(ckSession);
			return (KMF_ERR_INTERNAL);
		}

		out_data += out_len;
		total_encrypted += out_len;
		in_data += in_len;
	}

	ciphertext->Length = total_encrypted;

	if (ckKeyHandle != 0)
		(void) C_DestroyObject(ckSession, ckKeyHandle);

	(void) C_CloseSession(ckSession);
	return (rv);

}
Exemplo n.º 14
0
/*
 * Utility routine for verifying generic data using
 * the cryptographic framework (PKCS#11).
 * There are situations where we want to force this
 * operation to happen in a specific keystore.
 * For example:
 * libelfsign.so.1 verifies signatures on crypto libraries.
 * We must use pkcs11 functions to verify the pkcs11
 * plugins in order to keep the validation within the
 * Cryptographic Framework's FIPS-140 boundary. To avoid
 * a circular dependency, pksc11_softtoken.so.1 is
 * interposed by libkcfd.so.1 via kcfd, which prevents
 * libpkcs11.so.1's interfaces from being used when libkmf.so.1
 * is called from kcfd.
 *
 * This also saves code and time because verify operations
 * only use public keys and do not need acccess to any
 * keystore specific functions.
 */
KMF_RETURN
PKCS_VerifyData(KMF_HANDLE_T handle,
		KMF_ALGORITHM_INDEX AlgorithmId,
		KMF_X509_SPKI *keyp,
		KMF_DATA *data,
		KMF_DATA *signature)
{
	KMF_RETURN	rv = KMF_OK;
	CK_RV		ckRv;
	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
	CK_MECHANISM	ckMechanism;
	CK_MECHANISM_TYPE mechtype, hashmech;
	CK_OBJECT_HANDLE ckKeyHandle = 0;
	CK_KEY_TYPE	pk11keytype;
	CK_SESSION_HANDLE ckSession = 0;
	CK_ATTRIBUTE	subprime = { CKA_SUBPRIME, NULL, 0 };
	CK_BYTE		*dataptr;
	CK_ULONG	datalen;
	KMF_DATA	hashData = { 0, NULL };
	uchar_t		digest[1024];

	if (AlgorithmId == KMF_ALGID_NONE)
		return (KMF_ERR_BAD_ALGORITHM);

	if (get_pk11_data(AlgorithmId, &pk11keytype, &mechtype, &hashmech, 1))
		return (KMF_ERR_BAD_ALGORITHM);

	/*
	 * Verify in metaslot/softtoken since only the public key is needed
	 * and not all hardware tokens support the combined [hash]-RSA/DSA/EC
	 * mechanisms.
	 */
	rv = kmf_create_pk11_session(&ckSession, mechtype, 0);
	if (rv != KMF_OK)
		return (rv);

	/* Fetch the verifying key */
	rv = PKCS_AcquirePublicKeyHandle(ckSession, keyp,
	    pk11keytype, &ckKeyHandle);

	if (rv != KMF_OK) {
		(void) C_CloseSession(ckSession);
		return (rv);
	}
	dataptr = data->Data;
	datalen = data->Length;
	/*
	 * For some mechanisms, we must compute the hash separately
	 * and then do the verify.
	 */
	if (hashmech != 0 &&
	    (mechtype == CKM_ECDSA ||
	    mechtype == CKM_DSA ||
	    mechtype == CKM_RSA_PKCS)) {
		hashData.Data = digest;
		hashData.Length = sizeof (digest);

		rv = PKCS_DigestData(handle, ckSession,
		    hashmech, data, &hashData,
		    (mechtype == CKM_RSA_PKCS));
		if (rv)
			goto cleanup;

		dataptr = hashData.Data;
		datalen = hashData.Length;
	}
	if (mechtype == CKM_DSA &&
	    hashmech == CKM_SHA256) {
		/*
		 * FIPS 186-3 says that when using DSA
		 * the hash must be truncated to the size of the
		 * subprime.
		 */
		ckRv = C_GetAttributeValue(ckSession,
		    ckKeyHandle, &subprime, 1);
		if (ckRv != CKR_OK)  {
			kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
			kmfh->lasterr.errcode = ckRv;
			rv = KMF_ERR_INTERNAL;
			goto cleanup;
		}
		datalen = subprime.ulValueLen;
	}

	ckMechanism.mechanism = mechtype;
	ckMechanism.pParameter = NULL;
	ckMechanism.ulParameterLen = 0;

	ckRv = C_VerifyInit(ckSession, &ckMechanism, ckKeyHandle);
	if (ckRv != CKR_OK) {
		kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
		kmfh->lasterr.errcode = ckRv;
		rv = KMF_ERR_INTERNAL;
		goto cleanup;
	}
	ckRv = C_Verify(ckSession,
	    dataptr, datalen,
	    (CK_BYTE *)signature->Data,
	    (CK_ULONG)signature->Length);

	if (ckRv != CKR_OK) {
		kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
		kmfh->lasterr.errcode = ckRv;
		rv = KMF_ERR_INTERNAL;
	}

cleanup:
	if (ckKeyHandle != 0)
		(void) C_DestroyObject(ckSession, ckKeyHandle);
	(void) C_CloseSession(ckSession);
	return (rv);
}