diff options
-rw-r--r-- | lib/gnutls_x509.c | 35 | ||||
-rw-r--r-- | lib/x509/common.c | 19 | ||||
-rw-r--r-- | lib/x509/mpi.c | 94 | ||||
-rw-r--r-- | lib/x509/mpi.h | 4 | ||||
-rw-r--r-- | lib/x509/privkey.c | 252 | ||||
-rw-r--r-- | lib/x509/privkey.h | 4 | ||||
-rw-r--r-- | lib/x509/x509.c | 53 | ||||
-rw-r--r-- | lib/x509_b64.c | 2 | ||||
-rw-r--r-- | src/certtool-gaa.c | 75 | ||||
-rw-r--r-- | src/certtool-gaa.h | 6 | ||||
-rw-r--r-- | src/certtool.c | 140 | ||||
-rw-r--r-- | src/certtool.gaa | 8 |
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, ¶ms_size); + result = _gnutls_x509_crt_get_mpis( crt, params, ¶ms_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( ¶ms[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; } |