Hello,

tried to write a patch for pkcs11-tool, that would allow to write the
public key to the smartcard.

Hm, does not work for me, yet. Maybe due to the middle of the night... ;-)
...but maybe due to my pkcs11-library.
Maybe some of you got an enlighting idea.

Kind regards
Cornelius

--- opensc-0.11.1/src/tools/pkcs11-tool.c	2006-05-10 08:15:16.000000000 +0200
+++ opensc-0.11.1-new/src/tools/pkcs11-tool.c	2007-01-12 02:36:41.000000000 +0100
@@ -1148,6 +1148,31 @@
 	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;
+        X509 *x;
+	unsigned char *p;
+        p = data;
+        x = d2i_X509(NULL, &p, len);
+	EVP_PKEY *ppkey;
+
+        if( ! ( ppkey = X509_get_pubkey( x ) ) ) {
+                fatal( "X509 certificate was read, but X509_get_pkey() failed to extract public key" );
+        }
+
+	if ( ppkey->type!=EVP_PKEY_RSA) {
+		fatal("Public Key no RSA Key!");
+	}
+
+       RSA_GET_BN(modulus, ppkey->pkey.rsa->n);
+       RSA_GET_BN(public_exponent, ppkey->pkey.rsa->e);
+}
+
+
 #endif
 
 #define MAX_OBJECT_SIZE	5000
@@ -1158,6 +1183,7 @@
 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];
@@ -1166,11 +1192,11 @@
 	CK_OBJECT_HANDLE cert_obj, privkey_obj;
 	CK_ATTRIBUTE cert_templ[20], privkey_templ[20];
 	int n_cert_attr = 0, n_privkey_attr = 0;
-#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 HAVE_OPENSSL
@@ -1203,6 +1229,11 @@
 		certdata_len = contents_len;
 		need_to_parse_certdata = 1;
 	}
+        if (opt_object_class == CKO_PUBLIC_KEY && !opt_attr_from_file) {
+                memcpy(certdata, contents, MAX_OBJECT_SIZE);
+                certdata_len = contents_len;
+        }
+
 
 	if (need_to_parse_certdata) {
 #ifdef HAVE_OPENSSL
@@ -1211,6 +1242,13 @@
 		fatal("No OpenSSL support, cannot parse certificate\n");
 #endif
 	}
+	if (opt_object_class == CKO_PUBLIC_KEY) {
+#ifdef HAVE_OPENSSL
+                parse_rsa_public_key(&rsa, certdata, certdata_len);
+#else
+                fatal("No OpenSSL support, cannot parse RSA public key\n");
+#endif
+	}
 	if (opt_object_class == CKO_PRIVATE_KEY) {
 #ifdef HAVE_OPENSSL
 		parse_rsa_private_key(&rsa, contents, contents_len);
@@ -1252,6 +1290,33 @@
 		n_cert_attr++;
 #endif
 	}
+	else 
+	if (opt_object_class == CKO_PUBLIC_KEY) {
+                CK_OBJECT_CLASS pubclazz = CKO_PUBLIC_KEY;
+                CK_KEY_TYPE type = CKK_RSA;
+                FILL_ATTR(pubkey_templ[0], CKA_CLASS, &pubclazz, sizeof(pubclazz));
+                FILL_ATTR(pubkey_templ[1], CKA_KEY_TYPE, &type, sizeof(type));
+                FILL_ATTR(pubkey_templ[2], CKA_WRAP, &_true, sizeof(_true));
+		FILL_ATTR(pubkey_templ[3], CKA_PRIVATE, &_false, sizeof(_false));
+		FILL_ATTR(pubkey_templ[4], CKA_ENCRYPT, &_true, sizeof(_true));
+                n_pubkey_attr=5;
+                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++;
+                }
+                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_PUBLIC_EXPONENT,
+                        rsa.public_exponent, rsa.public_exponent_len);
+                n_pubkey_attr++;
+	}
 	else
 	if (opt_object_class == CKO_PRIVATE_KEY) {
 		CK_OBJECT_CLASS clazz = CKO_PRIVATE_KEY;
@@ -1318,7 +1383,6 @@
 		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)
@@ -1327,7 +1391,6 @@
 		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
[email protected]
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Reply via email to