summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2003-10-26 14:33:39 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2003-10-26 14:33:39 +0000
commit20f83df02d4910ccf791ed799aabee29c34509e4 (patch)
treee74aaf304110ab25a7083a474e290a96cdebd8c8
parenta151e388e3af2dc519e90ceb19f4061aa1799a77 (diff)
downloadgnutls-20f83df02d4910ccf791ed799aabee29c34509e4.tar.gz
Added capability to print the keyid of a certificate or a private key to certtool. Updated the key_id functions to return the hash of the SubjectPublicKey.
-rw-r--r--lib/gnutls_x509.c35
-rw-r--r--lib/x509/common.c19
-rw-r--r--lib/x509/mpi.c94
-rw-r--r--lib/x509/mpi.h4
-rw-r--r--lib/x509/privkey.c252
-rw-r--r--lib/x509/privkey.h4
-rw-r--r--lib/x509/x509.c53
-rw-r--r--lib/x509_b64.c2
-rw-r--r--src/certtool-gaa.c75
-rw-r--r--src/certtool-gaa.h6
-rw-r--r--src/certtool.c140
-rw-r--r--src/certtool.gaa8
12 files changed, 372 insertions, 320 deletions
diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c
index b90c70dfef..af0e47b436 100644
--- a/lib/gnutls_x509.c
+++ b/lib/gnutls_x509.c
@@ -153,9 +153,8 @@ int _gnutls_x509_cert_verify_peers(gnutls_session session)
*/
static int _gnutls_check_key_cert_match( gnutls_certificate_credentials res)
{
-opaque cid[20];
-opaque kid[20];
-int cid_size, kid_size;
+gnutls_datum cid;
+gnutls_datum kid;
uint pk = res->cert_list[res->ncerts-1][0].subject_pk_algorithm;
if (res->pkey[res->ncerts-1].pk_algorithm != pk)
@@ -165,29 +164,37 @@ uint pk = res->cert_list[res->ncerts-1][0].subject_pk_algorithm;
}
if (pk == GNUTLS_PK_RSA) {
- kid_size = sizeof(kid);
- _gnutls_x509_hash_rsa_key( res->pkey[res->ncerts-1].params, kid, &kid_size);
+ _gnutls_x509_write_rsa_params( res->pkey[res->ncerts-1].params,
+ res->pkey[res->ncerts-1].params_size, &kid);
- cid_size = sizeof(cid);
- _gnutls_x509_hash_rsa_key( res->cert_list[res->ncerts-1][0].params, cid, &cid_size);
+
+ _gnutls_x509_write_rsa_params( res->cert_list[res->ncerts-1][0].params,
+ res->cert_list[res->ncerts-1][0].params_size, &cid);
} else if ( pk == GNUTLS_PK_DSA) {
- kid_size = sizeof(kid);
- _gnutls_x509_hash_dsa_key( res->pkey[res->ncerts-1].params, kid, &kid_size);
- cid_size = sizeof(cid);
- _gnutls_x509_hash_dsa_key( res->cert_list[res->ncerts-1][0].params, cid, &cid_size);
+ _gnutls_x509_write_dsa_params( res->pkey[res->ncerts-1].params,
+ res->pkey[res->ncerts-1].params_size, &kid);
+
+ _gnutls_x509_write_dsa_params( res->cert_list[res->ncerts-1][0].params,
+ res->cert_list[res->ncerts-1][0].params_size, &cid);
}
- if (cid_size != kid_size) {
+ if (cid.size != kid.size) {
gnutls_assert();
+ _gnutls_free_datum( &kid);
+ _gnutls_free_datum( &cid);
return GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
}
- if (memcmp( kid, cid, kid_size) != 0) {
+ if (memcmp( kid.data, cid.data, kid.size) != 0) {
gnutls_assert();
+ _gnutls_free_datum( &kid);
+ _gnutls_free_datum( &cid);
return GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
}
+ _gnutls_free_datum( &kid);
+ _gnutls_free_datum( &cid);
return 0;
}
@@ -908,7 +915,7 @@ int gnutls_certificate_set_x509_key_file(gnutls_certificate_credentials res, con
static int generate_rdn_seq( gnutls_certificate_credentials res)
{
-gnutls_const_datum tmp;
+gnutls_datum tmp;
gnutls_datum _tmp;
int ret;
uint size, i;
diff --git a/lib/x509/common.c b/lib/x509/common.c
index 35978e574c..9c9c68c5b7 100644
--- a/lib/x509/common.c
+++ b/lib/x509/common.c
@@ -927,8 +927,8 @@ int _gnutls_x509_encode_and_copy_PKI_params( ASN1_TYPE dst, const char* dst_name
gnutls_pk_algorithm pk_algorithm, GNUTLS_MPI* params, int params_size)
{
const char* pk;
-opaque * der;
-int der_size, result;
+gnutls_datum der = {NULL, 0};
+int result;
char name[128];
if (pk_algorithm != GNUTLS_PK_RSA) {
@@ -962,18 +962,9 @@ char name[128];
return _gnutls_asn2err(result);
}
- _gnutls_x509_write_rsa_params( params, params_size, NULL, &der_size);
-
- der = gnutls_alloca( der_size);
- if (der == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- result = _gnutls_x509_write_rsa_params( params, params_size, der, &der_size);
+ result = _gnutls_x509_write_rsa_params( params, params_size, &der);
if (result < 0) {
gnutls_assert();
- gnutls_afree(der);
return result;
}
@@ -981,9 +972,9 @@ char name[128];
*/
_gnutls_str_cpy( name, sizeof(name), dst_name);
_gnutls_str_cat( name, sizeof(name), ".subjectPublicKey");
- result = asn1_write_value( dst, name, der, der_size*8);
+ result = asn1_write_value( dst, name, der.data, der.size*8);
- gnutls_afree(der);
+ _gnutls_free_datum(&der);
if (result != ASN1_SUCCESS) {
gnutls_assert();
diff --git a/lib/x509/mpi.c b/lib/x509/mpi.c
index 181aec9c0c..2eb76bb064 100644
--- a/lib/x509/mpi.c
+++ b/lib/x509/mpi.c
@@ -23,6 +23,7 @@
#include <gnutls_errors.h>
#include <gnutls_global.h>
#include <libtasn1.h>
+#include <gnutls_datum.h>
#include "common.h"
#include "x509.h"
#include <gnutls_num.h>
@@ -277,13 +278,24 @@ int pk_algorithm;
* some x509 certificate functions that relate to MPI parameter
* setting. This writes the BIT STRING subjectPublicKey.
* Needs 2 parameters (m,e).
+ *
+ * Allocates the space used to store the DER data.
*/
int _gnutls_x509_write_rsa_params( GNUTLS_MPI * params, int params_size,
- opaque * der, int* dersize)
+ gnutls_datum* der)
{
int result;
ASN1_TYPE spk = ASN1_TYPE_EMPTY;
+ der->data = NULL;
+ der->size = 0;
+
+ if (params_size < 2) {
+ gnutls_assert();
+ result = GNUTLS_E_INVALID_REQUEST;
+ goto cleanup;
+ }
+
if ((result=asn1_create_element
(_gnutls_get_gnutls_asn(), "GNUTLS.RSAPublicKey", &spk))
!= ASN1_SUCCESS) {
@@ -291,36 +303,94 @@ int _gnutls_x509_write_rsa_params( GNUTLS_MPI * params, int params_size,
return _gnutls_asn2err(result);
}
- if (params_size < 2) {
+ result = _gnutls_x509_write_int( spk, "modulus", params[0], 0);
+ if (result < 0) {
gnutls_assert();
- return GNUTLS_E_INVALID_REQUEST;
+ goto cleanup;
}
- result = _gnutls_x509_write_int( spk, "modulus", params[0], 0);
+ result = _gnutls_x509_write_int( spk, "publicExponent", params[1], 0);
if (result < 0) {
gnutls_assert();
- return result;
+ goto cleanup;
}
- result = _gnutls_x509_write_int( spk, "publicExponent", params[1], 0);
+ result = _gnutls_x509_der_encode( spk, "", der, 0);
if (result < 0) {
gnutls_assert();
- return result;
+ goto cleanup;
}
+
+ asn1_delete_structure(&spk);
+ return 0;
+
+cleanup:
+ asn1_delete_structure(&spk);
- if (der == NULL) *dersize = 0;
- result = asn1_der_coding( spk, "", der, dersize, NULL);
+ return result;
+}
- asn1_delete_structure(&spk);
+/*
+ * This function writes the BIT STRING subjectPublicKey for DSS keys.
+ * Needs 3 parameters (p,q,g).
+ *
+ * Allocates the space used to store the DER data.
+ */
+int _gnutls_x509_write_dsa_params( GNUTLS_MPI * params, int params_size,
+ gnutls_datum* der)
+{
+ int result;
+ ASN1_TYPE spk = ASN1_TYPE_EMPTY;
- if (result != ASN1_SUCCESS) {
+ der->data = NULL;
+ der->size = 0;
+
+ if (params_size < 3) {
+ gnutls_assert();
+ result = GNUTLS_E_INVALID_REQUEST;
+ goto cleanup;
+ }
+
+ if ((result=asn1_create_element
+ (_gnutls_get_gnutls_asn(), "GNUTLS.DSAParameters", &spk))
+ != ASN1_SUCCESS) {
+ gnutls_assert();
return _gnutls_asn2err(result);
}
- return 0;
+ result = _gnutls_x509_write_int( spk, "p", params[0], 0);
+ if (result < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ result = _gnutls_x509_write_int( spk, "q", params[1], 0);
+ if (result < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+ result = _gnutls_x509_write_int( spk, "g", params[2], 0);
+ if (result < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ result = _gnutls_x509_der_encode( spk, "", der, 0);
+ if (result < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ asn1_delete_structure(&spk);
+ return 0;
+
+cleanup:
+ asn1_delete_structure(&spk);
+ return result;
}
+
/* this function reads a (small) unsigned integer
* from asn1 structs. Combines the read and the convertion
* steps.
diff --git a/lib/x509/mpi.h b/lib/x509/mpi.h
index 9f27800f4e..471a01c8de 100644
--- a/lib/x509/mpi.h
+++ b/lib/x509/mpi.h
@@ -7,7 +7,9 @@ int _gnutls_x509_read_dsa_pubkey(opaque * der, int dersize, GNUTLS_MPI * params)
int _gnutls_x509_read_dsa_params(opaque * der, int dersize, GNUTLS_MPI * params);
int _gnutls_x509_write_rsa_params( GNUTLS_MPI * params, int params_size,
- opaque * der, int* dersize);
+ gnutls_datum* der);
+int _gnutls_x509_write_dsa_params( GNUTLS_MPI * params, int params_size,
+ gnutls_datum* der);
int _gnutls_x509_read_uint( ASN1_TYPE node, const char* value,
unsigned int* ret);
diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c
index d41e294915..034a60c966 100644
--- a/lib/x509/privkey.c
+++ b/lib/x509/privkey.c
@@ -850,211 +850,6 @@ int ret;
return ret;
}
-
-/* Hashes the public parameters of an RSA key.
- */
-int _gnutls_x509_hash_rsa_key( GNUTLS_MPI * params,
- unsigned char* output_data, int* output_data_size)
-{
-
-opaque* mod = NULL, *exp = NULL;
-size_t mod_size, exp_size;
-int ret = 0;
-GNUTLS_HASH_HANDLE hd;
-opaque algo = GNUTLS_PK_RSA;
-
- if ( *output_data_size < _gnutls_hash_get_algo_len( GNUTLS_MAC_SHA)) {
- gnutls_assert();
- *output_data_size = _gnutls_hash_get_algo_len( GNUTLS_MAC_SHA);
- return GNUTLS_E_SHORT_MEMORY_BUFFER;
- }
-
- /* get the size of modulus and the public
- * exponent.
- */
-
- _gnutls_mpi_print( NULL, &mod_size, params[0]);
-
- mod = gnutls_malloc( mod_size);
- if (mod == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- if (_gnutls_mpi_print( mod, &mod_size, params[0]) != 0) {
- gnutls_assert();
- ret = GNUTLS_E_MPI_PRINT_FAILED;
- goto error;
- }
-
- _gnutls_mpi_print( NULL, &exp_size, params[1]);
-
- exp = gnutls_malloc( exp_size);
- if (exp == NULL) {
- gnutls_assert();
- ret = GNUTLS_E_MEMORY_ERROR;
- goto error;
- }
-
- if (_gnutls_mpi_print( exp, &exp_size, params[1]) != 0) {
- gnutls_assert();
- ret = GNUTLS_E_MPI_PRINT_FAILED;
- goto error;
- }
-
- /* hash the parameters.
- */
-
- hd = _gnutls_hash_init( GNUTLS_MAC_SHA);
- if (hd == GNUTLS_HASH_FAILED) {
- gnutls_assert();
- ret = GNUTLS_E_INTERNAL_ERROR;
- goto error;
- }
-
- _gnutls_hash( hd, &algo, 1);
- _gnutls_hash( hd, mod, mod_size);
- _gnutls_hash( hd, exp, exp_size);
-
- _gnutls_hash_deinit( hd, output_data);
-
- gnutls_free( mod);
- gnutls_free( exp);
-
- *output_data_size = _gnutls_hash_get_algo_len( GNUTLS_MAC_SHA);
-
- return 0;
-
- error:
- gnutls_free( mod);
- gnutls_free( exp);
-
- return ret;
-}
-
-/* Hashes the public parameters of a DSA key.
- */
-int _gnutls_x509_hash_dsa_key( GNUTLS_MPI * params,
- unsigned char* output_data, int* output_data_size)
-{
-
-opaque* p = NULL, *q = NULL;
-opaque* g = NULL, *y = NULL;
-size_t p_size, q_size;
-size_t g_size, y_size;
-int ret = 0;
-GNUTLS_HASH_HANDLE hd;
-opaque algo = GNUTLS_PK_DSA;
-
- if ( *output_data_size < _gnutls_hash_get_algo_len( GNUTLS_MAC_SHA)) {
- gnutls_assert();
- *output_data_size = _gnutls_hash_get_algo_len( GNUTLS_MAC_SHA);
- return GNUTLS_E_SHORT_MEMORY_BUFFER;
- }
-
- /* get the size of modulus and the public
- * exponent.
- */
-
- _gnutls_mpi_print( NULL, &p_size, params[0]);
-
- p = gnutls_malloc( p_size);
- if (p == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- if (_gnutls_mpi_print( p, &p_size, params[0]) != 0) {
- gnutls_assert();
- ret = GNUTLS_E_MPI_PRINT_FAILED;
- goto error;
- }
-
- /* Read q.
- */
- _gnutls_mpi_print( NULL, &q_size, params[1]);
-
- q = gnutls_malloc( q_size);
- if (q == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- if (_gnutls_mpi_print( q, &q_size, params[1]) != 0) {
- gnutls_assert();
- ret = GNUTLS_E_MPI_PRINT_FAILED;
- goto error;
- }
-
- /* Read g.
- */
- _gnutls_mpi_print( NULL, &g_size, params[2]);
-
- g = gnutls_malloc( g_size);
- if (g == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- if (_gnutls_mpi_print( g, &g_size, params[2]) != 0) {
- gnutls_assert();
- ret = GNUTLS_E_MPI_PRINT_FAILED;
- goto error;
- }
-
- /* Read y.
- */
- _gnutls_mpi_print( NULL, &y_size, params[3]);
-
- y = gnutls_malloc( y_size);
- if (y == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- if (_gnutls_mpi_print( y, &y_size, params[3]) != 0) {
- gnutls_assert();
- ret = GNUTLS_E_MPI_PRINT_FAILED;
- goto error;
- }
-
-
- /* hash the parameters.
- */
-
- hd = _gnutls_hash_init( GNUTLS_MAC_SHA);
- if (hd == GNUTLS_HASH_FAILED) {
- gnutls_assert();
- ret = GNUTLS_E_INTERNAL_ERROR;
- goto error;
- }
-
- _gnutls_hash( hd, &algo, 1);
- _gnutls_hash( hd, p, p_size);
- _gnutls_hash( hd, q, q_size);
- _gnutls_hash( hd, g, g_size);
- _gnutls_hash( hd, y, y_size);
-
- _gnutls_hash_deinit( hd, output_data);
-
- gnutls_free( p);
- gnutls_free( q);
- gnutls_free( g);
- gnutls_free( y);
-
- *output_data_size = _gnutls_hash_get_algo_len( GNUTLS_MAC_SHA);
-
- return 0;
-
- error:
- gnutls_free( p);
- gnutls_free( q);
- gnutls_free( g);
- gnutls_free( y);
-
- return ret;
-}
-
/**
* gnutls_x509_privkey_get_key_id - This function will return a unique ID of the key's parameters
* @key: Holds the key
@@ -1077,12 +872,45 @@ opaque algo = GNUTLS_PK_DSA;
int gnutls_x509_privkey_get_key_id( gnutls_x509_privkey key, unsigned int flags,
unsigned char* output_data, size_t* output_data_size)
{
-
- if (key->pk_algorithm == GNUTLS_PK_RSA)
- return _gnutls_x509_hash_rsa_key( key->params, output_data, output_data_size);
- else if (key->pk_algorithm == GNUTLS_PK_DSA)
- return _gnutls_x509_hash_dsa_key( key->params, output_data, output_data_size);
- else return GNUTLS_E_INTERNAL_ERROR;
+int result;
+GNUTLS_HASH_HANDLE hd;
+gnutls_datum der = { NULL, 0 };
- return 0;
+ if (*output_data_size < 20) {
+ gnutls_assert();
+ return GNUTLS_E_SHORT_MEMORY_BUFFER;
+ }
+
+ if (key->pk_algorithm == GNUTLS_PK_RSA) {
+ result = _gnutls_x509_write_rsa_params( key->params, key->params_size, &der);
+ if (result < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+ } else if (key->pk_algorithm == GNUTLS_PK_DSA) {
+ result = _gnutls_x509_write_dsa_params( key->params, key->params_size, &der);
+ if (result < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+ } else return GNUTLS_E_INTERNAL_ERROR;
+
+ hd = _gnutls_hash_init( GNUTLS_MAC_SHA);
+ if (hd == GNUTLS_HASH_FAILED) {
+ gnutls_assert();
+ result = GNUTLS_E_INTERNAL_ERROR;
+ goto cleanup;
+ }
+
+ _gnutls_hash( hd, der.data, der.size);
+
+ _gnutls_hash_deinit( hd, output_data);
+ *output_data_size = 20;
+
+ result = 0;
+
+cleanup:
+
+ _gnutls_free_datum( &der);
+ return result;
}
diff --git a/lib/x509/privkey.h b/lib/x509/privkey.h
index c2a2c39e38..91f80e09b2 100644
--- a/lib/x509/privkey.h
+++ b/lib/x509/privkey.h
@@ -11,7 +11,3 @@ int gnutls_x509_privkey_import(gnutls_x509_privkey key, const gnutls_datum * dat
gnutls_x509_crt_fmt format);
ASN1_TYPE _gnutls_privkey_decode_pkcs1_rsa_key( const gnutls_datum *raw_key,
gnutls_x509_privkey pkey);
-int _gnutls_x509_hash_rsa_key( GNUTLS_MPI * params,
- unsigned char* output_data, int* output_data_size);
-int _gnutls_x509_hash_dsa_key( GNUTLS_MPI * params,
- unsigned char* output_data, int* output_data_size);
diff --git a/lib/x509/x509.c b/lib/x509/x509.c
index 83e5a23125..ea408a8b4f 100644
--- a/lib/x509/x509.c
+++ b/lib/x509/x509.c
@@ -932,7 +932,14 @@ int gnutls_x509_crt_get_key_id( gnutls_x509_crt crt, unsigned int flags,
{
GNUTLS_MPI params[MAX_PUBLIC_PARAMS_SIZE];
int params_size = MAX_PUBLIC_PARAMS_SIZE;
-int i, pk, ret = 0;
+int i, pk, result = 0;
+gnutls_datum der = { NULL, 0 };
+GNUTLS_HASH_HANDLE hd;
+
+ if (*output_data_size < 20) {
+ gnutls_assert();
+ return GNUTLS_E_SHORT_MEMORY_BUFFER;
+ }
pk = gnutls_x509_crt_get_pk_algorithm( crt, NULL);
@@ -941,25 +948,51 @@ int i, pk, ret = 0;
return pk;
}
- ret = _gnutls_x509_crt_get_mpis( crt, params, &params_size);
+ result = _gnutls_x509_crt_get_mpis( crt, params, &params_size);
- if (ret < 0) {
+ if (result < 0) {
gnutls_assert();
- return ret;
+ return result;
}
+
+ if (pk == GNUTLS_PK_RSA) {
+ result = _gnutls_x509_write_rsa_params( params, params_size, &der);
+ if (result < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+ } else if (pk == GNUTLS_PK_DSA) {
+ result = _gnutls_x509_write_dsa_params( params, params_size, &der);
+ if (result < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+ } else return GNUTLS_E_INTERNAL_ERROR;
- if (pk == GNUTLS_PK_RSA)
- ret = _gnutls_x509_hash_rsa_key( params, output_data, output_data_size);
- else if (pk == GNUTLS_PK_DSA)
- ret = _gnutls_x509_hash_dsa_key( params, output_data, output_data_size);
- else ret = GNUTLS_E_INTERNAL_ERROR;
+ hd = _gnutls_hash_init( GNUTLS_MAC_SHA);
+ if (hd == GNUTLS_HASH_FAILED) {
+ gnutls_assert();
+ result = GNUTLS_E_INTERNAL_ERROR;
+ goto cleanup;
+ }
+
+ _gnutls_hash( hd, der.data, der.size);
+
+ _gnutls_hash_deinit( hd, output_data);
+ *output_data_size = 20;
+
+ result = 0;
+
+ cleanup:
+
+ _gnutls_free_datum( &der);
/* release all allocated MPIs
*/
for (i = 0; i < params_size; i++) {
_gnutls_mpi_release( &params[i]);
}
- return ret;
+ return result;
}
diff --git a/lib/x509_b64.c b/lib/x509_b64.c
index fb3d829622..196bd1b70d 100644
--- a/lib/x509_b64.c
+++ b/lib/x509_b64.c
@@ -375,7 +375,7 @@ int _gnutls_fbase64_decode( const opaque* header, const opaque * data, size_t da
if (rdata==NULL) {
gnutls_assert();
- _gnutls_x509_log( "Could not find '%s'\n", pem_header);
+ _gnutls_debug_log( "Could not find '%s'\n", pem_header);
return GNUTLS_E_BASE64_DECODING_ERROR;
}
diff --git a/src/certtool-gaa.c b/src/certtool-gaa.c
index 4c8c143063..dee438e60c 100644
--- a/src/certtool-gaa.c
+++ b/src/certtool-gaa.c
@@ -126,8 +126,10 @@ void gaa_help(void)
__gaa_helpsingle(0, "load-ca-privkey", "FILE ", "Certificate authority's private key file to use.");
__gaa_helpsingle(0, "load-ca-cert", "FILE ", "Certificate authority's certificate file to use.");
__gaa_helpsingle('i', "cert-info", "", "Print information on a certificate.");
+ __gaa_helpsingle('k', "key-info", "", "Print information on a private key.");
__gaa_helpsingle('8', "pkcs8", "", "Use PKCS #8 format for private keys.");
__gaa_helpsingle(0, "bits", "BITS ", "specify the number of bits for key generation.");
+ __gaa_helpsingle('d', "debug", "LEVEL ", "specify the debug level. Default is 1.");
__gaa_helpsingle('h', "help", "", "shows this help text");
__gaa_helpsingle('v', "version", "", "shows the program version");
@@ -144,9 +146,11 @@ typedef struct _gaainfo gaainfo;
struct _gaainfo
{
-#line 29 "certtool.gaa"
+#line 34 "certtool.gaa"
+ int debug;
+#line 31 "certtool.gaa"
int bits;
-#line 26 "certtool.gaa"
+#line 28 "certtool.gaa"
int pkcs8;
#line 20 "certtool.gaa"
char *ca;
@@ -210,20 +214,22 @@ int gaa_error = 0;
#define GAA_MULTIPLE_OPTION 3
#define GAA_REST 0
-#define GAA_NB_OPTION 13
+#define GAA_NB_OPTION 15
#define GAAOPTID_version 1
#define GAAOPTID_help 2
-#define GAAOPTID_bits 3
-#define GAAOPTID_pkcs8 4
-#define GAAOPTID_cert_info 5
-#define GAAOPTID_load_ca_cert 6
-#define GAAOPTID_load_ca_privkey 7
-#define GAAOPTID_load_privkey 8
-#define GAAOPTID_verify_chain 9
-#define GAAOPTID_generate_request 10
-#define GAAOPTID_generate_privkey 11
-#define GAAOPTID_generate_certificate 12
-#define GAAOPTID_generate_self_signed 13
+#define GAAOPTID_debug 3
+#define GAAOPTID_bits 4
+#define GAAOPTID_pkcs8 5
+#define GAAOPTID_key_info 6
+#define GAAOPTID_cert_info 7
+#define GAAOPTID_load_ca_cert 8
+#define GAAOPTID_load_ca_privkey 9
+#define GAAOPTID_load_privkey 10
+#define GAAOPTID_verify_chain 11
+#define GAAOPTID_generate_request 12
+#define GAAOPTID_generate_privkey 13
+#define GAAOPTID_generate_certificate 14
+#define GAAOPTID_generate_self_signed 15
#line 168 "gaa.skel"
@@ -410,6 +416,12 @@ float gaa_getfloat(char *arg)
}
/* option structures */
+struct GAAOPTION_debug
+{
+ int arg1;
+ int size1;
+};
+
struct GAAOPTION_bits
{
int arg1;
@@ -463,6 +475,7 @@ int gaa_get_option_num(char *str, int status)
switch(status)
{
case GAA_LETTER_OPTION:
+ GAA_CHECK1STR("d", GAAOPTID_debug);
GAA_CHECK1STR("", GAAOPTID_bits);
GAA_CHECK1STR("", GAAOPTID_load_ca_cert);
GAA_CHECK1STR("", GAAOPTID_load_ca_privkey);
@@ -472,6 +485,7 @@ int gaa_get_option_num(char *str, int status)
GAA_CHECK1STR("v", GAAOPTID_version);
GAA_CHECK1STR("h", GAAOPTID_help);
GAA_CHECK1STR("8", GAAOPTID_pkcs8);
+ GAA_CHECK1STR("k", GAAOPTID_key_info);
GAA_CHECK1STR("i", GAAOPTID_cert_info);
GAA_CHECK1STR("e", GAAOPTID_verify_chain);
GAA_CHECK1STR("q", GAAOPTID_generate_request);
@@ -484,8 +498,10 @@ int gaa_get_option_num(char *str, int status)
case GAA_WORD_OPTION:
GAA_CHECKSTR("version", GAAOPTID_version);
GAA_CHECKSTR("help", GAAOPTID_help);
+ GAA_CHECKSTR("debug", GAAOPTID_debug);
GAA_CHECKSTR("bits", GAAOPTID_bits);
GAA_CHECKSTR("pkcs8", GAAOPTID_pkcs8);
+ GAA_CHECKSTR("key-info", GAAOPTID_key_info);
GAA_CHECKSTR("cert-info", GAAOPTID_cert_info);
GAA_CHECKSTR("load-ca-cert", GAAOPTID_load_ca_cert);
GAA_CHECKSTR("load-ca-privkey", GAAOPTID_load_ca_privkey);
@@ -507,6 +523,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
{
int OK = 0;
int gaa_last_non_option;
+ struct GAAOPTION_debug GAATMP_debug;
struct GAAOPTION_bits GAATMP_bits;
struct GAAOPTION_load_ca_cert GAATMP_load_ca_cert;
struct GAAOPTION_load_ca_privkey GAATMP_load_ca_privkey;
@@ -533,35 +550,52 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
{
case GAAOPTID_version:
OK = 0;
-#line 34 "certtool.gaa"
+#line 39 "certtool.gaa"
{ certtool_version(); exit(0); ;};
return GAA_OK;
break;
case GAAOPTID_help:
OK = 0;
-#line 32 "certtool.gaa"
+#line 37 "certtool.gaa"
{ gaa_help(); exit(0); ;};
return GAA_OK;
break;
+ case GAAOPTID_debug:
+ OK = 0;
+ GAA_TESTMOREARGS;
+ GAA_FILL(GAATMP_debug.arg1, gaa_getint, GAATMP_debug.size1);
+ gaa_index++;
+#line 35 "certtool.gaa"
+{ gaaval->debug = GAATMP_debug.arg1 ;};
+
+ return GAA_OK;
+ break;
case GAAOPTID_bits:
OK = 0;
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_bits.arg1, gaa_getint, GAATMP_bits.size1);
gaa_index++;
-#line 30 "certtool.gaa"
+#line 32 "certtool.gaa"
{ gaaval->bits = GAATMP_bits.arg1 ;};
return GAA_OK;
break;
case GAAOPTID_pkcs8:
OK = 0;
-#line 27 "certtool.gaa"
+#line 29 "certtool.gaa"
{ gaaval->pkcs8=1 ;};
return GAA_OK;
break;
+ case GAAOPTID_key_info:
+ OK = 0;
+#line 25 "certtool.gaa"
+{ gaaval->action = 6; ;};
+
+ return GAA_OK;
+ break;
case GAAOPTID_cert_info:
OK = 0;
#line 23 "certtool.gaa"
@@ -658,8 +692,9 @@ int gaa(int argc, char **argv, gaainfo *gaaval)
if(inited == 0)
{
-#line 36 "certtool.gaa"
-{ gaaval->bits = 1024; gaaval->pkcs8 = 0; gaaval->privkey = NULL; gaaval->ca=NULL; gaaval->ca_privkey = NULL; ;};
+#line 41 "certtool.gaa"
+{ gaaval->bits = 1024; gaaval->pkcs8 = 0; gaaval->privkey = NULL; gaaval->ca=NULL; gaaval->ca_privkey = NULL;
+ gaaval->debug=1; ;};
}
inited = 1;
diff --git a/src/certtool-gaa.h b/src/certtool-gaa.h
index e25adf6966..8d000c7ecf 100644
--- a/src/certtool-gaa.h
+++ b/src/certtool-gaa.h
@@ -8,9 +8,11 @@ typedef struct _gaainfo gaainfo;
struct _gaainfo
{
-#line 29 "certtool.gaa"
+#line 34 "certtool.gaa"
+ int debug;
+#line 31 "certtool.gaa"
int bits;
-#line 26 "certtool.gaa"
+#line 28 "certtool.gaa"
int pkcs8;
#line 20 "certtool.gaa"
char *ca;
diff --git a/src/certtool.c b/src/certtool.c
index e8ddf4309a..9b50efb866 100644
--- a/src/certtool.c
+++ b/src/certtool.c
@@ -11,6 +11,7 @@ gnutls_x509_privkey load_private_key(void);
gnutls_x509_privkey load_ca_private_key(void);
gnutls_x509_crt load_ca_cert(void);
void certificate_info( void);
+void privkey_info( void);
static void gaa_parser(int argc, char **argv);
void generate_self_signed( void);
void generate_request(void);
@@ -27,10 +28,6 @@ static void tls_log_func( int level, const char* str)
int main(int argc, char** argv)
{
- gnutls_global_init();
- gnutls_global_set_log_function( tls_log_func);
- gnutls_global_set_log_level(1);
-
gaa_parser(argc, argv);
return 0;
@@ -383,6 +380,10 @@ void gaa_parser(int argc, char **argv)
exit(1);
}
+ gnutls_global_init();
+ gnutls_global_set_log_function( tls_log_func);
+ gnutls_global_set_log_level(info.debug);
+
switch( info.action) {
case 0:
generate_self_signed();
@@ -402,6 +403,9 @@ void gaa_parser(int argc, char **argv)
case 5:
verify_chain();
return;
+ case 6:
+ privkey_info();
+ return;
}
}
@@ -436,6 +440,7 @@ void certificate_info( void)
size_t serial_size = sizeof(serial), dn_size;
char printable[256];
char *print;
+ const char* cprint;
char dn[256];
size = fread( buffer, 1, sizeof(buffer)-1, stdin);
@@ -479,8 +484,8 @@ void certificate_info( void)
printf("Signature Algorithm: ");
ret = gnutls_x509_crt_get_signature_algorithm(crt);
- print = get_algorithm( ret);
- printf( "%s\n", print);
+ cprint = get_algorithm( ret);
+ printf( "%s\n", cprint);
/* Validity
*/
@@ -505,25 +510,9 @@ void certificate_info( void)
ret = gnutls_x509_crt_get_pk_algorithm(crt, NULL);
printf("\tPublic Key Algorithm: ");
- print = get_algorithm( ret);
- printf( "%s\n", print);
+ cprint = get_algorithm( ret);
+ printf( "%s\n", cprint);
- /* fingerprint
- */
- size = sizeof(buffer);
- if ((ret=gnutls_x509_crt_get_fingerprint(crt, GNUTLS_DIG_MD5, buffer, &size)) < 0)
- {
- const char* str = gnutls_strerror(ret);
- if (str == NULL) str = "unknown error";
- fprintf(stderr, "Error in fingerprint calculation: %s\n", str);
- } else {
- print = printable;
- for (i = 0; i < size; i++) {
- sprintf(print, "%.2x ", (unsigned char) buffer[i]);
- print += 3;
- }
- printf("\nFingerprint: %s\n", printable);
- }
printf("\nX.509 Extensions:\n");
@@ -571,7 +560,9 @@ void certificate_info( void)
else printf("\t\tCA:TRUE\n");
}
-
+
+ /* Key Usage.
+ */
ret = gnutls_x509_crt_get_key_usage( crt, &key_usage, &critical);
if (ret >= 0) {
@@ -580,8 +571,98 @@ void certificate_info( void)
}
+ /* fingerprint
+ */
+ size = sizeof(buffer);
+ if ((ret=gnutls_x509_crt_get_fingerprint(crt, GNUTLS_DIG_MD5, buffer, &size)) < 0)
+ {
+ const char* str = gnutls_strerror(ret);
+ if (str == NULL) str = "unknown error";
+ fprintf(stderr, "Error in fingerprint calculation: %s\n", str);
+ } else {
+ print = printable;
+ for (i = 0; i < size; i++) {
+ sprintf(print, "%.2x ", (unsigned char) buffer[i]);
+ print += 3;
+ }
+ printf("\nFingerprint: %s\n", printable);
+ }
+
+ size = sizeof(buffer);
+ if ((ret=gnutls_x509_crt_get_key_id(crt, 0, buffer, &size)) < 0)
+ {
+ const char* str = gnutls_strerror(ret);
+ if (str == NULL) str = "unknown error";
+ fprintf(stderr, "Error in key id calculation: %s\n", str);
+ } else {
+ print = printable;
+ for (i = 0; i < size; i++) {
+ sprintf(print, "%.2x ", (unsigned char) buffer[i]);
+ print += 3;
+ }
+ printf("Key ID: %s\n", printable);
+ }
+
+ printf("\n");
+}
+
+void privkey_info( void)
+{
+ gnutls_x509_privkey key;
+ int size, ret, i;
+ gnutls_datum pem;
+ char printable[256];
+ char *print;
+ const char* cprint;
+
+ size = fread( buffer, 1, sizeof(buffer)-1, stdin);
+ buffer[size] = 0;
+
+ gnutls_x509_privkey_init(&key);
+
+ pem.data = buffer;
+ pem.size = size;
+
+ if (!info.pkcs8) {
+ ret = gnutls_x509_privkey_import(key, &pem, GNUTLS_X509_FMT_PEM);
+ } else {
+ ret = gnutls_x509_privkey_import_pkcs8(key, &pem, GNUTLS_X509_FMT_PEM, NULL, GNUTLS_PKCS8_PLAIN);
+ }
+
+ if (ret < 0) {
+ fprintf(stderr, "Decoding error: %s\n", gnutls_strerror(ret));
+ exit(1);
+ }
+
+ /* Public key algorithm
+ */
+ printf("Public Key Info:\n");
+ ret = gnutls_x509_privkey_get_pk_algorithm(key);
+ printf("\tPublic Key Algorithm: ");
+
+ cprint = get_algorithm( ret);
+ printf( "%s\n", cprint);
+
+
+ size = sizeof(buffer);
+ if ((ret=gnutls_x509_privkey_get_key_id(key, 0, buffer, &size)) < 0)
+ {
+ const char* str = gnutls_strerror(ret);
+ if (str == NULL) str = "unknown error";
+ fprintf(stderr, "Error in key id calculation: %s\n", str);
+ } else {
+ print = printable;
+ for (i = 0; i < size; i++) {
+ sprintf(print, "%.2x ", (unsigned char) buffer[i]);
+ print += 3;
+ }
+ printf("Key ID: %s\n", printable);
+ }
+
+ printf("\n");
}
+
gnutls_x509_privkey load_private_key()
{
FILE* fd;
@@ -939,16 +1020,17 @@ static void print_verification_res( unsigned int x)
printf("\tcertificate chain is invalid.\n");
else
printf("\tcertificate chain is valid.\n");
+
if (x&GNUTLS_CERT_NOT_TRUSTED)
- printf("\tcertificate is NOT trusted\n");
+ printf("\tThe certificate chain was NOT verified.\n");
else
- printf("\tcertificate is trusted.\n");
+ printf("\tThe certificate chain was verified.\n");
if (x&GNUTLS_CERT_CORRUPTED)
- printf("\tcertificate is corrupt.\n");
+ printf("\tA certificate is corrupt.\n");
if (x&GNUTLS_CERT_REVOKED)
- printf("\tcertificate is revoked.\n");
+ printf("\tA certificate has been revoked.\n");
}
void verify_chain( void)
diff --git a/src/certtool.gaa b/src/certtool.gaa
index dbe935ab5d..955d96f5a6 100644
--- a/src/certtool.gaa
+++ b/src/certtool.gaa
@@ -22,6 +22,8 @@ option (load-ca-cert) STR "FILE" { $ca = $1 } "Certificate authority's certifica
option (i, cert-info) { $action = 2; } "Print information on a certificate."
+option (k, key-info) { $action = 6; } "Print information on a private key."
+
#int pkcs8;
option (8, pkcs8) { $pkcs8=1 } "Use PKCS #8 format for private keys."
@@ -29,9 +31,13 @@ option (8, pkcs8) { $pkcs8=1 } "Use PKCS #8 format for private keys."
#int bits;
option (bits) INT "BITS" { $bits = $1 } "specify the number of bits for key generation."
+#int debug;
+option (d, debug) INT "LEVEL" { $debug = $1 } "specify the debug level. Default is 1."
+
option (h, help) { gaa_help(); exit(0); } "shows this help text"
option (v, version) { certtool_version(); exit(0); } "shows the program version"
-init { $bits = 1024; $pkcs8 = 0; $privkey = NULL; $ca=NULL; $ca_privkey = NULL; }
+init { $bits = 1024; $pkcs8 = 0; $privkey = NULL; $ca=NULL; $ca_privkey = NULL;
+ $debug=1; }