From: Nikos Mavrogiannopoulos Date: Sun, 8 Jul 2012 12:08:38 +0000 (+0200) Subject: Added functionality to extract the pubkey key from a TPM key. X-Git-Tag: gnutls_3_1_0pre0~84 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=60a19bacc312dc7190c65ef449505abbb09a947a;p=thirdparty%2Fgnutls.git Added functionality to extract the pubkey key from a TPM key. Added new function gnutls_pubkey_import_tpm_raw(). tpmtool can now print the pubkey key from a TPM key. --- diff --git a/NEWS b/NEWS index 04e8a72765..ba0f658869 100644 --- a/NEWS +++ b/NEWS @@ -47,6 +47,7 @@ by Alexandre Bique. ** API and ABI modifications: GNUTLS_CERT_SIGNATURE_FAILURE: Added GNUTLS_CAMELLIA_192_CBC: Added +gnutls_pubkey_import_tpm_raw: Added gnutls_privkey_import_tpm_raw: Added gnutls_privkey_import_pkcs11_url: Added gnutls_privkey_import_openpgp_raw: Added diff --git a/doc/Makefile.am b/doc/Makefile.am index ce3e25be98..59b2a0dd57 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -483,6 +483,7 @@ FUNCS += functions/gnutls_pubkey_import_x509 FUNCS += functions/gnutls_pubkey_import_pkcs11 FUNCS += functions/gnutls_pubkey_import_openpgp FUNCS += functions/gnutls_pubkey_import_privkey +FUNCS += functions/gnutls_pubkey_import_tpm_raw FUNCS += functions/gnutls_pubkey_get_preferred_hash_algorithm FUNCS += functions/gnutls_pubkey_get_pk_rsa_raw FUNCS += functions/gnutls_pubkey_get_pk_dsa_raw @@ -995,6 +996,7 @@ FUNCS += functions/gnutls_pkcs12_bag_get_key_id FUNCS += functions/gnutls_pkcs12_bag_set_key_id FUNCS += functions/gnutls_pkcs12_bag_get_friendly_name FUNCS += functions/gnutls_pkcs12_bag_set_friendly_name +FUNCS += functions/gnutls_tpm_privkey_generate FUNCS += functions/gnutls_x509_crt_init FUNCS += functions/gnutls_x509_crt_deinit FUNCS += functions/gnutls_x509_crt_import diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h index 69dde115a9..623c7740d3 100644 --- a/lib/includes/gnutls/abstract.h +++ b/lib/includes/gnutls/abstract.h @@ -68,6 +68,11 @@ int gnutls_pubkey_import_privkey (gnutls_pubkey_t key, gnutls_privkey_t pkey, unsigned int usage, unsigned int flags); +int +gnutls_pubkey_import_tpm_raw (gnutls_pubkey_t pkey, + const gnutls_datum_t * fdata, + gnutls_x509_crt_fmt_t format, + const char *srk_password); int gnutls_pubkey_get_preferred_hash_algorithm (gnutls_pubkey_t key, gnutls_digest_algorithm_t * diff --git a/lib/libgnutls.map b/lib/libgnutls.map index 54034150dd..d7579aac35 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -808,6 +808,7 @@ GNUTLS_3_1_0 { gnutls_privkey_import_ext2; gnutls_privkey_import_tpm_raw; gnutls_tpm_privkey_generate; + gnutls_pubkey_import_tpm_raw; } GNUTLS_3_0_0; GNUTLS_PRIVATE { diff --git a/lib/tpm.c b/lib/tpm.c index 6054bfab71..c6f37a807b 100644 --- a/lib/tpm.c +++ b/lib/tpm.c @@ -111,6 +111,7 @@ tpm_sign_fn (gnutls_privkey_t key, void *_s, } static const unsigned char nullpass[20]; +const TSS_UUID srk_uuid = TSS_UUID_SRK; /** * gnutls_privkey_import_tpm_raw: @@ -140,7 +141,6 @@ gnutls_privkey_import_tpm_raw (gnutls_privkey_t pkey, const char *srk_password, const char *key_password) { - static const TSS_UUID SRK_UUID = TSS_UUID_SRK; gnutls_datum_t asn1; size_t slen; int err, ret; @@ -193,7 +193,7 @@ gnutls_privkey_import_tpm_raw (gnutls_privkey_t pkey, } err = Tspi_Context_LoadKeyByUUID (s->tpm_context, TSS_PS_TYPE_SYSTEM, - SRK_UUID, &s->srk); + srk_uuid, &s->srk); if (err) { gnutls_assert (); @@ -339,7 +339,213 @@ out_blob: return ret; } -const TSS_UUID srk_uuid = TSS_UUID_SRK; +/* reads the RSA public key from the given TSS key. + * If psize is non-null it contains the total size of the parameters + * in bytes */ +static int read_pubkey(gnutls_pubkey_t pub, TSS_HKEY key_ctx, size_t *psize) +{ +void* tdata; +UINT32 tint; +TSS_RESULT tssret; +gnutls_datum_t m, e; +int ret; + + /* read the public key */ + + tssret = Tspi_GetAttribData(key_ctx, TSS_TSPATTRIB_RSAKEY_INFO, + TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &tint, (void*)&tdata); + if (tssret != 0) + { + gnutls_assert(); + return GNUTLS_E_TPM_ERROR; + } + + 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); + return GNUTLS_E_TPM_ERROR; + } + + e.data = tdata; + e.size = tint; + + ret = gnutls_pubkey_import_rsa_raw(pub, &m, &e); + + Tspi_Context_FreeMemory(key_ctx, m.data); + Tspi_Context_FreeMemory(key_ctx, e.data); + + if (ret < 0) + return gnutls_assert_val(ret); + + if (psize) + *psize = e.size + m.size; + + return 0; +} + + +/** + * gnutls_pubkey_import_tpm_raw: + * @pkey: The public key + * @fdata: The TPM key to be imported + * @format: The format of the private key + * @srk_password: The password for the SRK key (optional) + * @key_password: A password for the key (optional) + * + * This function will import the public key from the provided + * TPM key 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_KEY_PASSWORD_ERROR + * is returned. + * + * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a + * negative error value. + * + * Since: 3.1.0 + * + **/ +int +gnutls_pubkey_import_tpm_raw (gnutls_pubkey_t pkey, + const gnutls_datum_t * fdata, + gnutls_x509_crt_fmt_t format, + const char *srk_password) +{ +gnutls_datum_t asn1; +size_t slen; +int err, ret; +struct tpm_ctx_st s; + + ret = gnutls_pem_base64_decode_alloc ("TSS KEY BLOB", fdata, &asn1); + if (ret) + { + gnutls_assert (); + _gnutls_debug_log ("Error decoding TSS key blob: %s\n", + gnutls_strerror (ret)); + return ret; + } + + slen = asn1.size; + ret = _gnutls_x509_decode_octet_string(NULL, asn1.data, asn1.size, asn1.data, &slen); + if (ret < 0) + { + gnutls_assert(); + goto out_blob; + } + asn1.size = slen; + + err = Tspi_Context_Create (&s.tpm_context); + if (err) + { + gnutls_assert (); + _gnutls_debug_log ("Failed to create TPM context: %s\n", + Trspi_Error_String (err)); + ret = GNUTLS_E_TPM_ERROR; + goto out_blob; + } + err = Tspi_Context_Connect (s.tpm_context, NULL); + if (err) + { + gnutls_assert (); + _gnutls_debug_log ("Failed to connect TPM context: %s\n", + Trspi_Error_String (err)); + ret = GNUTLS_E_TPM_ERROR; + goto out_tspi_ctx; + } + err = + Tspi_Context_LoadKeyByUUID (s.tpm_context, TSS_PS_TYPE_SYSTEM, + srk_uuid, &s.srk); + if (err) + { + gnutls_assert (); + _gnutls_debug_log + ("Failed to load TPM SRK key: %s\n", Trspi_Error_String (err)); + ret = GNUTLS_E_TPM_ERROR; + goto out_tspi_ctx; + } + err = Tspi_GetPolicyObject (s.srk, TSS_POLICY_USAGE, &s.srk_policy); + if (err) + { + gnutls_assert (); + _gnutls_debug_log ("Failed to load TPM SRK policy object: %s\n", + Trspi_Error_String (err)); + ret = GNUTLS_E_TPM_ERROR; + goto out_srk; + } + + /* We don't seem to get the error here... */ + if (srk_password) + err = Tspi_Policy_SetSecret (s.srk_policy, + TSS_SECRET_MODE_PLAIN, + strlen (srk_password), (BYTE *) srk_password); + else /* Well-known NULL key */ + err = Tspi_Policy_SetSecret (s.srk_policy, + TSS_SECRET_MODE_SHA1, + sizeof (nullpass), (BYTE *) nullpass); + if (err) + { + gnutls_assert (); + _gnutls_debug_log ("Failed to set TPM PIN: %s\n", + Trspi_Error_String (err)); + ret = GNUTLS_E_TPM_ERROR; + goto out_srkpol; + } + + /* ... we get it here instead. */ + err = Tspi_Context_LoadKeyByBlob (s.tpm_context, s.srk, + asn1.size, asn1.data, &s.tpm_key); + if (err != 0) + { + if (srk_password) + { + gnutls_assert (); + _gnutls_debug_log + ("Failed to load TPM key blob: %s\n", + Trspi_Error_String (err)); + } + + if (err != TPM_E_AUTHFAIL) + { + gnutls_assert (); + ret = GNUTLS_E_TPM_ERROR; + goto out_srkpol; + } + else + { + ret = gnutls_assert_val (GNUTLS_E_TPM_SRK_PASSWORD_ERROR); + goto out_srkpol; + } + } + + ret = read_pubkey(pkey, s.tpm_key, NULL); + if (ret < 0) + { + gnutls_assert(); + goto out_srkpol; + } + + gnutls_free (asn1.data); + return 0; +out_srkpol: + Tspi_Context_CloseObject (s.tpm_context, s.srk_policy); + s.srk_policy = 0; +out_srk: + Tspi_Context_CloseObject (s.tpm_context, s.srk); + s.srk = 0; +out_tspi_ctx: + Tspi_Context_Close (s.tpm_context); + s.tpm_context = 0; +out_blob: + gnutls_free (asn1.data); + return ret; +} + /** * gnutls_tpm_privkey_generate: @@ -549,8 +755,8 @@ gnutls_pubkey_t pub; tmpkey.data = NULL; } + /* read the public key */ { - gnutls_datum_t m, e; size_t psize; ret = gnutls_pubkey_init(&pub); @@ -559,40 +765,15 @@ gnutls_pubkey_t pub; 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); + ret = read_pubkey(pub, key_ctx, &psize); if (ret < 0) { gnutls_assert(); - goto pubkey_cleanup; + goto privkey_cleanup; } + psize+=512; - psize = e.size+m.size+512; pubkey->data = gnutls_malloc(psize); if (pubkey->data == NULL) { diff --git a/src/certtool-common.c b/src/certtool-common.c index 13aee71243..e8e2f1c7f4 100644 --- a/src/certtool-common.c +++ b/src/certtool-common.c @@ -664,3 +664,247 @@ gnutls_sec_param_t str_to_sec_param (const char *str) } } + +static void +print_hex_datum (FILE* outfile, gnutls_datum_t * dat) +{ + unsigned int j; +#define SPACE "\t" + fprintf (outfile, "\n" SPACE); + for (j = 0; j < dat->size; j++) + { + fprintf (outfile, "%.2x:", (unsigned char) dat->data[j]); + if ((j + 1) % 15 == 0) + fprintf (outfile, "\n" SPACE); + } + fprintf (outfile, "\n"); +} + +void +print_dsa_pkey (FILE* outfile, gnutls_datum_t * x, gnutls_datum_t * y, gnutls_datum_t * p, + gnutls_datum_t * q, gnutls_datum_t * g) +{ + if (x) + { + fprintf (outfile, "private key:"); + print_hex_datum (outfile, x); + } + fprintf (outfile, "public key:"); + print_hex_datum (outfile, y); + fprintf (outfile, "p:"); + print_hex_datum (outfile, p); + fprintf (outfile, "q:"); + print_hex_datum (outfile, q); + fprintf (outfile, "g:"); + print_hex_datum (outfile, g); +} + +void +print_ecc_pkey (FILE* outfile, gnutls_ecc_curve_t curve, gnutls_datum_t* k, gnutls_datum_t * x, gnutls_datum_t * y) +{ + fprintf (outfile, "curve:\t%s\n", gnutls_ecc_curve_get_name(curve)); + if (k) + { + fprintf (outfile, "private key:"); + print_hex_datum (outfile, k); + } + fprintf (outfile, "x:"); + print_hex_datum (outfile, x); + fprintf (outfile, "y:"); + print_hex_datum (outfile, y); +} + +void +print_rsa_pkey (FILE* outfile, gnutls_datum_t * m, gnutls_datum_t * e, gnutls_datum_t * d, + gnutls_datum_t * p, gnutls_datum_t * q, gnutls_datum_t * u, + gnutls_datum_t * exp1, gnutls_datum_t * exp2) +{ + fprintf (outfile, "modulus:"); + print_hex_datum (outfile, m); + fprintf (outfile, "public exponent:"); + print_hex_datum (outfile, e); + if (d) + { + fprintf (outfile, "private exponent:"); + print_hex_datum (outfile, d); + fprintf (outfile, "prime1:"); + print_hex_datum (outfile, p); + fprintf (outfile, "prime2:"); + print_hex_datum (outfile, q); + fprintf (outfile, "coefficient:"); + print_hex_datum (outfile, u); + if (exp1 && exp2) + { + fprintf (outfile, "exp1:"); + print_hex_datum (outfile, exp1); + fprintf (outfile, "exp2:"); + print_hex_datum (outfile, exp2); + } + } +} + +static void +print_key_usage (FILE * outfile, unsigned int usage) +{ + if (usage & GNUTLS_KEY_DIGITAL_SIGNATURE) + { + fprintf (outfile, "\tDigital signature.\n"); + } + + if (usage & GNUTLS_KEY_NON_REPUDIATION) + { + fprintf (outfile, "\tNon repudiation.\n"); + } + + if (usage & GNUTLS_KEY_KEY_ENCIPHERMENT) + { + fprintf (outfile, "\tKey encipherment.\n"); + } + + if (usage & GNUTLS_KEY_DATA_ENCIPHERMENT) + { + fprintf (outfile, "\tData encipherment.\n"); + } + + if (usage & GNUTLS_KEY_KEY_AGREEMENT) + { + fprintf (outfile, "\tKey agreement.\n"); + } + + if (usage & GNUTLS_KEY_KEY_CERT_SIGN) + { + fprintf (outfile, "\tCertificate signing.\n"); + } + + if (usage & GNUTLS_KEY_NON_REPUDIATION) + { + fprintf (outfile, "\tCRL signing.\n"); + } + + if (usage & GNUTLS_KEY_ENCIPHER_ONLY) + { + fprintf (outfile, "\tKey encipher only.\n"); + } + + if (usage & GNUTLS_KEY_DECIPHER_ONLY) + { + fprintf (outfile, "\tKey decipher only.\n"); + } +} + +const char * +raw_to_string (const unsigned char *raw, size_t raw_size) +{ + static char buf[1024]; + size_t i; + if (raw_size == 0) + return NULL; + + if (raw_size * 3 + 1 >= sizeof (buf)) + return NULL; + + for (i = 0; i < raw_size; i++) + { + sprintf (&(buf[i * 3]), "%02X%s", raw[i], + (i == raw_size - 1) ? "" : ":"); + } + buf[sizeof (buf) - 1] = '\0'; + + return buf; +} + +void _pubkey_info(FILE* outfile, gnutls_pubkey_t pubkey) +{ +unsigned int usage; +int ret; +size_t size; +unsigned int bits; +const char *cprint; + + fprintf (outfile, "Public Key Info:\n\n"); + ret = gnutls_pubkey_get_pk_algorithm (pubkey, &bits); + fprintf (outfile, "Public Key Algorithm: "); + cprint = gnutls_pk_algorithm_get_name (ret); + fprintf (outfile, "%s (%u bits)\n", cprint ? cprint : "Unknown", bits); + + /* Print the raw public and private keys + */ + if (ret == GNUTLS_PK_RSA) + { + gnutls_datum_t m, e; + + ret = gnutls_pubkey_get_pk_rsa_raw (pubkey, &m, &e); + if (ret < 0) + fprintf (stderr, "Error in key RSA data export: %s\n", + gnutls_strerror (ret)); + else + { + print_rsa_pkey (outfile, &m, &e, NULL, NULL, NULL, NULL, NULL, NULL); + gnutls_free (m.data); + gnutls_free (e.data); + } + } + else if (ret == GNUTLS_PK_DSA) + { + gnutls_datum_t p, q, g, y; + + ret = gnutls_pubkey_get_pk_dsa_raw (pubkey, &p, &q, &g, &y); + if (ret < 0) + fprintf (stderr, "Error in key DSA data export: %s\n", + gnutls_strerror (ret)); + else + { + print_dsa_pkey (outfile, NULL, &y, &p, &q, &g); + gnutls_free (y.data); + gnutls_free (p.data); + gnutls_free (q.data); + gnutls_free (g.data); + } + } + else if (ret == GNUTLS_PK_EC) + { + gnutls_datum_t x, y; + gnutls_ecc_curve_t curve; + + ret = gnutls_pubkey_get_pk_ecc_raw (pubkey, &curve, &x, &y); + if (ret < 0) + fprintf (stderr, "Error in key ECC data export: %s\n", + gnutls_strerror (ret)); + else + { + print_ecc_pkey (outfile, curve, NULL, &y, &x); + gnutls_free (y.data); + gnutls_free (x.data); + } + } + + ret = gnutls_pubkey_get_key_usage (pubkey, &usage); + if (ret < 0) + { + error (EXIT_FAILURE, 0, "pubkey_get_key_usage: %s", + gnutls_strerror (ret)); + } + + fprintf (outfile, "Public Key Usage:\n"); + print_key_usage (outfile, usage); + + fprintf (outfile, "\n"); + + size = buffer_size; + if ((ret = gnutls_pubkey_get_key_id (pubkey, 0, buffer, &size)) < 0) + { + fprintf (stderr, "Error in key id calculation: %s\n", + gnutls_strerror (ret)); + } + else + { + fprintf (outfile, "Public Key ID: %s\n", raw_to_string (buffer, size)); + } + + size = buffer_size; + ret = gnutls_pubkey_export (pubkey, GNUTLS_X509_FMT_PEM, buffer, &size); + if (ret < 0) + error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret)); + + fprintf (outfile, "\n%s\n", buffer); +} diff --git a/src/certtool-common.h b/src/certtool-common.h index deb3853b22..7bedfb5fc8 100644 --- a/src/certtool-common.h +++ b/src/certtool-common.h @@ -74,8 +74,22 @@ void dh_info (common_info_st * ci); gnutls_x509_privkey_t * load_privkey_list (int mand, size_t * privkey_size, common_info_st * info); +void _pubkey_info(FILE* outfile, gnutls_pubkey_t pubkey); +void +print_ecc_pkey (FILE* outfile, gnutls_ecc_curve_t curve, gnutls_datum_t* k, gnutls_datum_t * x, gnutls_datum_t * y); +void +print_rsa_pkey (FILE* outfile, gnutls_datum_t * m, gnutls_datum_t * e, gnutls_datum_t * d, + gnutls_datum_t * p, gnutls_datum_t * q, gnutls_datum_t * u, + gnutls_datum_t * exp1, gnutls_datum_t * exp2); +void +print_dsa_pkey (FILE* outfile, gnutls_datum_t * x, gnutls_datum_t * y, gnutls_datum_t * p, + gnutls_datum_t * q, gnutls_datum_t * g); + FILE *safe_open_rw (const char *file, int privkey_op); +const char * +raw_to_string (const unsigned char *raw, size_t raw_size); + extern unsigned char buffer[]; extern const int buffer_size; diff --git a/src/certtool.c b/src/certtool.c index 8d3e393e69..7078d243b7 100644 --- a/src/certtool.c +++ b/src/certtool.c @@ -75,8 +75,6 @@ static void print_certificate_info (gnutls_x509_crt_t crt, FILE * out, unsigned int all); static void verify_certificate (common_info_st * cinfo); -static void print_hex_datum (gnutls_datum_t * dat); - FILE *outfile; FILE *infile; static gnutls_digest_algorithm_t default_dig; @@ -104,90 +102,6 @@ main (int argc, char **argv) return 0; } -static const char * -raw_to_string (const unsigned char *raw, size_t raw_size) -{ - static char buf[1024]; - size_t i; - if (raw_size == 0) - return NULL; - - if (raw_size * 3 + 1 >= sizeof (buf)) - return NULL; - - for (i = 0; i < raw_size; i++) - { - sprintf (&(buf[i * 3]), "%02X%s", raw[i], - (i == raw_size - 1) ? "" : ":"); - } - buf[sizeof (buf) - 1] = '\0'; - - return buf; -} - -static void -print_dsa_pkey (gnutls_datum_t * x, gnutls_datum_t * y, gnutls_datum_t * p, - gnutls_datum_t * q, gnutls_datum_t * g) -{ - if (x) - { - fprintf (outfile, "private key:"); - print_hex_datum (x); - } - fprintf (outfile, "public key:"); - print_hex_datum (y); - fprintf (outfile, "p:"); - print_hex_datum (p); - fprintf (outfile, "q:"); - print_hex_datum (q); - fprintf (outfile, "g:"); - print_hex_datum (g); -} - -static void -print_ecc_pkey (gnutls_ecc_curve_t curve, gnutls_datum_t* k, gnutls_datum_t * x, gnutls_datum_t * y) -{ - fprintf (outfile, "curve:\t%s\n", gnutls_ecc_curve_get_name(curve)); - if (k) - { - fprintf (outfile, "private key:"); - print_hex_datum (k); - } - fprintf (outfile, "x:"); - print_hex_datum (x); - fprintf (outfile, "y:"); - print_hex_datum (y); -} - -static void -print_rsa_pkey (gnutls_datum_t * m, gnutls_datum_t * e, gnutls_datum_t * d, - gnutls_datum_t * p, gnutls_datum_t * q, gnutls_datum_t * u, - gnutls_datum_t * exp1, gnutls_datum_t * exp2) -{ - fprintf (outfile, "modulus:"); - print_hex_datum (m); - fprintf (outfile, "public exponent:"); - print_hex_datum (e); - if (d) - { - fprintf (outfile, "private exponent:"); - print_hex_datum (d); - fprintf (outfile, "prime1:"); - print_hex_datum (p); - fprintf (outfile, "prime2:"); - print_hex_datum (q); - fprintf (outfile, "coefficient:"); - print_hex_datum (u); - if (exp1 && exp2) - { - fprintf (outfile, "exp1:"); - print_hex_datum (exp1); - fprintf (outfile, "exp2:"); - print_hex_datum (exp2); - } - } -} - static gnutls_x509_privkey_t generate_private_key_int (common_info_st * cinfo) { @@ -1354,7 +1268,7 @@ pgp_privkey_info (void) fprintf (stderr, "Error in key RSA data export: %s\n", gnutls_strerror (ret)); else - print_rsa_pkey (&m, &e, &d, &p, &q, &u, NULL, NULL); + print_rsa_pkey (outfile, &m, &e, &d, &p, &q, &u, NULL, NULL); bits = m.size * 8; } @@ -1373,7 +1287,7 @@ pgp_privkey_info (void) fprintf (stderr, "Error in key DSA data export: %s\n", gnutls_strerror (ret)); else - print_dsa_pkey (&x, &y, &p, &q, &g); + print_dsa_pkey (outfile, &x, &y, &p, &q, &g); bits = y.size * 8; } @@ -1489,20 +1403,6 @@ pgp_ring_info (void) #endif -static void -print_hex_datum (gnutls_datum_t * dat) -{ - unsigned int j; -#define SPACE "\t" - fprintf (outfile, "\n" SPACE); - for (j = 0; j < dat->size; j++) - { - fprintf (outfile, "%.2x:", (unsigned char) dat->data[j]); - if ((j + 1) % 15 == 0) - fprintf (outfile, "\n" SPACE); - } - fprintf (outfile, "\n"); -} static void @@ -1680,7 +1580,7 @@ const char *cprint; gnutls_strerror (ret)); else { - print_rsa_pkey (&m, &e, &d, &p, &q, &u, &exp1, &exp2); + print_rsa_pkey (outfile, &m, &e, &d, &p, &q, &u, &exp1, &exp2); bits = m.size * 8; gnutls_free (m.data); @@ -1703,7 +1603,7 @@ const char *cprint; gnutls_strerror (ret)); else { - print_dsa_pkey (&x, &y, &p, &q, &g); + print_dsa_pkey (outfile, &x, &y, &p, &q, &g); bits = y.size * 8; gnutls_free (x.data); @@ -1724,7 +1624,7 @@ const char *cprint; gnutls_strerror (ret)); else { - print_ecc_pkey (curve, &k, &x, &y); + print_ecc_pkey (outfile, curve, &k, &x, &y); bits = gnutls_ecc_curve_get_size(curve) * 8; gnutls_free (x.data); @@ -2848,63 +2748,13 @@ smime_to_pkcs7 (void) free (lineptr); } -static void -print_key_usage (FILE * outfile, unsigned int usage) -{ - if (usage & GNUTLS_KEY_DIGITAL_SIGNATURE) - { - fprintf (outfile, "\tDigital signature.\n"); - } - - if (usage & GNUTLS_KEY_NON_REPUDIATION) - { - fprintf (outfile, "\tNon repudiation.\n"); - } - - if (usage & GNUTLS_KEY_KEY_ENCIPHERMENT) - { - fprintf (outfile, "\tKey encipherment.\n"); - } - - if (usage & GNUTLS_KEY_DATA_ENCIPHERMENT) - { - fprintf (outfile, "\tData encipherment.\n"); - } - - if (usage & GNUTLS_KEY_KEY_AGREEMENT) - { - fprintf (outfile, "\tKey agreement.\n"); - } - - if (usage & GNUTLS_KEY_KEY_CERT_SIGN) - { - fprintf (outfile, "\tCertificate signing.\n"); - } - - if (usage & GNUTLS_KEY_NON_REPUDIATION) - { - fprintf (outfile, "\tCRL signing.\n"); - } - - if (usage & GNUTLS_KEY_ENCIPHER_ONLY) - { - fprintf (outfile, "\tKey encipher only.\n"); - } - - if (usage & GNUTLS_KEY_DECIPHER_ONLY) - { - fprintf (outfile, "\tKey decipher only.\n"); - } -} void pubkey_info (gnutls_x509_crt_t crt, common_info_st * cinfo) { gnutls_pubkey_t pubkey; - unsigned int bits, usage; int ret; size_t size; - const char *cprint; ret = gnutls_pubkey_init (&pubkey); if (ret < 0) @@ -2947,94 +2797,6 @@ pubkey_info (gnutls_x509_crt_t crt, common_info_st * cinfo) /* PEM */ - fprintf (outfile, "Public Key Info:\n\n"); - ret = gnutls_pubkey_get_pk_algorithm (pubkey, &bits); - fprintf (outfile, "Public Key Algorithm: "); - - cprint = gnutls_pk_algorithm_get_name (ret); - fprintf (outfile, "%s (%u bits)\n", cprint ? cprint : "Unknown", bits); - - - /* Print the raw public and private keys - */ - if (ret == GNUTLS_PK_RSA) - { - gnutls_datum_t m, e; - - ret = gnutls_pubkey_get_pk_rsa_raw (pubkey, &m, &e); - if (ret < 0) - fprintf (stderr, "Error in key RSA data export: %s\n", - gnutls_strerror (ret)); - else - { - print_rsa_pkey (&m, &e, NULL, NULL, NULL, NULL, NULL, NULL); - gnutls_free (m.data); - gnutls_free (e.data); - } - } - else if (ret == GNUTLS_PK_DSA) - { - gnutls_datum_t p, q, g, y; - - ret = gnutls_pubkey_get_pk_dsa_raw (pubkey, &p, &q, &g, &y); - if (ret < 0) - fprintf (stderr, "Error in key DSA data export: %s\n", - gnutls_strerror (ret)); - else - { - print_dsa_pkey (NULL, &y, &p, &q, &g); - gnutls_free (y.data); - gnutls_free (p.data); - gnutls_free (q.data); - gnutls_free (g.data); - } - } - else if (ret == GNUTLS_PK_EC) - { - gnutls_datum_t x, y; - gnutls_ecc_curve_t curve; - - ret = gnutls_pubkey_get_pk_ecc_raw (pubkey, &curve, &x, &y); - if (ret < 0) - fprintf (stderr, "Error in key ECC data export: %s\n", - gnutls_strerror (ret)); - else - { - print_ecc_pkey (curve, NULL, &y, &x); - gnutls_free (y.data); - gnutls_free (x.data); - } - } - - ret = gnutls_pubkey_get_key_usage (pubkey, &usage); - if (ret < 0) - { - error (EXIT_FAILURE, 0, "pubkey_get_key_usage: %s", - gnutls_strerror (ret)); - } - - fprintf (outfile, "Public Key Usage:\n"); - print_key_usage (outfile, usage); - - fprintf (outfile, "\n"); - - size = buffer_size; - if ((ret = gnutls_pubkey_get_key_id (pubkey, 0, buffer, &size)) < 0) - { - fprintf (stderr, "Error in key id calculation: %s\n", - gnutls_strerror (ret)); - } - else - { - fprintf (outfile, "Public Key ID: %s\n", raw_to_string (buffer, size)); - } - - size = buffer_size; - ret = gnutls_pubkey_export (pubkey, GNUTLS_X509_FMT_PEM, buffer, &size); - if (ret < 0) - error (EXIT_FAILURE, 0, "export error: %s", gnutls_strerror (ret)); - - fprintf (outfile, "\n%s\n", buffer); - + _pubkey_info(outfile, pubkey); gnutls_pubkey_deinit (pubkey); } diff --git a/src/tpmtool-args.c b/src/tpmtool-args.c index f4dcd20536..12021794b2 100644 --- a/src/tpmtool-args.c +++ b/src/tpmtool-args.c @@ -2,7 +2,7 @@ * * DO NOT EDIT THIS FILE (tpmtool-args.c) * - * It has been AutoGen-ed July 6, 2012 at 10:34:04 PM by AutoGen 5.16 + * It has been AutoGen-ed July 8, 2012 at 01:42:38 PM by AutoGen 5.16 * From the definitions tpmtool-args.def * and the template file options * @@ -67,7 +67,7 @@ extern FILE * option_usage_fp; /* * tpmtool option static const strings */ -static char const tpmtool_opt_strs[1483] = +static char const tpmtool_opt_strs[1564] = /* 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" @@ -87,30 +87,36 @@ static char const tpmtool_opt_strs[1483] = /* 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" +/* 911 */ "Input file\0" +/* 922 */ "INFILE\0" +/* 929 */ "infile\0" +/* 936 */ "Output file\0" +/* 948 */ "OUTFILE\0" +/* 956 */ "outfile\0" +/* 964 */ "Generate an RSA private-public key pair\0" +/* 1004 */ "GENERATE_RSA\0" +/* 1017 */ "generate-rsa\0" +/* 1030 */ "Prints the public key of the provided key\0" +/* 1072 */ "PUBKEY\0" +/* 1079 */ "pubkey\0" +/* 1086 */ "Specify the number of bits for key generate\0" +/* 1130 */ "BITS\0" +/* 1135 */ "bits\0" +/* 1140 */ "Display extended usage information and exit\0" +/* 1184 */ "help\0" +/* 1189 */ "Extended usage information passed thru pager\0" +/* 1234 */ "more-help\0" +/* 1244 */ "Output version information and exit\0" +/* 1280 */ "version\0" +/* 1288 */ "TPMTOOL\0" +/* 1296 */ "tpmtool - GnuTLS TPM tool - Ver. @VERSION@\n" "USAGE: %s [ - [] | --[{=| }] ]...\n\0" -/* 1316 */ "bug-gnutls@gnu.org\0" -/* 1335 */ "\n\n\0" -/* 1338 */ "\n" +/* 1397 */ "bug-gnutls@gnu.org\0" +/* 1416 */ "\n\n\0" +/* 1419 */ "\n" "Program that allows handling cryptographic data from the TPM chip.\n\0" -/* 1407 */ "tpmtool @VERSION@\0" -/* 1425 */ "tpmtool [options]\n" +/* 1488 */ "tpmtool @VERSION@\0" +/* 1506 */ "tpmtool [options]\n" "tpmtool --help for usage instructions.\n"; /* @@ -122,40 +128,57 @@ static char const tpmtool_opt_strs[1483] = #define DEBUG_FLAGS (OPTST_DISABLED \ | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) +/* + * infile option description: + */ +#define INFILE_DESC (tpmtool_opt_strs+911) +#define INFILE_NAME (tpmtool_opt_strs+922) +#define INFILE_name (tpmtool_opt_strs+929) +#define INFILE_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_FILE)) + /* * 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_DESC (tpmtool_opt_strs+936) +#define OUTFILE_NAME (tpmtool_opt_strs+948) +#define OUTFILE_name (tpmtool_opt_strs+956) #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_DESC (tpmtool_opt_strs+964) +#define GENERATE_RSA_NAME (tpmtool_opt_strs+1004) +#define GENERATE_RSA_name (tpmtool_opt_strs+1017) #define GENERATE_RSA_FLAGS (OPTST_DISABLED) +/* + * pubkey option description: + */ +#define PUBKEY_DESC (tpmtool_opt_strs+1030) +#define PUBKEY_NAME (tpmtool_opt_strs+1072) +#define PUBKEY_name (tpmtool_opt_strs+1079) +#define PUBKEY_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_DESC (tpmtool_opt_strs+1086) +#define BITS_NAME (tpmtool_opt_strs+1130) +#define BITS_name (tpmtool_opt_strs+1135) #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) +#define HELP_DESC (tpmtool_opt_strs+1140) +#define HELP_name (tpmtool_opt_strs+1184) #ifdef HAVE_WORKING_FORK -#define MORE_HELP_DESC (tpmtool_opt_strs+1108) -#define MORE_HELP_name (tpmtool_opt_strs+1153) +#define MORE_HELP_DESC (tpmtool_opt_strs+1189) +#define MORE_HELP_name (tpmtool_opt_strs+1234) #define MORE_HELP_FLAGS (OPTST_IMM | OPTST_NO_INIT) #else #define MORE_HELP_DESC NULL @@ -168,8 +191,8 @@ static char const tpmtool_opt_strs[1483] = # 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) +#define VER_DESC (tpmtool_opt_strs+1244) +#define VER_name (tpmtool_opt_strs+1280) /* * Declare option callback procedures */ @@ -179,7 +202,7 @@ extern tOptProc optionStackArg, optionTimeDate, optionTimeVal, optionUnstackArg, optionVendorOption; static tOptProc - doOptDebug, doUsageOpt; + doOptDebug, doOptInfile, doUsageOpt; #define VER_PROC optionPrintVersion /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -201,8 +224,20 @@ static tOptDesc optDesc[OPTION_CT] = { /* 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, + { /* entry idx, value */ 1, VALUE_OPT_INFILE, + /* equiv idx, value */ 1, VALUE_OPT_INFILE, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ INFILE_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --infile */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptInfile, + /* desc, NAME, name */ INFILE_DESC, INFILE_NAME, INFILE_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 2, VALUE_OPT_OUTFILE, + /* equiv idx, value */ 2, VALUE_OPT_OUTFILE, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, /* opt state flags */ OUTFILE_FLAGS, 0, @@ -213,8 +248,8 @@ static tOptDesc optDesc[OPTION_CT] = { /* 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, + { /* entry idx, value */ 3, VALUE_OPT_GENERATE_RSA, + /* equiv idx, value */ 3, VALUE_OPT_GENERATE_RSA, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, /* opt state flags */ GENERATE_RSA_FLAGS, 0, @@ -225,8 +260,20 @@ static tOptDesc optDesc[OPTION_CT] = { /* 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, + { /* entry idx, value */ 4, VALUE_OPT_PUBKEY, + /* equiv idx, value */ 4, VALUE_OPT_PUBKEY, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ PUBKEY_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --pubkey */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ PUBKEY_DESC, PUBKEY_NAME, PUBKEY_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 5, VALUE_OPT_BITS, + /* equiv idx, value */ 5, VALUE_OPT_BITS, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, /* opt state flags */ BITS_FLAGS, 0, @@ -281,14 +328,14 @@ static tOptDesc optDesc[OPTION_CT] = { * * Define the tpmtool Option Environment */ -#define zPROGNAME (tpmtool_opt_strs+1207) -#define zUsageTitle (tpmtool_opt_strs+1215) +#define zPROGNAME (tpmtool_opt_strs+1288) +#define zUsageTitle (tpmtool_opt_strs+1296) #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) +#define zBugsAddr (tpmtool_opt_strs+1397) +#define zExplain (tpmtool_opt_strs+1416) +#define zDetail (tpmtool_opt_strs+1419) +#define zFullVersion (tpmtool_opt_strs+1488) /* extracted from optcode.tlib near line 350 */ #if defined(ENABLE_NLS) @@ -302,7 +349,7 @@ static tOptDesc optDesc[OPTION_CT] = { #define tpmtool_full_usage (NULL) -#define tpmtool_short_usage (tpmtool_opt_strs+1425) +#define tpmtool_short_usage (tpmtool_opt_strs+1506) #endif /* not defined __doxygen__ */ @@ -360,6 +407,27 @@ emit_ranges: optionShowRange(pOptions, pOptDesc, (void *)rng, 1); } + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the infile option. + * + * @param pOptions the tpmtool options data structure + * @param pOptDesc the option descriptor for this option. + */ +static void +doOptInfile(tOptions* pOptions, tOptDesc* pOptDesc) +{ + static teOptFileType const type = + FTYPE_MODE_MUST_EXIST + FTYPE_MODE_NO_OPEN; + static tuFileMode mode; +#ifndef O_CLOEXEC +# define O_CLOEXEC 0 +#endif + mode.file_flags = O_CLOEXEC; + + optionFileCheck(pOptions, pOptDesc, type, mode); +} /* extracted from optmain.tlib near line 1113 */ /** @@ -423,7 +491,7 @@ tOptions tpmtoolOptions = { NO_EQUIVALENT, /* '-#' option index */ NO_EQUIVALENT /* index of default opt */ }, - 7 /* full option count */, 4 /* user option count */, + 9 /* full option count */, 6 /* user option count */, tpmtool_full_usage, tpmtool_short_usage, NULL, NULL, PKGDATADIR, tpmtool_packager_info diff --git a/src/tpmtool-args.def b/src/tpmtool-args.def index a72a92131f..e933dcf966 100644 --- a/src/tpmtool-args.def +++ b/src/tpmtool-args.def @@ -7,6 +7,7 @@ short-usage = "tpmtool [options]\ntpmtool --help for usage instructions.\n"; explain = ""; #define OUTFILE_OPT 1 +#define INFILE_OPT 1 #include args-std.def flag = { @@ -15,6 +16,12 @@ flag = { doc = "Generates an RSA private-public key pair on the specified token."; }; +flag = { + name = pubkey; + descrip = "Prints the public key of the provided key"; + doc = ""; +}; + flag = { name = bits; arg-type = number; @@ -36,7 +43,12 @@ doc-section = { ds-text = <<-_EOT_ To generate a public key use: @example -$ tpmtool --generate-rsa --bits 1024 +$ tpmtool --generate-rsa --bits 1024 --outfile tpmkey.pem +@end example + +To get the public key of a TPM key use: +@example +$ tpmtool --pubkey --infile tpmkey.tpm --outfile pubkey.pem @end example _EOT_; }; diff --git a/src/tpmtool-args.h b/src/tpmtool-args.h index 134e36443a..e9f7a586e9 100644 --- a/src/tpmtool-args.h +++ b/src/tpmtool-args.h @@ -2,7 +2,7 @@ * * DO NOT EDIT THIS FILE (tpmtool-args.h) * - * It has been AutoGen-ed July 6, 2012 at 10:34:04 PM by AutoGen 5.16 + * It has been AutoGen-ed July 8, 2012 at 01:42:38 PM by AutoGen 5.16 * From the definitions tpmtool-args.def * and the template file options * @@ -68,15 +68,17 @@ */ 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 + INDEX_OPT_INFILE = 1, + INDEX_OPT_OUTFILE = 2, + INDEX_OPT_GENERATE_RSA = 3, + INDEX_OPT_PUBKEY = 4, + INDEX_OPT_BITS = 5, + INDEX_OPT_VERSION = 6, + INDEX_OPT_HELP = 7, + INDEX_OPT_MORE_HELP = 8 } teOptIndex; -#define OPTION_CT 7 +#define OPTION_CT 9 #define TPMTOOL_VERSION "@VERSION@" #define TPMTOOL_FULL_VERSION "tpmtool @VERSION@" @@ -117,9 +119,11 @@ typedef enum { #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 VALUE_OPT_INFILE 1 +#define VALUE_OPT_OUTFILE 2 +#define VALUE_OPT_GENERATE_RSA 3 +#define VALUE_OPT_PUBKEY 4 +#define VALUE_OPT_BITS 5 #define OPT_VALUE_BITS (DESC(BITS).optArg.argInt) #define VALUE_OPT_HELP 'h' diff --git a/src/tpmtool.c b/src/tpmtool.c index bc26e2cf87..3370480ddc 100644 --- a/src/tpmtool.c +++ b/src/tpmtool.c @@ -51,8 +51,10 @@ static void cmd_parser (int argc, char **argv); static void tpm_generate(FILE* outfile, unsigned int key_type, unsigned int bits); +static void tpm_pubkey(FILE* infile, FILE* outfile); static FILE *outfile; +static FILE *infile; int batch = 0; static void @@ -103,6 +105,15 @@ cmd_parser (int argc, char **argv) else outfile = stdout; + if (HAVE_OPT(INFILE)) + { + infile = fopen (OPT_ARG(INFILE), "rb"); + if (infile == NULL) + error (EXIT_FAILURE, errno, "%s", OPT_ARG(INFILE)); + } + else + infile = stdin; + if (HAVE_OPT(BITS)) bits = OPT_VALUE_BITS; else @@ -113,6 +124,10 @@ cmd_parser (int argc, char **argv) key_type = GNUTLS_PK_RSA; tpm_generate (outfile, key_type, bits); } + else if (HAVE_OPT(PUBKEY)) + { + tpm_pubkey (infile, outfile); + } else { USAGE(1); @@ -150,4 +165,35 @@ static void tpm_generate(FILE* outfile, unsigned int key_type, unsigned int bits fwrite (pubkey.data, 1, pubkey.size, outfile); fputs ("\n", outfile); fwrite (privkey.data, 1, privkey.size, outfile); + fputs ("\n", outfile); +} + +static void tpm_pubkey(FILE* infile, FILE* outfile) +{ + int ret; + char* srk_pass; + gnutls_datum_t data; + gnutls_pubkey_t pubkey; + size_t size; + + srk_pass = getpass ("Enter SRK password: "); + if (srk_pass != NULL) + srk_pass = strdup(srk_pass); + + data.data = (void*)fread_file (infile, &size); + data.size = size; + + gnutls_pubkey_init(&pubkey); + + ret = gnutls_pubkey_import_tpm_raw(pubkey, &data, GNUTLS_X509_FMT_PEM, + srk_pass); + + free(srk_pass); + + if (ret < 0) + error (EXIT_FAILURE, 0, "gnutls_pubkey_import_tpm_raw: %s", gnutls_strerror (ret)); + + _pubkey_info(outfile, pubkey); + + gnutls_pubkey_deinit(pubkey); }