summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Makefile.am2
-rw-r--r--lib/gnutls_x509.c31
-rw-r--r--lib/pkcs11_privkey.c5
-rw-r--r--lib/urls.c92
-rw-r--r--lib/urls.h21
-rw-r--r--lib/x509/x509.c20
6 files changed, 158 insertions, 13 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index b1b680068c..ce82c92f78 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -83,7 +83,7 @@ COBJECTS = gnutls_range.c gnutls_record.c \
gnutls_pubkey.c locks.c gnutls_dtls.c system_override.c \
crypto-backend.c verify-tofu.c pin.c tpm.c fips.c \
safe-memfuncs.c inet_pton.c atfork.c atfork.h system-keys.c \
- system-keys.h
+ system-keys.h urls.c urls.h
if ENABLE_SELF_CHECKS
COBJECTS += crypto-selftests.c crypto-selftests-pk.c
diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c
index 3a82cb834b..b582d61f0a 100644
--- a/lib/gnutls_x509.c
+++ b/lib/gnutls_x509.c
@@ -45,6 +45,7 @@
#include <gnutls/x509.h>
#include "read-file.h"
#include "system-keys.h"
+#include "urls.h"
#ifdef _WIN32
#include <wincrypt.h>
#endif
@@ -656,17 +657,22 @@ read_key_mem(gnutls_certificate_credentials_t res,
/* Reads a private key from a token.
*/
static int
-read_key_url(gnutls_certificate_credentials_t res, const char *url)
+read_key_url(gnutls_certificate_credentials_t res, const char *_url)
{
int ret;
gnutls_privkey_t pkey = NULL;
+ char *url;
+
+ url = _gnutls_sanitize_url(_url, 1);
+ if (url == NULL)
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
/* allocate space for the pkey list
*/
ret = gnutls_privkey_init(&pkey);
if (ret < 0) {
gnutls_assert();
- return ret;
+ goto cleanup;
}
if (res->pin.cb)
@@ -685,9 +691,11 @@ read_key_url(gnutls_certificate_credentials_t res, const char *url)
goto cleanup;
}
+ gnutls_free(url);
return 0;
cleanup:
+ gnutls_free(url);
if (pkey)
gnutls_privkey_deinit(pkey);
@@ -699,7 +707,7 @@ read_key_url(gnutls_certificate_credentials_t res, const char *url)
/* Reads a certificate key from a token.
*/
static int
-read_cert_url(gnutls_certificate_credentials_t res, const char *url)
+read_cert_url(gnutls_certificate_credentials_t res, const char *_url)
{
int ret;
gnutls_x509_crt_t crt = NULL;
@@ -707,13 +715,24 @@ read_cert_url(gnutls_certificate_credentials_t res, const char *url)
gnutls_str_array_t names;
gnutls_datum_t t = {NULL, 0};
unsigned i, count = 0;
+ unsigned is_pkcs11 = 0;
+ char *url;
+
+ url = _gnutls_sanitize_url(_url, 0);
+ if (url == NULL)
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+ if (strncmp(url, "pkcs11:", 7) == 0) {
+ is_pkcs11 = 1;
+ }
_gnutls_str_array_init(&names);
ccert = gnutls_malloc(sizeof(*ccert)*MAX_PKCS11_CERT_CHAIN);
if (ccert == NULL) {
gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
+ ret = GNUTLS_E_MEMORY_ERROR;
+ goto cleanup;
}
ret = gnutls_x509_crt_init(&crt);
@@ -758,7 +777,7 @@ read_cert_url(gnutls_certificate_credentials_t res, const char *url)
count++;
#ifdef ENABLE_PKCS11
- if (strncmp(certfile, "pkcs11:", 7) == 0) {
+ if (is_pkcs11 != 0) {
ret = gnutls_pkcs11_get_raw_issuer(url, crt, &t, GNUTLS_X509_FMT_DER, 0);
if (ret < 0)
break;
@@ -793,10 +812,12 @@ read_cert_url(gnutls_certificate_credentials_t res, const char *url)
if (crt != NULL)
gnutls_x509_crt_deinit(crt);
+ gnutls_free(url);
return 0;
cleanup:
if (crt != NULL)
gnutls_x509_crt_deinit(crt);
+ gnutls_free(url);
gnutls_free(t.data);
_gnutls_str_array_clear(&names);
gnutls_free(ccert);
diff --git a/lib/pkcs11_privkey.c b/lib/pkcs11_privkey.c
index f06121d848..d59b77c9d5 100644
--- a/lib/pkcs11_privkey.c
+++ b/lib/pkcs11_privkey.c
@@ -28,6 +28,7 @@
#include <gnutls_sig.h>
#include <gnutls_pk.h>
#include <fips.h>
+#include "urls.h"
#include <p11-kit/uri.h>
/* In case of a fork, it will invalidate the open session
@@ -402,11 +403,11 @@ gnutls_pkcs11_privkey_import_url(gnutls_pkcs11_privkey_t pkey,
memset(&pkey->sinfo, 0, sizeof(pkey->sinfo));
- pkey->url = gnutls_strdup(url);
+ pkey->url = _gnutls_sanitize_url(url, 1);
if (pkey->url == NULL)
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
- ret = pkcs11_url_to_info(url, &pkey->uinfo);
+ ret = pkcs11_url_to_info(pkey->url, &pkey->uinfo);
if (ret < 0) {
gnutls_assert();
return ret;
diff --git a/lib/urls.c b/lib/urls.c
new file mode 100644
index 0000000000..f68bec71cb
--- /dev/null
+++ b/lib/urls.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright © 2014 Nikos Mavrogiannopoulos
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include <gnutls_int.h>
+#include <gnutls_errors.h>
+#include <gnutls_str.h>
+#include "urls.h"
+
+static const char *_types[] =
+{ "object-type=cert", "object-type=private", NULL };
+
+static char *append_to_str(const char *str1, const char *str2)
+{
+ char *str = NULL;
+ gnutls_buffer_st buf;
+ int ret;
+
+ _gnutls_buffer_init(&buf);
+
+ ret = _gnutls_buffer_append_str(&buf, str1);
+ if (ret < 0) {
+ goto cleanup;
+ }
+
+ ret = _gnutls_buffer_append_data(&buf, ";", 1);
+ if (ret < 0) {
+ goto cleanup;
+ }
+
+ ret = _gnutls_buffer_append_str(&buf, str2);
+ if (ret < 0) {
+ goto cleanup;
+ }
+
+ ret = _gnutls_buffer_append_data(&buf, "\x00", 1);
+ if (ret < 0) {
+ goto cleanup;
+ }
+
+ str = (void*)buf.data;
+ ret = 0;
+fprintf(stderr, "str: %s\n", str);
+ cleanup:
+ if (ret < 0) {
+ _gnutls_buffer_clear(&buf);
+ }
+ return str;
+
+}
+
+/*
+ * @type: 0 for cert, 1 for privkey
+ *
+ * This function will make sure that the URL is ok (e.g.,
+ * that it contains type=cert, when it is a certificate,
+ * or type=privkey for PKCS #11 URLs. That allows to use
+ * the common URL part as input for keys and certificates.
+ *
+ *
+ */
+char *_gnutls_sanitize_url(const char *url, unsigned type)
+{
+#ifdef ENABLE_PKCS11
+ if (strncmp(url, "pkcs11:", 7) == 0) {
+ if (strstr(url, _types[type]) != NULL) {
+ return gnutls_strdup(url);
+ } else {
+ return append_to_str(url, _types[type]);
+ }
+ } else
+#endif
+ {
+ return gnutls_strdup(url);
+ }
+}
diff --git a/lib/urls.h b/lib/urls.h
new file mode 100644
index 0000000000..5473359bac
--- /dev/null
+++ b/lib/urls.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright © 2014 Nikos Mavrogiannopoulos
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+char *_gnutls_sanitize_url(const char *url, unsigned type);
diff --git a/lib/x509/x509.c b/lib/x509/x509.c
index d8c54356c5..211a4c0634 100644
--- a/lib/x509/x509.c
+++ b/lib/x509/x509.c
@@ -34,6 +34,7 @@
#include <libtasn1.h>
#include <gnutls_pk.h>
#include <pkcs11_int.h>
+#include "urls.h"
#include "system-keys.h"
static int crt_reinit(gnutls_x509_crt_t crt)
@@ -3810,13 +3811,22 @@ int
gnutls_x509_crt_import_pkcs11_url(gnutls_x509_crt_t crt,
const char *url, unsigned int flags)
{
- if (strncmp(url, "system:", 7) == 0) {
- return _gnutls_x509_crt_import_system_url(crt, url);
+ char *xurl;
+ int ret;
+
+ xurl = _gnutls_sanitize_url(url, 0);
+ if (xurl == NULL)
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+ if (strncmp(xurl, "system:", 7) == 0) {
+ ret = _gnutls_x509_crt_import_system_url(crt, xurl);
#ifdef ENABLE_PKCS11
- } else if (strncmp(url, "pkcs11:", 7) == 0) {
- return _gnutls_x509_crt_import_pkcs11_url(crt, url, flags);
+ } else if (strncmp(xurl, "pkcs11:", 7) == 0) {
+ ret = _gnutls_x509_crt_import_pkcs11_url(crt, xurl, flags);
#endif
} else {
- return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
}
+ gnutls_free(xurl);
+ return ret;
}