]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
prior to importing objects with URLs sanitize them
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Wed, 19 Nov 2014 23:13:45 +0000 (00:13 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Wed, 19 Nov 2014 23:13:47 +0000 (00:13 +0100)
That allows to use out of band information to complete missing
parts in URLs (e.g., object-type=cert, when there is a certificate).

lib/Makefile.am
lib/gnutls_x509.c
lib/pkcs11_privkey.c
lib/urls.c [new file with mode: 0644]
lib/urls.h [new file with mode: 0644]
lib/x509/x509.c

index b1b680068c70a55e2bbab81e26ed687f28a4d7cf..ce82c92f782d27eab7623db3d71e11a3fd83fff4 100644 (file)
@@ -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
index 3a82cb834b5a2d21d368708133f998a797760082..b582d61f0a62617ab4187a6c61d8613fcaae7918 100644 (file)
@@ -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);
index f06121d8480ac316f684210f5dfecb94f5f256e7..d59b77c9d5b340d63dca4c5b763c2a4fc176bc94 100644 (file)
@@ -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 (file)
index 0000000..f68bec7
--- /dev/null
@@ -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 (file)
index 0000000..5473359
--- /dev/null
@@ -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);
index d8c54356c5905413dd09d246a240874b84c4598e..211a4c063402b6e5b2ff561a6a0db663718ebfc3 100644 (file)
@@ -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;
 }