From: Nikos Mavrogiannopoulos Date: Sat, 14 Jul 2012 10:56:06 +0000 (+0200) Subject: Added gnutls_url_is_supported() X-Git-Tag: gnutls_3_1_0pre0~56 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=da20d68ee5373a73395995357a9f4a41b485d63a;p=thirdparty%2Fgnutls.git Added gnutls_url_is_supported() --- diff --git a/NEWS b/NEWS index 9823753b2b..10583564f1 100644 --- a/NEWS +++ b/NEWS @@ -13,11 +13,6 @@ and --benchmark-tls-ciphers ** certtool: generated PKCS #12 structures may hold more than one private key. Patch by Lucas Fisher. -** libgnutls: Added support for an old version of the DTLS protocol -used by openconnect vpn client for compatibility with Cisco's AnyConnect -SSL VPN. It is marked as GNUTLS_DTLS0_9. Do not use it for newer protocols -as it has issues. Implemented by David Woodhouse. - ** libgnutls: requires libnettle 2.5. ** libgnutls: Use the PKCS #1 1.5 encoding provided by nettle (2.5) @@ -47,6 +42,7 @@ by Alexandre Bique. ** API and ABI modifications: GNUTLS_CERT_SIGNATURE_FAILURE: Added GNUTLS_CAMELLIA_192_CBC: Added +gnutls_url_is_supported: Added gnutls_pkcs11_advset_pin_function: Added gnutls_pkcs11_advset_token_function: Added gnutls_privkey_import_tpm_raw: Added diff --git a/lib/gnutls_privkey.c b/lib/gnutls_privkey.c index cb0aa00621..0b56e5c8e4 100644 --- a/lib/gnutls_privkey.c +++ b/lib/gnutls_privkey.c @@ -970,7 +970,8 @@ cleanup: * @flags: should be zero * * This function will import a PKCS11 or TPM URL as a - * private key. + * private key. The supported URL types can be checked + * using gnutls_url_is_supported(). * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c index 267896aab7..fc5b1417aa 100644 --- a/lib/gnutls_pubkey.c +++ b/lib/gnutls_pubkey.c @@ -280,15 +280,48 @@ int gnutls_pubkey_import_pkcs11 (gnutls_pubkey_t key, gnutls_pkcs11_obj_t obj, unsigned int flags) { - int ret; + int ret, type; - ret = gnutls_pkcs11_obj_get_type (obj); - if (ret != GNUTLS_PKCS11_OBJ_PUBKEY) + type = gnutls_pkcs11_obj_get_type (obj); + if (type != GNUTLS_PKCS11_OBJ_PUBKEY && type != GNUTLS_PKCS11_OBJ_X509_CRT) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } + if (type == GNUTLS_PKCS11_OBJ_X509_CRT) + { + gnutls_x509_crt_t xcrt; + + ret = gnutls_x509_crt_init (&xcrt); + if (ret < 0) + { + gnutls_assert() + return ret; + } + + ret = gnutls_x509_crt_import_pkcs11 (xcrt, obj); + if (ret < 0) + { + gnutls_assert(); + goto cleanup_crt; + } + + ret = gnutls_pubkey_import_x509 (key, xcrt, 0); + if (ret < 0) + { + gnutls_assert(); + goto cleanup_crt; + } + + gnutls_x509_crt_get_key_usage(xcrt, &key->key_usage, NULL); + + ret = 0; +cleanup_crt: + gnutls_x509_crt_deinit(xcrt); + return ret; + } + key->key_usage = obj->key_usage; switch (obj->pk_algorithm) diff --git a/lib/gnutls_ui.c b/lib/gnutls_ui.c index b5c0eb9400..c3525ed98e 100644 --- a/lib/gnutls_ui.c +++ b/lib/gnutls_ui.c @@ -772,3 +772,26 @@ size_t len; return 0; } + +/** + * gnutls_url_is_supported: + * @url: A PKCS 11 url + * + * This function will return non-zero if the given URL + * is supported, and zero if it is not known. + * + * Since: 3.1.0 + **/ +int +gnutls_url_is_supported (const char* url) +{ +#ifdef ENABLE_PKCS11 + if (strstr(url, "pkcs11:") != NULL) + return 1; +#endif +#ifdef HAVE_TROUSERS + if (strstr(url, "tpmkey:") != NULL) + return 1; +#endif + return 0; +} diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index ea1db6e1a2..f39813a094 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -1737,9 +1737,11 @@ gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t session); time_t expiration, unsigned int flags); - /* Other help functions */ + /* Other helper functions */ int gnutls_load_file(const char* filename, gnutls_datum_t * data); +int gnutls_url_is_supported (const char* url); + /* Gnutls error codes. The mapping to a TLS alert is also shown in * comments. */ diff --git a/lib/libgnutls.map b/lib/libgnutls.map index e8097a87b5..4c8826f610 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -819,6 +819,7 @@ GNUTLS_3_1_0 { gnutls_privkey_import_tpm_url; gnutls_privkey_import_url; gnutls_pubkey_import_url; + gnutls_url_is_supported; } GNUTLS_3_0_0; GNUTLS_PRIVATE { diff --git a/src/certtool-common.c b/src/certtool-common.c index 9dcca84cec..9942da0ca4 100644 --- a/src/certtool-common.c +++ b/src/certtool-common.c @@ -144,9 +144,7 @@ gnutls_x509_privkey_t xkey; return key; } -#ifdef HAVE_TROUSERS - -static gnutls_privkey_t _load_tpm_privkey(const char* url) +static gnutls_privkey_t _load_url_privkey(const char* url) { int ret; gnutls_privkey_t key; @@ -155,50 +153,17 @@ gnutls_privkey_t key; if (ret < 0) error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret)); - ret = gnutls_privkey_import_tpm_url(key, url, NULL, NULL, 0); + ret = gnutls_privkey_import_url(key, url, 0); if (ret < 0) - error (EXIT_FAILURE, 0, "importing TPM key: %s: %s", + error (EXIT_FAILURE, 0, "importing key: %s: %s", url, gnutls_strerror (ret)); return key; } -#endif - -#ifdef ENABLE_PKCS11 - -static gnutls_privkey_t _load_pkcs11_privkey(const char* url) +static gnutls_pubkey_t _load_url_pubkey(const char* url) { int ret; -gnutls_pkcs11_privkey_t p11key; -gnutls_privkey_t key; - - ret = gnutls_privkey_init (&key); - if (ret < 0) - error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret)); - - ret = gnutls_pkcs11_privkey_init (&p11key); - if (ret < 0) - error (EXIT_FAILURE, 0, "pkcs11_privkey_init: %s", gnutls_strerror (ret)); - - ret = gnutls_pkcs11_privkey_import_url(p11key, url, 0); - if (ret < 0) - error (EXIT_FAILURE, 0, "importing PKCS #11 key: %s: %s", - url, gnutls_strerror (ret)); - - ret = gnutls_privkey_import_pkcs11(key, p11key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE); - if (ret < 0) - error (EXIT_FAILURE, 0, "gnutls_privkey_import_pkcs11: %s", - gnutls_strerror (ret)); - - return key; -} - -static gnutls_pubkey_t _load_pkcs11_pubkey(const char* url) -{ -int ret; -gnutls_pkcs11_obj_t obj; -gnutls_x509_crt_t xcrt; gnutls_pubkey_t pubkey; unsigned int obj_flags = 0; @@ -210,15 +175,7 @@ unsigned int obj_flags = 0; exit (1); } - ret = gnutls_pkcs11_obj_init (&obj); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - ret = gnutls_pkcs11_obj_import_url (obj, url, obj_flags); + ret = gnutls_pubkey_import_url (pubkey, url, obj_flags); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s: %s\n", __func__, __LINE__, @@ -226,60 +183,9 @@ unsigned int obj_flags = 0; exit (1); } - switch (gnutls_pkcs11_obj_get_type (obj)) - { - case GNUTLS_PKCS11_OBJ_X509_CRT: - ret = gnutls_x509_crt_init (&xcrt); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - ret = gnutls_x509_crt_import_pkcs11 (xcrt, obj); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - ret = gnutls_pubkey_import_x509 (pubkey, xcrt, 0); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - gnutls_x509_crt_deinit (xcrt); - break; - case GNUTLS_PKCS11_OBJ_PUBKEY: - - ret = gnutls_pubkey_import_pkcs11 (pubkey, obj, 0); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - break; - default: - { - fprintf(stderr, "Unsupported PKCS #11 object\n"); - exit (1); - break; - } - } - - gnutls_pkcs11_obj_deinit (obj); return pubkey; } -#endif /* ENABLE_PKCS11 */ - /* Load the private key. * @mand should be non zero if it is required to read a private key. */ @@ -296,15 +202,8 @@ load_private_key (int mand, common_info_st * info) if (info->privkey == NULL) error (EXIT_FAILURE, 0, "missing --load-privkey"); -#ifdef ENABLE_PKCS11 - if (strncmp(info->privkey, "pkcs11:", 7) == 0) - return _load_pkcs11_privkey(info->privkey); -#endif - -#ifdef HAVE_TROUSERS - if (strncmp(info->privkey, "tpmkey:", 7) == 0) - return _load_tpm_privkey(info->privkey); -#endif + if (gnutls_url_is_supported(info->privkey) != 0) + return _load_url_privkey(info->privkey); dat.data = (void*)read_binary_file (info->privkey, &size); dat.size = size; @@ -510,15 +409,8 @@ load_ca_private_key (common_info_st * info) if (info->ca_privkey == NULL) error (EXIT_FAILURE, 0, "missing --load-ca-privkey"); -#ifdef ENABLE_PKCS11 - if (strncmp(info->ca_privkey, "pkcs11:", 7) == 0) - return _load_pkcs11_privkey(info->ca_privkey); -#endif - -#ifdef HAVE_TROUSERS - if (strncmp(info->ca_privkey, "tpmkey:", 7) == 0) - return _load_tpm_privkey(info->privkey); -#endif + if (gnutls_url_is_supported(info->ca_privkey) != 0) + return _load_url_privkey(info->ca_privkey); dat.data = (void*)read_binary_file (info->ca_privkey, &size); dat.size = size; @@ -584,10 +476,8 @@ load_pubkey (int mand, common_info_st * info) if (info->pubkey == NULL) error (EXIT_FAILURE, 0, "missing --load-pubkey"); -#ifdef ENABLE_PKCS11 - if (strncmp(info->pubkey, "pkcs11:", 7) == 0) - return _load_pkcs11_pubkey(info->pubkey); -#endif + if (gnutls_url_is_supported(info->pubkey) != 0) + return _load_url_pubkey(info->pubkey); ret = gnutls_pubkey_init (&key); if (ret < 0) diff --git a/src/cli.c b/src/cli.c index 218515a0a5..4256903b29 100644 --- a/src/cli.c +++ b/src/cli.c @@ -224,7 +224,7 @@ load_keys (void) gnutls_strerror (ret)); exit (1); } - else if (strncmp (x509_keyfile, "tpmkey:", 7) == 0 || strncmp (x509_keyfile, "pkcs11:", 7) == 0) + else if (gnutls_url_is_supported(x509_keyfile) != 0) { ret = gnutls_privkey_import_url (x509_key, x509_keyfile, 0); @@ -299,7 +299,7 @@ load_keys (void) exit (1); } - if (strncmp (pgp_keyfile, "pkcs11:", 7) == 0 || strncmp (pgp_keyfile, "tpmkey:", 7) == 0) + if (gnutls_url_is_supported (pgp_keyfile)) { ret = gnutls_privkey_import_url( pgp_key, pgp_keyfile, 0); if (ret < 0)