diff -urN src0\libp11-int.h src\libp11-int.h
--- src0\libp11-int.h	Mon Dec 26 22:22:44 2005
+++ src\libp11-int.h	Mon Sep 04 19:52:30 2006
@@ -144,6 +144,7 @@
 typedef int (*pkcs11_i2d_fn) (void *, unsigned char **);
 extern void pkcs11_addattr(CK_ATTRIBUTE_PTR, int, const void *, size_t);
 extern void pkcs11_addattr_int(CK_ATTRIBUTE_PTR, int, unsigned long);
+extern void pkcs11_addattr_bool(CK_ATTRIBUTE_PTR, int, int);
 extern void pkcs11_addattr_s(CK_ATTRIBUTE_PTR, int, const char *);
 extern void pkcs11_addattr_bn(CK_ATTRIBUTE_PTR, int, const BIGNUM *);
 extern void pkcs11_addattr_obj(CK_ATTRIBUTE_PTR, int, pkcs11_i2d_fn, void *);
diff -urN src0\libp11.h src\libp11.h
--- src0\libp11.h	Mon Dec 26 22:22:44 2005
+++ src\libp11.h	Mon Sep 04 20:53:44 2006
@@ -271,9 +271,33 @@
 extern int PKCS11_change_pin(PKCS11_SLOT * slot, const char *old_pin,
 	const char *new_pin);
 
-/* Store various objects on the token */
-extern int PKCS11_generate_key(PKCS11_TOKEN *, int, unsigned int, char *);
-extern int PKCS11_store_private_key(PKCS11_TOKEN *, EVP_PKEY *, char *);
+/** 
+ * Generate and store a private key on the token
+ *
+ * @param token token returned by PKCS11_find_token()
+ * @param algorithm EVP_PKEY_RSA
+ * @param label label for this key
+ * @param id bytes to use as id value
+ * @param id_len length of id value.
+ * @retval 0 success
+ * @retval -1 error
+ */
+
+extern int PKCS11_generate_key(PKCS11_TOKEN * token, int algorithm, unsigned int bits, char *label, unsigned char* id, unsigned int id_len);
+
+/** 
+ * Store private key on a token
+ *
+ * @param token token returned by PKCS11_find_token()
+ * @param pk private key
+ * @param label label for this key
+ * @param id bytes to use as id value
+ * @param id_len length of id value.
+ * @retval 0 success
+ * @retval -1 error
+ */
+extern int PKCS11_store_private_key(PKCS11_TOKEN * token, EVP_PKEY * pk, char *label, unsigned char *id, unsigned int id_len);
+
 
 /** 
  * Store certificate on a token
diff -urN src0\p11_attr.c src\p11_attr.c
--- src0\p11_attr.c	Mon Sep 04 16:36:36 2006
+++ src\p11_attr.c	Mon Sep 04 20:41:40 2006
@@ -116,9 +116,14 @@
 	pkcs11_addattr(ap, type, &ulValue, sizeof(ulValue));
 }
 
+void pkcs11_addattr_bool(CK_ATTRIBUTE_PTR ap, int type, int value)
+{
+	pkcs11_addattr(ap, type, &value, sizeof(CK_BBOOL));
+}
+
 void pkcs11_addattr_s(CK_ATTRIBUTE_PTR ap, int type, const char *s)
 {
-	pkcs11_addattr(ap, type, s, s ? strlen(s) + 1 : 0);
+	pkcs11_addattr(ap, type, s, s ? strlen(s) : 0); // RFC2279 string an unpadded string of CK_UTF8CHARs with no null-termination
 }
 
 void pkcs11_addattr_bn(CK_ATTRIBUTE_PTR ap, int type, const BIGNUM * bn)
diff -urN src0\p11_cert.c src\p11_cert.c
--- src0\p11_cert.c	Mon Dec 26 22:22:44 2005
+++ src\p11_cert.c	Mon Sep 04 21:29:10 2006
@@ -237,6 +237,7 @@
 
 	/* Now build the template */
 	pkcs11_addattr_int(attrs + n++, CKA_CLASS, CKO_CERTIFICATE);
+	pkcs11_addattr_bool(attrs + n++, CKA_TOKEN, TRUE);
 	pkcs11_addattr_int(attrs + n++, CKA_CERTIFICATE_TYPE, CKC_X_509);
 	pkcs11_addattr_obj(attrs + n++, CKA_VALUE, (pkcs11_i2d_fn) i2d_X509, x509);
 	if (label)
diff -urN src0\p11_key.c src\p11_key.c
--- src0\p11_key.c	Mon Dec 26 22:22:44 2005
+++ src\p11_key.c	Mon Sep 04 21:30:06 2006
@@ -93,9 +93,16 @@
 /*
  * Store a private key on the token
  */
-int PKCS11_store_private_key(PKCS11_TOKEN * token, EVP_PKEY * pk, char *label)
+int PKCS11_store_private_key(PKCS11_TOKEN * token, EVP_PKEY * pk, char *label, unsigned char *id, unsigned int id_len)
 {
-	if (pkcs11_store_private_key(token, pk, label, NULL, 0, NULL))
+	if (pkcs11_store_private_key(token, pk, label, id, id_len, NULL))
+		return -1;
+	return 0;
+}
+
+int PKCS11_store_public_key(PKCS11_TOKEN * token, EVP_PKEY * pk, char *label, unsigned char *id, unsigned int id_len)
+{
+	if (pkcs11_store_public_key(token, pk, label, id, id_len, NULL))
 		return -1;
 	return 0;
 }
@@ -107,7 +114,7 @@
  */
 int
 PKCS11_generate_key(PKCS11_TOKEN * token,
-		    int algorithm, unsigned int bits, char *label)
+		    int algorithm, unsigned int bits, char *label, unsigned char* id, unsigned int id_len)
 {
 	PKCS11_KEY *key_obj;
 	EVP_PKEY *pk;
@@ -130,7 +137,7 @@
 
 	pk = EVP_PKEY_new();
 	EVP_PKEY_assign_RSA(pk, rsa);
-	rc = pkcs11_store_private_key(token, pk, label, NULL, 0, &key_obj);
+	rc = pkcs11_store_private_key(token, pk, label, id, id_len, &key_obj);
 
 	if (rc == 0) {
 		PKCS11_KEY_private *kpriv;
@@ -347,15 +354,25 @@
 
 		pkcs11_addattr_int(attrs + n++, CKA_CLASS, CKO_PRIVATE_KEY);
 		pkcs11_addattr_int(attrs + n++, CKA_KEY_TYPE, CKK_RSA);
+
+		pkcs11_addattr_bool(attrs + n++, CKA_TOKEN, TRUE);
+		pkcs11_addattr_bool(attrs + n++, CKA_PRIVATE, TRUE);
+		pkcs11_addattr_bool(attrs + n++, CKA_SENSITIVE, TRUE);
+		pkcs11_addattr_bool(attrs + n++, CKA_DECRYPT, TRUE);
+		pkcs11_addattr_bool(attrs + n++, CKA_SIGN, TRUE);
+		pkcs11_addattr_bool(attrs + n++, CKA_UNWRAP, TRUE);
+
 		pkcs11_addattr_bn(attrs + n++, CKA_MODULUS, rsa->n);
 		pkcs11_addattr_bn(attrs + n++, CKA_PUBLIC_EXPONENT, rsa->e);
 		pkcs11_addattr_bn(attrs + n++, CKA_PRIVATE_EXPONENT, rsa->d);
 		pkcs11_addattr_bn(attrs + n++, CKA_PRIME_1, rsa->p);
 		pkcs11_addattr_bn(attrs + n++, CKA_PRIME_2, rsa->q);
+
 		if (label)
 			pkcs11_addattr_s(attrs + n++, CKA_LABEL, label);
 		if (id && id_len)
 			pkcs11_addattr(attrs + n++, CKA_ID, id, id_len);
+
 	} else {
 		PKCS11err(PKCS11_F_PKCS11_STORE_PRIVATE_KEY, PKCS11_NOT_SUPPORTED);
 		return -1;
@@ -401,6 +418,12 @@
 
 		pkcs11_addattr_int(attrs + n++, CKA_CLASS, CKO_PUBLIC_KEY);
 		pkcs11_addattr_int(attrs + n++, CKA_KEY_TYPE, CKK_RSA);
+
+		pkcs11_addattr_bool(attrs + n++, CKA_TOKEN, TRUE);
+		pkcs11_addattr_bool(attrs + n++, CKA_ENCRYPT, TRUE);
+		pkcs11_addattr_bool(attrs + n++, CKA_VERIFY, TRUE);
+		pkcs11_addattr_bool(attrs + n++, CKA_WRAP, TRUE);
+
 		pkcs11_addattr_bn(attrs + n++, CKA_MODULUS, rsa->n);
 		pkcs11_addattr_bn(attrs + n++, CKA_PUBLIC_EXPONENT, rsa->e);
 		if (label)
