blob: 691c70395e84579c6a8e93da30b4f769c2ac0966 [file] [log] [blame]
diff -u openvpn-2.3.2.orig/src/openvpn/pkcs11.c openvpn-2.3.2/pkcs11.c
--- openvpn-2.3.2.orig/src/openvpn/pkcs11.c 2011-03-17 12:57:45.000000000 -0700
+++ openvpn-2.3.2/src/openvpn/pkcs11.c 2011-10-10 09:36:55.000000000 -0700
@@ -602,6 +602,115 @@
return success;
}
+static CK_RV
+_hexToBinary(
+ unsigned char * const target,
+ const char * const source,
+ size_t * const p_target_size
+) {
+ size_t target_max_size = *p_target_size;
+ const char *p;
+ char buf[3] = { 0, 0, 0 };
+ int i;
+
+ i = 0;
+ *p_target_size = 0;
+ for (p = source; *p != '\0' && *p_target_size < target_max_size; p++) {
+ if (!isxdigit (*p))
+ continue;
+ buf[i%2] = *p;
+ if ((i%2) == 1) {
+ unsigned v;
+ if (sscanf (buf, "%x", &v) != 1)
+ v = 0;
+ target[*p_target_size] = v & 0xff;
+ (*p_target_size)++;
+ }
+ i++;
+ }
+ return (*p == '\0' ? CKR_OK : CKR_ATTRIBUTE_VALUE_INVALID);
+}
+
+static CK_RV
+get_certificate_id(
+ pkcs11h_certificate_id_t *p_certificate_id,
+ const char * const pkcs11_id
+) {
+ pkcs11h_certificate_id_list_t user_certificates = NULL;
+ pkcs11h_certificate_id_list_t current = NULL;
+ char *cka_id = NULL;
+ size_t cka_id_size;
+ CK_RV rv;
+
+ rv = pkcs11h_certificate_deserializeCertificateId (
+ p_certificate_id,
+ pkcs11_id
+ );
+ if (rv == CKR_OK)
+ return rv;
+ if (rv != CKR_ATTRIBUTE_VALUE_INVALID) {
+ msg (M_WARN, "PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage (rv));
+ return rv;
+ }
+
+ /*
+ * The specified certificate id lacks the token id, search the
+ * cert list for first matching id.
+ */
+ cka_id_size = strlen(pkcs11_id)/2;
+ if (
+ (cka_id = (char *)malloc (cka_id_size)) == NULL ||
+ (rv = _hexToBinary (cka_id, pkcs11_id, &cka_id_size)) != CKR_OK
+ ) {
+ msg (M_FATAL, "PKCS#11: get_certificate_id: Cannot convert id %ld-'%s'", rv, pkcs11h_getMessage (rv));
+ goto cleanup;
+ }
+
+ 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: get_certificate_id: Cannot enumerate certificates %ld-'%s'", rv, pkcs11h_getMessage (rv));
+ goto cleanup;
+ }
+
+ rv = CKR_ATTRIBUTE_VALUE_INVALID;
+ for (current = user_certificates;current != NULL; current = current->next) {
+ pkcs11h_certificate_id_t cid = current->certificate_id;
+
+ if (
+ cka_id_size == cid->attrCKA_ID_size &&
+ memcmp(
+ cka_id,
+ cid->attrCKA_ID,
+ cid->attrCKA_ID_size
+ ) == 0
+ ) {
+ rv = pkcs11h_certificate_duplicateCertificateId(
+ p_certificate_id,
+ cid
+ );
+ break;
+ }
+ }
+
+cleanup:
+ if (user_certificates != NULL) {
+ pkcs11h_certificate_freeCertificateIdList (user_certificates);
+ user_certificates = NULL;
+ }
+ if (cka_id != NULL) {
+ free (cka_id);
+ cka_id = NULL;
+ }
+ return rv;
+}
+
int
SSL_CTX_use_pkcs11 (
SSL_CTX * const ssl_ctx,
@@ -653,23 +762,21 @@
}
if (
- (rv = pkcs11h_certificate_deserializeCertificateId (
+ (rv = get_certificate_id (
&certificate_id,
id_resp.password
)) != CKR_OK
) {
- msg (M_WARN, "PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage (rv));
goto cleanup;
}
}
else {
if (
- (rv = pkcs11h_certificate_deserializeCertificateId (
+ (rv = get_certificate_id (
&certificate_id,
pkcs11_id
)) != CKR_OK
) {
- msg (M_WARN, "PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage (rv));
goto cleanup;
}
}