From: Nikos Mavrogiannopoulos Date: Fri, 6 Jul 2012 20:27:38 +0000 (+0200) Subject: Added tpmtool. X-Git-Tag: gnutls_3_1_0pre0~87 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6f8a057be73f64dfb1928277d5112ce0c8c5300a;p=thirdparty%2Fgnutls.git Added tpmtool. It is a tool to generate TPM private keys. In addition gnutls_tpm_privkey_generate() was added. --- diff --git a/NEWS b/NEWS index 20e8886854..04e8a72765 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,9 @@ See the end for copying conditions. * Version 3.1.0 (unreleased) +** tpmtool: Added. It is a tool to generate private keys in the +TPM. + ** gnutls-cli: --benchmark-tls was split to --benchmark-tls-kx and --benchmark-tls-ciphers @@ -49,6 +52,7 @@ gnutls_privkey_import_pkcs11_url: Added gnutls_privkey_import_openpgp_raw: Added gnutls_privkey_import_x509_raw: Added gnutls_privkey_import_ext2: Added +gnutls_tpm_privkey_generate: Added gnutls_x509_privkey_import2: Added gnutls_x509_privkey_import_openssl: Added gnutls_load_file: Added diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c index ec90423dfa..83e78db669 100644 --- a/lib/gnutls_errors.c +++ b/lib/gnutls_errors.c @@ -296,10 +296,10 @@ static const gnutls_error_entry error_algorithms[] = { GNUTLS_E_PARSING_ERROR, 1), ERROR_ENTRY (N_("Error in provided PIN."), GNUTLS_E_PKCS11_PIN_ERROR, 1), - ERROR_ENTRY (N_("Error in provided password for TPM."), - GNUTLS_E_TPM_PASSWORD_ERROR, 1), - ERROR_ENTRY (N_("Error in provided password for key to be loaded in TPM."), + ERROR_ENTRY (N_("Error in provided SRK password for TPM."), GNUTLS_E_TPM_SRK_PASSWORD_ERROR, 1), + ERROR_ENTRY (N_("Error in provided password for key to be loaded in TPM."), + GNUTLS_E_TPM_KEY_PASSWORD_ERROR, 1), ERROR_ENTRY (N_("PKCS #11 error in slot"), GNUTLS_E_PKCS11_SLOT_ERROR, 1), ERROR_ENTRY (N_("Thread locking error"), diff --git a/lib/includes/Makefile.am b/lib/includes/Makefile.am index 31650c1c3e..bf32cdb4c8 100644 --- a/lib/includes/Makefile.am +++ b/lib/includes/Makefile.am @@ -20,7 +20,7 @@ nobase_include_HEADERS = gnutls/x509.h gnutls/pkcs12.h gnutls/compat.h \ gnutls/openpgp.h gnutls/crypto.h gnutls/pkcs11.h \ - gnutls/abstract.h gnutls/dtls.h gnutls/ocsp.h + gnutls/abstract.h gnutls/dtls.h gnutls/ocsp.h gnutls/tpm.h if ENABLE_CXX nobase_include_HEADERS += gnutls/gnutlsxx.h diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index c729ae046d..35c9367f37 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -1915,7 +1915,7 @@ int gnutls_load_file(const char* filename, gnutls_datum_t * data); #define GNUTLS_E_SESSION_EOF -328 #define GNUTLS_E_TPM_ERROR -329 -#define GNUTLS_E_TPM_PASSWORD_ERROR -330 +#define GNUTLS_E_TPM_KEY_PASSWORD_ERROR -330 #define GNUTLS_E_TPM_SRK_PASSWORD_ERROR -331 #define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250 diff --git a/lib/includes/gnutls/tpm.h b/lib/includes/gnutls/tpm.h new file mode 100644 index 0000000000..9eb3c92b73 --- /dev/null +++ b/lib/includes/gnutls/tpm.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2010-2012 Free Software Foundation, Inc. + * + * Author: Nikos Mavrogiannopoulos + * + * This file is part of GnuTLS. + * + * The 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 3 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 + * + */ + +#ifndef __GNUTLS_TPM_H +#define __GNUTLS_TPM_H + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define GNUTLS_TPM_SIG_PKCS1V15 1 +#define GNUTLS_TPM_SIG_PKCS1V15_SHA1 2 + +int +gnutls_tpm_privkey_generate (gnutls_pk_algorithm_t pk, unsigned int bits, + const char* srk_password, + const char* key_password, + gnutls_x509_crt_fmt_t format, + gnutls_datum_t* privkey, + gnutls_datum_t* pubkey, + unsigned int flags); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/libgnutls.map b/lib/libgnutls.map index cf7a7dc608..54034150dd 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -807,6 +807,7 @@ GNUTLS_3_1_0 { gnutls_x509_privkey_import2; gnutls_privkey_import_ext2; gnutls_privkey_import_tpm_raw; + gnutls_tpm_privkey_generate; } GNUTLS_3_0_0; GNUTLS_PRIVATE { diff --git a/lib/pkcs11_privkey.c b/lib/pkcs11_privkey.c index 487230cdcf..1cc4d18c6b 100644 --- a/lib/pkcs11_privkey.c +++ b/lib/pkcs11_privkey.c @@ -451,7 +451,7 @@ gnutls_pkcs11_privkey_export_url (gnutls_pkcs11_privkey_t key, * @flags: should be zero * * This function will generate a private key in the specified - * by the @url token. The pivate key will be generate within + * by the @url token. The private key will be generate within * the token and will not be exportable. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a diff --git a/lib/tpm.c b/lib/tpm.c index 366b560158..221836414b 100644 --- a/lib/tpm.c +++ b/lib/tpm.c @@ -29,11 +29,13 @@ #include #include +#include #include #include #include #include +#include #include #include @@ -108,20 +110,21 @@ tpm_sign_fn (gnutls_privkey_t key, void *_s, return 0; } +static const unsigned char nullpass[20]; /** * gnutls_privkey_import_tpm_raw: * @pkey: The private key * @fdata: The TPM key to be imported * @format: The format of the private key - * @srk_password: A password for the key (optional) - * @tpm_password: A password for the TPM (optional) + * @srk_password: The password for the SRK key (optional) + * @key_password: A password for the key (optional) * * This function will import the given private key to the abstract * #gnutls_privkey_t structure. If a password is needed to decrypt * the provided key or the provided password is wrong, then * %GNUTLS_E_TPM_SRK_PASSWORD_ERROR is returned. If the TPM password - * is wrong or not provided then %GNUTLS_E_TPM_PASSWORD_ERROR + * is wrong or not provided then %GNUTLS_E_TPM_KEY_PASSWORD_ERROR * is returned. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a @@ -135,7 +138,7 @@ gnutls_privkey_import_tpm_raw (gnutls_privkey_t pkey, const gnutls_datum_t * fdata, gnutls_x509_crt_fmt_t format, const char *srk_password, - const char *tpm_password) + const char *key_password) { static const TSS_UUID SRK_UUID = TSS_UUID_SRK; gnutls_datum_t asn1; @@ -143,7 +146,6 @@ gnutls_privkey_import_tpm_raw (gnutls_privkey_t pkey, int err, ret; struct tpm_ctx_st *s; gnutls_datum_t tmp_sig; - static const char nullpass[20]; ret = gnutls_pem_base64_decode_alloc ("TSS KEY BLOB", fdata, &asn1); if (ret) @@ -263,7 +265,6 @@ gnutls_privkey_import_tpm_raw (gnutls_privkey_t pkey, goto out_srkpol; } -retry_sign: ret = gnutls_privkey_sign_data (pkey, GNUTLS_DIG_SHA1, 0, fdata, &tmp_sig); if (ret == GNUTLS_E_INSUFFICIENT_CREDENTIALS) @@ -283,6 +284,7 @@ retry_sign: ret = GNUTLS_E_TPM_ERROR; goto out_key; } + err = Tspi_Policy_AssignToObject (s->tpm_key_policy, s->tpm_key); if (err) { @@ -296,17 +298,16 @@ retry_sign: err = Tspi_Policy_SetSecret (s->tpm_key_policy, TSS_SECRET_MODE_PLAIN, - strlen (tpm_password), (void *) tpm_password); + strlen (key_password), (void *) key_password); if (err) { gnutls_assert (); _gnutls_debug_log ("Failed to set key PIN: %s\n", Trspi_Error_String (err)); - ret = GNUTLS_E_TPM_PASSWORD_ERROR; + ret = GNUTLS_E_TPM_KEY_PASSWORD_ERROR; goto out_key_policy; } - goto retry_sign; } else if (ret < 0) { @@ -338,3 +339,291 @@ out_blob: return ret; } +const TSS_UUID srk_uuid = TSS_UUID_SRK; + +/** + * gnutls_tpm_privkey_generate: + * @pk: the public key algorithm + * @bits: the security bits + * @srk_password: a password to protect the exported key (optional) + * @key_password: the password for the TPM (optional) + * @privkey: the generated key + * @pubkey: the corresponding public key + * @flags: should be a list of %GNUTLS_TPM flags + * + * This function will generate a private key in the TPM + * chip. The private key will be generated within the chip + * and will be exported in a wrapped with TPM's master key + * form. Furthermore the wrapped key can be protected with + * the provided @password. + * + * Allowed flags are %GNUTLS_TPM_SIG_PKCS1V15 and %GNUTLS_TPM_SIG_PKCS1V15_SHA1. + * + * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a + * negative error value. + * + * Since: 3.1.0 + **/ +int +gnutls_tpm_privkey_generate (gnutls_pk_algorithm_t pk, unsigned int bits, + const char* srk_password, + const char* key_password, + gnutls_x509_crt_fmt_t format, + gnutls_datum_t* privkey, + gnutls_datum_t* pubkey, + unsigned int flags) +{ +TSS_HCONTEXT ctx; +TSS_FLAG tpm_flags = TSS_KEY_TYPE_LEGACY | TSS_KEY_VOLATILE; +TSS_HKEY key_ctx; +TSS_HKEY srk_ctx; +TSS_RESULT tssret; +int ret; +void* tdata; +UINT32 tint; +gnutls_datum_t tmpkey; +TSS_HPOLICY srk_policy, key_policy; +unsigned int sig; +gnutls_pubkey_t pub; + + switch(bits) { + case 512: + tpm_flags |= TSS_KEY_SIZE_512; + break; + case 1024: + tpm_flags |= TSS_KEY_SIZE_1024; + break; + case 2048: + tpm_flags |= TSS_KEY_SIZE_2048; + break; + case 4096: + tpm_flags |= TSS_KEY_SIZE_4096; + break; + case 8192: + tpm_flags |= TSS_KEY_SIZE_8192; + break; + case 16384: + tpm_flags |= TSS_KEY_SIZE_16384; + break; + default: + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + } + + tssret = Tspi_Context_Create(&ctx); + if (tssret != 0) + { + gnutls_assert(); + return GNUTLS_E_TPM_ERROR; + } + + tssret = Tspi_Context_Connect(ctx, NULL); + if (tssret != 0) + { + gnutls_assert(); + ret = GNUTLS_E_TPM_ERROR; + goto err_cc; + } + + tssret = Tspi_Context_CreateObject(ctx, TSS_OBJECT_TYPE_RSAKEY, tpm_flags, &key_ctx); + if (tssret != 0) + { + gnutls_assert(); + ret = GNUTLS_E_TPM_ERROR; + goto err_cc; + } + + if (flags & GNUTLS_TPM_SIG_PKCS1V15_SHA1) + sig = TSS_SS_RSASSAPKCS1V15_SHA1; + else + sig = TSS_SS_RSASSAPKCS1V15_DER; + + tssret = Tspi_SetAttribUint32(key_ctx, TSS_TSPATTRIB_KEY_INFO, TSS_TSPATTRIB_KEYINFO_SIGSCHEME, + sig); + if (tssret != 0) + { + gnutls_assert(); + ret = GNUTLS_E_TPM_ERROR; + goto err_sa; + } + + tssret = Tspi_Context_LoadKeyByUUID(ctx, TSS_PS_TYPE_SYSTEM, srk_uuid, + &srk_ctx); + if (tssret != 0) + { + gnutls_assert(); + ret = GNUTLS_E_TPM_ERROR; + goto err_sa; + } + + /* set SRK key */ + tssret = Tspi_GetPolicyObject(srk_ctx, TSS_POLICY_USAGE, &srk_policy); + if (tssret != 0) + { + gnutls_assert(); + ret = GNUTLS_E_TPM_ERROR; + goto err_sa; + } + + if (srk_password == NULL) + { + tssret = Tspi_Policy_SetSecret(srk_policy, TSS_SECRET_MODE_SHA1, + 20, (void*)nullpass); + } + else + { + tssret = Tspi_Policy_SetSecret(srk_policy, TSS_SECRET_MODE_PLAIN, + strlen(srk_password), (void*)srk_password); + } + + if (tssret != 0) + { + gnutls_assert(); + ret = GNUTLS_E_TPM_SRK_PASSWORD_ERROR; + goto err_sa; + } + + /* set the key of the actual key */ + if (key_password) + { + tssret = Tspi_GetPolicyObject(key_ctx, TSS_POLICY_USAGE, &key_policy); + if (tssret != 0) + { + gnutls_assert(); + ret = GNUTLS_E_TPM_ERROR; + goto err_sa; + } + + tssret = Tspi_Policy_SetSecret(key_policy, TSS_SECRET_MODE_PLAIN, + strlen(key_password), (void*)key_password); + if (tssret != 0) + { + gnutls_assert(); + ret = GNUTLS_E_TPM_ERROR; + goto err_sa; + } + } + + tssret = Tspi_Key_CreateKey(key_ctx, srk_ctx, 0); + if (tssret != 0) + { + gnutls_assert(); + if (tssret == TPM_E_AUTHFAIL) + ret = GNUTLS_E_TPM_SRK_PASSWORD_ERROR; + else + ret = GNUTLS_E_TPM_ERROR; + goto err_sa; + } + + tssret = Tspi_GetAttribData(key_ctx, TSS_TSPATTRIB_KEY_BLOB, + TSS_TSPATTRIB_KEYBLOB_BLOB, &tint, (void*)&tdata); + if (tssret != 0) + { + gnutls_assert(); + ret = GNUTLS_E_TPM_ERROR; + goto err_sa; + } + + ret = _gnutls_x509_encode_octet_string(tdata, tint, &tmpkey); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + + if (format == GNUTLS_X509_FMT_PEM) + { + ret = _gnutls_fbase64_encode ("TSS KEY BLOB", tmpkey.data, tmpkey.size, &privkey->data); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + privkey->size = ret; + } + else + { + privkey->data = tmpkey.data; + privkey->size = tmpkey.size; + tmpkey.data = NULL; + } + + { + gnutls_datum_t m, e; + size_t psize; + + ret = gnutls_pubkey_init(&pub); + if (ret < 0) + { + gnutls_assert(); + goto privkey_cleanup; + } + + tssret = Tspi_GetAttribData(key_ctx, TSS_TSPATTRIB_RSAKEY_INFO, + TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &tint, (void*)&tdata); + if (tssret != 0) + { + gnutls_assert(); + ret = GNUTLS_E_TPM_ERROR; + goto pubkey_cleanup; + } + + m.data = tdata; + m.size = tint; + + tssret = Tspi_GetAttribData(key_ctx, TSS_TSPATTRIB_RSAKEY_INFO, + TSS_TSPATTRIB_KEYINFO_RSA_EXPONENT, &tint, (void*)&tdata); + if (tssret != 0) + { + gnutls_assert(); + Tspi_Context_FreeMemory(key_ctx, m.data); + ret = GNUTLS_E_TPM_ERROR; + goto pubkey_cleanup; + } + + e.data = tdata; + e.size = tint; + + ret = gnutls_pubkey_import_rsa_raw(pub, &m, &e); + if (ret < 0) + { + gnutls_assert(); + goto pubkey_cleanup; + } + + psize = e.size+m.size+512; + pubkey->data = gnutls_malloc(psize); + if (pubkey->data == NULL) + { + gnutls_assert(); + ret = GNUTLS_E_MEMORY_ERROR; + goto pubkey_cleanup; + } + + ret = gnutls_pubkey_export(pub, format, pubkey->data, &psize); + if (ret < 0) + { + gnutls_assert(); + goto pubkey_cleanup; + } + pubkey->size = psize; + + gnutls_pubkey_deinit(pub); + } + + ret = 0; + goto cleanup; + +pubkey_cleanup: + gnutls_pubkey_deinit(pub); +privkey_cleanup: + gnutls_free(privkey->data); + privkey->data = NULL; +cleanup: + gnutls_free(tmpkey.data); + tmpkey.data = NULL; +err_sa: + Tspi_Context_CloseObject(ctx, key_ctx); +err_cc: + Tspi_Context_Close(ctx); + return ret; +} diff --git a/lib/x509/common.c b/lib/x509/common.c index 052eb7cd73..2e4ff2e500 100644 --- a/lib/x509/common.c +++ b/lib/x509/common.c @@ -996,6 +996,42 @@ cleanup: } +int _gnutls_x509_encode_octet_string(const void* input_data, size_t input_size, + gnutls_datum_t* output) +{ + int ret; + ASN1_TYPE c2 = ASN1_TYPE_EMPTY; + + if ((ret = asn1_create_element + (_gnutls_get_pkix (), "PKIX1.pkcs-7-Data", &c2)) != ASN1_SUCCESS) + { + gnutls_assert (); + ret = _gnutls_asn2err (ret); + goto cleanup; + } + + ret = asn1_write_value (c2, "", input_data, input_size); + if (ret != ASN1_SUCCESS) + { + gnutls_assert (); + ret = _gnutls_asn2err (ret); + goto cleanup; + } + + ret = _gnutls_x509_der_encode(c2, "", output, 0); + if (ret < 0) + { + gnutls_assert (); + goto cleanup; + } + + ret = 0; + +cleanup: + asn1_delete_structure (&c2); + return ret; +} + /* DER Encodes the src ASN1_TYPE and stores it to * the given datum. If str is non zero then the data are encoded as * an OCTET STRING. diff --git a/lib/x509/common.h b/lib/x509/common.h index 1d7116ccb6..e48e0f88e5 100644 --- a/lib/x509/common.h +++ b/lib/x509/common.h @@ -71,6 +71,9 @@ int _gnutls_x509_set_time (ASN1_TYPE c2, const char *where, time_t tim, int gene int _gnutls_x509_decode_octet_string (const char *string_type, const uint8_t * der, size_t der_size, uint8_t * output, size_t * output_size); +int _gnutls_x509_encode_octet_string(const void* input_data, size_t input_size, + gnutls_datum_t* output); + int _gnutls_x509_oid_data2string (const char *OID, void *value, int value_size, char *res, size_t * res_size); diff --git a/src/Makefile.am b/src/Makefile.am index 48f32861ad..cf775c3944 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -46,6 +46,10 @@ if ENABLE_OCSP bin_PROGRAMS += ocsptool endif +if ENABLE_TROUSERS +bin_PROGRAMS += tpmtool +endif + if ENABLE_PKCS11 bin_PROGRAMS += p11tool PKCS11_SRCS = p11common.c p11common.h @@ -150,11 +154,29 @@ libcmd_p11tool_la_LIBADD += ../gl/libgnu.la $(INET_PTON_LIB) endif # ENABLE_PKCS11 +if ENABLE_TROUSERS + +tpmtool_SOURCES = tpmtool-args.def tpmtool.c certtool-common.c certtool-extras.c +tpmtool_LDADD = ../lib/libgnutls.la $(LIBOPTS_LDADD) $(LTLIBINTL) +tpmtool_LDADD += libcmd-tpmtool.la ../gl/libgnu.la + +noinst_LTLIBRARIES += libcmd-tpmtool.la +libcmd_tpmtool_la_CFLAGS = +libcmd_tpmtool_la_SOURCES = tpmtool-args.def tpmtool-args.c tpmtool-args.h \ + certtool-cfg.h certtool-cfg.c +libcmd_tpmtool_la_LIBADD = ../gl/libgnu.la $(LTLIBREADLINE) +libcmd_tpmtool_la_LIBADD += ../lib/libgnutls.la +libcmd_tpmtool_la_LIBADD += ../gl/libgnu.la $(INET_PTON_LIB) + +endif # ENABLE_TROUSERS + BUILT_SOURCES = ocsptool-args.c p11tool-args.c psk-args.c cli-debug-args.c \ cli-args.c serv-args.c srptool-args.c certtool-args.c ocsptool-args.c: $(srcdir)/args-std.def $(srcdir)/ocsptool-args.def -autogen ocsptool-args.def +tpmtool-args.c: $(srcdir)/args-std.def $(srcdir)/tpmtool-args.def + -autogen tpmtool-args.def p11tool-args.c: $(srcdir)/args-std.def $(srcdir)/p11tool-args.def -autogen p11tool-args.def psk-args.c: $(srcdir)/args-std.def $(srcdir)/psk-args.def diff --git a/src/tpmtool-args.c b/src/tpmtool-args.c new file mode 100644 index 0000000000..8e77bb4e39 --- /dev/null +++ b/src/tpmtool-args.c @@ -0,0 +1,531 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (tpmtool-args.c) + * + * It has been AutoGen-ed July 6, 2012 at 09:41:37 PM by AutoGen 5.16 + * From the definitions tpmtool-args.def + * and the template file options + * + * Generated from AutoOpts 36:4:11 templates. + * + * AutoOpts is a copyrighted work. This source file is not encumbered + * by AutoOpts licensing, but is provided under the licensing terms chosen + * by the tpmtool author or copyright holder. AutoOpts is + * licensed under the terms of the LGPL. The redistributable library + * (``libopts'') is licensed under the terms of either the LGPL or, at the + * users discretion, the BSD license. See the AutoOpts and/or libopts sources + * for details. + * + * The tpmtool program is copyrighted and licensed + * under the following terms: + * + * Copyright (C) 2000-2012 Free Software Foundation, all rights reserved. + * This is free software. It is licensed for use, modification and + * redistribution under the terms of the + * GNU General Public License, version 3 or later + * + * + * tpmtool 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. + * + * tpmtool 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 . + */ + +#ifndef __doxygen__ +#define OPTION_CODE_COMPILE 1 +#include "tpmtool-args.h" +#include + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +extern FILE * option_usage_fp; + +/* TRANSLATORS: choose the translation for option names wisely because you + cannot ever change your mind. */ +#define zCopyright (tpmtool_opt_strs+0) +#define zLicenseDescrip (tpmtool_opt_strs+278) + + +#ifndef NULL +# define NULL 0 +#endif + +/* + * tpmtool option static const strings + */ +static char const tpmtool_opt_strs[1489] = +/* 0 */ "tpmtool @VERSION@\n" + "Copyright (C) 2000-2012 Free Software Foundation, all rights reserved.\n" + "This is free software. It is licensed for use, modification and\n" + "redistribution under the terms of the\n" + "GNU General Public License, version 3 or later\n" + " \n\0" +/* 278 */ "tpmtool is free software: you can redistribute it and/or modify it under\n" + "the terms of the GNU General Public License as published by the Free\n" + "Software Foundation, either version 3 of the License, or (at your option)\n" + "any later version.\n\n" + "tpmtool is distributed in the hope that it will be useful, but WITHOUT ANY\n" + "WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\n" + "FOR A PARTICULAR PURPOSE. See the GNU General Public License for more\n" + "details.\n\n" + "You should have received a copy of the GNU General Public License along\n" + "with this program. If not, see .\n\0" +/* 881 */ "Enable debugging.\0" +/* 899 */ "DEBUG\0" +/* 905 */ "debug\0" +/* 911 */ "Output file\0" +/* 923 */ "OUTFILE\0" +/* 931 */ "outfile\0" +/* 939 */ "Generate an RSA private-public key pair\0" +/* 979 */ "GENERATE_RSA\0" +/* 992 */ "generate-rsa\0" +/* 1005 */ "Specify the number of bits for key generate\0" +/* 1049 */ "BITS\0" +/* 1054 */ "bits\0" +/* 1059 */ "Display extended usage information and exit\0" +/* 1103 */ "help\0" +/* 1108 */ "Extended usage information passed thru pager\0" +/* 1153 */ "more-help\0" +/* 1163 */ "Output version information and exit\0" +/* 1199 */ "version\0" +/* 1207 */ "TPMTOOL\0" +/* 1215 */ "tpmtool - GnuTLS TPM tool - Ver. @VERSION@\n" + "USAGE: %s [ - [] | --[{=| }] ]...\n\0" +/* 1316 */ "bug-gnutls@gnu.org\0" +/* 1335 */ "\n\n\0" +/* 1338 */ "\n" + "Program that allows handling cryptographic data from the TPM chip.\n\0" +/* 1407 */ "tpmtool @VERSION@\0" +/* 1425 */ "tpmtool [options] [url]\n" + "tpmtool --help for usage instructions.\n"; + +/* + * debug option description: + */ +#define DEBUG_DESC (tpmtool_opt_strs+881) +#define DEBUG_NAME (tpmtool_opt_strs+899) +#define DEBUG_name (tpmtool_opt_strs+905) +#define DEBUG_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) + +/* + * outfile option description: + */ +#define OUTFILE_DESC (tpmtool_opt_strs+911) +#define OUTFILE_NAME (tpmtool_opt_strs+923) +#define OUTFILE_name (tpmtool_opt_strs+931) +#define OUTFILE_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/* + * generate-rsa option description: + */ +#define GENERATE_RSA_DESC (tpmtool_opt_strs+939) +#define GENERATE_RSA_NAME (tpmtool_opt_strs+979) +#define GENERATE_RSA_name (tpmtool_opt_strs+992) +#define GENERATE_RSA_FLAGS (OPTST_DISABLED) + +/* + * bits option description: + */ +#define BITS_DESC (tpmtool_opt_strs+1005) +#define BITS_NAME (tpmtool_opt_strs+1049) +#define BITS_name (tpmtool_opt_strs+1054) +#define BITS_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) + +/* + * Help/More_Help/Version option descriptions: + */ +#define HELP_DESC (tpmtool_opt_strs+1059) +#define HELP_name (tpmtool_opt_strs+1103) +#ifdef HAVE_WORKING_FORK +#define MORE_HELP_DESC (tpmtool_opt_strs+1108) +#define MORE_HELP_name (tpmtool_opt_strs+1153) +#define MORE_HELP_FLAGS (OPTST_IMM | OPTST_NO_INIT) +#else +#define MORE_HELP_DESC NULL +#define MORE_HELP_name NULL +#define MORE_HELP_FLAGS (OPTST_OMITTED | OPTST_NO_INIT) +#endif +#ifdef NO_OPTIONAL_OPT_ARGS +# define VER_FLAGS (OPTST_IMM | OPTST_NO_INIT) +#else +# define VER_FLAGS (OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | \ + OPTST_ARG_OPTIONAL | OPTST_IMM | OPTST_NO_INIT) +#endif +#define VER_DESC (tpmtool_opt_strs+1163) +#define VER_name (tpmtool_opt_strs+1199) +/* + * Declare option callback procedures + */ +extern tOptProc + optionBooleanVal, optionNestedVal, optionNumericVal, + optionPagedUsage, optionPrintVersion, optionResetOpt, + optionStackArg, optionTimeDate, optionTimeVal, + optionUnstackArg, optionVendorOption; +static tOptProc + doOptDebug, doUsageOpt; +#define VER_PROC optionPrintVersion + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Define the tpmtool Option Descriptions. + * This is an array of OPTION_CT entries, one for each + * option that the tpmtool program responds to. + */ +static tOptDesc optDesc[OPTION_CT] = { + { /* entry idx, value */ 0, VALUE_OPT_DEBUG, + /* equiv idx, value */ 0, VALUE_OPT_DEBUG, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ DEBUG_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --debug */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptDebug, + /* desc, NAME, name */ DEBUG_DESC, DEBUG_NAME, DEBUG_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 1, VALUE_OPT_OUTFILE, + /* equiv idx, value */ 1, VALUE_OPT_OUTFILE, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OUTFILE_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --outfile */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ OUTFILE_DESC, OUTFILE_NAME, OUTFILE_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 2, VALUE_OPT_GENERATE_RSA, + /* equiv idx, value */ 2, VALUE_OPT_GENERATE_RSA, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ GENERATE_RSA_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --generate-rsa */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ GENERATE_RSA_DESC, GENERATE_RSA_NAME, GENERATE_RSA_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 3, VALUE_OPT_BITS, + /* equiv idx, value */ 3, VALUE_OPT_BITS, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ BITS_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --bits */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionNumericVal, + /* desc, NAME, name */ BITS_DESC, BITS_NAME, BITS_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ INDEX_OPT_VERSION, VALUE_OPT_VERSION, + /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_VERSION, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ VER_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ VER_PROC, + /* desc, NAME, name */ VER_DESC, NULL, VER_name, + /* disablement strs */ NULL, NULL }, + + + + { /* entry idx, value */ INDEX_OPT_HELP, VALUE_OPT_HELP, + /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_HELP, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OPTST_IMM | OPTST_NO_INIT, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doUsageOpt, + /* desc, NAME, name */ HELP_DESC, NULL, HELP_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ INDEX_OPT_MORE_HELP, VALUE_OPT_MORE_HELP, + /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_MORE_HELP, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ MORE_HELP_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionPagedUsage, + /* desc, NAME, name */ MORE_HELP_DESC, NULL, MORE_HELP_name, + /* disablement strs */ NULL, NULL } +}; + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Define the tpmtool Option Environment + */ +#define zPROGNAME (tpmtool_opt_strs+1207) +#define zUsageTitle (tpmtool_opt_strs+1215) +#define zRcName NULL +#define apzHomeList NULL +#define zBugsAddr (tpmtool_opt_strs+1316) +#define zExplain (tpmtool_opt_strs+1335) +#define zDetail (tpmtool_opt_strs+1338) +#define zFullVersion (tpmtool_opt_strs+1407) +/* extracted from optcode.tlib near line 350 */ + +#if defined(ENABLE_NLS) +# define OPTPROC_BASE OPTPROC_TRANSLATE | OPTPROC_NXLAT_OPT + static tOptionXlateProc translate_option_strings; +#else +# define OPTPROC_BASE OPTPROC_NONE +# define translate_option_strings NULL +#endif /* ENABLE_NLS */ + + +#define tpmtool_full_usage (NULL) + +#define tpmtool_short_usage (tpmtool_opt_strs+1425) + +#endif /* not defined __doxygen__ */ + +/* + * Create the static procedure(s) declared above. + */ +/** + * The callout function that invokes the optionUsage function. + * + * @param pOptions the AutoOpts option description structure + * @param pOptDesc the descriptor for the "help" (usage) option. + * @noreturn + */ +static void +doUsageOpt(tOptions * pOptions, tOptDesc * pOptDesc) +{ + optionUsage(&tpmtoolOptions, TPMTOOL_EXIT_SUCCESS); + /* NOTREACHED */ + (void)pOptDesc; + (void)pOptions; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the debug option. + * + * @param pOptions the tpmtool options data structure + * @param pOptDesc the option descriptor for this option. + */ +static void +doOptDebug(tOptions* pOptions, tOptDesc* pOptDesc) +{ + static struct {long rmin, rmax;} const rng[1] = { + { 0 , 9999 } }; + int ix; + + if (pOptions <= OPTPROC_EMIT_LIMIT) + goto emit_ranges; + optionNumericVal(pOptions, pOptDesc); + + for (ix = 0; ix < 1; ix++) { + if (pOptDesc->optArg.argInt < rng[ix].rmin) + continue; /* ranges need not be ordered. */ + if (pOptDesc->optArg.argInt == rng[ix].rmin) + return; + if (rng[ix].rmax == LONG_MIN) + continue; + if (pOptDesc->optArg.argInt <= rng[ix].rmax) + return; + } + + option_usage_fp = stderr; + +emit_ranges: + + optionShowRange(pOptions, pOptDesc, (void *)rng, 1); +} +/* extracted from optmain.tlib near line 1113 */ + +/** + * The directory containing the data associated with tpmtool. + */ +#ifndef PKGDATADIR +# define PKGDATADIR "" +#endif + +/** + * Information about the person or institution that packaged tpmtool + * for the current distribution. + */ +#ifndef WITH_PACKAGER +# define tpmtool_packager_info NULL +#else +static char const tpmtool_packager_info[] = + "Packaged by " WITH_PACKAGER + +# ifdef WITH_PACKAGER_VERSION + " ("WITH_PACKAGER_VERSION")" +# endif + +# ifdef WITH_PACKAGER_BUG_REPORTS + "\nReport tpmtool bugs to " WITH_PACKAGER_BUG_REPORTS +# endif + "\n"; +#endif +#ifndef __doxygen__ + +#endif /* __doxygen__ */ +/** + * The option definitions for tpmtool. The one structure that + * binds them all. + */ +tOptions tpmtoolOptions = { + OPTIONS_STRUCT_VERSION, + 0, NULL, /* original argc + argv */ + ( OPTPROC_BASE + + OPTPROC_ERRSTOP + + OPTPROC_SHORTOPT + + OPTPROC_LONGOPT + + OPTPROC_NO_REQ_OPT + + OPTPROC_NO_ARGS + + OPTPROC_GNUUSAGE + + OPTPROC_MISUSE ), + 0, NULL, /* current option index, current option */ + NULL, NULL, zPROGNAME, + zRcName, zCopyright, zLicenseDescrip, + zFullVersion, apzHomeList, zUsageTitle, + zExplain, zDetail, optDesc, + zBugsAddr, /* address to send bugs to */ + NULL, NULL, /* extensions/saved state */ + optionUsage, /* usage procedure */ + translate_option_strings, /* translation procedure */ + /* + * Indexes to special options + */ + { INDEX_OPT_MORE_HELP, /* more-help option index */ + NO_EQUIVALENT, /* save option index */ + NO_EQUIVALENT, /* '-#' option index */ + NO_EQUIVALENT /* index of default opt */ + }, + 7 /* full option count */, 4 /* user option count */, + tpmtool_full_usage, tpmtool_short_usage, + NULL, NULL, + PKGDATADIR, tpmtool_packager_info +}; + +#if ENABLE_NLS +#include +#include +#include +#include +#include + +static char* AO_gettext(char const* pz); +static void coerce_it(void** s); + +/** + * AutoGen specific wrapper function for gettext. + * It relies on the macro _() to convert from English to the target + * language, then strdup-duplicates the result string. + * + * @param[in] pz the input text used as a lookup key. + * @returns the translated text (if there is one), + * or the original text (if not). + */ +static char * +AO_gettext(char const* pz) +{ + char* pzRes; + if (pz == NULL) + return NULL; + pzRes = _(pz); + if (pzRes == pz) + return pzRes; + pzRes = strdup(pzRes); + if (pzRes == NULL) { + fputs(_("No memory for duping translated strings\n"), stderr); + exit(TPMTOOL_EXIT_FAILURE); + } + return pzRes; +} + +static void coerce_it(void** s) { *s = AO_gettext(*s); +} + +/** + * Translate all the translatable strings in the tpmtoolOptions + * structure defined above. This is done only once. + */ +static void +translate_option_strings(void) +{ + tOptions * const pOpt = &tpmtoolOptions; + + /* + * Guard against re-translation. It won't work. The strings will have + * been changed by the first pass through this code. One shot only. + */ + if (option_usage_text.field_ct != 0) { + /* + * Do the translations. The first pointer follows the field count + * field. The field count field is the size of a pointer. + */ + tOptDesc * pOD = pOpt->pOptDesc; + char ** ppz = (char**)(void*)&(option_usage_text); + int ix = option_usage_text.field_ct; + + do { + ppz++; + *ppz = AO_gettext(*ppz); + } while (--ix > 0); + + coerce_it((void*)&(pOpt->pzCopyright)); + coerce_it((void*)&(pOpt->pzCopyNotice)); + coerce_it((void*)&(pOpt->pzFullVersion)); + coerce_it((void*)&(pOpt->pzUsageTitle)); + coerce_it((void*)&(pOpt->pzExplain)); + coerce_it((void*)&(pOpt->pzDetail)); + coerce_it((void*)&(pOpt->pzPackager)); + coerce_it((void*)&(pOpt->pzShortUsage)); + option_usage_text.field_ct = 0; + + for (ix = pOpt->optCt; ix > 0; ix--, pOD++) + coerce_it((void*)&(pOD->pzText)); + } + + if ((pOpt->fOptSet & OPTPROC_NXLAT_OPT_CFG) == 0) { + tOptDesc * pOD = pOpt->pOptDesc; + int ix; + + for (ix = pOpt->optCt; ix > 0; ix--, pOD++) { + coerce_it((void*)&(pOD->pz_Name)); + coerce_it((void*)&(pOD->pz_DisableName)); + coerce_it((void*)&(pOD->pz_DisablePfx)); + } + /* prevent re-translation */ + tpmtoolOptions.fOptSet |= OPTPROC_NXLAT_OPT_CFG | OPTPROC_NXLAT_OPT; + } +} + +#endif /* ENABLE_NLS */ + +#ifdef __cplusplus +} +#endif +/* tpmtool-args.c ends here */ diff --git a/src/tpmtool-args.def b/src/tpmtool-args.def new file mode 100644 index 0000000000..a14fa643e4 --- /dev/null +++ b/src/tpmtool-args.def @@ -0,0 +1,43 @@ +AutoGen Definitions options; +prog-name = tpmtool; +prog-title = "GnuTLS TPM tool"; +prog-desc = "Program to handle TPM as a cryptographic device.\n"; +detail = "Program that allows handling cryptographic data from the TPM chip."; +short-usage = "tpmtool [options] [url]\ntpmtool --help for usage instructions.\n"; +explain = ""; + +#define OUTFILE_OPT 1 +#include args-std.def + +flag = { + name = generate-rsa; + descrip = "Generate an RSA private-public key pair"; + doc = "Generates an RSA private-public key pair on the specified token."; +}; + +flag = { + name = bits; + arg-type = number; + descrip = "Specify the number of bits for key generate"; + doc = ""; +}; + +doc-section = { + ds-type = 'SEE ALSO'; + ds-format = 'texi'; + ds-text = <<-_EOT_ + p11tool (1), certtool (1) +_EOT_; +}; + +doc-section = { + ds-type = 'EXAMPLES'; + ds-format = 'texi'; + ds-text = <<-_EOT_ +To generate a public key use: +@example +$ tpmtool --generate-rsa --bits 1024 +@end example +_EOT_; +}; + diff --git a/src/tpmtool-args.h b/src/tpmtool-args.h new file mode 100644 index 0000000000..ea6625c948 --- /dev/null +++ b/src/tpmtool-args.h @@ -0,0 +1,191 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (tpmtool-args.h) + * + * It has been AutoGen-ed July 6, 2012 at 09:41:37 PM by AutoGen 5.16 + * From the definitions tpmtool-args.def + * and the template file options + * + * Generated from AutoOpts 36:4:11 templates. + * + * AutoOpts is a copyrighted work. This header file is not encumbered + * by AutoOpts licensing, but is provided under the licensing terms chosen + * by the tpmtool author or copyright holder. AutoOpts is + * licensed under the terms of the LGPL. The redistributable library + * (``libopts'') is licensed under the terms of either the LGPL or, at the + * users discretion, the BSD license. See the AutoOpts and/or libopts sources + * for details. + * + * The tpmtool program is copyrighted and licensed + * under the following terms: + * + * Copyright (C) 2000-2012 Free Software Foundation, all rights reserved. + * This is free software. It is licensed for use, modification and + * redistribution under the terms of the + * GNU General Public License, version 3 or later + * + * + * tpmtool 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. + * + * tpmtool 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 . + */ +/* + * This file contains the programmatic interface to the Automated + * Options generated for the tpmtool program. + * These macros are documented in the AutoGen info file in the + * "AutoOpts" chapter. Please refer to that doc for usage help. + */ +#ifndef AUTOOPTS_TPMTOOL_ARGS_H_GUARD +#define AUTOOPTS_TPMTOOL_ARGS_H_GUARD 1 +#include "config.h" +#include + +/* + * Ensure that the library used for compiling this generated header is at + * least as new as the version current when the header template was released + * (not counting patch version increments). Also ensure that the oldest + * tolerable version is at least as old as what was current when the header + * template was released. + */ +#define AO_TEMPLATE_VERSION 147460 +#if (AO_TEMPLATE_VERSION < OPTIONS_MINIMUM_VERSION) \ + || (AO_TEMPLATE_VERSION > OPTIONS_STRUCT_VERSION) +# error option template version mismatches autoopts/options.h header + Choke Me. +#endif + +/* + * Enumeration of each option: + */ +typedef enum { + INDEX_OPT_DEBUG = 0, + INDEX_OPT_OUTFILE = 1, + INDEX_OPT_GENERATE_RSA = 2, + INDEX_OPT_BITS = 3, + INDEX_OPT_VERSION = 4, + INDEX_OPT_HELP = 5, + INDEX_OPT_MORE_HELP = 6 +} teOptIndex; + +#define OPTION_CT 7 +#define TPMTOOL_VERSION "@VERSION@" +#define TPMTOOL_FULL_VERSION "tpmtool @VERSION@" + +/* + * Interface defines for all options. Replace "n" with the UPPER_CASED + * option name (as in the teOptIndex enumeration above). + * e.g. HAVE_OPT(DEBUG) + */ +#define DESC(n) (tpmtoolOptions.pOptDesc[INDEX_OPT_## n]) +#define HAVE_OPT(n) (! UNUSED_OPT(& DESC(n))) +#define OPT_ARG(n) (DESC(n).optArg.argString) +#define STATE_OPT(n) (DESC(n).fOptState & OPTST_SET_MASK) +#define COUNT_OPT(n) (DESC(n).optOccCt) +#define ISSEL_OPT(n) (SELECTED_OPT(&DESC(n))) +#define ISUNUSED_OPT(n) (UNUSED_OPT(& DESC(n))) +#define ENABLED_OPT(n) (! DISABLED_OPT(& DESC(n))) +#define STACKCT_OPT(n) (((tArgList*)(DESC(n).optCookie))->useCt) +#define STACKLST_OPT(n) (((tArgList*)(DESC(n).optCookie))->apzArgs) +#define CLEAR_OPT(n) STMTS( \ + DESC(n).fOptState &= OPTST_PERSISTENT_MASK; \ + if ((DESC(n).fOptState & OPTST_INITENABLED) == 0) \ + DESC(n).fOptState |= OPTST_DISABLED; \ + DESC(n).optCookie = NULL ) + +/* * * * * * + * + * Enumeration of tpmtool exit codes + */ +typedef enum { + TPMTOOL_EXIT_SUCCESS = 0, + TPMTOOL_EXIT_FAILURE = 1, + TPMTOOL_EXIT_LIBOPTS_FAILURE = 70 +} tpmtool_exit_code_t; +/* * * * * * + * + * Interface defines for specific options. + */ +#define VALUE_OPT_DEBUG 'd' + +#define OPT_VALUE_DEBUG (DESC(DEBUG).optArg.argInt) +#define VALUE_OPT_OUTFILE 1 +#define VALUE_OPT_GENERATE_RSA 2 +#define VALUE_OPT_BITS 3 + +#define OPT_VALUE_BITS (DESC(BITS).optArg.argInt) +#define VALUE_OPT_HELP 'h' +#define VALUE_OPT_MORE_HELP '!' +#define VALUE_OPT_VERSION 'v' +/* + * Interface defines not associated with particular options + */ +#define ERRSKIP_OPTERR STMTS(tpmtoolOptions.fOptSet &= ~OPTPROC_ERRSTOP) +#define ERRSTOP_OPTERR STMTS(tpmtoolOptions.fOptSet |= OPTPROC_ERRSTOP) +#define RESTART_OPT(n) STMTS( \ + tpmtoolOptions.curOptIdx = (n); \ + tpmtoolOptions.pzCurOpt = NULL) +#define START_OPT RESTART_OPT(1) +#define USAGE(c) (*tpmtoolOptions.pUsageProc)(&tpmtoolOptions, c) +/* extracted from opthead.tlib near line 484 */ + +#ifdef __cplusplus +extern "C" { +#endif +/* + * global exported definitions + */ +#include + + +/* * * * * * + * + * Declare the tpmtool option descriptor. + */ +extern tOptions tpmtoolOptions; + +#if defined(ENABLE_NLS) +# ifndef _ +# include +static inline char* aoGetsText(char const* pz) { + if (pz == NULL) return NULL; + return (char*)gettext(pz); +} +# define _(s) aoGetsText(s) +# endif /* _() */ + +# define OPT_NO_XLAT_CFG_NAMES STMTS(tpmtoolOptions.fOptSet |= \ + OPTPROC_NXLAT_OPT_CFG;) +# define OPT_NO_XLAT_OPT_NAMES STMTS(tpmtoolOptions.fOptSet |= \ + OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG;) + +# define OPT_XLAT_CFG_NAMES STMTS(tpmtoolOptions.fOptSet &= \ + ~(OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG);) +# define OPT_XLAT_OPT_NAMES STMTS(tpmtoolOptions.fOptSet &= \ + ~OPTPROC_NXLAT_OPT;) + +#else /* ENABLE_NLS */ +# define OPT_NO_XLAT_CFG_NAMES +# define OPT_NO_XLAT_OPT_NAMES + +# define OPT_XLAT_CFG_NAMES +# define OPT_XLAT_OPT_NAMES + +# ifndef _ +# define _(_s) _s +# endif +#endif /* ENABLE_NLS */ + +#ifdef __cplusplus +} +#endif +#endif /* AUTOOPTS_TPMTOOL_ARGS_H_GUARD */ +/* tpmtool-args.h ends here */ diff --git a/src/tpmtool.c b/src/tpmtool.c new file mode 100644 index 0000000000..bc26e2cf87 --- /dev/null +++ b/src/tpmtool.c @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2010-2012 Free Software Foundation, Inc. + * + * 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 + * . + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Gnulib portability files. */ +#include +#include +#include + +#include "certtool-common.h" +#include "tpmtool-args.h" + +static void cmd_parser (int argc, char **argv); +static void tpm_generate(FILE* outfile, unsigned int key_type, unsigned int bits); + +static FILE *outfile; +int batch = 0; + +static void +tls_log_func (int level, const char *str) +{ + fprintf (stderr, "|<%d>| %s", level, str); +} + + +int +main (int argc, char **argv) +{ + set_program_name (argv[0]); + cmd_parser (argc, argv); + + return 0; +} + +static void +cmd_parser (int argc, char **argv) +{ + int ret, debug = 0; + unsigned int optct; + unsigned int key_type = GNUTLS_PK_UNKNOWN; + unsigned int bits = 0; + + optct = optionProcess( &tpmtoolOptions, argc, argv); + argc += optct; + argv += optct; + + 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) + error (EXIT_FAILURE, 0, "global_init: %s", gnutls_strerror (ret)); + + if (HAVE_OPT(OUTFILE)) + { + outfile = safe_open_rw (OPT_ARG(OUTFILE), 0); + if (outfile == NULL) + error (EXIT_FAILURE, errno, "%s", OPT_ARG(OUTFILE)); + } + else + outfile = stdout; + + if (HAVE_OPT(BITS)) + bits = OPT_VALUE_BITS; + else + bits = 2048; + + if (HAVE_OPT(GENERATE_RSA)) + { + key_type = GNUTLS_PK_RSA; + tpm_generate (outfile, key_type, bits); + } + else + { + USAGE(1); + } + + fclose (outfile); + + gnutls_global_deinit (); +} + +static void tpm_generate(FILE* outfile, unsigned int key_type, unsigned int bits) +{ + int ret; + char* srk_pass, *key_pass; + gnutls_datum_t privkey, pubkey; + + srk_pass = getpass ("Enter SRK password: "); + if (srk_pass != NULL) + srk_pass = strdup(srk_pass); + + key_pass = getpass ("Enter key password: "); + if (key_pass != NULL) + key_pass = strdup(srk_pass); + + ret = gnutls_tpm_privkey_generate(key_type, bits, srk_pass, key_pass, + GNUTLS_X509_FMT_PEM, &privkey, &pubkey, + GNUTLS_TPM_SIG_PKCS1V15); + + free(key_pass); + free(srk_pass); + + if (ret < 0) + error (EXIT_FAILURE, 0, "gnutls_tpm_privkey_generate: %s", gnutls_strerror (ret)); + + fwrite (pubkey.data, 1, pubkey.size, outfile); + fputs ("\n", outfile); + fwrite (privkey.data, 1, privkey.size, outfile); +}