From: Nikos Date: Sun, 13 Jan 2008 18:49:57 +0000 (+0200) Subject: Additions to make certtool print information on openpgp keys. X-Git-Tag: gnutls_2_3_1~66 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=07a8af3713d3d8fecf383d48dfd775e1b6160fab;p=thirdparty%2Fgnutls.git Additions to make certtool print information on openpgp keys. --- diff --git a/NEWS b/NEWS index fc53d5cfe1..e01f486465 100644 --- a/NEWS +++ b/NEWS @@ -8,12 +8,13 @@ See the end for copying conditions. ** Several improvements in the OpenPGP authentication. The authentication subkey is used if present. -** certtool can print information on openpgp certificates. +** certtool can print information on OpenPGP certificates and keys. ** Included the LGPL version of opencdk ** API and ABI modifications: gnutls_openpgp_privkey_sign_hash: MODIFIED to account for keyid +gnutls_openpgp_privkey_get_id: RENAMED to gnutls_openpgp_privkey_get_key_id gnutls_openpgp_crt_get_revoked_status: ADDED gnutls_openpgp_crt_get_subkey_count: ADDED gnutls_openpgp_crt_get_subkey_idx: ADDED @@ -33,6 +34,15 @@ gnutls_openpgp_privkey_get_subkey_pk_algorithm: ADDED gnutls_openpgp_privkey_get_subkey_expiration_time: ADDED gnutls_openpgp_privkey_get_subkey_id: ADDED gnutls_openpgp_privkey_get_subkey_creation_time: ADDED +gnutls_openpgp_crt_get_subkey_pk_dsa_raw: ADDED +gnutls_openpgp_crt_get_subkey_pk_rsa_raw: ADDED +gnutls_openpgp_crt_get_pk_dsa_raw: ADDED +gnutls_openpgp_crt_get_pk_rsa_raw: ADDED +gnutls_openpgp_privkey_export_subkey_dsa_raw: ADDED +gnutls_openpgp_privkey_export_subkey_rsa_raw: ADDED +gnutls_openpgp_privkey_export_dsa_raw: ADDED +gnutls_openpgp_privkey_export_rsa_raw: ADDED +gnutls_openpgp_privkey_export: ADDED * Version 2.3.0 (released 2008-01-08) diff --git a/includes/gnutls/compat.h b/includes/gnutls/compat.h index ee23e49ad2..280b410d05 100644 --- a/includes/gnutls/compat.h +++ b/includes/gnutls/compat.h @@ -19,6 +19,8 @@ #define _GNUTLS_GCC_ATTR_DEPRECATED #endif +#define gnutls_openpgp_crt_get_id gnutls_openpgp_crt_get_key_id + #define gnutls_cipher_algorithm gnutls_cipher_algorithm_t #define gnutls_kx_algorithm gnutls_kx_algorithm_t #define gnutls_paramsype gnutls_paramsype_t diff --git a/includes/gnutls/openpgp.h b/includes/gnutls/openpgp.h index 850dfa08c5..b45047cb5b 100644 --- a/includes/gnutls/openpgp.h +++ b/includes/gnutls/openpgp.h @@ -82,7 +82,7 @@ extern "C" time_t gnutls_openpgp_crt_get_creation_time (gnutls_openpgp_crt_t key); time_t gnutls_openpgp_crt_get_expiration_time (gnutls_openpgp_crt_t key); - int gnutls_openpgp_crt_get_id (gnutls_openpgp_crt_t key, + int gnutls_openpgp_crt_get_key_id (gnutls_openpgp_crt_t key, gnutls_openpgp_keyid_t* keyid); int gnutls_openpgp_crt_check_hostname (gnutls_openpgp_crt_t key, @@ -101,6 +101,17 @@ extern "C" int gnutls_openpgp_crt_get_subkey_usage (gnutls_openpgp_crt_t key, unsigned int idx, unsigned int *key_usage); + int gnutls_openpgp_crt_get_subkey_pk_dsa_raw (gnutls_openpgp_crt_t crt, unsigned int idx, + gnutls_datum_t * p, gnutls_datum_t * q, + gnutls_datum_t * g, gnutls_datum_t * y); + int gnutls_openpgp_crt_get_subkey_pk_rsa_raw (gnutls_openpgp_crt_t crt, unsigned int idx, + gnutls_datum_t * m, gnutls_datum_t * e); + int gnutls_openpgp_crt_get_pk_dsa_raw (gnutls_openpgp_crt_t crt, + gnutls_datum_t * p, gnutls_datum_t * q, + gnutls_datum_t * g, gnutls_datum_t * y); + int gnutls_openpgp_crt_get_pk_rsa_raw (gnutls_openpgp_crt_t crt, + gnutls_datum_t * m, gnutls_datum_t * e); + /* privkey stuff. */ int gnutls_openpgp_privkey_init (gnutls_openpgp_privkey_t * key); @@ -135,6 +146,28 @@ extern "C" time_t gnutls_openpgp_privkey_get_subkey_creation_time (gnutls_openpgp_privkey_t key, unsigned int idx); + int gnutls_openpgp_privkey_export_subkey_dsa_raw (gnutls_openpgp_privkey_t crt, unsigned int idx, + gnutls_datum_t * p, gnutls_datum_t * q, + gnutls_datum_t * g, gnutls_datum_t * y, + gnutls_datum_t * x); + int gnutls_openpgp_privkey_export_subkey_rsa_raw (gnutls_openpgp_privkey_t crt, unsigned int idx, + gnutls_datum_t * m, gnutls_datum_t * e, + gnutls_datum_t * d, gnutls_datum_t * p, + gnutls_datum_t * q, gnutls_datum_t * u); + + int gnutls_openpgp_privkey_export_dsa_raw (gnutls_openpgp_privkey_t crt, + gnutls_datum_t * p, gnutls_datum_t * q, + gnutls_datum_t * g, gnutls_datum_t * y, + gnutls_datum_t * x); + int gnutls_openpgp_privkey_export_rsa_raw (gnutls_openpgp_privkey_t crt, + gnutls_datum_t * m, gnutls_datum_t * e, + gnutls_datum_t * d, gnutls_datum_t * p, + gnutls_datum_t * q, gnutls_datum_t * u); + + int gnutls_openpgp_privkey_export (gnutls_openpgp_privkey_t key, + gnutls_openpgp_crt_fmt_t format, + void *output_data, size_t * output_data_size); + /* Keyring stuff. */ struct gnutls_openpgp_keyring_int; /* object to hold (parsed) openpgp keyrings */ diff --git a/lib/openpgp/openpgp.h b/lib/openpgp/openpgp.h index 3ec9ba9111..9eacadfd10 100644 --- a/lib/openpgp/openpgp.h +++ b/lib/openpgp/openpgp.h @@ -52,7 +52,7 @@ void gnutls_openpgp_crt_deinit (gnutls_openpgp_crt_t key); int gnutls_openpgp_crt_import (gnutls_openpgp_crt_t key, const gnutls_datum_t * data, gnutls_openpgp_crt_fmt_t format); -int gnutls_openpgp_crt_export (gnutls_openpgp_crt_t key, +int _gnutls_openpgp_export (cdk_kbnode_t node, gnutls_openpgp_crt_fmt_t format, void *output_data, size_t * output_data_size); @@ -98,6 +98,8 @@ int _gnutls_read_pgp_mpi( cdk_packet_t pkt, unsigned int priv, size_t idx, mpi_t int _gnutls_openpgp_find_subkey_idx( cdk_kbnode_t knode, uint32_t keyid[2], unsigned int priv); +int _gnutls_openpgp_get_algo( int cdk_algo); + #else /* no opencdk */ typedef void *gnutls_openpgp_keyring_t; diff --git a/lib/openpgp/output.c b/lib/openpgp/output.c index 71b997133f..9cf82997c1 100644 --- a/lib/openpgp/output.c +++ b/lib/openpgp/output.c @@ -108,23 +108,15 @@ print_key_usage (gnutls_string * str, gnutls_openpgp_crt_t cert, unsigned int id } if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE) - addf (str, _("\t\t\tDigital signature.\n")); - if (key_usage & GNUTLS_KEY_NON_REPUDIATION) - addf (str, _("\t\t\tNon repudiation.\n")); + addf (str, _("\t\t\tDigital signatures.\n")); if (key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT) - addf (str, _("\t\t\tKey encipherment.\n")); + addf (str, _("\t\t\tCommunications encipherment.\n")); if (key_usage & GNUTLS_KEY_DATA_ENCIPHERMENT) - addf (str, _("\t\t\tData encipherment.\n")); + addf (str, _("\t\t\tStorage data encipherment.\n")); if (key_usage & GNUTLS_KEY_KEY_AGREEMENT) - addf (str, _("\t\t\tKey agreement.\n")); + addf (str, _("\t\t\tAuthentication.\n")); if (key_usage & GNUTLS_KEY_KEY_CERT_SIGN) addf (str, _("\t\t\tCertificate signing.\n")); - if (key_usage & GNUTLS_KEY_CRL_SIGN) - addf (str, _("\t\t\tCRL signing.\n")); - if (key_usage & GNUTLS_KEY_ENCIPHER_ONLY) - addf (str, _("\t\t\tKey encipher only.\n")); - if (key_usage & GNUTLS_KEY_DECIPHER_ONLY) - addf (str, _("\t\t\tKey decipher only.\n")); } /* idx == -1 indicates main key @@ -137,12 +129,12 @@ print_key_id (gnutls_string * str, gnutls_openpgp_crt_t cert, int idx) int err; if (idx < 0) - err = gnutls_openpgp_crt_get_id (cert, &id); + err = gnutls_openpgp_crt_get_key_id (cert, &id); else err = gnutls_openpgp_crt_get_subkey_id( cert, idx, &id); if (err < 0) - addf (str, "error: get_id: %s\n", gnutls_strerror (err)); + addf (str, "error: get_key_id: %s\n", gnutls_strerror (err)); else { addf (str, _("\tID (hex): ")); @@ -251,14 +243,17 @@ print_key_info(gnutls_string * str, gnutls_openpgp_crt_t cert, int idx) name = "Unknown"; addf (str, _("\tPublic Key Algorithm: %s\n"), name); -#if 0 switch (err) { case GNUTLS_PK_RSA: { gnutls_datum_t m, e; - err = gnutls_openpgp_crt_get_pk_rsa_raw (cert, &m, &e); + if (idx == -1) + err = gnutls_openpgp_crt_get_pk_rsa_raw (cert, &m, &e); + else + err = gnutls_openpgp_crt_get_subkey_pk_rsa_raw (cert, idx, &m, &e); + if (err < 0) addf (str, "error: get_pk_rsa_raw: %s\n", gnutls_strerror (err)); @@ -279,7 +274,10 @@ print_key_info(gnutls_string * str, gnutls_openpgp_crt_t cert, int idx) { gnutls_datum_t p, q, g, y; - err = gnutls_openpgp_crt_get_pk_dsa_raw (cert, &p, &q, &g, &y); + if (idx == -1) + err = gnutls_openpgp_crt_get_pk_dsa_raw (cert, &p, &q, &g, &y); + else + err = gnutls_openpgp_crt_get_subkey_pk_dsa_raw (cert, idx, &p, &q, &g, &y); if (err < 0) addf (str, "error: get_pk_dsa_raw: %s\n", gnutls_strerror (err)); @@ -300,7 +298,6 @@ print_key_info(gnutls_string * str, gnutls_openpgp_crt_t cert, int idx) default: break; } -#endif } } diff --git a/lib/openpgp/pgp.c b/lib/openpgp/pgp.c index e0f0472bf6..d36a5c34c9 100644 --- a/lib/openpgp/pgp.c +++ b/lib/openpgp/pgp.c @@ -116,30 +116,17 @@ gnutls_openpgp_crt_import (gnutls_openpgp_crt_t key, return 0; } -/** - * gnutls_openpgp_crt_export - This function will export a RAW or BASE64 encoded key - * @key: Holds the key. - * @format: One of gnutls_openpgp_crt_fmt_t elements. - * @output_data: will contain the key base64 encoded or raw - * @output_data_size: holds the size of output_data (and will be replaced by the actual size of parameters) - * - * This function will convert the given key to RAW or Base64 format. - * If the buffer provided is not long enough to hold the output, then - * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned. - * - * Returns 0 on success. - * - **/ -int -gnutls_openpgp_crt_export (gnutls_openpgp_crt_t key, - gnutls_openpgp_crt_fmt_t format, - void *output_data, size_t * output_data_size) +/* internal version of export + */ +int _gnutls_openpgp_export (cdk_kbnode_t node, + gnutls_openpgp_crt_fmt_t format, + void *output_data, size_t * output_data_size) { size_t input_data_size = *output_data_size; size_t calc_size; int rc; - rc = cdk_kbnode_write_to_mem (key->knode, output_data, output_data_size); + rc = cdk_kbnode_write_to_mem (node, output_data, output_data_size); if (rc) { rc = _gnutls_map_cdk_rc (rc); @@ -180,6 +167,29 @@ gnutls_openpgp_crt_export (gnutls_openpgp_crt_t key, } return 0; + +} + +/** + * gnutls_openpgp_crt_export - This function will export a RAW or BASE64 encoded key + * @key: Holds the key. + * @format: One of gnutls_openpgp_crt_fmt_t elements. + * @output_data: will contain the key base64 encoded or raw + * @output_data_size: holds the size of output_data (and will be replaced by the actual size of parameters) + * + * This function will convert the given key to RAW or Base64 format. + * If the buffer provided is not long enough to hold the output, then + * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned. + * + * Returns 0 on success. + * + **/ +int +gnutls_openpgp_crt_export (gnutls_openpgp_crt_t key, + gnutls_openpgp_crt_fmt_t format, + void *output_data, size_t * output_data_size) +{ + return _gnutls_openpgp_export( key->knode, format, output_data, output_data_size); } @@ -349,13 +359,7 @@ gnutls_openpgp_crt_get_pk_algorithm (gnutls_openpgp_crt_t key, { if (bits) *bits = cdk_pk_get_nbits (pkt->pkt.public_key); - algo = pkt->pkt.public_key->pubkey_algo; - if (is_RSA (algo)) - algo = GNUTLS_PK_RSA; - else if (is_DSA (algo)) - algo = GNUTLS_PK_DSA; - else - algo = GNUTLS_E_UNKNOWN_PK_ALGORITHM; + algo = _gnutls_openpgp_get_algo(pkt->pkt.public_key->pubkey_algo); } return algo; @@ -438,14 +442,14 @@ gnutls_openpgp_crt_get_expiration_time (gnutls_openpgp_crt_t key) } /** - * gnutls_openpgp_crt_get_id - Gets the keyID + * gnutls_openpgp_crt_get_key_id - Gets the keyID * @key: the structure that contains the OpenPGP public key. * @keyid: the buffer to save the keyid. * * Returns the 64-bit keyID of the OpenPGP key. **/ int -gnutls_openpgp_crt_get_id (gnutls_openpgp_crt_t key, gnutls_openpgp_keyid_t* keyid) +gnutls_openpgp_crt_get_key_id (gnutls_openpgp_crt_t key, gnutls_openpgp_keyid_t* keyid) { cdk_packet_t pkt; uint32_t kid[2]; @@ -640,7 +644,7 @@ static cdk_packet_t _get_public_subkey(gnutls_openpgp_crt_t key, unsigned int in return NULL; } -/* returns the key with the given keyid +/* returns the key with the given keyid. It can be either key or subkey. * depending on what requested: * pkt->pkt.secret_key; * pkt->pkt.public_key; @@ -675,6 +679,7 @@ cdk_packet_t _gnutls_openpgp_find_key( cdk_kbnode_t knode, uint32_t keyid[2], } } + gnutls_assert(); return NULL; } @@ -995,7 +1000,6 @@ int max_pub_params; if (err != CDK_Success) { -_gnutls_x509_log( "err: %d/%d\n", err, idx); gnutls_assert(); gnutls_free( buf); return _gnutls_map_cdk_rc( err); @@ -1020,13 +1024,18 @@ int _gnutls_openpgp_crt_get_mpis (gnutls_openpgp_crt_t cert, uint32_t keyid[2], mpi_t * params, int *params_size) { - int result, i; + int result, i, idx; int pk_algorithm, local_params; cdk_packet_t pkt; - /* Read the algorithm's OID - */ - pk_algorithm = gnutls_openpgp_crt_get_pk_algorithm (cert, NULL); + pkt = _gnutls_openpgp_find_key( cert->knode, keyid, 0); + if (pkt == NULL) + { + gnutls_assert(); + return GNUTLS_E_OPENPGP_GETKEY_FAILED; + } + + pk_algorithm = _gnutls_openpgp_get_algo( pkt->pkt.public_key->pubkey_algo); switch (pk_algorithm) { @@ -1049,13 +1058,6 @@ _gnutls_openpgp_crt_get_mpis (gnutls_openpgp_crt_t cert, uint32_t keyid[2], *params_size = local_params; - pkt = _gnutls_openpgp_find_key( cert->knode, keyid, 0); - if (pkt == NULL) - { - gnutls_assert(); - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - } - for (i = 0; i < local_params; i++) { result = _gnutls_read_pgp_mpi( pkt, 0, i, ¶ms[i]); @@ -1077,3 +1079,286 @@ error: return result; } + +/* The internal version of export + */ +static +int _get_pk_rsa_raw(gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, + gnutls_datum_t * m, gnutls_datum_t * e) +{ + int pk_algorithm, ret, i; + cdk_packet_t pkt; + uint32_t kid32[2]; + mpi_t params[MAX_PUBLIC_PARAMS_SIZE]; + int params_size = MAX_PUBLIC_PARAMS_SIZE; + + if (crt == NULL) + { + gnutls_assert (); + return GNUTLS_E_INVALID_REQUEST; + } + + KEYID_IMPORT(kid32, keyid); + + pkt = _gnutls_openpgp_find_key( crt->knode, kid32, 0); + if (pkt == NULL) + { + gnutls_assert(); + return GNUTLS_E_OPENPGP_GETKEY_FAILED; + } + + pk_algorithm = _gnutls_openpgp_get_algo( pkt->pkt.public_key->pubkey_algo); + + if (pk_algorithm != GNUTLS_PK_RSA) + { + gnutls_assert (); + return GNUTLS_E_INVALID_REQUEST; + } + + ret = _gnutls_openpgp_crt_get_mpis (crt, kid32, params, ¶ms_size); + if (ret < 0) + { + gnutls_assert (); + return ret; + } + + ret = _gnutls_mpi_dprint (m, params[0]); + if (ret < 0) + { + gnutls_assert (); + goto cleanup; + } + + ret = _gnutls_mpi_dprint (e, params[1]); + if (ret < 0) + { + gnutls_assert (); + _gnutls_free_datum (m); + goto cleanup; + } + + ret = 0; + +cleanup: + for (i = 0; i < params_size; i++) + { + _gnutls_mpi_release (¶ms[i]); + } + return ret; +} + +static +int _get_pk_dsa_raw(gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, + gnutls_datum_t * p, gnutls_datum_t * q, + gnutls_datum_t * g, gnutls_datum_t * y) +{ + int pk_algorithm, ret, i; + cdk_packet_t pkt; + uint32_t kid32[2]; + mpi_t params[MAX_PUBLIC_PARAMS_SIZE]; + int params_size = MAX_PUBLIC_PARAMS_SIZE; + + if (crt == NULL) + { + gnutls_assert (); + return GNUTLS_E_INVALID_REQUEST; + } + + KEYID_IMPORT(kid32, keyid); + + pkt = _gnutls_openpgp_find_key( crt->knode, kid32, 0); + if (pkt == NULL) + { + gnutls_assert(); + return GNUTLS_E_OPENPGP_GETKEY_FAILED; + } + + pk_algorithm = _gnutls_openpgp_get_algo( pkt->pkt.public_key->pubkey_algo); + + if (pk_algorithm != GNUTLS_PK_DSA) + { + gnutls_assert (); + return GNUTLS_E_INVALID_REQUEST; + } + + ret = _gnutls_openpgp_crt_get_mpis (crt, kid32, params, ¶ms_size); + if (ret < 0) + { + gnutls_assert (); + return ret; + } + + /* P */ + ret = _gnutls_mpi_dprint (p, params[0]); + if (ret < 0) + { + gnutls_assert (); + goto cleanup; + } + + /* Q */ + ret = _gnutls_mpi_dprint (q, params[1]); + if (ret < 0) + { + gnutls_assert (); + _gnutls_free_datum (p); + goto cleanup; + } + + + /* G */ + ret = _gnutls_mpi_dprint (g, params[2]); + if (ret < 0) + { + gnutls_assert (); + _gnutls_free_datum (p); + _gnutls_free_datum (q); + goto cleanup; + } + + + /* Y */ + ret = _gnutls_mpi_dprint (y, params[3]); + if (ret < 0) + { + gnutls_assert (); + _gnutls_free_datum (p); + _gnutls_free_datum (g); + _gnutls_free_datum (q); + goto cleanup; + } + + ret = 0; + +cleanup: + for (i = 0; i < params_size; i++) + { + _gnutls_mpi_release (¶ms[i]); + } + return ret; +} + + +/** + * gnutls_openpgp_crt_get_pk_rsa_raw - This function will export the RSA public key + * @crt: Holds the certificate + * @m: will hold the modulus + * @e: will hold the public exponent + * + * This function will export the RSA public key's parameters found in + * the given structure. The new parameters will be allocated using + * gnutls_malloc() and will be stored in the appropriate datum. + * + * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error. + **/ +int +gnutls_openpgp_crt_get_pk_rsa_raw (gnutls_openpgp_crt_t crt, + gnutls_datum_t * m, gnutls_datum_t * e) +{ +gnutls_openpgp_keyid_t keyid; +int ret; + + ret = gnutls_openpgp_crt_get_key_id( crt, &keyid); + if (ret < 0) + { + gnutls_assert (); + return ret; + } + + return _get_pk_rsa_raw( crt, keyid, m, e); +} + +/** + * gnutls_openpgp_crt_get_pk_dsa_raw - This function will export the DSA public key + * @crt: Holds the certificate + * @p: will hold the p + * @q: will hold the q + * @g: will hold the g + * @y: will hold the y + * + * This function will export the DSA public key's parameters found in + * the given certificate. The new parameters will be allocated using + * gnutls_malloc() and will be stored in the appropriate datum. + * + * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error. + **/ +int +gnutls_openpgp_crt_get_pk_dsa_raw (gnutls_openpgp_crt_t crt, + gnutls_datum_t * p, gnutls_datum_t * q, + gnutls_datum_t * g, gnutls_datum_t * y) +{ +gnutls_openpgp_keyid_t keyid; +int ret; + + ret = gnutls_openpgp_crt_get_key_id( crt, &keyid); + if (ret < 0) + { + gnutls_assert (); + return ret; + } + + return _get_pk_dsa_raw( crt, keyid, p, q, g, y); +} + +/** + * gnutls_openpgp_crt_get_subkey_pk_rsa_raw - This function will export the RSA public key + * @crt: Holds the certificate + * @idx: Is the subkey index + * @m: will hold the modulus + * @e: will hold the public exponent + * + * This function will export the RSA public key's parameters found in + * the given structure. The new parameters will be allocated using + * gnutls_malloc() and will be stored in the appropriate datum. + * + * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error. + **/ +int +gnutls_openpgp_crt_get_subkey_pk_rsa_raw (gnutls_openpgp_crt_t crt, unsigned int idx, + gnutls_datum_t * m, gnutls_datum_t * e) +{ +gnutls_openpgp_keyid_t keyid; +int ret; + + ret = gnutls_openpgp_crt_get_subkey_id( crt, idx, &keyid); + if (ret < 0) + { + gnutls_assert (); + return ret; + } + + return _get_pk_rsa_raw( crt, keyid, m, e); +} + +/** + * gnutls_openpgp_crt_get_subkey_pk_dsa_raw - This function will export the DSA public key + * @crt: Holds the certificate + * @idx: Is the subkey index + * @p: will hold the p + * @q: will hold the q + * @g: will hold the g + * @y: will hold the y + * + * This function will export the DSA public key's parameters found in + * the given certificate. The new parameters will be allocated using + * gnutls_malloc() and will be stored in the appropriate datum. + * + * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error. + **/ +int +gnutls_openpgp_crt_get_subkey_pk_dsa_raw (gnutls_openpgp_crt_t crt, unsigned int idx, + gnutls_datum_t * p, gnutls_datum_t * q, + gnutls_datum_t * g, gnutls_datum_t * y) +{ +gnutls_openpgp_keyid_t keyid; +int ret; + + ret = gnutls_openpgp_crt_get_subkey_id( crt, idx, &keyid); + if (ret < 0) + { + gnutls_assert (); + return ret; + } + + return _get_pk_dsa_raw( crt, keyid, p, q, g, y); +} diff --git a/lib/openpgp/pgpverify.c b/lib/openpgp/pgpverify.c index 34b06a0834..d0d1d360e0 100644 --- a/lib/openpgp/pgpverify.c +++ b/lib/openpgp/pgpverify.c @@ -95,7 +95,7 @@ gnutls_openpgp_crt_verify_ring (gnutls_openpgp_crt_t key, /* Check if the key is included in the ring. */ if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME)) { - rc = gnutls_openpgp_crt_get_id (key, &id); + rc = gnutls_openpgp_crt_get_key_id (key, &id); if (rc < 0) { gnutls_assert (); diff --git a/lib/openpgp/privkey.c b/lib/openpgp/privkey.c index 1083e30f22..7b01324828 100644 --- a/lib/openpgp/privkey.c +++ b/lib/openpgp/privkey.c @@ -123,6 +123,28 @@ gnutls_openpgp_privkey_import (gnutls_openpgp_privkey_t key, return 0; } +/** + * gnutls_openpgp_privkey_export - This function will export a RAW or BASE64 encoded key + * @key: Holds the key. + * @format: One of gnutls_openpgp_crt_fmt_t elements. + * @output_data: will contain the key base64 encoded or raw + * @output_data_size: holds the size of output_data (and will be replaced by the actual size of parameters) + * + * This function will convert the given key to RAW or Base64 format. + * If the buffer provided is not long enough to hold the output, then + * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned. + * + * Returns 0 on success. + * + **/ +int +gnutls_openpgp_privkey_export (gnutls_openpgp_privkey_t key, + gnutls_openpgp_crt_fmt_t format, + void *output_data, size_t * output_data_size) +{ + return _gnutls_openpgp_export( key->knode, format, output_data, output_data_size); +} + /** * gnutls_openpgp_privkey_get_pk_algorithm - This function returns the key's PublicKey algorithm @@ -156,21 +178,29 @@ gnutls_openpgp_privkey_get_pk_algorithm (gnutls_openpgp_privkey_t key, { if (bits) *bits = cdk_pk_get_nbits (pkt->pkt.secret_key->pk); - algo = pkt->pkt.secret_key->pk->pubkey_algo; - if (is_RSA (algo)) + algo = _gnutls_openpgp_get_algo(pkt->pkt.secret_key->pk->pubkey_algo); + } + + return algo; +} + +int _gnutls_openpgp_get_algo( int cdk_algo) +{ +int algo; + + if (is_RSA (cdk_algo)) algo = GNUTLS_PK_RSA; - else if (is_DSA (algo)) + else if (is_DSA (cdk_algo)) algo = GNUTLS_PK_DSA; else algo = GNUTLS_PK_UNKNOWN; - } - - return algo; + + return algo; } /** * gnutls_openpgp_privkey_get_revoked_ status - Gets the revoked status of the key - * @key: the structure that contains the OpenPGP public key. + * @key: the structure that contains the OpenPGP private key. * * Returns the true (1) or false (0) based on whether this key has been revoked * or not. A negative value indicates an error. @@ -324,7 +354,7 @@ static cdk_packet_t _get_secret_subkey(gnutls_openpgp_privkey_t key, unsigned in /** * gnutls_openpgp_privkey_get_subkey_revoked_ status - Gets the revoked status of the key - * @key: the structure that contains the OpenPGP public key. + * @key: the structure that contains the OpenPGP private key. * @idx: is the subkey index * * Returns the true (1) or false (0) based on whether this key has been revoked @@ -398,7 +428,7 @@ gnutls_openpgp_privkey_get_subkey_pk_algorithm (gnutls_openpgp_privkey_t key, /** * gnutls_openpgp_privkey_get_subkey_idx - Returns the subkey's index - * @key: the structure that contains the OpenPGP public key. + * @key: the structure that contains the OpenPGP private key. * @keyid: the keyid. * * Returns the index of the subkey or a negative error value. @@ -430,7 +460,7 @@ gnutls_openpgp_privkey_get_subkey_idx (gnutls_openpgp_privkey_t key, gnutls_open /** * gnutls_openpgp_privkey_get_subkey_creation_time - Extract the timestamp - * @key: the structure that contains the OpenPGP public key. + * @key: the structure that contains the OpenPGP private key. * @idx: the subkey index * * Returns the timestamp when the OpenPGP key was created. @@ -455,7 +485,7 @@ gnutls_openpgp_privkey_get_subkey_creation_time (gnutls_openpgp_privkey_t key, u /** * gnutls_openpgp_privkey_get_subkey_expiration_time - Extract the expire date - * @key: the structure that contains the OpenPGP public key. + * @key: the structure that contains the OpenPGP private key. * @idx: the subkey index * * Returns the time when the OpenPGP key expires. A value of '0' means @@ -520,9 +550,14 @@ _gnutls_openpgp_privkey_get_mpis (gnutls_openpgp_privkey_t pkey, uint32_t keyid[ int pk_algorithm, local_params; cdk_packet_t pkt; - /* Read the algorithm's OID - */ - pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (pkey, NULL); + pkt = _gnutls_openpgp_find_key( pkey->knode, keyid, 1); + if (pkt == NULL) + { + gnutls_assert(); + return GNUTLS_E_OPENPGP_GETKEY_FAILED; + } + + pk_algorithm = _gnutls_openpgp_get_algo( pkt->pkt.secret_key->pk->pubkey_algo); switch (pk_algorithm) { @@ -545,12 +580,6 @@ _gnutls_openpgp_privkey_get_mpis (gnutls_openpgp_privkey_t pkey, uint32_t keyid[ *params_size = local_params; - pkt = _gnutls_openpgp_find_key( pkey->knode, keyid, 1); - if (pkt == NULL) - { - gnutls_assert(); - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - } for (i = 0; i < local_params; i++) { @@ -573,3 +602,358 @@ error: return result; } + +/* The internal version of export + */ +static +int _get_sk_rsa_raw(gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, + gnutls_datum_t * m, gnutls_datum_t * e, + gnutls_datum_t * d, gnutls_datum_t * p, + gnutls_datum_t * q, gnutls_datum_t * u) +{ + int pk_algorithm, ret, i; + cdk_packet_t pkt; + uint32_t kid32[2]; + mpi_t params[MAX_PRIV_PARAMS_SIZE]; + int params_size = MAX_PRIV_PARAMS_SIZE; + + if (pkey == NULL) + { + gnutls_assert (); + return GNUTLS_E_INVALID_REQUEST; + } + + KEYID_IMPORT(kid32, keyid); + + pkt = _gnutls_openpgp_find_key( pkey->knode, kid32, 1); + if (pkt == NULL) + { + gnutls_assert(); + return GNUTLS_E_OPENPGP_GETKEY_FAILED; + } + + pk_algorithm = _gnutls_openpgp_get_algo( pkt->pkt.secret_key->pk->pubkey_algo); + + if (pk_algorithm != GNUTLS_PK_RSA) + { + gnutls_assert (); + return GNUTLS_E_INVALID_REQUEST; + } + + ret = _gnutls_openpgp_privkey_get_mpis (pkey, kid32, params, ¶ms_size); + if (ret < 0) + { + gnutls_assert (); + return ret; + } + + ret = _gnutls_mpi_dprint (m, params[0]); + if (ret < 0) + { + gnutls_assert (); + goto cleanup; + } + + ret = _gnutls_mpi_dprint (e, params[1]); + if (ret < 0) + { + gnutls_assert (); + _gnutls_free_datum (m); + goto cleanup; + } + + ret = _gnutls_mpi_dprint (d, params[2]); + if (ret < 0) + { + gnutls_assert (); + _gnutls_free_datum (m); + _gnutls_free_datum (e); + goto cleanup; + } + + ret = _gnutls_mpi_dprint (p, params[3]); + if (ret < 0) + { + gnutls_assert (); + _gnutls_free_datum (m); + _gnutls_free_datum (e); + _gnutls_free_datum (d); + goto cleanup; + } + + ret = _gnutls_mpi_dprint (q, params[4]); + if (ret < 0) + { + gnutls_assert (); + _gnutls_free_datum (m); + _gnutls_free_datum (e); + _gnutls_free_datum (d); + _gnutls_free_datum (p); + goto cleanup; + } + + ret = _gnutls_mpi_dprint (u, params[5]); + if (ret < 0) + { + gnutls_assert (); + _gnutls_free_datum (q); + _gnutls_free_datum (m); + _gnutls_free_datum (e); + _gnutls_free_datum (d); + _gnutls_free_datum (p); + goto cleanup; + } + + ret = 0; + +cleanup: + for (i = 0; i < params_size; i++) + { + _gnutls_mpi_release (¶ms[i]); + } + return ret; +} + +static +int _get_sk_dsa_raw(gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, + gnutls_datum_t * p, gnutls_datum_t * q, + gnutls_datum_t * g, gnutls_datum_t * y, + gnutls_datum_t * x) +{ + int pk_algorithm, ret, i; + cdk_packet_t pkt; + uint32_t kid32[2]; + mpi_t params[MAX_PRIV_PARAMS_SIZE]; + int params_size = MAX_PRIV_PARAMS_SIZE; + + if (pkey == NULL) + { + gnutls_assert (); + return GNUTLS_E_INVALID_REQUEST; + } + + KEYID_IMPORT(kid32, keyid); + + pkt = _gnutls_openpgp_find_key( pkey->knode, kid32, 0); + if (pkt == NULL) + { + gnutls_assert(); + return GNUTLS_E_OPENPGP_GETKEY_FAILED; + } + + pk_algorithm = _gnutls_openpgp_get_algo( pkt->pkt.secret_key->pk->pubkey_algo); + + if (pk_algorithm != GNUTLS_PK_DSA) + { + gnutls_assert (); + return GNUTLS_E_INVALID_REQUEST; + } + + ret = _gnutls_openpgp_privkey_get_mpis (pkey, kid32, params, ¶ms_size); + if (ret < 0) + { + gnutls_assert (); + return ret; + } + + /* P */ + ret = _gnutls_mpi_dprint (p, params[0]); + if (ret < 0) + { + gnutls_assert (); + goto cleanup; + } + + /* Q */ + ret = _gnutls_mpi_dprint (q, params[1]); + if (ret < 0) + { + gnutls_assert (); + _gnutls_free_datum (p); + goto cleanup; + } + + + /* G */ + ret = _gnutls_mpi_dprint (g, params[2]); + if (ret < 0) + { + gnutls_assert (); + _gnutls_free_datum (p); + _gnutls_free_datum (q); + goto cleanup; + } + + + /* Y */ + ret = _gnutls_mpi_dprint (y, params[3]); + if (ret < 0) + { + gnutls_assert (); + _gnutls_free_datum (p); + _gnutls_free_datum (g); + _gnutls_free_datum (q); + goto cleanup; + } + + ret = _gnutls_mpi_dprint (x, params[4]); + if (ret < 0) + { + gnutls_assert (); + _gnutls_free_datum (y); + _gnutls_free_datum (p); + _gnutls_free_datum (g); + _gnutls_free_datum (q); + goto cleanup; + } + + ret = 0; + +cleanup: + for (i = 0; i < params_size; i++) + { + _gnutls_mpi_release (¶ms[i]); + } + return ret; +} + + +/** + * gnutls_openpgp_privkey_export_rsa_raw - This function will export the RSA private key + * @pkey: Holds the certificate + * @m: will hold the modulus + * @e: will hold the public exponent + * @d: will hold the private exponent + * @p: will hold the first prime (p) + * @q: will hold the second prime (q) + * @u: will hold the coefficient + * + * This function will export the RSA private key's parameters found in + * the given structure. The new parameters will be allocated using + * gnutls_malloc() and will be stored in the appropriate datum. + * + * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error. + **/ +int +gnutls_openpgp_privkey_export_rsa_raw (gnutls_openpgp_privkey_t 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_openpgp_keyid_t keyid; +int ret; + + ret = gnutls_openpgp_privkey_get_key_id( pkey, &keyid); + if (ret < 0) + { + gnutls_assert (); + return ret; + } + + return _get_sk_rsa_raw( pkey, keyid, m, e, d, p, q, u); +} + +/** + * gnutls_openpgp_privkey_export_dsa_raw - This function will export the DSA private key + * @pkey: Holds the certificate + * @p: will hold the p + * @q: will hold the q + * @g: will hold the g + * @y: will hold the y + * @x: will hold the x + * + * This function will export the DSA private key's parameters found in + * the given certificate. The new parameters will be allocated using + * gnutls_malloc() and will be stored in the appropriate datum. + * + * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error. + **/ +int +gnutls_openpgp_privkey_export_dsa_raw (gnutls_openpgp_privkey_t pkey, + gnutls_datum_t * p, gnutls_datum_t * q, + gnutls_datum_t * g, gnutls_datum_t * y, + gnutls_datum_t * x) +{ +gnutls_openpgp_keyid_t keyid; +int ret; + + ret = gnutls_openpgp_privkey_get_key_id( pkey, &keyid); + if (ret < 0) + { + gnutls_assert (); + return ret; + } + + return _get_sk_dsa_raw( pkey, keyid, p, q, g, y, x); +} + +/** + * gnutls_openpgp_privkey_export_subkey_rsa_raw - This function will export the RSA private key + * @pkey: Holds the certificate + * @idx: Is the subkey index + * @m: will hold the modulus + * @e: will hold the public exponent + * @d: will hold the private exponent + * @p: will hold the first prime (p) + * @q: will hold the second prime (q) + * @u: will hold the coefficient + * + * This function will export the RSA private key's parameters found in + * the given structure. The new parameters will be allocated using + * gnutls_malloc() and will be stored in the appropriate datum. + * + * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error. + **/ +int +gnutls_openpgp_privkey_export_subkey_rsa_raw (gnutls_openpgp_privkey_t pkey, unsigned int idx, + 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_openpgp_keyid_t keyid; +int ret; + + ret = gnutls_openpgp_privkey_get_subkey_id( pkey, idx, &keyid); + if (ret < 0) + { + gnutls_assert (); + return ret; + } + + return _get_sk_rsa_raw( pkey, keyid, m, e, d, p, q, u); +} + +/** + * gnutls_openpgp_privkey_export_subkey_dsa_raw - This function will export the DSA private key + * @pkey: Holds the certificate + * @idx: Is the subkey index + * @p: will hold the p + * @q: will hold the q + * @g: will hold the g + * @y: will hold the y + * @x: will hold the x + * + * This function will export the DSA private key's parameters found in + * the given certificate. The new parameters will be allocated using + * gnutls_malloc() and will be stored in the appropriate datum. + * + * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error. + **/ +int +gnutls_openpgp_privkey_export_subkey_dsa_raw (gnutls_openpgp_privkey_t pkey, unsigned int idx, + gnutls_datum_t * p, gnutls_datum_t * q, + gnutls_datum_t * g, gnutls_datum_t * y, + gnutls_datum_t * x) +{ +gnutls_openpgp_keyid_t keyid; +int ret; + + ret = gnutls_openpgp_privkey_get_subkey_id( pkey, idx, &keyid); + if (ret < 0) + { + gnutls_assert (); + return ret; + } + + return _get_sk_dsa_raw( pkey, keyid, p, q, g, y, x); +} diff --git a/src/certtool-gaa.c b/src/certtool-gaa.c index 77130b6b10..3383040799 100644 --- a/src/certtool-gaa.c +++ b/src/certtool-gaa.c @@ -153,6 +153,7 @@ void gaa_help(void) __gaa_helpsingle(0, "p7-info", "", "Print information on a PKCS #7 structure."); __gaa_helpsingle(0, "smime-to-p7", "", "Convert S/MIME to PKCS #7 structure."); __gaa_helpsingle('k', "key-info", "", "Print information on a private key."); + __gaa_helpsingle(0, "pgp-key-info", "", "Print information on a OpenPGP private key."); __gaa_helpsingle(0, "fix-key", "", "Regenerate the parameters in a private key."); __gaa_helpsingle(0, "v1", "", "Generate an X.509 version 1 certificate (no extensions)."); __gaa_helpsingle(0, "to-p12", "", "Generate a PKCS #12 structure."); @@ -185,33 +186,33 @@ typedef struct _gaainfo gaainfo; struct _gaainfo { -#line 114 "certtool.gaa" +#line 116 "certtool.gaa" int debug; -#line 110 "certtool.gaa" +#line 112 "certtool.gaa" char *template; -#line 107 "certtool.gaa" +#line 109 "certtool.gaa" char *infile; -#line 104 "certtool.gaa" +#line 106 "certtool.gaa" char *outfile; -#line 101 "certtool.gaa" +#line 103 "certtool.gaa" int quick_random; -#line 98 "certtool.gaa" +#line 100 "certtool.gaa" int bits; -#line 95 "certtool.gaa" +#line 97 "certtool.gaa" int outcert_format; -#line 92 "certtool.gaa" +#line 94 "certtool.gaa" int incert_format; -#line 89 "certtool.gaa" +#line 91 "certtool.gaa" int export; -#line 86 "certtool.gaa" +#line 88 "certtool.gaa" char *hash; -#line 83 "certtool.gaa" +#line 85 "certtool.gaa" int dsa; -#line 80 "certtool.gaa" +#line 82 "certtool.gaa" int pkcs8; -#line 73 "certtool.gaa" +#line 75 "certtool.gaa" int v1_cert; -#line 70 "certtool.gaa" +#line 72 "certtool.gaa" int fix_key; #line 53 "certtool.gaa" char *pass; @@ -281,7 +282,7 @@ static int gaa_error = 0; #define GAA_MULTIPLE_OPTION 3 #define GAA_REST 0 -#define GAA_NB_OPTION 42 +#define GAA_NB_OPTION 43 #define GAAOPTID_version 1 #define GAAOPTID_help 2 #define GAAOPTID_debug 3 @@ -300,30 +301,31 @@ static int gaa_error = 0; #define GAAOPTID_to_p12 16 #define GAAOPTID_v1 17 #define GAAOPTID_fix_key 18 -#define GAAOPTID_key_info 19 -#define GAAOPTID_smime_to_p7 20 -#define GAAOPTID_p7_info 21 -#define GAAOPTID_p12_info 22 -#define GAAOPTID_crl_info 23 -#define GAAOPTID_pgp_certificate_info 24 -#define GAAOPTID_certificate_info 25 -#define GAAOPTID_password 26 -#define GAAOPTID_load_ca_certificate 27 -#define GAAOPTID_load_ca_privkey 28 -#define GAAOPTID_load_certificate 29 -#define GAAOPTID_load_request 30 -#define GAAOPTID_load_privkey 31 -#define GAAOPTID_get_dh_params 32 -#define GAAOPTID_generate_dh_params 33 -#define GAAOPTID_verify_crl 34 -#define GAAOPTID_verify_chain 35 -#define GAAOPTID_generate_request 36 -#define GAAOPTID_generate_privkey 37 -#define GAAOPTID_update_certificate 38 -#define GAAOPTID_generate_crl 39 -#define GAAOPTID_generate_proxy 40 -#define GAAOPTID_generate_certificate 41 -#define GAAOPTID_generate_self_signed 42 +#define GAAOPTID_pgp_key_info 19 +#define GAAOPTID_key_info 20 +#define GAAOPTID_smime_to_p7 21 +#define GAAOPTID_p7_info 22 +#define GAAOPTID_p12_info 23 +#define GAAOPTID_crl_info 24 +#define GAAOPTID_pgp_certificate_info 25 +#define GAAOPTID_certificate_info 26 +#define GAAOPTID_password 27 +#define GAAOPTID_load_ca_certificate 28 +#define GAAOPTID_load_ca_privkey 29 +#define GAAOPTID_load_certificate 30 +#define GAAOPTID_load_request 31 +#define GAAOPTID_load_privkey 32 +#define GAAOPTID_get_dh_params 33 +#define GAAOPTID_generate_dh_params 34 +#define GAAOPTID_verify_crl 35 +#define GAAOPTID_verify_chain 36 +#define GAAOPTID_generate_request 37 +#define GAAOPTID_generate_privkey 38 +#define GAAOPTID_update_certificate 39 +#define GAAOPTID_generate_crl 40 +#define GAAOPTID_generate_proxy 41 +#define GAAOPTID_generate_certificate 42 +#define GAAOPTID_generate_self_signed 43 #line 168 "gaa.skel" @@ -637,6 +639,7 @@ static int gaa_get_option_num(char *str, int status) GAA_CHECK1STR("", GAAOPTID_to_p12); GAA_CHECK1STR("", GAAOPTID_v1); GAA_CHECK1STR("", GAAOPTID_fix_key); + GAA_CHECK1STR("", GAAOPTID_pgp_key_info); GAA_CHECK1STR("k", GAAOPTID_key_info); GAA_CHECK1STR("", GAAOPTID_smime_to_p7); GAA_CHECK1STR("", GAAOPTID_p7_info); @@ -677,6 +680,7 @@ static int gaa_get_option_num(char *str, int status) GAA_CHECKSTR("to-p12", GAAOPTID_to_p12); GAA_CHECKSTR("v1", GAAOPTID_v1); GAA_CHECKSTR("fix-key", GAAOPTID_fix_key); + GAA_CHECKSTR("pgp-key-info", GAAOPTID_pgp_key_info); GAA_CHECKSTR("key-info", GAAOPTID_key_info); GAA_CHECKSTR("smime-to-p7", GAAOPTID_smime_to_p7); GAA_CHECKSTR("p7-info", GAAOPTID_p7_info); @@ -747,14 +751,14 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) { case GAAOPTID_version: OK = 0; -#line 119 "certtool.gaa" +#line 121 "certtool.gaa" { certtool_version(); exit(0); ;}; return GAA_OK; break; case GAAOPTID_help: OK = 0; -#line 117 "certtool.gaa" +#line 119 "certtool.gaa" { gaa_help(); exit(0); ;}; return GAA_OK; @@ -764,7 +768,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_debug.arg1, gaa_getint, GAATMP_debug.size1); gaa_index++; -#line 115 "certtool.gaa" +#line 117 "certtool.gaa" { gaaval->debug = GAATMP_debug.arg1 ;}; return GAA_OK; @@ -774,7 +778,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_template.arg1, gaa_getstr, GAATMP_template.size1); gaa_index++; -#line 111 "certtool.gaa" +#line 113 "certtool.gaa" { gaaval->template = GAATMP_template.arg1 ;}; return GAA_OK; @@ -784,7 +788,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_infile.arg1, gaa_getstr, GAATMP_infile.size1); gaa_index++; -#line 108 "certtool.gaa" +#line 110 "certtool.gaa" { gaaval->infile = GAATMP_infile.arg1 ;}; return GAA_OK; @@ -794,14 +798,14 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_outfile.arg1, gaa_getstr, GAATMP_outfile.size1); gaa_index++; -#line 105 "certtool.gaa" +#line 107 "certtool.gaa" { gaaval->outfile = GAATMP_outfile.arg1 ;}; return GAA_OK; break; case GAAOPTID_disable_quick_random: OK = 0; -#line 102 "certtool.gaa" +#line 104 "certtool.gaa" { gaaval->quick_random = 0; ;}; return GAA_OK; @@ -811,28 +815,28 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_bits.arg1, gaa_getint, GAATMP_bits.size1); gaa_index++; -#line 99 "certtool.gaa" +#line 101 "certtool.gaa" { gaaval->bits = GAATMP_bits.arg1 ;}; return GAA_OK; break; case GAAOPTID_outder: OK = 0; -#line 96 "certtool.gaa" +#line 98 "certtool.gaa" { gaaval->outcert_format=1 ;}; return GAA_OK; break; case GAAOPTID_inder: OK = 0; -#line 93 "certtool.gaa" +#line 95 "certtool.gaa" { gaaval->incert_format=1 ;}; return GAA_OK; break; case GAAOPTID_export_ciphers: OK = 0; -#line 90 "certtool.gaa" +#line 92 "certtool.gaa" { gaaval->export=1 ;}; return GAA_OK; @@ -842,51 +846,58 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_hash.arg1, gaa_getstr, GAATMP_hash.size1); gaa_index++; -#line 87 "certtool.gaa" +#line 89 "certtool.gaa" { gaaval->hash = GAATMP_hash.arg1 ;}; return GAA_OK; break; case GAAOPTID_dsa: OK = 0; -#line 84 "certtool.gaa" +#line 86 "certtool.gaa" { gaaval->dsa=1 ;}; return GAA_OK; break; case GAAOPTID_pkcs8: OK = 0; -#line 81 "certtool.gaa" +#line 83 "certtool.gaa" { gaaval->pkcs8=1 ;}; return GAA_OK; break; case GAAOPTID_to_p8: OK = 0; -#line 78 "certtool.gaa" +#line 80 "certtool.gaa" { gaaval->action = 18; ;}; return GAA_OK; break; case GAAOPTID_to_p12: OK = 0; -#line 76 "certtool.gaa" +#line 78 "certtool.gaa" { gaaval->action = 8; ;}; return GAA_OK; break; case GAAOPTID_v1: OK = 0; -#line 74 "certtool.gaa" +#line 76 "certtool.gaa" { gaaval->v1_cert = 1; ;}; return GAA_OK; break; case GAAOPTID_fix_key: OK = 0; -#line 71 "certtool.gaa" +#line 73 "certtool.gaa" { gaaval->fix_key = 1; ;}; + return GAA_OK; + break; + case GAAOPTID_pgp_key_info: + OK = 0; +#line 70 "certtool.gaa" +{ gaaval->action = 20; ;}; + return GAA_OK; break; case GAAOPTID_key_info: @@ -1099,7 +1110,7 @@ int gaa(int argc, char **argv, gaainfo *gaaval) if(inited == 0) { -#line 121 "certtool.gaa" +#line 123 "certtool.gaa" { gaaval->bits = 2048; gaaval->pkcs8 = 0; gaaval->privkey = NULL; gaaval->ca=NULL; gaaval->ca_privkey = NULL; gaaval->debug=1; gaaval->request = NULL; gaaval->infile = NULL; gaaval->outfile = NULL; gaaval->cert = NULL; gaaval->incert_format = 0; gaaval->outcert_format = 0; gaaval->action=-1; gaaval->pass = NULL; gaaval->v1_cert = 0; diff --git a/src/certtool-gaa.h b/src/certtool-gaa.h index a7f70bbc6f..ab251cc89e 100644 --- a/src/certtool-gaa.h +++ b/src/certtool-gaa.h @@ -8,33 +8,33 @@ typedef struct _gaainfo gaainfo; struct _gaainfo { -#line 114 "certtool.gaa" +#line 116 "certtool.gaa" int debug; -#line 110 "certtool.gaa" +#line 112 "certtool.gaa" char *template; -#line 107 "certtool.gaa" +#line 109 "certtool.gaa" char *infile; -#line 104 "certtool.gaa" +#line 106 "certtool.gaa" char *outfile; -#line 101 "certtool.gaa" +#line 103 "certtool.gaa" int quick_random; -#line 98 "certtool.gaa" +#line 100 "certtool.gaa" int bits; -#line 95 "certtool.gaa" +#line 97 "certtool.gaa" int outcert_format; -#line 92 "certtool.gaa" +#line 94 "certtool.gaa" int incert_format; -#line 89 "certtool.gaa" +#line 91 "certtool.gaa" int export; -#line 86 "certtool.gaa" +#line 88 "certtool.gaa" char *hash; -#line 83 "certtool.gaa" +#line 85 "certtool.gaa" int dsa; -#line 80 "certtool.gaa" +#line 82 "certtool.gaa" int pkcs8; -#line 73 "certtool.gaa" +#line 75 "certtool.gaa" int v1_cert; -#line 70 "certtool.gaa" +#line 72 "certtool.gaa" int fix_key; #line 53 "certtool.gaa" char *pass; diff --git a/src/certtool.c b/src/certtool.c index ff006ff169..eb0dfb6a50 100644 --- a/src/certtool.c +++ b/src/certtool.c @@ -50,6 +50,7 @@ void generate_pkcs12 (void); void generate_pkcs8 (void); void verify_chain (void); void verify_crl (void); +void pgp_privkey_info (void); gnutls_x509_privkey_t load_private_key (int mand); gnutls_x509_crq_t load_request (void); gnutls_x509_privkey_t load_ca_private_key (void); @@ -66,6 +67,9 @@ void generate_self_signed (void); void generate_request (void); gnutls_x509_crt_t *load_cert_list (int mand, int *size); +static void print_hex_datum (gnutls_datum_t * dat); + + static gaainfo info; FILE *outfile; FILE *infile; @@ -117,6 +121,38 @@ raw_to_string (const unsigned char *raw, size_t raw_size) return buf; } +void print_dsa_pkey (gnutls_datum * x, gnutls_datum * y, gnutls_datum * p, + gnutls_datum * q, gnutls_datum * g) +{ + 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); +} + +void print_rsa_pkey (gnutls_datum * m, gnutls_datum * e, gnutls_datum * d, + gnutls_datum * p, gnutls_datum * q, gnutls_datum * u) +{ + fprintf (outfile, "modulus:"); + print_hex_datum (m); + fprintf (outfile, "public exponent:"); + print_hex_datum (e); + 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); +} + static gnutls_x509_privkey_t generate_private_key_int (void) { @@ -127,8 +163,8 @@ generate_private_key_int (void) { key_type = GNUTLS_PK_DSA; /* FIXME: Remove me once we depend on 1.3.x */ - if (info.bits > 1024 && gcry_check_version("1.3.1")==NULL) - info.bits = 1024; + if (info.bits > 1024 && gcry_check_version ("1.3.1") == NULL) + info.bits = 1024; } else key_type = GNUTLS_PK_RSA; @@ -167,7 +203,8 @@ print_private_key (gnutls_x509_privkey_t key) ret = gnutls_x509_privkey_export (key, info.outcert_format, buffer, &size); if (ret < 0) - error (EXIT_FAILURE, 0, "privkey_export: %s", gnutls_strerror (ret)); + error (EXIT_FAILURE, 0, "privkey_export: %s", + gnutls_strerror (ret)); } else { @@ -184,8 +221,8 @@ print_private_key (gnutls_x509_privkey_t key) size = sizeof (buffer); ret = - gnutls_x509_privkey_export_pkcs8 (key, info.outcert_format, pass, - flags, buffer, &size); + gnutls_x509_privkey_export_pkcs8 (key, info.outcert_format, pass, + flags, buffer, &size); if (ret < 0) error (EXIT_FAILURE, 0, "privkey_export_pkcs8: %s", gnutls_strerror (ret)); @@ -298,10 +335,12 @@ generate_certificate (gnutls_x509_privkey_t * ret_key, days = get_days (); result = - gnutls_x509_crt_set_expiration_time (crt, - time (NULL) + days * 24 * 60 * 60); + gnutls_x509_crt_set_expiration_time (crt, + time (NULL) + + days * 24 * 60 * 60); if (result < 0) - error (EXIT_FAILURE, 0, "set_expiration: %s", gnutls_strerror (result)); + error (EXIT_FAILURE, 0, "set_expiration: %s", + gnutls_strerror (result)); if (!batch) fprintf (stderr, "\n\nExtensions.\n"); @@ -326,8 +365,8 @@ generate_certificate (gnutls_x509_privkey_t * ret_key, policylanguage = get_proxy_policy (&policy, &policylen); result = - gnutls_x509_crt_set_proxy (crt, proxypathlen, policylanguage, - policy, policylen); + gnutls_x509_crt_set_proxy (crt, proxypathlen, policylanguage, + policy, policylen); if (result < 0) error (EXIT_FAILURE, 0, "set_proxy: %s", gnutls_strerror (result)); @@ -341,7 +380,7 @@ generate_certificate (gnutls_x509_privkey_t * ret_key, path_len = -1; result = - gnutls_x509_crt_set_basic_constraints (crt, ca_status, path_len); + gnutls_x509_crt_set_basic_constraints (crt, ca_status, path_len); if (result < 0) error (EXIT_FAILURE, 0, "basic_constraints: %s", gnutls_strerror (result)); @@ -353,7 +392,8 @@ generate_certificate (gnutls_x509_privkey_t * ret_key, GNUTLS_KP_TLS_WWW_CLIENT, 0); if (result < 0) - error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (result)); + error (EXIT_FAILURE, 0, "key_kp: %s", + gnutls_strerror (result)); } server = get_tls_server_status (); @@ -367,7 +407,7 @@ generate_certificate (gnutls_x509_privkey_t * ret_key, if (str != NULL) { result = gnutls_x509_crt_set_subject_alternative_name - (crt, GNUTLS_SAN_DNSNAME, str); + (crt, GNUTLS_SAN_DNSNAME, str); } else { @@ -375,7 +415,7 @@ generate_certificate (gnutls_x509_privkey_t * ret_key, if (str != NULL) { result = gnutls_x509_crt_set_subject_alternative_name - (crt, GNUTLS_SAN_IPADDRESS, str); + (crt, GNUTLS_SAN_IPADDRESS, str); } } @@ -385,10 +425,12 @@ generate_certificate (gnutls_x509_privkey_t * ret_key, } result = - gnutls_x509_crt_set_key_purpose_oid (crt, - GNUTLS_KP_TLS_WWW_SERVER, 0); + gnutls_x509_crt_set_key_purpose_oid (crt, + GNUTLS_KP_TLS_WWW_SERVER, + 0); if (result < 0) - error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (result)); + error (EXIT_FAILURE, 0, "key_kp: %s", + gnutls_strerror (result)); } else if (!proxy) { @@ -397,7 +439,7 @@ generate_certificate (gnutls_x509_privkey_t * ret_key, if (str != NULL) { result = gnutls_x509_crt_set_subject_alternative_name - (crt, GNUTLS_SAN_RFC822NAME, str); + (crt, GNUTLS_SAN_RFC822NAME, str); if (result < 0) error (EXIT_FAILURE, 0, "subject_alt_name: %s", gnutls_strerror (result)); @@ -441,9 +483,9 @@ generate_certificate (gnutls_x509_privkey_t * ret_key, if (result) { result = - gnutls_x509_crt_set_key_purpose_oid (crt, - GNUTLS_KP_CODE_SIGNING, - 0); + gnutls_x509_crt_set_key_purpose_oid (crt, + GNUTLS_KP_CODE_SIGNING, + 0); if (result < 0) error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (result)); @@ -453,9 +495,9 @@ generate_certificate (gnutls_x509_privkey_t * ret_key, if (result) { result = - gnutls_x509_crt_set_key_purpose_oid (crt, - GNUTLS_KP_OCSP_SIGNING, - 0); + gnutls_x509_crt_set_key_purpose_oid (crt, + GNUTLS_KP_OCSP_SIGNING, + 0); if (result < 0) error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (result)); @@ -465,9 +507,9 @@ generate_certificate (gnutls_x509_privkey_t * ret_key, if (result) { result = - gnutls_x509_crt_set_key_purpose_oid (crt, - GNUTLS_KP_TIME_STAMPING, - 0); + gnutls_x509_crt_set_key_purpose_oid (crt, + GNUTLS_KP_TIME_STAMPING, + 0); if (result < 0) error (EXIT_FAILURE, 0, "key_kp: %s", gnutls_strerror (result)); @@ -504,12 +546,13 @@ generate_certificate (gnutls_x509_privkey_t * ret_key, if (result < 0) { size = sizeof (buffer); - result = gnutls_x509_crt_get_key_id (ca_crt, 0, buffer, &size); + result = + gnutls_x509_crt_get_key_id (ca_crt, 0, buffer, &size); } if (result >= 0) { result = - gnutls_x509_crt_set_authority_key_id (crt, buffer, size); + gnutls_x509_crt_set_authority_key_id (crt, buffer, size); if (result < 0) error (EXIT_FAILURE, 0, "set_authority_key_id: %s", gnutls_strerror (result)); @@ -551,7 +594,8 @@ generate_crl (void) { result = gnutls_x509_crl_set_crt (crl, crts[i], now); if (result < 0) - error (EXIT_FAILURE, 0, "crl_set_crt: %s", gnutls_strerror (result)); + error (EXIT_FAILURE, 0, "crl_set_crt: %s", + gnutls_strerror (result)); } result = gnutls_x509_crl_set_this_update (crl, now); @@ -561,7 +605,8 @@ generate_crl (void) fprintf (stderr, "Update times.\n"); days = get_crl_next_update (); - result = gnutls_x509_crl_set_next_update (crl, now + days * 24 * 60 * 60); + result = + gnutls_x509_crl_set_next_update (crl, now + days * 24 * 60 * 60); if (result < 0) error (EXIT_FAILURE, 0, "next_update: %s", gnutls_strerror (result)); @@ -608,7 +653,8 @@ generate_self_signed (void) error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result)); size = sizeof (buffer); - result = gnutls_x509_crt_export (crt, info.outcert_format, buffer, &size); + result = + gnutls_x509_crt_export (crt, info.outcert_format, buffer, &size); if (result < 0) error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result)); @@ -650,7 +696,8 @@ generate_signed_certificate (void) error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result)); size = sizeof (buffer); - result = gnutls_x509_crt_export (crt, info.outcert_format, buffer, &size); + result = + gnutls_x509_crt_export (crt, info.outcert_format, buffer, &size); if (result < 0) error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result)); @@ -684,7 +731,8 @@ generate_proxy_certificate (void) error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result)); size = sizeof (buffer); - result = gnutls_x509_crt_export (crt, info.outcert_format, buffer, &size); + result = + gnutls_x509_crt_export (crt, info.outcert_format, buffer, &size); if (result < 0) error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result)); @@ -742,9 +790,10 @@ update_signed_certificate (void) days = get_days (); result = - gnutls_x509_crt_set_expiration_time (crt, tim + days * 24 * 60 * 60); + gnutls_x509_crt_set_expiration_time (crt, tim + days * 24 * 60 * 60); if (result < 0) - error (EXIT_FAILURE, 0, "set_expiration: %s", gnutls_strerror (result)); + error (EXIT_FAILURE, 0, "set_expiration: %s", + gnutls_strerror (result)); fprintf (stderr, "\n\nSigning certificate...\n"); @@ -753,7 +802,8 @@ update_signed_certificate (void) error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result)); size = sizeof (buffer); - result = gnutls_x509_crt_export (crt, info.outcert_format, buffer, &size); + result = + gnutls_x509_crt_export (crt, info.outcert_format, buffer, &size); if (result < 0) error (EXIT_FAILURE, 0, "crt_export: %s", gnutls_strerror (result)); @@ -899,9 +949,14 @@ gaa_parser (int argc, char **argv) case 18: generate_pkcs8 (); break; +#ifdef ENABLE_OPENPGP case 19: - pgp_certificate_info(); + pgp_certificate_info (); + break; + case 20: + pgp_privkey_info (); break; +#endif default: gaa_help (); exit (0); @@ -923,11 +978,13 @@ certificate_info (void) pem.size = size; crt_num = MAX_CRTS; - ret = gnutls_x509_crt_list_import (crt, &crt_num, &pem, info.incert_format, - GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED); + ret = + gnutls_x509_crt_list_import (crt, &crt_num, &pem, info.incert_format, + GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED); if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { - error (0, 0, "Too many certificates (%d), will only read the first %d.", + error (0, 0, + "Too many certificates (%d), will only read the first %d.", crt_num, MAX_CRTS); crt_num = MAX_CRTS; ret = gnutls_x509_crt_list_import (crt, &crt_num, &pem, @@ -964,6 +1021,8 @@ certificate_info (void) } } +#ifdef ENABLE_OPENPGP + void pgp_certificate_info (void) { @@ -974,8 +1033,8 @@ pgp_certificate_info (void) pem.data = fread_file (infile, &size); pem.size = size; - - ret = gnutls_openpgp_crt_init( &crt); + + ret = gnutls_openpgp_crt_init (&crt); if (ret < 0) error (EXIT_FAILURE, 0, "openpgp_crt_init: %s", gnutls_strerror (ret)); @@ -991,25 +1050,156 @@ pgp_certificate_info (void) ret = gnutls_openpgp_crt_print (crt, 0, &out_data); if (ret == 0) - { - fprintf (outfile, "%s\n", out_data.data); - gnutls_free (out_data.data); - } + { + fprintf (outfile, "%s\n", out_data.data); + gnutls_free (out_data.data); + } } size = sizeof (buffer); - ret = gnutls_openpgp_crt_export (crt, info.outcert_format, buffer, - &size); - if (ret < 0) { - error (EXIT_FAILURE, 0, "Export error: %s", gnutls_strerror (ret)); - fwrite (buffer, 1, size, outfile); - } + ret = + gnutls_openpgp_crt_export (crt, info.outcert_format, buffer, &size); + if (ret < 0) + { + error (EXIT_FAILURE, 0, "Export error: %s", gnutls_strerror (ret)); + fwrite (buffer, 1, size, outfile); + } fprintf (outfile, "%s\n", buffer); - gnutls_openpgp_crt_deinit( crt); + gnutls_openpgp_crt_deinit (crt); } +void +pgp_privkey_info (void) +{ + gnutls_openpgp_privkey_t key; + gnutls_openpgp_keyid_t keyid; + size_t size; + int ret, i, subkeys; + gnutls_datum_t pem; + const char *cprint; + const char *pass; + + size = fread (buffer, 1, sizeof (buffer) - 1, infile); + buffer[size] = 0; + + gnutls_openpgp_privkey_init (&key); + + pem.data = buffer; + pem.size = size; + + ret = + gnutls_openpgp_privkey_import (key, &pem, info.incert_format, NULL, + 0); + + if (ret < 0) + error (EXIT_FAILURE, 0, "Import error: %s", gnutls_strerror (ret)); + + /* Public key algorithm + */ + subkeys = gnutls_openpgp_privkey_get_subkey_count (key); + if (subkeys < 0) + error (EXIT_FAILURE, 0, "privkey_get_subkey_count: %s", + gnutls_strerror (subkeys)); + + for (i = -1; i < subkeys; i++) + { + + if (i != -1) + fprintf (outfile, "Subkey[%d]:\n", i); + + fprintf (outfile, "Public Key Info:\n"); + + if (i == -1) + ret = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL); + else + ret = + gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, i, NULL); + + fprintf (outfile, "\tPublic Key Algorithm: "); + + cprint = gnutls_pk_algorithm_get_name (ret); + if (cprint == NULL) + cprint = UNKNOWN; + fprintf (outfile, "%s\n", cprint); + + /* Print the raw public and private keys + */ + + if (ret == GNUTLS_PK_RSA) + { + gnutls_datum_t m, e, d, p, q, u; + + if (i == -1) + ret = + gnutls_openpgp_privkey_export_rsa_raw (key, &m, &e, &d, &p, + &q, &u); + else + ret = + gnutls_openpgp_privkey_export_subkey_rsa_raw (key, i, &m, + &e, &d, &p, + &q, &u); + if (ret < 0) + fprintf (stderr, "Error in key RSA data export: %s\n", + gnutls_strerror (ret)); + else + print_rsa_pkey (&m, &e, &d, &p, &q, &u); + + } + else if (ret == GNUTLS_PK_DSA) + { + gnutls_datum_t p, q, g, y, x; + + if (i == -1) + ret = + gnutls_openpgp_privkey_export_dsa_raw (key, &p, &q, &g, &y, + &x); + else + ret = + gnutls_openpgp_privkey_export_subkey_dsa_raw (key, i, &p, + &q, &g, &y, + &x); + if (ret < 0) + fprintf (stderr, "Error in key DSA data export: %s\n", + gnutls_strerror (ret)); + else + print_dsa_pkey (&x, &y, &p, &q, &g); + } + + fprintf (outfile, "\n"); + + size = sizeof (buffer); + if (i == -1) + ret = gnutls_openpgp_privkey_get_key_id (key, &keyid); + else + ret = gnutls_openpgp_privkey_get_subkey_id (key, i, &keyid); + + if (ret < 0) + { + fprintf (stderr, "Error in key id calculation: %s\n", + gnutls_strerror (ret)); + } + else + { + fprintf (outfile, "Public Key ID: %s\n", + raw_to_string (keyid.keyid, 8)); + } + + } + + size = sizeof (buffer); + ret = + gnutls_openpgp_privkey_export (key, GNUTLS_OPENPGP_FMT_BASE64, + buffer, &size); + if (ret < 0) + error (EXIT_FAILURE, 0, "Export error: %s", gnutls_strerror (ret)); + + fprintf (outfile, "\n%s\n", buffer); +} + +#endif + static void print_hex_datum (gnutls_datum_t * dat) { @@ -1027,7 +1217,8 @@ print_hex_datum (gnutls_datum_t * dat) static void -print_certificate_info (gnutls_x509_crt_t crt, FILE * out, unsigned int all) +print_certificate_info (gnutls_x509_crt_t crt, FILE * out, + unsigned int all) { gnutls_datum_t info; int ret; @@ -1035,7 +1226,8 @@ print_certificate_info (gnutls_x509_crt_t crt, FILE * out, unsigned int all) if (all) ret = gnutls_x509_crt_print (crt, GNUTLS_X509_CRT_FULL, &info); else - ret = gnutls_x509_crt_print (crt, GNUTLS_X509_CRT_UNSIGNED_FULL, &info); + ret = + gnutls_x509_crt_print (crt, GNUTLS_X509_CRT_UNSIGNED_FULL, &info); if (ret == 0) { fprintf (out, "%s\n", info.data); @@ -1120,7 +1312,7 @@ privkey_info (void) ret = 0; if (!info.pkcs8) - ret = gnutls_x509_privkey_import (key, &pem, info.incert_format); + ret = gnutls_x509_privkey_import (key, &pem, info.incert_format); /* If we failed to import the certificate previously try PKCS #8 */ if (info.pkcs8 || ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) @@ -1129,8 +1321,9 @@ privkey_info (void) pass = info.pass; else pass = get_pass (); - ret = gnutls_x509_privkey_import_pkcs8 (key, &pem, info.incert_format, - pass, 0); + ret = + gnutls_x509_privkey_import_pkcs8 (key, &pem, info.incert_format, + pass, 0); } if (ret < 0) error (EXIT_FAILURE, 0, "Import error: %s", gnutls_strerror (ret)); @@ -1152,25 +1345,13 @@ privkey_info (void) { gnutls_datum_t m, e, d, p, q, u; - ret = gnutls_x509_privkey_export_rsa_raw (key, &m, &e, &d, &p, &q, &u); + ret = + gnutls_x509_privkey_export_rsa_raw (key, &m, &e, &d, &p, &q, &u); if (ret < 0) - { - fprintf (stderr, "Error in key RSA data export: %s\n", - gnutls_strerror (ret)); - } - - fprintf (outfile, "modulus:"); - print_hex_datum (&m); - fprintf (outfile, "public exponent:"); - print_hex_datum (&e); - 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); + fprintf (stderr, "Error in key RSA data export: %s\n", + gnutls_strerror (ret)); + else + print_rsa_pkey (&m, &e, &d, &p, &q, &u); } else if (ret == GNUTLS_PK_DSA) @@ -1179,21 +1360,10 @@ privkey_info (void) ret = gnutls_x509_privkey_export_dsa_raw (key, &p, &q, &g, &y, &x); if (ret < 0) - { - fprintf (stderr, "Error in key DSA data export: %s\n", - gnutls_strerror (ret)); - } - - 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); + fprintf (stderr, "Error in key DSA data export: %s\n", + gnutls_strerror (ret)); + else + print_dsa_pkey (&x, &y, &p, &q, &g); } fprintf (outfile, "\n"); @@ -1206,7 +1376,8 @@ privkey_info (void) } else { - fprintf (outfile, "Public Key ID: %s\n", raw_to_string (buffer, size)); + fprintf (outfile, "Public Key ID: %s\n", + raw_to_string (buffer, size)); } if (info.fix_key != 0) @@ -1217,13 +1388,15 @@ privkey_info (void) } size = sizeof (buffer); - ret = gnutls_x509_privkey_export (key, GNUTLS_X509_FMT_PEM, buffer, &size); + ret = + gnutls_x509_privkey_export (key, 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); } + /* Load the private key. * @mand should be non zero if it is required to read a private key. */ @@ -1249,22 +1422,26 @@ load_private_key (int mand) dat.size = size; if (!dat.data) - error (EXIT_FAILURE, errno, "reading --load-privkey: %s", info.privkey); + error (EXIT_FAILURE, errno, "reading --load-privkey: %s", + info.privkey); if (info.pkcs8) { const char *pass = get_pass (); - ret = gnutls_x509_privkey_import_pkcs8 (key, &dat, info.incert_format, - pass, 0); + ret = + gnutls_x509_privkey_import_pkcs8 (key, &dat, info.incert_format, + pass, 0); } else ret = gnutls_x509_privkey_import (key, &dat, info.incert_format); free (dat.data); - if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) { - error (EXIT_FAILURE, 0, "Import error: Could not find a valid PEM header. Check if your key is PKCS #8 or PKCS #12 encoded."); - } + if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) + { + error (EXIT_FAILURE, 0, + "Import error: Could not find a valid PEM header. Check if your key is PKCS #8 or PKCS #12 encoded."); + } if (ret < 0) error (EXIT_FAILURE, 0, "importing --load-privkey: %s: %s", @@ -1294,12 +1471,15 @@ load_request (void) dat.size = size; if (!dat.data) - error (EXIT_FAILURE, errno, "reading --load-request: %s", info.request); + error (EXIT_FAILURE, errno, "reading --load-request: %s", + info.request); ret = gnutls_x509_crq_import (crq, &dat, info.incert_format); - if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) { - error (EXIT_FAILURE, 0, "Import error: Could not find a valid PEM header."); - } + if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) + { + error (EXIT_FAILURE, 0, + "Import error: Could not find a valid PEM header."); + } free (dat.data); if (ret < 0) @@ -1336,8 +1516,9 @@ load_ca_private_key (void) if (info.pkcs8) { const char *pass = get_pass (); - ret = gnutls_x509_privkey_import_pkcs8 (key, &dat, info.incert_format, - pass, 0); + ret = + gnutls_x509_privkey_import_pkcs8 (key, &dat, info.incert_format, + pass, 0); } else ret = gnutls_x509_privkey_import (key, &dat, info.incert_format); @@ -1370,7 +1551,8 @@ load_ca_cert (void) dat.size = size; if (!dat.data) - error (EXIT_FAILURE, errno, "reading --load-ca-certificate: %s", info.ca); + error (EXIT_FAILURE, errno, "reading --load-ca-certificate: %s", + info.ca); ret = gnutls_x509_crt_import (crt, &dat, info.incert_format); free (dat.data); @@ -1456,7 +1638,8 @@ load_cert_list (int mand, int *crt_size) ptr_size = size; ptr_size -= - (unsigned int) ((unsigned char *) ptr - (unsigned char *) buffer); + (unsigned int) ((unsigned char *) ptr - + (unsigned char *) buffer); if (ptr_size < 0) break; @@ -1573,15 +1756,16 @@ _verify_x509_mem (const void *cert, int cert_size) do { x509_crl_list = - (gnutls_x509_crl_t *) realloc (x509_crl_list, - i * sizeof (gnutls_x509_crl_t)); + (gnutls_x509_crl_t *) realloc (x509_crl_list, + i * sizeof (gnutls_x509_crl_t)); if (x509_crl_list == NULL) error (EXIT_FAILURE, 0, "memory error"); tmp.data = (char *) ptr; tmp.size = cert_size; tmp.size -= - (unsigned int) ((unsigned char *) ptr - (unsigned char *) cert); + (unsigned int) ((unsigned char *) ptr - + (unsigned char *) cert); ret = gnutls_x509_crl_init (&x509_crl_list[i - 1]); if (ret < 0) @@ -1616,8 +1800,8 @@ _verify_x509_mem (const void *cert, int cert_size) do { x509_cert_list = - (gnutls_x509_crt_t *) realloc (x509_cert_list, - i * sizeof (gnutls_x509_crt_t)); + (gnutls_x509_crt_t *) realloc (x509_cert_list, + i * sizeof (gnutls_x509_crt_t)); if (x509_cert_list == NULL) error (EXIT_FAILURE, 0, "memory error"); @@ -1625,7 +1809,7 @@ _verify_x509_mem (const void *cert, int cert_size) tmp.data = (char *) ptr; tmp.size = cert_size; tmp.size -= - (unsigned int) ((unsigned char *) ptr - (unsigned char *) cert); + (unsigned int) ((unsigned char *) ptr - (unsigned char *) cert); ret = gnutls_x509_crt_init (&x509_cert_list[i - 1]); if (ret < 0) @@ -1633,8 +1817,8 @@ _verify_x509_mem (const void *cert, int cert_size) gnutls_strerror (ret)); ret = - gnutls_x509_crt_import (x509_cert_list[i - 1], &tmp, - GNUTLS_X509_FMT_PEM); + gnutls_x509_crt_import (x509_cert_list[i - 1], &tmp, + GNUTLS_X509_FMT_PEM); if (ret < 0) error (EXIT_FAILURE, 0, "Error parsing the certificate[%d]: %s", i, gnutls_strerror (ret)); @@ -1648,7 +1832,8 @@ _verify_x509_mem (const void *cert, int cert_size) name_size = sizeof (name); ret = - gnutls_x509_crt_get_dn (x509_cert_list[i - 2], name, &name_size); + gnutls_x509_crt_get_dn (x509_cert_list[i - 2], name, + &name_size); if (ret < 0) error (EXIT_FAILURE, 0, "get_dn: %s", gnutls_strerror (ret)); @@ -1658,8 +1843,9 @@ _verify_x509_mem (const void *cert, int cert_size) */ issuer_name_size = sizeof (issuer_name); ret = - gnutls_x509_crt_get_issuer_dn (x509_cert_list[i - 2], - issuer_name, &issuer_name_size); + gnutls_x509_crt_get_issuer_dn (x509_cert_list[i - 2], + issuer_name, + &issuer_name_size); if (ret < 0) error (EXIT_FAILURE, 0, "get_issuer_dn: %s", gnutls_strerror (ret)); @@ -1670,11 +1856,13 @@ _verify_x509_mem (const void *cert, int cert_size) */ name_size = sizeof (name); ret = - gnutls_x509_crt_get_dn (x509_cert_list[i - 1], name, &name_size); + gnutls_x509_crt_get_dn (x509_cert_list[i - 1], name, + &name_size); if (ret < 0) error (EXIT_FAILURE, 0, "get_dn: %s", gnutls_strerror (ret)); - fprintf (outfile, "\tVerifying against certificate[%d].\n", i - 1); + fprintf (outfile, "\tVerifying against certificate[%d].\n", + i - 1); if (strcmp (issuer_name, name) != 0) { @@ -1719,8 +1907,8 @@ _verify_x509_mem (const void *cert, int cert_size) */ issuer_name_size = sizeof (issuer_name); ret = - gnutls_x509_crt_get_issuer_dn (x509_cert_list[x509_ncerts - 1], - issuer_name, &issuer_name_size); + gnutls_x509_crt_get_issuer_dn (x509_cert_list[x509_ncerts - 1], + issuer_name, &issuer_name_size); if (ret < 0) error (EXIT_FAILURE, 0, "get_issuer_dn: %s", gnutls_strerror (ret)); @@ -1884,7 +2072,8 @@ verify_crl (void) fprintf (outfile, "Verification output: "); ret = gnutls_x509_crl_verify (crl, &issuer, 1, 0, &output); if (ret < 0) - error (EXIT_FAILURE, 0, "Verification error: %s", gnutls_strerror (ret)); + error (EXIT_FAILURE, 0, "Verification error: %s", + gnutls_strerror (ret)); if (output & GNUTLS_CERT_INVALID) { @@ -1942,7 +2131,7 @@ generate_pkcs8 (void) int result; size_t size; int flags = 0; - const char* password; + const char *password; fprintf (stderr, "Generating a PKCS #8 key structure...\n"); @@ -1957,19 +2146,20 @@ generate_pkcs8 (void) flags = GNUTLS_PKCS_USE_PKCS12_RC2_40; else flags = GNUTLS_PKCS_USE_PKCS12_3DES; - - if (password == NULL || password[0] == 0) { - flags = GNUTLS_PKCS_PLAIN; - } + + if (password == NULL || password[0] == 0) + { + flags = GNUTLS_PKCS_PLAIN; + } size = sizeof (buffer); result = - gnutls_x509_privkey_export_pkcs8 (key, info.outcert_format, - password, flags, buffer, &size); + gnutls_x509_privkey_export_pkcs8 (key, info.outcert_format, + password, flags, buffer, &size); if (result < 0) - error (EXIT_FAILURE, 0, "key_export: %s", gnutls_strerror (result)); + error (EXIT_FAILURE, 0, "key_export: %s", gnutls_strerror (result)); fwrite (buffer, 1, size, outfile); @@ -2054,7 +2244,8 @@ generate_pkcs12 (void) result = gnutls_pkcs12_bag_encrypt (bag, password, flags); if (result < 0) - error (EXIT_FAILURE, 0, "bag_encrypt: %s", gnutls_strerror (result)); + error (EXIT_FAILURE, 0, "bag_encrypt: %s", + gnutls_strerror (result)); result = gnutls_pkcs12_set_bag (pkcs12, bag); if (result < 0) @@ -2076,18 +2267,22 @@ generate_pkcs12 (void) size = sizeof (buffer); result = - gnutls_x509_privkey_export_pkcs8 (key, GNUTLS_X509_FMT_DER, - password, flags, buffer, &size); + gnutls_x509_privkey_export_pkcs8 (key, GNUTLS_X509_FMT_DER, + password, flags, buffer, + &size); if (result < 0) - error (EXIT_FAILURE, 0, "key_export: %s", gnutls_strerror (result)); + error (EXIT_FAILURE, 0, "key_export: %s", + gnutls_strerror (result)); data.data = buffer; data.size = size; result = - gnutls_pkcs12_bag_set_data (kbag, - GNUTLS_BAG_PKCS8_ENCRYPTED_KEY, &data); + gnutls_pkcs12_bag_set_data (kbag, + GNUTLS_BAG_PKCS8_ENCRYPTED_KEY, + &data); if (result < 0) - error (EXIT_FAILURE, 0, "bag_set_data: %s", gnutls_strerror (result)); + error (EXIT_FAILURE, 0, "bag_set_data: %s", + gnutls_strerror (result)); index = result; @@ -2119,7 +2314,8 @@ generate_pkcs12 (void) error (EXIT_FAILURE, 0, "generate_mac: %s", gnutls_strerror (result)); size = sizeof (buffer); - result = gnutls_pkcs12_export (pkcs12, info.outcert_format, buffer, &size); + result = + gnutls_pkcs12_export (pkcs12, info.outcert_format, buffer, &size); if (result < 0) error (EXIT_FAILURE, 0, "pkcs12_export: %s", gnutls_strerror (result)); @@ -2173,7 +2369,8 @@ print_bag_data (gnutls_pkcs12_bag_t bag) fprintf (stderr, "\tType: %s\n", BAGTYPE (type)); name = NULL; - result = gnutls_pkcs12_bag_get_friendly_name (bag, i, (char **) &name); + result = + gnutls_pkcs12_bag_get_friendly_name (bag, i, (char **) &name); if (result < 0) error (EXIT_FAILURE, 0, "get_friendly_name: %s", gnutls_strerror (type)); @@ -2185,7 +2382,8 @@ print_bag_data (gnutls_pkcs12_bag_t bag) result = gnutls_pkcs12_bag_get_key_id (bag, i, &id); if (result < 0) error (EXIT_FAILURE, 0, "get_key_id: %s", gnutls_strerror (type)); - fprintf (outfile, "\tKey ID: %s\n", raw_to_string (id.data, id.size)); + fprintf (outfile, "\tKey ID: %s\n", + raw_to_string (id.data, id.size)); result = gnutls_pkcs12_bag_get_data (bag, i, &cdata); if (result < 0) @@ -2396,7 +2594,8 @@ smime_to_pkcs7 (void) { len = getline (&lineptr, &linesize, infile); if (len == -1) - error (EXIT_FAILURE, 0, "Cannot find RFC 2822 header/body separator"); + error (EXIT_FAILURE, 0, + "Cannot find RFC 2822 header/body separator"); } while (strcmp (lineptr, "\r\n") != 0 && strcmp (lineptr, "\n") != 0); diff --git a/src/certtool.gaa b/src/certtool.gaa index 9575ab4184..75695a3856 100644 --- a/src/certtool.gaa +++ b/src/certtool.gaa @@ -67,6 +67,8 @@ option (smime-to-p7) { $action = 15; } "Convert S/MIME to PKCS #7 structure." option (k, key-info) { $action = 6; } "Print information on a private key." +option (pgp-key-info) { $action = 20; } "Print information on a OpenPGP private key." + #int fix_key; option (fix-key) { $fix_key = 1; } "Regenerate the parameters in a private key."