diff -Naur openvpn-2.1_rc7/options.c openvpn/options.c
--- openvpn-2.1_rc7/options.c	2008-01-24 01:55:18.000000000 +0100
+++ openvpn/options.c	2008-03-16 16:22:11.000000000 +0100
@@ -520,6 +520,7 @@
   "--pkcs11-pin-cache seconds  : Number of seconds to cache PIN. The default is -1\n"
   "                              cache until token is removed.\n"
   "--pkcs11-id serialized-id   : Identity to use, get using standalone --show-pkcs11-ids\n"
+  "--pkcs11-match string       : String to match the Identity to use, see pkcs11-id\n"
 #endif			/* ENABLE_PKCS11 */
  "\n"
   "SSL Library information:\n"
@@ -1766,8 +1767,11 @@
       if (options->pkcs11_providers[0])
        {
         notnull (options->ca_file, "CA file (--ca)");
-	notnull (options->pkcs11_id, "PKCS#11 id (--pkcs11-id)");
-
+//	notnull (options->pkcs11_id, "PKCS#11 id (--pkcs11-id)");
+	if (!options->pkcs11_id && !options->pkcs11_match)
+	  msg(M_USAGE, "You must define PKCS#11 id (--pkcs11-id) or string to match (--pkcs11-match).");
+	if (options->pkcs11_id && options->pkcs11_match)
+	  msg(M_USAGE, "Parameter --pkcs11-match cannot not be used when --pkcs11-id is also specified.");
 	if (options->cert_file)
 	  msg(M_USAGE, "Parameter --cert cannot be used when --pkcs11-provider is also specified.");
 	if (options->priv_key_file)
@@ -5137,6 +5141,11 @@
       VERIFY_PERMISSION (OPT_P_GENERAL);
       options->pkcs11_id = p[1];
     }
+  else if (streq (p[0], "pkcs11-match") && p[1])
+  {
+      VERIFY_PERMISSION (OPT_P_GENERAL);
+      options->pkcs11_match = p[1];
+  }
 #endif
 #ifdef TUNSETPERSIST
   else if (streq (p[0], "rmtun"))
diff -Naur openvpn-2.1_rc7/options.h openvpn/options.h
--- openvpn-2.1_rc7/options.h	2008-01-23 22:08:41.000000000 +0100
+++ openvpn/options.h	2008-03-16 11:59:45.000000000 +0100
@@ -419,6 +419,7 @@
   bool pkcs11_cert_private[MAX_PARMS];
   int pkcs11_pin_cache_period;
   const char *pkcs11_id;
+  const char *pkcs11_match;
 #endif
 
 #ifdef WIN32
diff -Naur openvpn-2.1_rc7/pkcs11.c openvpn/pkcs11.c
--- openvpn-2.1_rc7/pkcs11.c	2008-01-23 22:08:41.000000000 +0100
+++ openvpn/pkcs11.c	2008-03-16 16:25:37.000000000 +0100
@@ -543,6 +543,135 @@
 	}
 }
 
+char * 
+find_pkcs11_id (
+	const char * const pkcs11_match
+) {	
+	ASSERT (pkcs11_match!=NULL);
+
+	char *ret = NULL;
+	
+	pkcs11h_certificate_id_list_t user_certificates = NULL;
+	pkcs11h_certificate_id_list_t current = NULL;
+	CK_RV rv = CKR_FUNCTION_FAILED;
+	
+	if (
+		(rv = pkcs11h_certificate_enumCertificateIds (
+			PKCS11H_ENUM_METHOD_CACHE_EXIST,
+			NULL,
+			PKCS11H_PROMPT_MASK_ALLOW_ALL,
+			NULL,
+			&user_certificates
+		)) != CKR_OK
+	   ) {
+		msg (M_FATAL, "PKCS#11: Cannot enumerate certificates %ld-'%s'", rv, pkcs11h_getMessage (rv));
+		goto cleanup;
+	}
+	
+	// loop over the certs till a) the last one b) we have a hit
+	for (current = user_certificates;current != NULL && ret == NULL; current = current->next) {
+		pkcs11h_certificate_t certificate = NULL;
+		X509 *x509 = NULL;
+		char dn[1024] = {0};
+		char *ser = NULL;
+		size_t ser_len = 0;
+		int n;
+
+		if (
+			(rv = pkcs11h_certificate_serializeCertificateId (
+				NULL,
+				&ser_len,
+				current->certificate_id
+			)) != CKR_OK
+		) {
+			msg (M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv, pkcs11h_getMessage (rv));
+			goto cleanup1;
+		}
+
+		if (
+			rv == CKR_OK &&
+			(ser = (char *)malloc (ser_len)) == NULL
+		) {
+			msg (M_FATAL, "PKCS#11: Cannot allocate memory");
+			goto cleanup1;
+		}
+		
+		if (
+			(rv = pkcs11h_certificate_serializeCertificateId (
+				ser,
+				&ser_len,
+				current->certificate_id
+			)) != CKR_OK
+		) {
+			msg (M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv, pkcs11h_getMessage (rv));
+			goto cleanup1;
+		}
+
+		if (
+			(rv = pkcs11h_certificate_create (
+				current->certificate_id,
+				NULL,
+				PKCS11H_PROMPT_MASK_ALLOW_ALL,
+				PKCS11H_PIN_CACHE_INFINITE,
+				&certificate
+			))
+		) {
+			msg (M_FATAL, "PKCS#11: Cannot create certificate %ld-'%s'", rv, pkcs11h_getMessage (rv));
+			goto cleanup1;
+		}
+
+		if ((x509 = pkcs11h_openssl_getX509 (certificate)) == NULL) {
+			msg (M_FATAL, "PKCS#11: Cannot get X509");
+			goto cleanup1;
+		}
+
+		X509_NAME_oneline (
+			X509_get_subject_name (x509),
+			dn,
+			sizeof (dn)
+		);
+
+		/*msg (
+			M_INFO|M_NOPREFIX|M_NOLF,
+			(
+				"Certificate\n"
+				"       DN:             %s\n"
+				"       Serialized id:  %s\n"
+			),
+			dn,
+			ser
+		);*/
+		
+		// if we have a match, save it to the ret value.
+		if (NULL!=strstr(ser, pkcs11_match)) {
+			ret = malloc (ser_len);
+			strcpy(ret, ser); 
+		}
+		
+	cleanup1:
+		if (x509 != NULL) {
+			X509_free (x509);
+			x509 = NULL;
+		}
+
+		if (certificate != NULL) {
+			pkcs11h_certificate_freeCertificate (certificate);
+			certificate = NULL;
+		}
+
+		if (ser != NULL) {
+			free (ser);
+			ser = NULL;
+		}
+	}
+	cleanup:
+	if (user_certificates != NULL) {
+		pkcs11h_certificate_freeCertificateIdList (user_certificates);
+		user_certificates = NULL;
+	}
+	return ret;
+}
+
 void
 show_pkcs11_ids (
 	const char * const provider,
diff -Naur openvpn-2.1_rc7/pkcs11.h openvpn/pkcs11.h
--- openvpn-2.1_rc7/pkcs11.h	2008-01-23 22:08:41.000000000 +0100
+++ openvpn/pkcs11.h	2008-03-16 16:10:21.000000000 +0100
@@ -58,6 +58,12 @@
 	const char * const pkcs11_id
 );
 
+char *
+find_pkcs11_id (
+	const char * const pkcs11_match
+);
+
+
 void
 show_pkcs11_ids (
 	const char * const provider,
diff -Naur openvpn-2.1_rc7/ssl.c openvpn/ssl.c
--- openvpn-2.1_rc7/ssl.c	2008-01-23 22:08:41.000000000 +0100
+++ openvpn/ssl.c	2008-03-16 16:53:02.000000000 +0100
@@ -30,6 +30,8 @@
  * over the same TCP/UDP port.
  */
 
+# define __UNCONST(a) ((void *)(unsigned long)(const void *)(a))
+
 #ifdef WIN32
 #include "config-win32.h"
 #else
@@ -1075,7 +1077,7 @@
  * All files are in PEM format.
  */
 SSL_CTX *
-init_ssl (const struct options *options)
+init_ssl (const struct options *options) 
 {
   SSL_CTX *ctx = NULL;
   DH *dh;
@@ -1195,10 +1197,20 @@
   else
     {
       /* Use seperate PEM files for key, cert and CA certs */
-
+	  
 #ifdef ENABLE_PKCS11
       if (options->pkcs11_providers[0])
         {
+	 if (options->pkcs11_match)
+	   {
+		 __UNCONST( options->pkcs11_id) = find_pkcs11_id(options->pkcs11_match);
+		 msg (M_WARN, "PKCS#11-id has been found: %s", options->pkcs11_id);
+		 
+		 if (options->pkcs11_id==NULL) {
+			 msg (M_WARN, "Cannot find valid certificate ID using PKCS#11 interface and string to match");
+			 goto err;
+		 }
+	   }
          /* Load Certificate and Private Key */
 	 if (!SSL_CTX_use_pkcs11 (ctx, options->pkcs11_id))
 	   {
