summaryrefslogtreecommitdiffstats
path: root/src/p11tool.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/p11tool.c')
-rw-r--r--src/p11tool.c382
1 files changed, 382 insertions, 0 deletions
diff --git a/src/p11tool.c b/src/p11tool.c
new file mode 100644
index 0000000..e60f74a
--- /dev/null
+++ b/src/p11tool.c
@@ -0,0 +1,382 @@
+/*
+ * Copyright (C) 2010-2014 Free Software Foundation, Inc.
+ * Copyright (C) 2013-2014 Nikos Mavrogiannopoulos
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see
+ * <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+#include <gnutls/openpgp.h>
+#include <gnutls/pkcs12.h>
+#include <gnutls/pkcs11.h>
+#include <gnutls/abstract.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/* Gnulib portability files. */
+#include <read-file.h>
+
+#include "p11tool-options.h"
+#include "p11tool.h"
+#include "certtool-common.h"
+
+static void cmd_parser(int argc, char **argv);
+
+static FILE *outfile;
+static const char *outfile_name = NULL;
+int batch = 0;
+int ask_pass = 0;
+
+void app_exit(int val)
+{
+ if (val != 0) {
+ if (outfile_name)
+ (void)remove(outfile_name);
+ }
+ exit(val);
+}
+
+static void tls_log_func(int level, const char *str)
+{
+ fprintf(stderr, "|<%d>| %s", level, str);
+}
+
+
+int main(int argc, char **argv)
+{
+ cmd_parser(argc, argv);
+
+ return 0;
+}
+
+static
+unsigned opt_to_flags(common_info_st *cinfo, unsigned *key_usage)
+{
+ unsigned flags = 0;
+
+ *key_usage = 0;
+
+ if (HAVE_OPT(MARK_PRIVATE)) {
+ if (ENABLED_OPT(MARK_PRIVATE)) {
+ flags |= GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE;
+ } else {
+ flags |= GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_PRIVATE;
+ }
+ } else { /* if not given mark as private the private objects, and public the public ones */
+ if (cinfo->privkey)
+ flags |= GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE;
+ else if (cinfo->pubkey || cinfo->cert)
+ flags |= GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_PRIVATE;
+ /* else set the defaults of the token */
+ }
+
+ if (ENABLED_OPT(MARK_ALWAYS_AUTHENTICATE)) {
+ flags |= GNUTLS_PKCS11_OBJ_FLAG_MARK_ALWAYS_AUTH;
+ }
+
+ if (HAVE_OPT(MARK_DISTRUSTED)) {
+ flags |=
+ GNUTLS_PKCS11_OBJ_FLAG_MARK_DISTRUSTED;
+ } else {
+ if (ENABLED_OPT(MARK_TRUSTED))
+ flags |=
+ GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED;
+ }
+
+ if (ENABLED_OPT(MARK_SIGN))
+ *key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
+
+ if (ENABLED_OPT(MARK_DECRYPT))
+ *key_usage |= GNUTLS_KEY_DECIPHER_ONLY;
+
+ if (ENABLED_OPT(MARK_CA))
+ flags |=
+ GNUTLS_PKCS11_OBJ_FLAG_MARK_CA;
+
+ if (ENABLED_OPT(MARK_WRAP))
+ flags |= GNUTLS_PKCS11_OBJ_FLAG_MARK_KEY_WRAP;
+
+ if (ENABLED_OPT(LOGIN))
+ flags |= GNUTLS_PKCS11_OBJ_FLAG_LOGIN;
+
+ if (ENABLED_OPT(SO_LOGIN))
+ flags |= GNUTLS_PKCS11_OBJ_FLAG_LOGIN_SO;
+
+ return flags;
+}
+
+static void cmd_parser(int argc, char **argv)
+{
+ int ret, debug = 0;
+ common_info_st cinfo;
+ unsigned int pkcs11_type = -1, key_type = GNUTLS_PK_UNKNOWN;
+ const char *url = NULL;
+ unsigned int detailed_url = 0, optct;
+ unsigned int bits = 0;
+ const char *label = NULL, *sec_param = NULL, *id = NULL;
+ unsigned flags;
+ unsigned key_usage;
+
+ optct = optionProcess(&p11toolOptions, argc, argv);
+ argc += optct;
+ argv += optct;
+
+ if (url == NULL && argc > 0)
+ url = argv[0];
+ else
+ url = "pkcs11:";
+
+ if (HAVE_OPT(DEBUG))
+ debug = OPT_VALUE_DEBUG;
+
+ gnutls_global_set_log_function(tls_log_func);
+ gnutls_global_set_log_level(debug);
+ if (debug > 1)
+ printf("Setting log level to %d\n", debug);
+
+ if ((ret = gnutls_global_init()) < 0) {
+ fprintf(stderr, "global_init: %s\n", gnutls_strerror(ret));
+ app_exit(1);
+ }
+
+ if (HAVE_OPT(PROVIDER)) {
+ const char *params = NULL;
+
+ if (HAVE_OPT(PROVIDER_OPTS))
+ params = OPT_ARG(PROVIDER_OPTS);
+
+ ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
+ if (ret < 0)
+ fprintf(stderr, "pkcs11_init: %s\n",
+ gnutls_strerror(ret));
+ else {
+ ret =
+ gnutls_pkcs11_add_provider(OPT_ARG(PROVIDER),
+ params);
+ if (ret < 0) {
+ fprintf(stderr, "pkcs11_add_provider: %s\n",
+ gnutls_strerror(ret));
+ app_exit(1);
+ }
+ }
+ } else {
+ ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_AUTO, NULL);
+ if (ret < 0)
+ fprintf(stderr, "pkcs11_init: %s\n",
+ gnutls_strerror(ret));
+ }
+
+ if (HAVE_OPT(OUTFILE)) {
+ outfile = safe_open_rw(OPT_ARG(OUTFILE), 0);
+ if (outfile == NULL) {
+ fprintf(stderr, "cannot open %s\n", OPT_ARG(OUTFILE));
+ app_exit(1);
+ }
+ outfile_name = OPT_ARG(OUTFILE);
+ } else
+ outfile = stdout;
+
+ memset(&cinfo, 0, sizeof(cinfo));
+
+ if (HAVE_OPT(HASH)) {
+ cinfo.hash = hash_to_id(OPT_ARG(HASH));
+ if (cinfo.hash == GNUTLS_DIG_UNKNOWN) {
+ fprintf(stderr, "invalid hash: %s\n", OPT_ARG(HASH));
+ app_exit(1);
+ }
+ }
+
+ if (HAVE_OPT(SIGN_PARAMS))
+ sign_params_to_flags(&cinfo, OPT_ARG(SIGN_PARAMS));
+
+ if (HAVE_OPT(SECRET_KEY))
+ cinfo.secret_key = OPT_ARG(SECRET_KEY);
+
+ if (HAVE_OPT(LOAD_PRIVKEY))
+ cinfo.privkey = OPT_ARG(LOAD_PRIVKEY);
+
+ if (HAVE_OPT(PKCS8))
+ cinfo.pkcs8 = 1;
+
+ if (HAVE_OPT(BATCH)) {
+ batch = cinfo.batch = 1;
+ }
+
+ if (HAVE_OPT(ONLY_URLS)) {
+ cinfo.only_urls = 1;
+ }
+
+ if (ENABLED_OPT(INDER))
+ cinfo.incert_format = GNUTLS_X509_FMT_DER;
+ else
+ cinfo.incert_format = GNUTLS_X509_FMT_PEM;
+
+ if (HAVE_OPT(OUTDER))
+ cinfo.outcert_format = GNUTLS_X509_FMT_DER;
+ else
+ cinfo.outcert_format = GNUTLS_X509_FMT_PEM;
+
+ if (HAVE_OPT(SET_PIN))
+ cinfo.pin = OPT_ARG(SET_PIN);
+
+ if (HAVE_OPT(SET_SO_PIN))
+ cinfo.so_pin = OPT_ARG(SET_SO_PIN);
+
+ if (HAVE_OPT(LOAD_CERTIFICATE))
+ cinfo.cert = OPT_ARG(LOAD_CERTIFICATE);
+
+ if (HAVE_OPT(LOAD_PUBKEY))
+ cinfo.pubkey = OPT_ARG(LOAD_PUBKEY);
+
+ if (ENABLED_OPT(DETAILED_URL))
+ detailed_url = 1;
+
+ if (HAVE_OPT(LABEL)) {
+ label = OPT_ARG(LABEL);
+ }
+
+ if (HAVE_OPT(ID)) {
+ id = OPT_ARG(ID);
+ }
+
+ if (HAVE_OPT(BITS)) {
+ bits = OPT_VALUE_BITS;
+ }
+
+ if (HAVE_OPT(CURVE)) {
+ gnutls_ecc_curve_t curve = str_to_curve(OPT_ARG(CURVE));
+ bits = GNUTLS_CURVE_TO_BITS(curve);
+ }
+
+ if (HAVE_OPT(SEC_PARAM)) {
+ sec_param = OPT_ARG(SEC_PARAM);
+ }
+
+ flags = opt_to_flags(&cinfo, &key_usage);
+ cinfo.key_usage = key_usage;
+
+ /* handle actions
+ */
+ if (HAVE_OPT(LIST_TOKENS)) {
+ pkcs11_token_list(outfile, detailed_url, &cinfo, 0);
+ } else if (HAVE_OPT(LIST_TOKEN_URLS)) {
+ pkcs11_token_list(outfile, detailed_url, &cinfo, 1);
+ } else if (HAVE_OPT(LIST_MECHANISMS)) {
+ pkcs11_mechanism_list(outfile, url, flags, &cinfo);
+ } else if (HAVE_OPT(GENERATE_RANDOM)) {
+ pkcs11_get_random(outfile, url, OPT_VALUE_GENERATE_RANDOM,
+ &cinfo);
+ } else if (HAVE_OPT(INFO)) {
+ pkcs11_type = PKCS11_TYPE_INFO;
+ pkcs11_list(outfile, url, pkcs11_type,
+ flags, detailed_url, &cinfo);
+ } else if (HAVE_OPT(LIST_ALL)) {
+ pkcs11_type = PKCS11_TYPE_ALL;
+ pkcs11_list(outfile, url, pkcs11_type,
+ flags, detailed_url, &cinfo);
+ } else if (HAVE_OPT(LIST_ALL_CERTS)) {
+ pkcs11_type = PKCS11_TYPE_CRT_ALL;
+ pkcs11_list(outfile, url, pkcs11_type,
+ flags, detailed_url, &cinfo);
+ } else if (HAVE_OPT(LIST_CERTS)) {
+ pkcs11_type = PKCS11_TYPE_PK;
+ pkcs11_list(outfile, url, pkcs11_type,
+ flags, detailed_url, &cinfo);
+ } else if (HAVE_OPT(LIST_ALL_PRIVKEYS)) {
+ pkcs11_type = PKCS11_TYPE_PRIVKEY;
+ pkcs11_list(outfile, url, pkcs11_type,
+ flags, detailed_url, &cinfo);
+ } else if (HAVE_OPT(LIST_ALL_TRUSTED)) {
+ pkcs11_type = PKCS11_TYPE_TRUSTED;
+ pkcs11_list(outfile, url, pkcs11_type,
+ flags, detailed_url, &cinfo);
+ } else if (HAVE_OPT(EXPORT)) {
+ pkcs11_export(outfile, url, flags, &cinfo);
+ } else if (HAVE_OPT(EXPORT_STAPLED)) {
+ pkcs11_export(outfile, url, flags|GNUTLS_PKCS11_OBJ_FLAG_OVERWRITE_TRUSTMOD_EXT, &cinfo);
+ } else if (HAVE_OPT(EXPORT_CHAIN)) {
+ pkcs11_export_chain(outfile, url, flags, &cinfo);
+ } else if (HAVE_OPT(WRITE)) {
+ pkcs11_write(outfile, url, label, id,
+ flags, &cinfo);
+ } else if (HAVE_OPT(TEST_SIGN)) {
+ pkcs11_test_sign(outfile, url, flags, &cinfo);
+ } else if (HAVE_OPT(INITIALIZE)) {
+ pkcs11_init(outfile, url, label, &cinfo);
+ } else if (HAVE_OPT(INITIALIZE_PIN)) {
+ pkcs11_set_token_pin(outfile, url, &cinfo, 0);
+ } else if (HAVE_OPT(INITIALIZE_SO_PIN)) {
+ pkcs11_set_token_pin(outfile, url, &cinfo, 1);
+ } else if (HAVE_OPT(DELETE)) {
+ pkcs11_delete(outfile, url, flags, &cinfo);
+ } else if (HAVE_OPT(GENERATE_PRIVKEY)) {
+ key_type = figure_key_type(OPT_ARG(GENERATE_PRIVKEY));
+ if (key_type == GNUTLS_PK_UNKNOWN)
+ app_exit(1);
+ pkcs11_generate(outfile, url, key_type,
+ get_bits(key_type, bits, sec_param, 0),
+ label, id, detailed_url,
+ flags, &cinfo);
+ } else if (HAVE_OPT(GENERATE_ECC)) {
+ key_type = GNUTLS_PK_EC;
+ pkcs11_generate(outfile, url, key_type,
+ get_bits(key_type, bits, sec_param, 0),
+ label, id, detailed_url,
+ flags, &cinfo);
+ } else if (HAVE_OPT(GENERATE_RSA)) {
+ key_type = GNUTLS_PK_RSA;
+ pkcs11_generate(outfile, url, key_type,
+ get_bits(key_type, bits, sec_param, 0),
+ label, id, detailed_url,
+ flags, &cinfo);
+ } else if (HAVE_OPT(GENERATE_DSA)) {
+ key_type = GNUTLS_PK_DSA;
+ pkcs11_generate(outfile, url, key_type,
+ get_bits(key_type, bits, sec_param, 0),
+ label, id, detailed_url,
+ flags, &cinfo);
+ } else if (HAVE_OPT(EXPORT_PUBKEY)) {
+ pkcs11_export_pubkey(outfile, url, detailed_url, flags, &cinfo);
+ } else if (HAVE_OPT(SET_ID)) {
+ pkcs11_set_id(outfile, url, detailed_url, flags, &cinfo, OPT_ARG(SET_ID));
+ } else if (HAVE_OPT(SET_LABEL)) {
+ pkcs11_set_label(outfile, url, detailed_url, flags, &cinfo, OPT_ARG(SET_LABEL));
+ } else {
+ USAGE(1);
+ }
+
+ fclose(outfile);
+
+#ifdef ENABLE_PKCS11
+ gnutls_pkcs11_deinit();
+#endif
+ gnutls_global_deinit();
+}