From: David W. <dw...@in...> - 2014-12-09 21:24:18
Attachments:
smime.p7s
|
Here's a proof of concept which makes it use p11-kit-proxy.so if not told to use anything different (which is a bit of a hack and definitely at least needs to *find* it in $libdir or something). And also parses PKCS#11 URIs for the key location. Ideally I think we want to be using p11-kit's functions for loading the modules, not p11-kit-proxy. But this is a start. With a corresponding patch¹ to the client application I can now use simple PKCS#11 URIs for keys when using OpenSSL just as I can when I build with GnuTLS. diff --git a/configure.ac b/configure.ac index b67256e..84178ad 100644 --- a/configure.ac +++ b/configure.ac @@ -109,6 +109,7 @@ AC_CHECK_HEADERS([ \ ]) PKG_CHECK_MODULES([LIBP11], [libp11 >= 0.2.5],, [AC_MSG_ERROR([libp11 >= 0.2.5 is required])]) +PKG_CHECK_MODULES([P11KIT], [p11-kit-1],, [AC_MSG_ERROR([p11-kit-1 is required])]) PKG_CHECK_MODULES( [OPENSSL], diff --git a/src/Makefile.am b/src/Makefile.am index 72a3ffe..404a63d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,8 +18,8 @@ else dist_noinst_DATA = versioninfo.rc endif engine_pkcs11_la_CFLAGS = $(AM_CFLAGS) $(OPENSSL_EXTRA_CFLAGS) $(OPENSSL_CFLAGS) \ - $(LIBP11_CFLAGS) -engine_pkcs11_la_LIBADD = $(ENGINE_LINK) $(OPENSSL_LIBS) $(LIBP11_LIBS) + $(LIBP11_CFLAGS) $(P11KIT_CFLAGS) +engine_pkcs11_la_LIBADD = $(ENGINE_LINK) $(OPENSSL_LIBS) $(LIBP11_LIBS) $(P11KIT_LIBS) engine_pkcs11_la_LDFLAGS = $(AM_LDFLAGS) $(OPENSSL_EXTRA_LDFLAGS) \ -module -shared -avoid-version \ -export-symbols "$(srcdir)/engine_pkcs11.exports" \ diff --git a/src/engine_pkcs11.c b/src/engine_pkcs11.c index c1b8fbb..5b28d89 100644 --- a/src/engine_pkcs11.c +++ b/src/engine_pkcs11.c @@ -34,6 +34,8 @@ #include <libp11.h> #include "engine_pkcs11.h" +#include <p11-kit/uri.h> + #ifdef _WIN32 #define strncasecmp strnicmp #endif @@ -56,7 +58,7 @@ static int pin_length = 0; static int verbose = 0; -static char *module = NULL; +static char *module = "/usr/lib64/p11-kit-proxy.so"; static char *init_args = NULL; @@ -538,6 +540,28 @@ int load_cert_ctrl(ENGINE * e, void *p) return 1; } +static int p11_match(const char *tokstr, const char *matchstr, size_t tokstrlen) +{ + int matchstrlen, i; + + if (!matchstr) + return 0; + + matchstrlen = strlen(matchstr); + + if (matchstrlen > tokstrlen) + return 0; + + if (strncmp(matchstr, tokstr, matchstrlen)) + return 0; + + for (i = matchstrlen; i < tokstrlen; i++) + if (tokstr[i] != ' ') + return 0; + + return 1; +} + static EVP_PKEY *pkcs11_load_key(ENGINE * e, const char *s_slot_key_id, UI_METHOD * ui_method, void *callback_data, int isPrivate) @@ -548,6 +572,8 @@ static EVP_PKEY *pkcs11_load_key(ENGINE * e, const char *s_slot_key_id, PKCS11_KEY *keys, *selected_key = NULL; PKCS11_CERT *certs; EVP_PKEY *pk; + P11KitUri *uri; + CK_ATTRIBUTE *uri_id = NULL, *uri_label = NULL; unsigned int slot_count, cert_count, key_count, n, m; unsigned char key_id[MAX_VALUE_LEN / 2]; size_t key_id_len = sizeof(key_id); @@ -556,6 +582,24 @@ static EVP_PKEY *pkcs11_load_key(ENGINE * e, const char *s_slot_key_id, char flags[64]; if (s_slot_key_id && *s_slot_key_id) { + if (!strncmp(s_slot_key_id, "pkcs11:", 7)) { + uri = p11_kit_uri_new(); + if (p11_kit_uri_parse(s_slot_key_id, P11_KIT_URI_FOR_ANY, uri)) { + fprintf(stderr, + "Failed to parse PKCS#11 URI\n"); + p11_kit_uri_free(uri); + return NULL; + } + uri_id = p11_kit_uri_get_attribute(uri, CKA_ID); + if (uri_id && uri_id->ulValueLen <= sizeof(key_id)) { + key_id_len = uri_id->ulValueLen; + memcpy(key_id, uri_id->pValue, uri_id->ulValueLen); + } else + key_id_len = 0; + uri_label = p11_kit_uri_get_attribute(uri, CKA_LABEL); + if (uri_label) + key_label = strdup(uri_label->pValue); + } else { n = parse_slot_id_string(s_slot_key_id, &slot_nr, key_id, &key_id_len, &key_label); @@ -580,6 +624,7 @@ static EVP_PKEY *pkcs11_load_key(ENGINE * e, const char *s_slot_key_id, } else fprintf(stderr, "label: %s\n", key_label); } + } } if (PKCS11_enumerate_slots(ctx, &slot_list, &slot_count) < 0) @@ -611,6 +656,22 @@ static EVP_PKEY *pkcs11_load_key(ENGINE * e, const char *s_slot_key_id, if (slot_nr != -1 && slot_nr == PKCS11_get_slotid_from_slot(slot)) { found_slot = slot; + } else if (uri && slot->token) { + CK_TOKEN_INFO *tokinfo = p11_kit_uri_get_token_info(uri); + int match = 1; + + if (tokinfo->label[0]) + match = p11_match(tokinfo->label, slot->token->label, sizeof(tokinfo->label)); + if (match && tokinfo->manufacturerID[0]) + match = p11_match(tokinfo->manufacturerID, slot->token->manufacturer, sizeof(tokinfo->manufacturerID)); + if (match && tokinfo->model[0]) + match = p11_match(tokinfo->model, slot->token->model, sizeof(tokinfo->model)); + if (match && tokinfo->serialNumber[0]) + match = p11_match(tokinfo->serialNumber, slot->token->serialnr, sizeof(tokinfo->serialNumber)); + if (match) { + slot_nr = PKCS11_get_slotid_from_slot(slot); + found_slot = slot; + } } if (verbose) { @@ -755,22 +816,22 @@ static EVP_PKEY *pkcs11_load_key(ENGINE * e, const char *s_slot_key_id, if (s_slot_key_id && *s_slot_key_id && (key_id_len != 0 || key_label != NULL)) { for (n = 0; n < key_count; n++) { PKCS11_KEY *k = keys + n; + int match = 1; if (verbose) { fprintf(stderr, " %2u %c%c %s\n", n + 1, k->isPrivate ? 'P' : ' ', k->needLogin ? 'L' : ' ', k->label); } - if (key_label == NULL) { - if (key_id_len != 0 && k->id_len == key_id_len - && memcmp(k->id, key_id, key_id_len) == 0) { - selected_key = k; - } - } else { - if (strcmp(k->label, key_label) == 0) { - selected_key = k; - } + if (key_id_len != 0 && (k->id_len != key_id_len || + memcmp(k->id, key_id, key_id_len) != 0)) { + match = 0; + } + if (key_label && strcmp(k->label, key_label) != 0) { + match = 0; } + if (match) + selected_key = k; } } else { selected_key = keys; /* use first */ @@ -790,6 +851,8 @@ static EVP_PKEY *pkcs11_load_key(ENGINE * e, const char *s_slot_key_id, } if (key_label != NULL) free(key_label); + if (uri) + p11_kit_uri_free(uri); return pk; } -- dwmw2 ¹ http://david.woodhou.se/openconnect-engine-pkcs11.patch |
From: Douglas E E. <dee...@gm...> - 2014-12-10 13:57:55
|
If you think there is a need for this, then get it working and submit a pull request. The issue with OpenSSL and engines that use keys other then RSA is still a show stopper for future engine development. I was looking for someone outside OpenSC to push OpenSSL to put some effort into the issue: http://rt.openssl.org/Ticket/Display.html?id=2568 Without that adding URI support for only RSA maybe a wasted effort. On 12/9/2014 3:24 PM, David Woodhouse wrote: > Here's a proof of concept which makes it use p11-kit-proxy.so if not > told to use anything different (which is a bit of a hack and definitely > at least needs to *find* it in $libdir or something). And also parses > PKCS#11 URIs for the key location. > > Ideally I think we want to be using p11-kit's functions for loading the > modules, not p11-kit-proxy. But this is a start. > > With a corresponding patch¹ to the client application I can now use > simple PKCS#11 URIs for keys when using OpenSSL just as I can when I > build with GnuTLS. > > diff --git a/configure.ac b/configure.ac > index b67256e..84178ad 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -109,6 +109,7 @@ AC_CHECK_HEADERS([ \ > ]) > > PKG_CHECK_MODULES([LIBP11], [libp11 >= 0.2.5],, [AC_MSG_ERROR([libp11 >= 0.2.5 is required])]) > +PKG_CHECK_MODULES([P11KIT], [p11-kit-1],, [AC_MSG_ERROR([p11-kit-1 is required])]) > > PKG_CHECK_MODULES( > [OPENSSL], > diff --git a/src/Makefile.am b/src/Makefile.am > index 72a3ffe..404a63d 100644 > --- a/src/Makefile.am > +++ b/src/Makefile.am > @@ -18,8 +18,8 @@ else > dist_noinst_DATA = versioninfo.rc > endif > engine_pkcs11_la_CFLAGS = $(AM_CFLAGS) $(OPENSSL_EXTRA_CFLAGS) $(OPENSSL_CFLAGS) \ > - $(LIBP11_CFLAGS) > -engine_pkcs11_la_LIBADD = $(ENGINE_LINK) $(OPENSSL_LIBS) $(LIBP11_LIBS) > + $(LIBP11_CFLAGS) $(P11KIT_CFLAGS) > +engine_pkcs11_la_LIBADD = $(ENGINE_LINK) $(OPENSSL_LIBS) $(LIBP11_LIBS) $(P11KIT_LIBS) > engine_pkcs11_la_LDFLAGS = $(AM_LDFLAGS) $(OPENSSL_EXTRA_LDFLAGS) \ > -module -shared -avoid-version \ > -export-symbols "$(srcdir)/engine_pkcs11.exports" \ > diff --git a/src/engine_pkcs11.c b/src/engine_pkcs11.c > index c1b8fbb..5b28d89 100644 > --- a/src/engine_pkcs11.c > +++ b/src/engine_pkcs11.c > @@ -34,6 +34,8 @@ > #include <libp11.h> > #include "engine_pkcs11.h" > > +#include <p11-kit/uri.h> > + > #ifdef _WIN32 > #define strncasecmp strnicmp > #endif > @@ -56,7 +58,7 @@ static int pin_length = 0; > > static int verbose = 0; > > -static char *module = NULL; > +static char *module = "/usr/lib64/p11-kit-proxy.so"; > > static char *init_args = NULL; > > @@ -538,6 +540,28 @@ int load_cert_ctrl(ENGINE * e, void *p) > return 1; > } > > +static int p11_match(const char *tokstr, const char *matchstr, size_t tokstrlen) > +{ > + int matchstrlen, i; > + > + if (!matchstr) > + return 0; > + > + matchstrlen = strlen(matchstr); > + > + if (matchstrlen > tokstrlen) > + return 0; > + > + if (strncmp(matchstr, tokstr, matchstrlen)) > + return 0; > + > + for (i = matchstrlen; i < tokstrlen; i++) > + if (tokstr[i] != ' ') > + return 0; > + > + return 1; > +} > + > static EVP_PKEY *pkcs11_load_key(ENGINE * e, const char *s_slot_key_id, > UI_METHOD * ui_method, void *callback_data, > int isPrivate) > @@ -548,6 +572,8 @@ static EVP_PKEY *pkcs11_load_key(ENGINE * e, const char *s_slot_key_id, > PKCS11_KEY *keys, *selected_key = NULL; > PKCS11_CERT *certs; > EVP_PKEY *pk; > + P11KitUri *uri; > + CK_ATTRIBUTE *uri_id = NULL, *uri_label = NULL; > unsigned int slot_count, cert_count, key_count, n, m; > unsigned char key_id[MAX_VALUE_LEN / 2]; > size_t key_id_len = sizeof(key_id); > @@ -556,6 +582,24 @@ static EVP_PKEY *pkcs11_load_key(ENGINE * e, const char *s_slot_key_id, > char flags[64]; > > if (s_slot_key_id && *s_slot_key_id) { > + if (!strncmp(s_slot_key_id, "pkcs11:", 7)) { > + uri = p11_kit_uri_new(); > + if (p11_kit_uri_parse(s_slot_key_id, P11_KIT_URI_FOR_ANY, uri)) { > + fprintf(stderr, > + "Failed to parse PKCS#11 URI\n"); > + p11_kit_uri_free(uri); > + return NULL; > + } > + uri_id = p11_kit_uri_get_attribute(uri, CKA_ID); > + if (uri_id && uri_id->ulValueLen <= sizeof(key_id)) { > + key_id_len = uri_id->ulValueLen; > + memcpy(key_id, uri_id->pValue, uri_id->ulValueLen); > + } else > + key_id_len = 0; > + uri_label = p11_kit_uri_get_attribute(uri, CKA_LABEL); > + if (uri_label) > + key_label = strdup(uri_label->pValue); > + } else { > n = parse_slot_id_string(s_slot_key_id, &slot_nr, > key_id, &key_id_len, &key_label); > > @@ -580,6 +624,7 @@ static EVP_PKEY *pkcs11_load_key(ENGINE * e, const char *s_slot_key_id, > } else > fprintf(stderr, "label: %s\n", key_label); > } > + } > } > > if (PKCS11_enumerate_slots(ctx, &slot_list, &slot_count) < 0) > @@ -611,6 +656,22 @@ static EVP_PKEY *pkcs11_load_key(ENGINE * e, const char *s_slot_key_id, > if (slot_nr != -1 && > slot_nr == PKCS11_get_slotid_from_slot(slot)) { > found_slot = slot; > + } else if (uri && slot->token) { > + CK_TOKEN_INFO *tokinfo = p11_kit_uri_get_token_info(uri); > + int match = 1; > + > + if (tokinfo->label[0]) > + match = p11_match(tokinfo->label, slot->token->label, sizeof(tokinfo->label)); > + if (match && tokinfo->manufacturerID[0]) > + match = p11_match(tokinfo->manufacturerID, slot->token->manufacturer, sizeof(tokinfo->manufacturerID)); > + if (match && tokinfo->model[0]) > + match = p11_match(tokinfo->model, slot->token->model, sizeof(tokinfo->model)); > + if (match && tokinfo->serialNumber[0]) > + match = p11_match(tokinfo->serialNumber, slot->token->serialnr, sizeof(tokinfo->serialNumber)); > + if (match) { > + slot_nr = PKCS11_get_slotid_from_slot(slot); > + found_slot = slot; > + } > } > > if (verbose) { > @@ -755,22 +816,22 @@ static EVP_PKEY *pkcs11_load_key(ENGINE * e, const char *s_slot_key_id, > if (s_slot_key_id && *s_slot_key_id && (key_id_len != 0 || key_label != NULL)) { > for (n = 0; n < key_count; n++) { > PKCS11_KEY *k = keys + n; > + int match = 1; > > if (verbose) { > fprintf(stderr, " %2u %c%c %s\n", n + 1, > k->isPrivate ? 'P' : ' ', > k->needLogin ? 'L' : ' ', k->label); > } > - if (key_label == NULL) { > - if (key_id_len != 0 && k->id_len == key_id_len > - && memcmp(k->id, key_id, key_id_len) == 0) { > - selected_key = k; > - } > - } else { > - if (strcmp(k->label, key_label) == 0) { > - selected_key = k; > - } > + if (key_id_len != 0 && (k->id_len != key_id_len || > + memcmp(k->id, key_id, key_id_len) != 0)) { > + match = 0; > + } > + if (key_label && strcmp(k->label, key_label) != 0) { > + match = 0; > } > + if (match) > + selected_key = k; > } > } else { > selected_key = keys; /* use first */ > @@ -790,6 +851,8 @@ static EVP_PKEY *pkcs11_load_key(ENGINE * e, const char *s_slot_key_id, > } > if (key_label != NULL) > free(key_label); > + if (uri) > + p11_kit_uri_free(uri); > return pk; > } > > > > > ------------------------------------------------------------------------------ > Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server > from Actuate! Instantly Supercharge Your Business Reports and Dashboards > with Interactivity, Sharing, Native Excel Exports, App Integration & more > Get technology previously reserved for billion-dollar corporations, FREE > http://pubads.g.doubleclick.net/gampad/clk?id=164703151&iu=/4140/ostg.clktrk > > > > _______________________________________________ > Opensc-devel mailing list > Ope...@li... > https://lists.sourceforge.net/lists/listinfo/opensc-devel > -- Douglas E. Engert <DEE...@gm...> |
From: David W. <dw...@in...> - 2014-12-14 23:35:02
Attachments:
smime.p7s
|
On Wed, 2014-12-10 at 07:52 -0600, Douglas E Engert wrote: > If you think there is a need for this, then get it working and submit > a pull request. https://github.com/OpenSC/engine_pkcs11/pull/9 I even made it work for certificates. Although libp11 is broken for certs larger than 2048 bytes, and I haven't quite worked out why we need to use a LOAD_CERT_CTRL command instead of just having the engine provide a normal load_ssl_client_cert() function. Having fixed the former in my local build and controlled my nausea at the latter for long enough to knock up a test, it's working fine with PKCS#11 URIs for certificates too. Now I can $ openconnect -c 'pkcs11:manufacturer=piv_II;id=%01' vpn.example.com and it works just as nicely as it does when built with GnuTLS. -- David Woodhouse Open Source Technology Centre Dav...@in... Intel Corporation |
From: David W. <dw...@in...> - 2015-04-29 11:49:32
Attachments:
smime.p7s
|
On Wed, 2014-12-10 at 07:52 -0600, Douglas E Engert wrote: > If you think there is a need for this, then get it working and > submit a pull request. Now that RFC7512 is published, I've finally gone ahead and pushed this. If we can do releases of libp11 and engine_pkcs11, then all we need is to get pkcs11_helper fixed... -- dwmw2 |
From: David W. <dw...@in...> - 2014-12-10 14:45:02
Attachments:
smime.p7s
|
On Wed, 2014-12-10 at 07:52 -0600, Douglas E Engert wrote: > If you think there is a need for this, then get it working and submit a pull request. > > The issue with OpenSSL and engines that use keys other then RSA is still a show stopper > for future engine development. I was looking for someone outside OpenSC to push > OpenSSL to put some effort into the issue: > > http://rt.openssl.org/Ticket/Display.html?id=2568 I still think that the easier option is to get the PKCS#11 engine merged *into* OpenSSL, and then we don't have to care about visibility of private headers. OpenSSL is the last major crypto library that doesn't have PKCS#11 support. > Without that adding URI support for only RSA maybe a wasted effort. Not entirely. It is still a problem that software in modern distributions is using anything *other* than the (soon to be) standard PKCS#11 URI format for identifying objects in PKCS#11. I've just submitted a pull request for pkcs11-helper which makes OpenVPN behave properly. Fixing ENGINE_PKCS11 would at least allow us to fix the bizarreness of the user-facing configuration of things like wpa_supplicant which do currently use it for RSA keys. And would allow it to be used from other things like my OpenConnect VPN client. The lack of EC support isn't entirely a showstopper, although I agree it's a pain. -- dwmw2 |
From: Douglas E E. <dee...@gm...> - 2014-12-10 15:00:54
|
On 12/10/2014 8:44 AM, David Woodhouse wrote: > On Wed, 2014-12-10 at 07:52 -0600, Douglas E Engert wrote: >> If you think there is a need for this, then get it working and submit a pull request. >> >> The issue with OpenSSL and engines that use keys other then RSA is still a show stopper >> for future engine development. I was looking for someone outside OpenSC to push >> OpenSSL to put some effort into the issue: >> >> http://rt.openssl.org/Ticket/Display.html?id=2568 > > I still think that the easier option is to get the PKCS#11 engine merged > *into* OpenSSL, and then we don't have to care about visibility of > private headers. OpenSSL is the last major crypto library that doesn't > have PKCS#11 support. Easier? Have you every dealt with the OpenSSL developers? > >> Without that adding URI support for only RSA maybe a wasted effort. > > Not entirely. It is still a problem that software in modern > distributions is using anything *other* than the (soon to be) standard > PKCS#11 URI format for identifying objects in PKCS#11. > > I've just submitted a pull request for pkcs11-helper which makes OpenVPN > behave properly. > > Fixing ENGINE_PKCS11 would at least allow us to fix the bizarreness of > the user-facing configuration of things like wpa_supplicant which do > currently use it for RSA keys. And would allow it to be used from other > things like my OpenConnect VPN client. The lack of EC support isn't > entirely a showstopper, although I agree it's a pain. > > -- Douglas E. Engert <DEE...@gm...> |
From: David W. <dw...@in...> - 2014-12-10 15:11:48
Attachments:
smime.p7s
|
On Wed, 2014-12-10 at 08:55 -0600, Douglas E Engert wrote: > > Easier? > Have you every dealt with the OpenSSL developers? Haha. Yes, and it's like pulling teeth. So OK, *maybe* the easier option is to trawl through *all* the software that's still using OpenSSL and convert it all to something saner like GnuTLS. But if we must attempt to deal with OpenSSL, it might turn out that merging ENGINE_PKCS11 *into* OpenSSL is marginally less painful than pushing changes *for* ENGINE_PKCS11 into OpenSSL without the engine code itself. -- dwmw2 |
From: Nikos M. <n.m...@gm...> - 2014-12-10 15:19:26
|
On Wed, Dec 10, 2014 at 3:55 PM, Douglas E Engert <dee...@gm...> wrote: >>> The issue with OpenSSL and engines that use keys other then RSA is still a show stopper >>> for future engine development. I was looking for someone outside OpenSC to push >>> OpenSSL to put some effort into the issue: >>> >>> http://rt.openssl.org/Ticket/Display.html?id=2568 >> >> I still think that the easier option is to get the PKCS#11 engine merged >> *into* OpenSSL, and then we don't have to care about visibility of >> private headers. OpenSSL is the last major crypto library that doesn't >> have PKCS#11 support. > Easier? > Have you every dealt with the OpenSSL developers? There was a recent message in the openssl mailing list because of an old ticket, and based on the last comment it seems they will be quite receptive on pkcs11 support: http://rt.openssl.org/Ticket/Display.html?id=11&user=guest&pass=guest regards, Nikos |