can you test if attached patch works for you?

I changed the "CKA_PRIVATE" so you can set it with a command
line option, but by default is is not set.

Also I removed CKA_ENCRYPT and CKA_WRAP for now. not sure
if that is the right thing. at least opensc doesn't work
with CKA_WRAP so either not setting it or false seems
to be true. same with CKA_ENCRYPT.

this patch is untested (well, compiles for me), and already
submitted to the svn trunk, so if this doesn't work, we only
need to commit further changes on top of it.

Regards, Andreas
diff -udrNPp --exclude=.svn opensc.orig/src/tools/pkcs11-tool.c opensc/src/tools/pkcs11-tool.c
--- opensc.orig/src/tools/pkcs11-tool.c	2010-03-07 13:00:03.000000000 +0100
+++ opensc/src/tools/pkcs11-tool.c	2010-03-16 14:59:19.000000000 +0100
@@ -1299,30 +1299,47 @@ static void	parse_rsa_private_key(struct
 	RSA_GET_BN(exponent_2, r->dmq1);
 	RSA_GET_BN(coefficient, r->iqmp);
 }
+
+static void	parse_rsa_public_key(struct rsakey_info *rsa,
+		unsigned char *data, int len)
+{
+	RSA *r = NULL;
+	const unsigned char *p;
+
+	p = data;
+	r = d2i_RSA_PUBKEY(NULL, &p, len);
+
+	if (!r) {
+		r = d2i_RSAPublicKey(NULL, &p, len);
+	}
+
+	if (!r) {
+		/* ERR_print_errors_fp(stderr); */
+		util_fatal("OpenSSL error during RSA public key parsing");
+	}
+	RSA_GET_BN(modulus, r->n);
+	RSA_GET_BN(public_exponent, r->e);
+}
 #endif
 
 #define MAX_OBJECT_SIZE	5000
 
-/* Currently only for certificates (-type cert),
-   private keys (-type privkey) and data objetcs (-type data).
+/* Currently for certificates (-type cert), private keys (-type privkey),
+   public keys (-type pubkey) and data objects (-type data).
    Note: only RSA private keys are supported. */
 static int write_object(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
 {
 	CK_BBOOL _true = TRUE;
+	CK_BBOOL _false = FALSE;
 	unsigned char contents[MAX_OBJECT_SIZE];
 	int contents_len = 0;
 	unsigned char certdata[MAX_OBJECT_SIZE];
 	int certdata_len = 0;
 	FILE *f;
-	CK_OBJECT_HANDLE cert_obj, privkey_obj, data_obj;
-	CK_ATTRIBUTE cert_templ[20], privkey_templ[20], data_templ[20];
-	int n_cert_attr = 0, n_privkey_attr = 0, n_data_attr = 0;
+	CK_OBJECT_HANDLE cert_obj, privkey_obj, pubkey_obj, data_obj;
+	CK_ATTRIBUTE cert_templ[20], privkey_templ[20], pubkey_templ[20], data_templ[20];
+	int n_cert_attr = 0, n_privkey_attr = 0, n_pubkey_attr = 0, n_data_attr = 0;
 	struct sc_object_id oid;
-#if 0 
-	CK_ATTRIBUTE pubkey_templ[20];
-	CK_OBJECT_HANDLE pubkey_obj;
-	int n_pubkey_attr = 0;
-#endif
 	CK_RV rv;
 	int need_to_parse_certdata = 0;
 #ifdef ENABLE_OPENSSL
@@ -1370,6 +1387,13 @@ static int write_object(CK_SLOT_ID slot,
 		util_fatal("No OpenSSL support, cannot parse RSA private key\n");
 #endif
 	}
+	if (opt_object_class == CKO_PUBLIC_KEY) {
+#ifdef ENABLE_OPENSSL
+		parse_rsa_public_key(&rsa, contents, contents_len);
+#else
+		util_fatal("No OpenSSL support, cannot parse RSA public key\n");
+#endif
+	}
 
 	if (opt_object_class == CKO_CERTIFICATE) {
 		CK_OBJECT_CLASS clazz = CKO_CERTIFICATE;
@@ -1459,6 +1483,50 @@ static int write_object(CK_SLOT_ID slot,
 #endif
 	}
 	else
+	if (opt_object_class == CKO_PUBLIC_KEY) {
+		CK_OBJECT_CLASS clazz = CKO_PUBLIC_KEY;
+		CK_KEY_TYPE type = CKK_RSA;
+		CK_ULONG modulus_bits = rsa.modulus_len * 8;
+
+		FILL_ATTR(pubkey_templ[0], CKA_CLASS, &clazz, sizeof(clazz));
+		FILL_ATTR(pubkey_templ[1], CKA_KEY_TYPE, &type, sizeof(type));
+		FILL_ATTR(pubkey_templ[2], CKA_TOKEN, &_true, sizeof(_true));
+		n_pubkey_attr = 3;
+
+		if (opt_is_private != 0) {
+			FILL_ATTR(data_templ[n_data_attr], CKA_PRIVATE,
+				&_true, sizeof(_true));
+			n_data_attr++;
+		}
+
+		if (opt_object_label != NULL) {
+			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_LABEL,
+				opt_object_label, strlen(opt_object_label));
+			n_pubkey_attr++;
+		}
+		if (opt_object_id_len != 0) {
+			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_ID,
+				opt_object_id, opt_object_id_len);
+			n_pubkey_attr++;
+		}
+#ifdef ENABLE_OPENSSL
+		if (cert.subject_len != 0) {
+			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_SUBJECT,
+				cert.subject, cert.subject_len);
+			n_pubkey_attr++;
+		}
+		FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_MODULUS,
+			rsa.modulus, rsa.modulus_len);
+		n_pubkey_attr++;
+		FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_MODULUS_BITS,
+			&modulus_bits, sizeof (modulus_bits));
+		n_pubkey_attr++;
+		FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_PUBLIC_EXPONENT,
+			rsa.public_exponent, rsa.public_exponent_len);
+		n_pubkey_attr++;
+#endif
+	}
+	else
 	if (opt_object_class == CKO_DATA) {
 		CK_OBJECT_CLASS clazz = CKO_DATA;
 		FILL_ATTR(data_templ[0], CKA_CLASS, &clazz, sizeof(clazz));
@@ -1513,7 +1581,6 @@ static int write_object(CK_SLOT_ID slot,
 		show_object(session, cert_obj);
 	}
 
-#if 0
 	if (n_pubkey_attr) {
 		rv = p11->C_CreateObject(session, pubkey_templ, n_pubkey_attr, &pubkey_obj);
 		if (rv != CKR_OK)
@@ -1522,7 +1589,6 @@ static int write_object(CK_SLOT_ID slot,
 		printf("Generated public key:\n");
 		show_object(session, pubkey_obj);
 	}
-#endif
 
 	if (n_privkey_attr) {
 		rv = p11->C_CreateObject(session, privkey_templ, n_privkey_attr, &privkey_obj);
_______________________________________________
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Reply via email to