** 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
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
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
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 *
gnutls_privkey_import_ext2;
gnutls_privkey_import_tpm_raw;
gnutls_tpm_privkey_generate;
+ gnutls_pubkey_import_tpm_raw;
} GNUTLS_3_0_0;
GNUTLS_PRIVATE {
}
static const unsigned char nullpass[20];
+const TSS_UUID srk_uuid = TSS_UUID_SRK;
/**
* gnutls_privkey_import_tpm_raw:
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;
}
err =
Tspi_Context_LoadKeyByUUID (s->tpm_context, TSS_PS_TYPE_SYSTEM,
- SRK_UUID, &s->srk);
+ srk_uuid, &s->srk);
if (err)
{
gnutls_assert ();
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:
tmpkey.data = NULL;
}
+ /* read the public key */
{
- gnutls_datum_t m, e;
size_t psize;
ret = gnutls_pubkey_init(&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)
{
}
}
+
+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);
+}
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;
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;
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)
{
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;
}
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;
}
#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
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);
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);
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);
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)
/* 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);
}
*
* 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
*
/*
* 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"
/* 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 [ -<flag> [<val>] | --<name>[{=| }<val>] ]...\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";
/*
#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
# 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
*/
optionStackArg, optionTimeDate, optionTimeVal,
optionUnstackArg, optionVendorOption;
static tOptProc
- doOptDebug, doUsageOpt;
+ doOptDebug, doOptInfile, doUsageOpt;
#define VER_PROC optionPrintVersion
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 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,
/* 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,
/* 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,
*
* 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)
#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__ */
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 */
/**
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
explain = "";
#define OUTFILE_OPT 1
+#define INFILE_OPT 1
#include args-std.def
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;
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_;
};
*
* 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
*
*/
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@"
#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'
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
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
key_type = GNUTLS_PK_RSA;
tpm_generate (outfile, key_type, bits);
}
+ else if (HAVE_OPT(PUBKEY))
+ {
+ tpm_pubkey (infile, outfile);
+ }
else
{
USAGE(1);
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);
}