diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2013-11-08 22:14:07 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2013-11-08 22:17:10 +0100 |
commit | 76c93d23c073ef8b885503b7d28a31ffe2add6d8 (patch) | |
tree | 1dd2d22a197bc40c5330e516969a7cb1ae9bc96f /src | |
parent | 559a144f6bbcbb611453f82e655dd7438c14d1a7 (diff) | |
download | gnutls-76c93d23c073ef8b885503b7d28a31ffe2add6d8.tar.gz |
reindented code
Diffstat (limited to 'src')
36 files changed, 15025 insertions, 15567 deletions
diff --git a/src/benchmark-cipher.c b/src/benchmark-cipher.c index 95e6806230..6f4983bb8b 100644 --- a/src/benchmark-cipher.c +++ b/src/benchmark-cipher.c @@ -33,201 +33,193 @@ static unsigned char data[64 * 1024]; -static void -tls_log_func (int level, const char *str) +static void tls_log_func(int level, const char *str) { - fprintf (stderr, "|<%d>| %s", level, str); + fprintf(stderr, "|<%d>| %s", level, str); } -static void -cipher_mac_bench (int algo, int mac_algo, int size) +static void cipher_mac_bench(int algo, int mac_algo, int size) { - int ret; - gnutls_cipher_hd_t ctx; - gnutls_hmac_hd_t mac_ctx; - void *_key, *_iv; - gnutls_datum_t key, iv; - int ivsize = gnutls_cipher_get_iv_size(algo); - int keysize = gnutls_cipher_get_key_size (algo); - int step = size*1024; - struct benchmark_st st; - - _key = malloc (keysize); - if (_key == NULL) - return; - memset (_key, 0xf0, keysize); - - _iv = malloc (ivsize); - if (_iv == NULL) - return; - memset (_iv, 0xf0, ivsize); - - iv.data = _iv; - iv.size = ivsize; - - key.data = _key; - key.size = keysize; - - printf ("%16s-%s ", gnutls_cipher_get_name (algo), - gnutls_mac_get_name(mac_algo)); - fflush (stdout); - - start_benchmark(&st); - - ret = gnutls_hmac_init(&mac_ctx, mac_algo, key.data, key.size); - if (ret < 0) - { - fprintf (stderr, "error: %s\n", gnutls_strerror (ret)); - goto leave; - } - - ret = gnutls_cipher_init (&ctx, algo, &key, &iv); - if (ret < 0) - { - fprintf (stderr, "error: %s\n", gnutls_strerror (ret)); - goto leave; - } - - gnutls_hmac(mac_ctx, data, 1024); - - do - { - gnutls_hmac(mac_ctx, data, step); - gnutls_cipher_encrypt2 (ctx, data, step, data, step+64); - st.size += step; - } - while (benchmark_must_finish == 0); - - gnutls_cipher_deinit (ctx); - gnutls_hmac_deinit(mac_ctx, NULL); - - stop_benchmark (&st, NULL, 1); - -leave: - free (_key); - free (_iv); + int ret; + gnutls_cipher_hd_t ctx; + gnutls_hmac_hd_t mac_ctx; + void *_key, *_iv; + gnutls_datum_t key, iv; + int ivsize = gnutls_cipher_get_iv_size(algo); + int keysize = gnutls_cipher_get_key_size(algo); + int step = size * 1024; + struct benchmark_st st; + + _key = malloc(keysize); + if (_key == NULL) + return; + memset(_key, 0xf0, keysize); + + _iv = malloc(ivsize); + if (_iv == NULL) + return; + memset(_iv, 0xf0, ivsize); + + iv.data = _iv; + iv.size = ivsize; + + key.data = _key; + key.size = keysize; + + printf("%16s-%s ", gnutls_cipher_get_name(algo), + gnutls_mac_get_name(mac_algo)); + fflush(stdout); + + start_benchmark(&st); + + ret = gnutls_hmac_init(&mac_ctx, mac_algo, key.data, key.size); + if (ret < 0) { + fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); + goto leave; + } + + ret = gnutls_cipher_init(&ctx, algo, &key, &iv); + if (ret < 0) { + fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); + goto leave; + } + + gnutls_hmac(mac_ctx, data, 1024); + + do { + gnutls_hmac(mac_ctx, data, step); + gnutls_cipher_encrypt2(ctx, data, step, data, step + 64); + st.size += step; + } + while (benchmark_must_finish == 0); + + gnutls_cipher_deinit(ctx); + gnutls_hmac_deinit(mac_ctx, NULL); + + stop_benchmark(&st, NULL, 1); + + leave: + free(_key); + free(_iv); } -static void -cipher_bench (int algo, int size, int aead) +static void cipher_bench(int algo, int size, int aead) { - int ret; - gnutls_cipher_hd_t ctx; - void *_key, *_iv; - gnutls_datum_t key, iv; - int ivsize = gnutls_cipher_get_iv_size(algo); - int keysize = gnutls_cipher_get_key_size (algo); - int step = size*1024; - struct benchmark_st st; - - _key = malloc (keysize); - if (_key == NULL) - return; - memset (_key, 0xf0, keysize); - - _iv = malloc (ivsize); - if (_iv == NULL) - return; - memset (_iv, 0xf0, ivsize); - - iv.data = _iv; - if (aead) iv.size = 12; - else iv.size = ivsize; - - key.data = _key; - key.size = keysize; - - printf ("%16s ", gnutls_cipher_get_name (algo)); - fflush (stdout); - - start_benchmark(&st); - - ret = gnutls_cipher_init (&ctx, algo, &key, &iv); - if (ret < 0) - { - fprintf (stderr, "error: %s\n", gnutls_strerror (ret)); - goto leave; - } - - if (aead) - gnutls_cipher_add_auth (ctx, data, 1024); - - do - { - gnutls_cipher_encrypt2 (ctx, data, step, data, step+64); - st.size += step; - } - while (benchmark_must_finish == 0); - - gnutls_cipher_deinit (ctx); - - stop_benchmark(&st, NULL, 1); - -leave: - free (_key); - free (_iv); + int ret; + gnutls_cipher_hd_t ctx; + void *_key, *_iv; + gnutls_datum_t key, iv; + int ivsize = gnutls_cipher_get_iv_size(algo); + int keysize = gnutls_cipher_get_key_size(algo); + int step = size * 1024; + struct benchmark_st st; + + _key = malloc(keysize); + if (_key == NULL) + return; + memset(_key, 0xf0, keysize); + + _iv = malloc(ivsize); + if (_iv == NULL) + return; + memset(_iv, 0xf0, ivsize); + + iv.data = _iv; + if (aead) + iv.size = 12; + else + iv.size = ivsize; + + key.data = _key; + key.size = keysize; + + printf("%16s ", gnutls_cipher_get_name(algo)); + fflush(stdout); + + start_benchmark(&st); + + ret = gnutls_cipher_init(&ctx, algo, &key, &iv); + if (ret < 0) { + fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); + goto leave; + } + + if (aead) + gnutls_cipher_add_auth(ctx, data, 1024); + + do { + gnutls_cipher_encrypt2(ctx, data, step, data, step + 64); + st.size += step; + } + while (benchmark_must_finish == 0); + + gnutls_cipher_deinit(ctx); + + stop_benchmark(&st, NULL, 1); + + leave: + free(_key); + free(_iv); } -static void -mac_bench (int algo, int size) +static void mac_bench(int algo, int size) { - void *_key; - int blocksize = gnutls_hmac_get_len (algo); - int step = size*1024; - struct benchmark_st st; - - _key = malloc (blocksize); - if (_key == NULL) - return; - memset (_key, 0xf0, blocksize); - - printf ("%16s ", gnutls_mac_get_name (algo)); - fflush (stdout); - - start_benchmark(&st); - - do - { - gnutls_hmac_fast (algo, _key, blocksize, data, step, _key); - st.size += step; - } - while (benchmark_must_finish == 0); - - stop_benchmark(&st, NULL, 1); - - free (_key); + void *_key; + int blocksize = gnutls_hmac_get_len(algo); + int step = size * 1024; + struct benchmark_st st; + + _key = malloc(blocksize); + if (_key == NULL) + return; + memset(_key, 0xf0, blocksize); + + printf("%16s ", gnutls_mac_get_name(algo)); + fflush(stdout); + + start_benchmark(&st); + + do { + gnutls_hmac_fast(algo, _key, blocksize, data, step, _key); + st.size += step; + } + while (benchmark_must_finish == 0); + + stop_benchmark(&st, NULL, 1); + + free(_key); } -void benchmark_cipher (int init, int debug_level) +void benchmark_cipher(int init, int debug_level) { - gnutls_global_set_log_function (tls_log_func); - gnutls_global_set_log_level (debug_level); - int size = 16; + gnutls_global_set_log_function(tls_log_func); + gnutls_global_set_log_level(debug_level); + int size = 16; - if (init) - { - gnutls_global_init (); - gnutls_rnd( GNUTLS_RND_NONCE, data, sizeof(data)); - } + if (init) { + gnutls_global_init(); + gnutls_rnd(GNUTLS_RND_NONCE, data, sizeof(data)); + } - printf("Checking ciphers, payload size: %u\n", size*1024); - cipher_mac_bench ( GNUTLS_CIPHER_SALSA20_256, GNUTLS_MAC_SHA1, size); - cipher_mac_bench ( GNUTLS_CIPHER_AES_128_CBC, GNUTLS_MAC_SHA1, size); - cipher_mac_bench ( GNUTLS_CIPHER_AES_128_CBC, GNUTLS_MAC_SHA256, size); - cipher_bench ( GNUTLS_CIPHER_AES_128_GCM, size, 1); + printf("Checking ciphers, payload size: %u\n", size * 1024); + cipher_mac_bench(GNUTLS_CIPHER_SALSA20_256, GNUTLS_MAC_SHA1, size); + cipher_mac_bench(GNUTLS_CIPHER_AES_128_CBC, GNUTLS_MAC_SHA1, size); + cipher_mac_bench(GNUTLS_CIPHER_AES_128_CBC, GNUTLS_MAC_SHA256, + size); + cipher_bench(GNUTLS_CIPHER_AES_128_GCM, size, 1); - mac_bench (GNUTLS_MAC_SHA1, size); - mac_bench (GNUTLS_MAC_SHA256, size); - mac_bench (GNUTLS_MAC_SHA512, size); + mac_bench(GNUTLS_MAC_SHA1, size); + mac_bench(GNUTLS_MAC_SHA256, size); + mac_bench(GNUTLS_MAC_SHA512, size); - cipher_bench (GNUTLS_CIPHER_3DES_CBC, size, 0); + cipher_bench(GNUTLS_CIPHER_3DES_CBC, size, 0); - cipher_bench (GNUTLS_CIPHER_AES_128_CBC, size, 0); + cipher_bench(GNUTLS_CIPHER_AES_128_CBC, size, 0); - cipher_bench (GNUTLS_CIPHER_ARCFOUR, size, 0); + cipher_bench(GNUTLS_CIPHER_ARCFOUR, size, 0); - cipher_bench ( GNUTLS_CIPHER_SALSA20_256, size, 0); + cipher_bench(GNUTLS_CIPHER_SALSA20_256, size, 0); - gnutls_global_deinit(); + gnutls_global_deinit(); } diff --git a/src/benchmark-tls.c b/src/benchmark-tls.c index 644fa12404..204c494227 100644 --- a/src/benchmark-tls.c +++ b/src/benchmark-tls.c @@ -41,7 +41,7 @@ #include "../tests/eagain-common.h" #include "benchmark.h" -const char* side = ""; +const char *side = ""; #define PRIO_DH "NONE:+VERS-TLS1.0:+AES-128-CBC:+SHA1:+SIGN-ALL:+COMP-NULL:+DHE-RSA" #define PRIO_ECDH "NONE:+VERS-TLS1.0:+AES-128-CBC:+SHA1:+SIGN-ALL:+COMP-NULL:+ECDHE-RSA:+CURVE-SECP192R1" @@ -64,414 +64,437 @@ static const int rsa_bits = 1776, ec_bits = 192; /* DH of 1840 bits that is pretty close equivalent to 192 bits of ECDH. */ const char *pkcs3 = -"-----BEGIN DH PARAMETERS-----\n" -"MIIBxgKB3gNZMD2odqYk7HGnT+kh72vcnGrDhFMad1m4VlYZoLClkRUOH05W9gKF\n" -"hjBzlg5zO1Pp14hpSNWdfXcd2glWE2wzkxxxztzt23gdXK1GjfupnALyPS2Q0Oj7\n" -"UiLDfos46vXOSzqO3vBElM2HJQ6N1TRU+EqD5t/6aTAV6iAD+yz2Fyv4Xs+rgJC2\n" -"IbpunLzM2IhH2u9tLUXGkBzHPW/6Q+fJRhn88OLBC9vwOHPQvw779+FB0NPue1Qs\n" -"vb+4HSywpOr4BtNLWST2MzhCYBApvV1dKcZLI5k5Cfmp5ryV+wKB3gEUe9uAk+5I\n" -"ENkTLC7XLLNGjPEKwQhBzE7Nh7RKWlZRX+B/cX5/iT7ZF9+N83O/wf2AxEV6CRWV\n" -"WiCjvML/wbskpGoGmrPyef7bLHI62x4/nNacGGWEichPW8Sn/qaT80FHyYM0m7Ha\n" -"+Q9kYUSx0u1CW//3nGvma5dh/c2iiq8r7J9w2PSYynHts4bYMrRRx2PVeGhvU8+X\n" -"nRkYOqptEqoB6NG5kPRL8b5jJSp7J2hN7shDjQB/s9/N8rvF8tRmMUTJpk3Fwr9F\n" -"LVdX3640cbukwFTKlkqZ1evymVzx0wICAL0=\n" -"-----END DH PARAMETERS-----\n"; + "-----BEGIN DH PARAMETERS-----\n" + "MIIBxgKB3gNZMD2odqYk7HGnT+kh72vcnGrDhFMad1m4VlYZoLClkRUOH05W9gKF\n" + "hjBzlg5zO1Pp14hpSNWdfXcd2glWE2wzkxxxztzt23gdXK1GjfupnALyPS2Q0Oj7\n" + "UiLDfos46vXOSzqO3vBElM2HJQ6N1TRU+EqD5t/6aTAV6iAD+yz2Fyv4Xs+rgJC2\n" + "IbpunLzM2IhH2u9tLUXGkBzHPW/6Q+fJRhn88OLBC9vwOHPQvw779+FB0NPue1Qs\n" + "vb+4HSywpOr4BtNLWST2MzhCYBApvV1dKcZLI5k5Cfmp5ryV+wKB3gEUe9uAk+5I\n" + "ENkTLC7XLLNGjPEKwQhBzE7Nh7RKWlZRX+B/cX5/iT7ZF9+N83O/wf2AxEV6CRWV\n" + "WiCjvML/wbskpGoGmrPyef7bLHI62x4/nNacGGWEichPW8Sn/qaT80FHyYM0m7Ha\n" + "+Q9kYUSx0u1CW//3nGvma5dh/c2iiq8r7J9w2PSYynHts4bYMrRRx2PVeGhvU8+X\n" + "nRkYOqptEqoB6NG5kPRL8b5jJSp7J2hN7shDjQB/s9/N8rvF8tRmMUTJpk3Fwr9F\n" + "LVdX3640cbukwFTKlkqZ1evymVzx0wICAL0=\n" + "-----END DH PARAMETERS-----\n"; static unsigned char server_cert_pem[] = -"-----BEGIN CERTIFICATE-----\n" -"MIIEEzCCAx6gAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBuDELMAkGA1UEBhMCR1Ix\n" -"EjAQBgNVBAoTCUtva28gaW5jLjEXMBUGA1UECxMOc2xlZXBpbmcgZGVwdC4xDzAN\n" -"BgNVBAgTBkF0dGlraTEVMBMGA1UEAxMMQ2luZHkgTGF1cGVyMRcwFQYKCZImiZPy\n" -"LGQBARMHY2xhdXBlcjEMMAoGA1UEDBMDRHIuMQ8wDQYDVQRBEwZqYWNrYWwxHDAa\n" -"BgkqhkiG9w0BCQEWDW5vbmVAbm9uZS5vcmcwIhgPMjAxMjA2MDYxOTAxMjdaGA8y\n" -"MDE5MDcxMDE5MDEyN1owgbgxCzAJBgNVBAYTAkdSMRIwEAYDVQQKEwlLb2tvIGlu\n" -"Yy4xFzAVBgNVBAsTDnNsZWVwaW5nIGRlcHQuMQ8wDQYDVQQIEwZBdHRpa2kxFTAT\n" -"BgNVBAMTDENpbmR5IExhdXBlcjEXMBUGCgmSJomT8ixkAQETB2NsYXVwZXIxDDAK\n" -"BgNVBAwTA0RyLjEPMA0GA1UEQRMGamFja2FsMRwwGgYJKoZIhvcNAQkBFg1ub25l\n" -"QG5vbmUub3JnMIH9MA0GCSqGSIb3DQEBAQUAA4HrADCB5wKB3wC/VSBHG5adM0r0\n" -"E80dgVvt+oVnnDcKYcm9q2WbknTL6dFgjjcEbiHDKmnr1hgyT9jfQVE/ve2XnZqA\n" -"kbpYMNrQbdieclNycjoXCj3BJSJXXz3Ra6O4DLNh0/XwsxbVd/tMSQvwAK0MR60K\n" -"/yfruL2oxe8j7uDmS5oY8b5O9nP/EVW2u7P1KVhrNxC2rGoaK6iRpgkAX3oP2YVM\n" -"hLfPONpDgYGxBvrO0tlpHCYL+miWdRzIDPMYtdcU1v1zVSKAsvJ2dgEwP6FoSiWP\n" -"nkw3U41i4oe+T7kVEk1F9QLCnXsCAwEAAaNrMGkwDAYDVR0TAQH/BAIwADAUBgNV\n" -"HREEDTALgglsb2NhbGhvc3QwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0PAQH/\n" -"BAUDAwegADAdBgNVHQ4EFgQUMwvofEmn5CtM4GygipfIuebOssgwDQYJKoZIhvcN\n" -"AQELBQADgd8AdP87xzJGv3ddODGoCaVNipkO96HDwt1fC4Jtp1VTn1V4JRaL4e4D\n" -"0dlFMq30kmrLTxNSET7MJ5l2m0XZS7jhbl5UW9jLCv1GurMaVuYK4v0LGGezODoH\n" -"8naZkxWYGS16kssPu0SDE0V9gWF31IXs2qs0PHvvpI5WFmjrOPX3RfFeVNhmc5sv\n" -"1cy+hnM9wxcT2r+jpKn3mYVVcnG7ANZyLKzLwN/PGkYB+tv8sS0ojxMKZLQjr9xs\n" -"z1plHeDzm0/t7gsAkrL8ynSkBBJ1SLqaKMmlP1DmgU/zTlMTyKrG\n" -"-----END CERTIFICATE-----\n"; + "-----BEGIN CERTIFICATE-----\n" + "MIIEEzCCAx6gAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBuDELMAkGA1UEBhMCR1Ix\n" + "EjAQBgNVBAoTCUtva28gaW5jLjEXMBUGA1UECxMOc2xlZXBpbmcgZGVwdC4xDzAN\n" + "BgNVBAgTBkF0dGlraTEVMBMGA1UEAxMMQ2luZHkgTGF1cGVyMRcwFQYKCZImiZPy\n" + "LGQBARMHY2xhdXBlcjEMMAoGA1UEDBMDRHIuMQ8wDQYDVQRBEwZqYWNrYWwxHDAa\n" + "BgkqhkiG9w0BCQEWDW5vbmVAbm9uZS5vcmcwIhgPMjAxMjA2MDYxOTAxMjdaGA8y\n" + "MDE5MDcxMDE5MDEyN1owgbgxCzAJBgNVBAYTAkdSMRIwEAYDVQQKEwlLb2tvIGlu\n" + "Yy4xFzAVBgNVBAsTDnNsZWVwaW5nIGRlcHQuMQ8wDQYDVQQIEwZBdHRpa2kxFTAT\n" + "BgNVBAMTDENpbmR5IExhdXBlcjEXMBUGCgmSJomT8ixkAQETB2NsYXVwZXIxDDAK\n" + "BgNVBAwTA0RyLjEPMA0GA1UEQRMGamFja2FsMRwwGgYJKoZIhvcNAQkBFg1ub25l\n" + "QG5vbmUub3JnMIH9MA0GCSqGSIb3DQEBAQUAA4HrADCB5wKB3wC/VSBHG5adM0r0\n" + "E80dgVvt+oVnnDcKYcm9q2WbknTL6dFgjjcEbiHDKmnr1hgyT9jfQVE/ve2XnZqA\n" + "kbpYMNrQbdieclNycjoXCj3BJSJXXz3Ra6O4DLNh0/XwsxbVd/tMSQvwAK0MR60K\n" + "/yfruL2oxe8j7uDmS5oY8b5O9nP/EVW2u7P1KVhrNxC2rGoaK6iRpgkAX3oP2YVM\n" + "hLfPONpDgYGxBvrO0tlpHCYL+miWdRzIDPMYtdcU1v1zVSKAsvJ2dgEwP6FoSiWP\n" + "nkw3U41i4oe+T7kVEk1F9QLCnXsCAwEAAaNrMGkwDAYDVR0TAQH/BAIwADAUBgNV\n" + "HREEDTALgglsb2NhbGhvc3QwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0PAQH/\n" + "BAUDAwegADAdBgNVHQ4EFgQUMwvofEmn5CtM4GygipfIuebOssgwDQYJKoZIhvcN\n" + "AQELBQADgd8AdP87xzJGv3ddODGoCaVNipkO96HDwt1fC4Jtp1VTn1V4JRaL4e4D\n" + "0dlFMq30kmrLTxNSET7MJ5l2m0XZS7jhbl5UW9jLCv1GurMaVuYK4v0LGGezODoH\n" + "8naZkxWYGS16kssPu0SDE0V9gWF31IXs2qs0PHvvpI5WFmjrOPX3RfFeVNhmc5sv\n" + "1cy+hnM9wxcT2r+jpKn3mYVVcnG7ANZyLKzLwN/PGkYB+tv8sS0ojxMKZLQjr9xs\n" + "z1plHeDzm0/t7gsAkrL8ynSkBBJ1SLqaKMmlP1DmgU/zTlMTyKrG\n" + "-----END CERTIFICATE-----\n"; static unsigned char server_key_pem[] = -"-----BEGIN RSA PRIVATE KEY-----\n" -"MIIEBAIBAAKB3wC/VSBHG5adM0r0E80dgVvt+oVnnDcKYcm9q2WbknTL6dFgjjcE\n" -"biHDKmnr1hgyT9jfQVE/ve2XnZqAkbpYMNrQbdieclNycjoXCj3BJSJXXz3Ra6O4\n" -"DLNh0/XwsxbVd/tMSQvwAK0MR60K/yfruL2oxe8j7uDmS5oY8b5O9nP/EVW2u7P1\n" -"KVhrNxC2rGoaK6iRpgkAX3oP2YVMhLfPONpDgYGxBvrO0tlpHCYL+miWdRzIDPMY\n" -"tdcU1v1zVSKAsvJ2dgEwP6FoSiWPnkw3U41i4oe+T7kVEk1F9QLCnXsCAwEAAQKB\n" -"3iYR2gpMAvvkaNWH2xgz1QbVAhZLjugR7QJASEdcLMEmFPMRWQEYqL8cgVbbkpTw\n" -"Lka9yFzWfZ/dTBCo7lr93Yv7T063kMME12oeL4tuyBZ6bOJueHT2kfq1Igpyl+iB\n" -"pw7WuflXKRd4a4X0nwzYBQxYWH7bKkQRZDlViKuOXKVzgT7GqD6cbTZbc/8wUTi7\n" -"HoyMlz4d+YH/XL5Zt6SM7cMuJ/VOGGUcBiXqlixzulloihkPwJeg6zxx0e1dVy4q\n" -"jvVhb+hmypWajjBDPUwIGFih0lZJ6rqIDyls/ZK2AQJwAPFeAMubo1KWcFU+nHoK\n" -"Q/jdOjpuAt7fwczkqhb6uOrJtS4RUtF3x3jfESFYf6Btnt6Slj1HpNKHbud2Weyw\n" -"i3lIkkmQq4+8uRjZXlNtp2Sd33NFeYE1D8ll3V2wiwiCOPJxYWpOOwHs7pkcOsAD\n" -"ywJwAMruluGFAUhoCxXOGzbJeXOC0U+LbwU72Xgk9zhEX6chaklKgdSnJ8DlHnYe\n" -"R+wc2vXRfSGlT1OH0X8ezn82QV8UmYo6cNpMTNarW0rzpFir51owvYSBPnPB+DLX\n" -"0JausRZoI6fyZSw4Vxt9PN13EQJwANnEX2FUfcmQs68le1ZclrEdIGEBSpO9PARZ\n" -"tuBeu6IR9OaoeJlGwXDbiYAVcajT3oefp++ICTxtNvGchUuYiW4WvO2kmjVoJ3Q1\n" -"Afaxs1qDWcyNvS+HKUQjJNNX6kj1/N040JRyGqkFFMyNfLArewJwAL/KfLkJjmvT\n" -"QV7LW3cNNYbRRWdLXZLxvJfLQAdiv5BiiWRZUZkcnfq10HNMLSdfIiYfZocNCIrm\n" -"mz3sbLdYHLJy8qXsk8oNQLXGX9LXsCTJ2y6nUAZSbCbVVPEgfRhcZCvMIp7Q/YOs\n" -"f88QLx0UMQJvYsEnYagLe9EfC0d8fXTKJr143FMxas7j3eftxLEBnx7ZsqCbJD1o\n" -"UsvWkp5I3kqIABEqY1ZJV/gU41MceuWURSVADpuuRDLzv8WPdeffad9o2hX/bkI6\n" -"2INKeuq1nILiEHAZLloH6/fdjpWZYF0D\n" -"-----END RSA PRIVATE KEY-----\n"; + "-----BEGIN RSA PRIVATE KEY-----\n" + "MIIEBAIBAAKB3wC/VSBHG5adM0r0E80dgVvt+oVnnDcKYcm9q2WbknTL6dFgjjcE\n" + "biHDKmnr1hgyT9jfQVE/ve2XnZqAkbpYMNrQbdieclNycjoXCj3BJSJXXz3Ra6O4\n" + "DLNh0/XwsxbVd/tMSQvwAK0MR60K/yfruL2oxe8j7uDmS5oY8b5O9nP/EVW2u7P1\n" + "KVhrNxC2rGoaK6iRpgkAX3oP2YVMhLfPONpDgYGxBvrO0tlpHCYL+miWdRzIDPMY\n" + "tdcU1v1zVSKAsvJ2dgEwP6FoSiWPnkw3U41i4oe+T7kVEk1F9QLCnXsCAwEAAQKB\n" + "3iYR2gpMAvvkaNWH2xgz1QbVAhZLjugR7QJASEdcLMEmFPMRWQEYqL8cgVbbkpTw\n" + "Lka9yFzWfZ/dTBCo7lr93Yv7T063kMME12oeL4tuyBZ6bOJueHT2kfq1Igpyl+iB\n" + "pw7WuflXKRd4a4X0nwzYBQxYWH7bKkQRZDlViKuOXKVzgT7GqD6cbTZbc/8wUTi7\n" + "HoyMlz4d+YH/XL5Zt6SM7cMuJ/VOGGUcBiXqlixzulloihkPwJeg6zxx0e1dVy4q\n" + "jvVhb+hmypWajjBDPUwIGFih0lZJ6rqIDyls/ZK2AQJwAPFeAMubo1KWcFU+nHoK\n" + "Q/jdOjpuAt7fwczkqhb6uOrJtS4RUtF3x3jfESFYf6Btnt6Slj1HpNKHbud2Weyw\n" + "i3lIkkmQq4+8uRjZXlNtp2Sd33NFeYE1D8ll3V2wiwiCOPJxYWpOOwHs7pkcOsAD\n" + "ywJwAMruluGFAUhoCxXOGzbJeXOC0U+LbwU72Xgk9zhEX6chaklKgdSnJ8DlHnYe\n" + "R+wc2vXRfSGlT1OH0X8ezn82QV8UmYo6cNpMTNarW0rzpFir51owvYSBPnPB+DLX\n" + "0JausRZoI6fyZSw4Vxt9PN13EQJwANnEX2FUfcmQs68le1ZclrEdIGEBSpO9PARZ\n" + "tuBeu6IR9OaoeJlGwXDbiYAVcajT3oefp++ICTxtNvGchUuYiW4WvO2kmjVoJ3Q1\n" + "Afaxs1qDWcyNvS+HKUQjJNNX6kj1/N040JRyGqkFFMyNfLArewJwAL/KfLkJjmvT\n" + "QV7LW3cNNYbRRWdLXZLxvJfLQAdiv5BiiWRZUZkcnfq10HNMLSdfIiYfZocNCIrm\n" + "mz3sbLdYHLJy8qXsk8oNQLXGX9LXsCTJ2y6nUAZSbCbVVPEgfRhcZCvMIp7Q/YOs\n" + "f88QLx0UMQJvYsEnYagLe9EfC0d8fXTKJr143FMxas7j3eftxLEBnx7ZsqCbJD1o\n" + "UsvWkp5I3kqIABEqY1ZJV/gU41MceuWURSVADpuuRDLzv8WPdeffad9o2hX/bkI6\n" + "2INKeuq1nILiEHAZLloH6/fdjpWZYF0D\n" "-----END RSA PRIVATE KEY-----\n"; static unsigned char server_ecc_key_pem[] = - "-----BEGIN EC PRIVATE KEY-----\n" - "MGACAQEEGQCovzs4UsfRncfJXO3WOZUe/Zf+usKzEcWgCgYIKoZIzj0DAQGhNAMy\n" - "AAREwuCcUHKNWyetsymkAaqA0GCgksI2AjewpOWsraGrfea3GPw1uuyOQRMR7kka\n" - "v6s=\n" - "-----END EC PRIVATE KEY-----\n"; + "-----BEGIN EC PRIVATE KEY-----\n" + "MGACAQEEGQCovzs4UsfRncfJXO3WOZUe/Zf+usKzEcWgCgYIKoZIzj0DAQGhNAMy\n" + "AAREwuCcUHKNWyetsymkAaqA0GCgksI2AjewpOWsraGrfea3GPw1uuyOQRMR7kka\n" + "v6s=\n" "-----END EC PRIVATE KEY-----\n"; static unsigned char server_ecc_cert_pem[] = - "-----BEGIN CERTIFICATE-----\n" - "MIIBYDCCARWgAwIBAgIETuILrDAKBggqhkjOPQQDAjAcMQswCQYDVQQGEwJCRTEN\n" - "MAsGA1UEChMEVGVzdDAeFw0xMTEyMDkxMzIyNTJaFw0xNzA4MTExMzIyNTlaMBwx\n" - "CzAJBgNVBAYTAkJFMQ0wCwYDVQQKEwRUZXN0MEkwEwYHKoZIzj0CAQYIKoZIzj0D\n" - "AQEDMgAERMLgnFByjVsnrbMppAGqgNBgoJLCNgI3sKTlrK2hq33mtxj8NbrsjkET\n" - "Ee5JGr+ro1UwUzAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8G\n" - "A1UdDwEB/wQFAwMHgAAwHQYDVR0OBBYEFKeR27mtYWFaH43U2zEvjd28Zf+CMAoG\n" - "CCqGSM49BAMCAzkAMDYCGQD7WWWiFV+ddI7tIyMFepKFA1dX4nlc/+ICGQCCPdHc\n" - "gMyHv2XyfOGHLhq0HmDTOOiwfC4=\n" - "-----END CERTIFICATE-----\n"; + "-----BEGIN CERTIFICATE-----\n" + "MIIBYDCCARWgAwIBAgIETuILrDAKBggqhkjOPQQDAjAcMQswCQYDVQQGEwJCRTEN\n" + "MAsGA1UEChMEVGVzdDAeFw0xMTEyMDkxMzIyNTJaFw0xNzA4MTExMzIyNTlaMBwx\n" + "CzAJBgNVBAYTAkJFMQ0wCwYDVQQKEwRUZXN0MEkwEwYHKoZIzj0CAQYIKoZIzj0D\n" + "AQEDMgAERMLgnFByjVsnrbMppAGqgNBgoJLCNgI3sKTlrK2hq33mtxj8NbrsjkET\n" + "Ee5JGr+ro1UwUzAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8G\n" + "A1UdDwEB/wQFAwMHgAAwHQYDVR0OBBYEFKeR27mtYWFaH43U2zEvjd28Zf+CMAoG\n" + "CCqGSM49BAMCAzkAMDYCGQD7WWWiFV+ddI7tIyMFepKFA1dX4nlc/+ICGQCCPdHc\n" + "gMyHv2XyfOGHLhq0HmDTOOiwfC4=\n" "-----END CERTIFICATE-----\n"; const gnutls_datum_t server_cert = { server_cert_pem, - sizeof (server_cert_pem) + sizeof(server_cert_pem) }; const gnutls_datum_t server_key = { server_key_pem, - sizeof (server_key_pem) + sizeof(server_key_pem) }; const gnutls_datum_t server_ecc_cert = { server_ecc_cert_pem, - sizeof (server_ecc_cert_pem) + sizeof(server_ecc_cert_pem) }; const gnutls_datum_t server_ecc_key = { server_ecc_key_pem, - sizeof (server_ecc_key_pem) + sizeof(server_ecc_key_pem) }; char buffer[64 * 1024]; static void tls_log_func(int level, const char *str) { - fprintf(stderr, "%s|<%d>| %s", side, level, str); + fprintf(stderr, "%s|<%d>| %s", side, level, str); } static void test_ciphersuite(const char *cipher_prio, int size) { - /* Server stuff. */ - gnutls_anon_server_credentials_t s_anoncred; - gnutls_certificate_credentials_t c_certcred, s_certcred; - const gnutls_datum_t p3 = { (void*) pkcs3, strlen(pkcs3) }; - static gnutls_dh_params_t dh_params; - gnutls_session_t server; - int sret, cret; - const char *str; - /* Client stuff. */ - gnutls_anon_client_credentials_t c_anoncred; - gnutls_session_t client; - /* Need to enable anonymous KX specifically. */ - int ret; - struct benchmark_st st; - - /* Init server */ - gnutls_anon_allocate_server_credentials(&s_anoncred); - gnutls_dh_params_init(&dh_params); - gnutls_dh_params_import_pkcs3(dh_params, &p3, GNUTLS_X509_FMT_PEM); - gnutls_anon_set_server_dh_params(s_anoncred, dh_params); - - gnutls_certificate_allocate_credentials(&s_certcred); - gnutls_certificate_set_dh_params(s_certcred, dh_params); - - gnutls_certificate_set_x509_key_mem (s_certcred, &server_cert, &server_key, - GNUTLS_X509_FMT_PEM); - gnutls_certificate_set_x509_key_mem (s_certcred, &server_ecc_cert, &server_ecc_key, - GNUTLS_X509_FMT_PEM); - - gnutls_init(&server, GNUTLS_SERVER); - ret = gnutls_priority_set_direct(server, cipher_prio, &str); - if (ret < 0) { - fprintf(stderr, "Error in %s\n", str); - exit(1); - } - gnutls_credentials_set(server, GNUTLS_CRD_ANON, s_anoncred); - gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, s_certcred); - gnutls_transport_set_push_function(server, server_push); - gnutls_transport_set_pull_function(server, server_pull); - gnutls_transport_set_ptr(server, (gnutls_transport_ptr_t) server); - reset_buffers(); - - /* Init client */ - gnutls_anon_allocate_client_credentials(&c_anoncred); - gnutls_certificate_allocate_credentials(&c_certcred); - gnutls_init(&client, GNUTLS_CLIENT); - - ret = gnutls_priority_set_direct(client, cipher_prio, &str); - if (ret < 0) { - fprintf(stderr, "Error in %s\n", str); - exit(1); - } - gnutls_credentials_set(client, GNUTLS_CRD_ANON, c_anoncred); - gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, c_certcred); - gnutls_transport_set_push_function(client, client_push); - gnutls_transport_set_pull_function(client, client_pull); - gnutls_transport_set_ptr(client, (gnutls_transport_ptr_t) client); - - HANDSHAKE(client, server); - - fprintf(stdout, "%38s ", - gnutls_cipher_suite_get_name(gnutls_kx_get(server), - gnutls_cipher_get(server), - gnutls_mac_get(server))); - fflush(stdout); - - gnutls_rnd(GNUTLS_RND_NONCE, buffer, sizeof(buffer)); - - start_benchmark(&st); - - do { - do { - ret = gnutls_record_send(client, buffer, size); - } - while (ret == GNUTLS_E_AGAIN); - - if (ret < 0) { - fprintf(stderr, "Failed sending to server\n"); - exit(1); - } - - do { - ret = gnutls_record_recv(server, buffer, sizeof(buffer)); - } - while (ret == GNUTLS_E_AGAIN); - - if (ret < 0) { - fprintf(stderr, "Failed receiving from client\n"); - exit(1); - } - - st.size += size; - } - while (benchmark_must_finish == 0); - - stop_benchmark(&st, NULL, 1); - - gnutls_bye(client, GNUTLS_SHUT_WR); - gnutls_bye(server, GNUTLS_SHUT_WR); - - gnutls_deinit(client); - gnutls_deinit(server); - - gnutls_anon_free_client_credentials(c_anoncred); - gnutls_anon_free_server_credentials(s_anoncred); - - gnutls_dh_params_deinit(dh_params); + /* Server stuff. */ + gnutls_anon_server_credentials_t s_anoncred; + gnutls_certificate_credentials_t c_certcred, s_certcred; + const gnutls_datum_t p3 = { (void *) pkcs3, strlen(pkcs3) }; + static gnutls_dh_params_t dh_params; + gnutls_session_t server; + int sret, cret; + const char *str; + /* Client stuff. */ + gnutls_anon_client_credentials_t c_anoncred; + gnutls_session_t client; + /* Need to enable anonymous KX specifically. */ + int ret; + struct benchmark_st st; + + /* Init server */ + gnutls_anon_allocate_server_credentials(&s_anoncred); + gnutls_dh_params_init(&dh_params); + gnutls_dh_params_import_pkcs3(dh_params, &p3, GNUTLS_X509_FMT_PEM); + gnutls_anon_set_server_dh_params(s_anoncred, dh_params); + + gnutls_certificate_allocate_credentials(&s_certcred); + gnutls_certificate_set_dh_params(s_certcred, dh_params); + + gnutls_certificate_set_x509_key_mem(s_certcred, &server_cert, + &server_key, + GNUTLS_X509_FMT_PEM); + gnutls_certificate_set_x509_key_mem(s_certcred, &server_ecc_cert, + &server_ecc_key, + GNUTLS_X509_FMT_PEM); + + gnutls_init(&server, GNUTLS_SERVER); + ret = gnutls_priority_set_direct(server, cipher_prio, &str); + if (ret < 0) { + fprintf(stderr, "Error in %s\n", str); + exit(1); + } + gnutls_credentials_set(server, GNUTLS_CRD_ANON, s_anoncred); + gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, s_certcred); + gnutls_transport_set_push_function(server, server_push); + gnutls_transport_set_pull_function(server, server_pull); + gnutls_transport_set_ptr(server, (gnutls_transport_ptr_t) server); + reset_buffers(); + + /* Init client */ + gnutls_anon_allocate_client_credentials(&c_anoncred); + gnutls_certificate_allocate_credentials(&c_certcred); + gnutls_init(&client, GNUTLS_CLIENT); + + ret = gnutls_priority_set_direct(client, cipher_prio, &str); + if (ret < 0) { + fprintf(stderr, "Error in %s\n", str); + exit(1); + } + gnutls_credentials_set(client, GNUTLS_CRD_ANON, c_anoncred); + gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, c_certcred); + gnutls_transport_set_push_function(client, client_push); + gnutls_transport_set_pull_function(client, client_pull); + gnutls_transport_set_ptr(client, (gnutls_transport_ptr_t) client); + + HANDSHAKE(client, server); + + fprintf(stdout, "%38s ", + gnutls_cipher_suite_get_name(gnutls_kx_get(server), + gnutls_cipher_get(server), + gnutls_mac_get(server))); + fflush(stdout); + + gnutls_rnd(GNUTLS_RND_NONCE, buffer, sizeof(buffer)); + + start_benchmark(&st); + + do { + do { + ret = gnutls_record_send(client, buffer, size); + } + while (ret == GNUTLS_E_AGAIN); + + if (ret < 0) { + fprintf(stderr, "Failed sending to server\n"); + exit(1); + } + + do { + ret = + gnutls_record_recv(server, buffer, + sizeof(buffer)); + } + while (ret == GNUTLS_E_AGAIN); + + if (ret < 0) { + fprintf(stderr, "Failed receiving from client\n"); + exit(1); + } + + st.size += size; + } + while (benchmark_must_finish == 0); + + stop_benchmark(&st, NULL, 1); + + gnutls_bye(client, GNUTLS_SHUT_WR); + gnutls_bye(server, GNUTLS_SHUT_WR); + + gnutls_deinit(client); + gnutls_deinit(server); + + gnutls_anon_free_client_credentials(c_anoncred); + gnutls_anon_free_server_credentials(s_anoncred); + + gnutls_dh_params_deinit(dh_params); } static double calc_avg(unsigned int *diffs, unsigned int diffs_size) { -double avg = 0; -unsigned int i; + double avg = 0; + unsigned int i; + + for (i = 0; i < diffs_size; i++) + avg += diffs[i]; - for(i=0;i<diffs_size;i++) - avg += diffs[i]; - - avg /= diffs_size; + avg /= diffs_size; - return avg; + return avg; } static -double calc_sstdev(unsigned int *diffs, unsigned int diffs_size, double avg) +double calc_sstdev(unsigned int *diffs, unsigned int diffs_size, + double avg) { -double sum = 0, d; -unsigned int i; - - for (i=0;i<diffs_size;i++) { - d = ((double)diffs[i] - avg); - d *= d; - - sum += d; - } - sum /= diffs_size - 1; - - return sum; + double sum = 0, d; + unsigned int i; + + for (i = 0; i < diffs_size; i++) { + d = ((double) diffs[i] - avg); + d *= d; + + sum += d; + } + sum /= diffs_size - 1; + + return sum; } -unsigned int diffs[32*1024]; +unsigned int diffs[32 * 1024]; unsigned int diffs_size = 0; static void test_ciphersuite_kx(const char *cipher_prio) { - /* Server stuff. */ - gnutls_anon_server_credentials_t s_anoncred; - const gnutls_datum_t p3 = { (void*) pkcs3, strlen(pkcs3) }; - static gnutls_dh_params_t dh_params; - gnutls_session_t server; - int sret, cret; - const char *str; - const char *suite = NULL; - /* Client stuff. */ - gnutls_anon_client_credentials_t c_anoncred; - gnutls_certificate_credentials_t c_certcred, s_certcred; - gnutls_session_t client; - /* Need to enable anonymous KX specifically. */ - int ret; - struct benchmark_st st; - struct timespec tr_start, tr_stop; - double avg, sstddev; - - diffs_size = 0; - - /* Init server */ - gnutls_certificate_allocate_credentials(&s_certcred); - gnutls_anon_allocate_server_credentials(&s_anoncred); - gnutls_dh_params_init(&dh_params); - if ((ret=gnutls_dh_params_import_pkcs3(dh_params, &p3, GNUTLS_X509_FMT_PEM)) < 0) { - fprintf(stderr, "Error importing the PKCS #3 params: %s\n", gnutls_strerror(ret)); - exit(1); - } - gnutls_anon_set_server_dh_params(s_anoncred, dh_params); - gnutls_certificate_set_dh_params(s_certcred, dh_params); - - gnutls_certificate_set_x509_key_mem (s_certcred, &server_cert, &server_key, - GNUTLS_X509_FMT_PEM); - gnutls_certificate_set_x509_key_mem (s_certcred, &server_ecc_cert, &server_ecc_key, - GNUTLS_X509_FMT_PEM); - - /* Init client */ - gnutls_anon_allocate_client_credentials(&c_anoncred); - gnutls_certificate_allocate_credentials(&c_certcred); - - start_benchmark(&st); - - do { - - gnutls_init(&server, GNUTLS_SERVER); - ret = gnutls_priority_set_direct(server, cipher_prio, &str); - if (ret < 0) { - fprintf(stderr, "Error in %s\n", str); - exit(1); - } - gnutls_credentials_set(server, GNUTLS_CRD_ANON, s_anoncred); - gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, s_certcred); - gnutls_transport_set_push_function(server, server_push); - gnutls_transport_set_pull_function(server, server_pull); - gnutls_transport_set_ptr(server, (gnutls_transport_ptr_t) server); - reset_buffers(); - - gnutls_init(&client, GNUTLS_CLIENT); - - ret = gnutls_priority_set_direct(client, cipher_prio, &str); - if (ret < 0) { - fprintf(stderr, "Error in %s\n", str); - exit(1); - } - gnutls_credentials_set(client, GNUTLS_CRD_ANON, c_anoncred); - gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, c_certcred); - - gnutls_transport_set_push_function(client, client_push); - gnutls_transport_set_pull_function(client, client_pull); - gnutls_transport_set_ptr(client, (gnutls_transport_ptr_t) client); - - gettime(&tr_start); - - HANDSHAKE(client, server); - - gettime(&tr_stop); - - if (suite == NULL) - suite = gnutls_cipher_suite_get_name(gnutls_kx_get(server), - gnutls_cipher_get(server), - gnutls_mac_get(server)); - - gnutls_deinit(client); - gnutls_deinit(server); - - diffs[diffs_size++] = timespec_sub_ms(&tr_stop, &tr_start); - if (diffs_size > sizeof(diffs)) - abort(); - - st.size += 1; - } - while (benchmark_must_finish == 0); - - fprintf(stdout, "%38s ", suite); - stop_benchmark(&st, "transactions", 1); - - avg = calc_avg(diffs, diffs_size); - sstddev = calc_sstdev(diffs, diffs_size, avg); - - printf("%32s %.2f ms, sample variance: %.2f)\n", "(avg. handshake time:", avg, sstddev); - - gnutls_anon_free_client_credentials(c_anoncred); - gnutls_anon_free_server_credentials(s_anoncred); - - gnutls_dh_params_deinit(dh_params); + /* Server stuff. */ + gnutls_anon_server_credentials_t s_anoncred; + const gnutls_datum_t p3 = { (void *) pkcs3, strlen(pkcs3) }; + static gnutls_dh_params_t dh_params; + gnutls_session_t server; + int sret, cret; + const char *str; + const char *suite = NULL; + /* Client stuff. */ + gnutls_anon_client_credentials_t c_anoncred; + gnutls_certificate_credentials_t c_certcred, s_certcred; + gnutls_session_t client; + /* Need to enable anonymous KX specifically. */ + int ret; + struct benchmark_st st; + struct timespec tr_start, tr_stop; + double avg, sstddev; + + diffs_size = 0; + + /* Init server */ + gnutls_certificate_allocate_credentials(&s_certcred); + gnutls_anon_allocate_server_credentials(&s_anoncred); + gnutls_dh_params_init(&dh_params); + if ((ret = + gnutls_dh_params_import_pkcs3(dh_params, &p3, + GNUTLS_X509_FMT_PEM)) < 0) { + fprintf(stderr, "Error importing the PKCS #3 params: %s\n", + gnutls_strerror(ret)); + exit(1); + } + gnutls_anon_set_server_dh_params(s_anoncred, dh_params); + gnutls_certificate_set_dh_params(s_certcred, dh_params); + + gnutls_certificate_set_x509_key_mem(s_certcred, &server_cert, + &server_key, + GNUTLS_X509_FMT_PEM); + gnutls_certificate_set_x509_key_mem(s_certcred, &server_ecc_cert, + &server_ecc_key, + GNUTLS_X509_FMT_PEM); + + /* Init client */ + gnutls_anon_allocate_client_credentials(&c_anoncred); + gnutls_certificate_allocate_credentials(&c_certcred); + + start_benchmark(&st); + + do { + + gnutls_init(&server, GNUTLS_SERVER); + ret = + gnutls_priority_set_direct(server, cipher_prio, &str); + if (ret < 0) { + fprintf(stderr, "Error in %s\n", str); + exit(1); + } + gnutls_credentials_set(server, GNUTLS_CRD_ANON, + s_anoncred); + gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, + s_certcred); + gnutls_transport_set_push_function(server, server_push); + gnutls_transport_set_pull_function(server, server_pull); + gnutls_transport_set_ptr(server, + (gnutls_transport_ptr_t) server); + reset_buffers(); + + gnutls_init(&client, GNUTLS_CLIENT); + + ret = + gnutls_priority_set_direct(client, cipher_prio, &str); + if (ret < 0) { + fprintf(stderr, "Error in %s\n", str); + exit(1); + } + gnutls_credentials_set(client, GNUTLS_CRD_ANON, + c_anoncred); + gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, + c_certcred); + + gnutls_transport_set_push_function(client, client_push); + gnutls_transport_set_pull_function(client, client_pull); + gnutls_transport_set_ptr(client, + (gnutls_transport_ptr_t) client); + + gettime(&tr_start); + + HANDSHAKE(client, server); + + gettime(&tr_stop); + + if (suite == NULL) + suite = + gnutls_cipher_suite_get_name(gnutls_kx_get + (server), + gnutls_cipher_get + (server), + gnutls_mac_get + (server)); + + gnutls_deinit(client); + gnutls_deinit(server); + + diffs[diffs_size++] = timespec_sub_ms(&tr_stop, &tr_start); + if (diffs_size > sizeof(diffs)) + abort(); + + st.size += 1; + } + while (benchmark_must_finish == 0); + + fprintf(stdout, "%38s ", suite); + stop_benchmark(&st, "transactions", 1); + + avg = calc_avg(diffs, diffs_size); + sstddev = calc_sstdev(diffs, diffs_size, avg); + + printf("%32s %.2f ms, sample variance: %.2f)\n", + "(avg. handshake time:", avg, sstddev); + + gnutls_anon_free_client_credentials(c_anoncred); + gnutls_anon_free_server_credentials(s_anoncred); + + gnutls_dh_params_deinit(dh_params); } void benchmark_tls(int debug_level, int ciphers) { - int size; - - gnutls_global_set_log_function(tls_log_func); - gnutls_global_set_log_level(debug_level); - gnutls_global_init(); - - if (ciphers != 0) - { - size = 1400; - printf("Testing throughput in cipher/MAC combinations (payload: %d bytes)\n", size); - - test_ciphersuite(PRIO_SALSA20_256_UMAC_96, size); - test_ciphersuite(PRIO_SALSA20_256_SHA1, size); - test_ciphersuite(PRIO_ESTREAM_SALSA20_256_UMAC_96, size); - test_ciphersuite(PRIO_ESTREAM_SALSA20_256_SHA1, size); - test_ciphersuite(PRIO_ARCFOUR_128_SHA1, size); - test_ciphersuite(PRIO_ARCFOUR_128_MD5, size); - test_ciphersuite(PRIO_AES_GCM, size); - test_ciphersuite(PRIO_AES_CBC_SHA1, size); - test_ciphersuite(PRIO_CAMELLIA_CBC_SHA1, size); - - size = 15*1024; - printf("\nTesting throughput in cipher/MAC combinations (payload: %d bytes)\n", size); - test_ciphersuite(PRIO_SALSA20_256_UMAC_96, size); - test_ciphersuite(PRIO_SALSA20_256_SHA1, size); - test_ciphersuite(PRIO_ESTREAM_SALSA20_256_UMAC_96, size); - test_ciphersuite(PRIO_ESTREAM_SALSA20_256_SHA1, size); - test_ciphersuite(PRIO_ARCFOUR_128_SHA1, size); - test_ciphersuite(PRIO_ARCFOUR_128_MD5, size); - test_ciphersuite(PRIO_AES_GCM, size); - test_ciphersuite(PRIO_AES_CBC_SHA1, size); - test_ciphersuite(PRIO_CAMELLIA_CBC_SHA1, size); - } - else - { - printf("Testing key exchanges (RSA/DH bits: %d, EC bits: %d)\n", rsa_bits, ec_bits); - test_ciphersuite_kx(PRIO_DH); - test_ciphersuite_kx(PRIO_ECDH); - test_ciphersuite_kx(PRIO_ECDHE_ECDSA); - test_ciphersuite_kx(PRIO_RSA); - } - - gnutls_global_deinit(); - + int size; + + gnutls_global_set_log_function(tls_log_func); + gnutls_global_set_log_level(debug_level); + gnutls_global_init(); + + if (ciphers != 0) { + size = 1400; + printf + ("Testing throughput in cipher/MAC combinations (payload: %d bytes)\n", + size); + + test_ciphersuite(PRIO_SALSA20_256_UMAC_96, size); + test_ciphersuite(PRIO_SALSA20_256_SHA1, size); + test_ciphersuite(PRIO_ESTREAM_SALSA20_256_UMAC_96, size); + test_ciphersuite(PRIO_ESTREAM_SALSA20_256_SHA1, size); + test_ciphersuite(PRIO_ARCFOUR_128_SHA1, size); + test_ciphersuite(PRIO_ARCFOUR_128_MD5, size); + test_ciphersuite(PRIO_AES_GCM, size); + test_ciphersuite(PRIO_AES_CBC_SHA1, size); + test_ciphersuite(PRIO_CAMELLIA_CBC_SHA1, size); + + size = 15 * 1024; + printf + ("\nTesting throughput in cipher/MAC combinations (payload: %d bytes)\n", + size); + test_ciphersuite(PRIO_SALSA20_256_UMAC_96, size); + test_ciphersuite(PRIO_SALSA20_256_SHA1, size); + test_ciphersuite(PRIO_ESTREAM_SALSA20_256_UMAC_96, size); + test_ciphersuite(PRIO_ESTREAM_SALSA20_256_SHA1, size); + test_ciphersuite(PRIO_ARCFOUR_128_SHA1, size); + test_ciphersuite(PRIO_ARCFOUR_128_MD5, size); + test_ciphersuite(PRIO_AES_GCM, size); + test_ciphersuite(PRIO_AES_CBC_SHA1, size); + test_ciphersuite(PRIO_CAMELLIA_CBC_SHA1, size); + } else { + printf + ("Testing key exchanges (RSA/DH bits: %d, EC bits: %d)\n", + rsa_bits, ec_bits); + test_ciphersuite_kx(PRIO_DH); + test_ciphersuite_kx(PRIO_ECDH); + test_ciphersuite_kx(PRIO_ECDHE_ECDSA); + test_ciphersuite_kx(PRIO_RSA); + } + + gnutls_global_deinit(); + } diff --git a/src/benchmark.c b/src/benchmark.c index 6cc79e2404..f8a9562529 100644 --- a/src/benchmark.c +++ b/src/benchmark.c @@ -32,130 +32,124 @@ int benchmark_must_finish = 0; #if defined(_WIN32) #include <windows.h> -DWORD WINAPI -alarm_handler (LPVOID lpParameter) +DWORD WINAPI alarm_handler(LPVOID lpParameter) { - HANDLE wtimer = *((HANDLE *) lpParameter); - WaitForSingleObject (wtimer, INFINITE); - benchmark_must_finish = 1; - return 0; + HANDLE wtimer = *((HANDLE *) lpParameter); + WaitForSingleObject(wtimer, INFINITE); + benchmark_must_finish = 1; + return 0; } #else -static void -alarm_handler (int signo) +static void alarm_handler(int signo) { - benchmark_must_finish = 1; + benchmark_must_finish = 1; } #endif static void -value2human (unsigned long bytes, double time, double *data, double *speed, - char *metric) +value2human(unsigned long bytes, double time, double *data, double *speed, + char *metric) { - if (bytes > 1000 && bytes < 1000 * 1000) - { - *data = ((double) bytes) / 1000; - *speed = *data / time; - strcpy (metric, "KB"); - return; - } - else if (bytes >= 1000 * 1000 && bytes < 1000 * 1000 * 1000) - { - *data = ((double) bytes) / (1000 * 1000); - *speed = *data / time; - strcpy (metric, "MB"); - return; - } - else if (bytes >= 1000 * 1000 * 1000) - { - *data = ((double) bytes) / (1000 * 1000 * 1000); - *speed = *data / time; - strcpy (metric, "GB"); - return; - } - else - { - *data = (double) bytes; - *speed = *data / time; - strcpy (metric, "bytes"); - return; - } + if (bytes > 1000 && bytes < 1000 * 1000) { + *data = ((double) bytes) / 1000; + *speed = *data / time; + strcpy(metric, "KB"); + return; + } else if (bytes >= 1000 * 1000 && bytes < 1000 * 1000 * 1000) { + *data = ((double) bytes) / (1000 * 1000); + *speed = *data / time; + strcpy(metric, "MB"); + return; + } else if (bytes >= 1000 * 1000 * 1000) { + *data = ((double) bytes) / (1000 * 1000 * 1000); + *speed = *data / time; + strcpy(metric, "GB"); + return; + } else { + *data = (double) bytes; + *speed = *data / time; + strcpy(metric, "bytes"); + return; + } } -void start_benchmark(struct benchmark_st * st) +void start_benchmark(struct benchmark_st *st) { - memset(st, 0, sizeof(*st)); + memset(st, 0, sizeof(*st)); #ifndef _WIN32 - st->old_handler = signal (SIGALRM, alarm_handler); + st->old_handler = signal(SIGALRM, alarm_handler); #endif - gettime (&st->start); - benchmark_must_finish = 0; + gettime(&st->start); + benchmark_must_finish = 0; #if defined(_WIN32) - st->wtimer = CreateWaitableTimer (NULL, TRUE, NULL); - if (st->wtimer == NULL) - { - fprintf (stderr, "error: CreateWaitableTimer %u\n", GetLastError ()); - exit(1); - } - st->wthread = CreateThread (NULL, 0, alarm_handler, &st->wtimer, 0, NULL); - if (st->wthread == NULL) - { - fprintf (stderr, "error: CreateThread %u\n", GetLastError ()); - exit(1); - } - st->alarm_timeout.QuadPart = (BSECS) * 10000000; - if (SetWaitableTimer (st->wtimer, &st->alarm_timeout, 0, NULL, NULL, FALSE) == 0) - { - fprintf (stderr, "error: SetWaitableTimer %u\n", GetLastError ()); - exit(1); - } + st->wtimer = CreateWaitableTimer(NULL, TRUE, NULL); + if (st->wtimer == NULL) { + fprintf(stderr, "error: CreateWaitableTimer %u\n", + GetLastError()); + exit(1); + } + st->wthread = + CreateThread(NULL, 0, alarm_handler, &st->wtimer, 0, NULL); + if (st->wthread == NULL) { + fprintf(stderr, "error: CreateThread %u\n", + GetLastError()); + exit(1); + } + st->alarm_timeout.QuadPart = (BSECS) * 10000000; + if (SetWaitableTimer + (st->wtimer, &st->alarm_timeout, 0, NULL, NULL, FALSE) == 0) { + fprintf(stderr, "error: SetWaitableTimer %u\n", + GetLastError()); + exit(1); + } #else - alarm (BSECS); + alarm(BSECS); #endif - + } /* returns the elapsed time */ -double stop_benchmark(struct benchmark_st * st, const char* metric, int quiet) +double stop_benchmark(struct benchmark_st *st, const char *metric, + int quiet) { - double secs; - unsigned long lsecs; - struct timespec stop; - double dspeed, ddata; - char imetric[16]; + double secs; + unsigned long lsecs; + struct timespec stop; + double dspeed, ddata; + char imetric[16]; #if defined(_WIN32) - if (st->wtimer != NULL) - CloseHandle (st->wtimer); - if (st->wthread != NULL) - CloseHandle (st->wthread); + if (st->wtimer != NULL) + CloseHandle(st->wtimer); + if (st->wthread != NULL) + CloseHandle(st->wthread); #else - signal(SIGALRM, st->old_handler); + signal(SIGALRM, st->old_handler); #endif - gettime (&stop); + gettime(&stop); - lsecs = (stop.tv_sec * 1000 + stop.tv_nsec / (1000 * 1000) - - (st->start.tv_sec * 1000 + st->start.tv_nsec / (1000 * 1000))); - secs = lsecs; - secs /= 1000; + lsecs = (stop.tv_sec * 1000 + stop.tv_nsec / (1000 * 1000) - + (st->start.tv_sec * 1000 + + st->start.tv_nsec / (1000 * 1000))); + secs = lsecs; + secs /= 1000; - if (metric == NULL) - { /* assume bytes/sec */ - value2human (st->size, secs, &ddata, &dspeed, imetric); - if (quiet == 0) - printf (" Processed %.2f %s in %.2f secs: ", ddata, imetric, secs); - printf ("%.2f %s/sec\n", dspeed, imetric); - } - else - { - ddata = (double) st->size; - dspeed = ddata / secs; - if (quiet == 0) - printf (" Processed %.2f %s in %.2f secs: ", ddata, metric, secs); - printf ("%.2f %s/sec\n", dspeed, metric); - } + if (metric == NULL) { /* assume bytes/sec */ + value2human(st->size, secs, &ddata, &dspeed, imetric); + if (quiet == 0) + printf(" Processed %.2f %s in %.2f secs: ", ddata, + imetric, secs); + printf("%.2f %s/sec\n", dspeed, imetric); + } else { + ddata = (double) st->size; + dspeed = ddata / secs; + if (quiet == 0) + printf(" Processed %.2f %s in %.2f secs: ", ddata, + metric, secs); + printf("%.2f %s/sec\n", dspeed, metric); + } - return secs; + return secs; } diff --git a/src/benchmark.h b/src/benchmark.h index 4f2619c96e..cadd0d2615 100644 --- a/src/benchmark.h +++ b/src/benchmark.h @@ -21,48 +21,47 @@ #include <time.h> #include <signal.h> #if defined(_WIN32) -# include <windows.h> +#include <windows.h> #endif #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_PROCESS_CPUTIME_ID) -# undef gettime -# define gettime(x) clock_gettime(CLOCK_PROCESS_CPUTIME_ID, x) +#undef gettime +#define gettime(x) clock_gettime(CLOCK_PROCESS_CPUTIME_ID, x) #else -inline static void -gettime (struct timespec *ts) +inline static void gettime(struct timespec *ts) { -struct timeval tv; - gettimeofday (&tv, NULL); - ts->tv_sec = tv.tv_sec; - ts->tv_nsec = tv.tv_usec * 1000; + struct timeval tv; + gettimeofday(&tv, NULL); + ts->tv_sec = tv.tv_sec; + ts->tv_nsec = tv.tv_usec * 1000; } #endif -typedef void (*sighandler_t)(int); +typedef void (*sighandler_t) (int); -void benchmark_cipher (int init, int debug_level); -void benchmark_tls (int debug_level, int ciphers); +void benchmark_cipher(int init, int debug_level); +void benchmark_tls(int debug_level, int ciphers); -struct benchmark_st -{ - struct timespec start; - unsigned long size; - sighandler_t old_handler; +struct benchmark_st { + struct timespec start; + unsigned long size; + sighandler_t old_handler; #if defined(_WIN32) - HANDLE wtimer; - HANDLE wthread; - LARGE_INTEGER alarm_timeout; + HANDLE wtimer; + HANDLE wthread; + LARGE_INTEGER alarm_timeout; #endif }; extern int benchmark_must_finish; -void start_benchmark(struct benchmark_st * st); -double stop_benchmark(struct benchmark_st * st, const char* metric, int quiet); +void start_benchmark(struct benchmark_st *st); +double stop_benchmark(struct benchmark_st *st, const char *metric, + int quiet); inline static unsigned int -timespec_sub_ms (struct timespec *a, struct timespec *b) +timespec_sub_ms(struct timespec *a, struct timespec *b) { - return (a->tv_sec * 1000 + a->tv_nsec / (1000 * 1000) - - (b->tv_sec * 1000 + b->tv_nsec / (1000 * 1000))); + return (a->tv_sec * 1000 + a->tv_nsec / (1000 * 1000) - + (b->tv_sec * 1000 + b->tv_nsec / (1000 * 1000))); } diff --git a/src/certtool-cfg.c b/src/certtool-cfg.c index 6e7211ce82..da95738d96 100644 --- a/src/certtool-cfg.c +++ b/src/certtool-cfg.c @@ -36,9 +36,9 @@ #include <sys/types.h> #if HAVE_SYS_SOCKET_H -# include <sys/socket.h> +#include <sys/socket.h> #elif HAVE_WS2TCPIP_H -# include <ws2tcpip.h> +#include <ws2tcpip.h> #endif #include <arpa/inet.h> @@ -51,61 +51,59 @@ extern int batch; #define MAX_ENTRIES 128 #define MAX_POLICIES 8 -typedef struct _cfg_ctx -{ - char *organization; - char *unit; - char *locality; - char *state; - char *dn; - char *cn; - char *uid; - char *challenge_password; - char *pkcs9_email; - char *country; - char *policy_oid[MAX_POLICIES]; - char *policy_txt[MAX_POLICIES]; - char *policy_url[MAX_POLICIES]; - char **dc; - char **dns_name; - char **uri; - char **ip_addr; - char **email; - char **dn_oid; - char *crl_dist_points; - char *password; - char *pkcs12_key_name; - int serial; - int expiration_days; - int ca; - int path_len; - int tls_www_client; - int tls_www_server; - int signing_key; - int encryption_key; - int cert_sign_key; - int crl_sign_key; - int code_sign_key; - int ocsp_sign_key; - int time_stamping_key; - int ipsec_ike_key; - char **key_purpose_oids; - int crl_next_update; - int crl_number; - int crq_extensions; - char *proxy_policy_language; - char **ocsp_uris; - char **ca_issuers_uris; +typedef struct _cfg_ctx { + char *organization; + char *unit; + char *locality; + char *state; + char *dn; + char *cn; + char *uid; + char *challenge_password; + char *pkcs9_email; + char *country; + char *policy_oid[MAX_POLICIES]; + char *policy_txt[MAX_POLICIES]; + char *policy_url[MAX_POLICIES]; + char **dc; + char **dns_name; + char **uri; + char **ip_addr; + char **email; + char **dn_oid; + char *crl_dist_points; + char *password; + char *pkcs12_key_name; + int serial; + int expiration_days; + int ca; + int path_len; + int tls_www_client; + int tls_www_server; + int signing_key; + int encryption_key; + int cert_sign_key; + int crl_sign_key; + int code_sign_key; + int ocsp_sign_key; + int time_stamping_key; + int ipsec_ike_key; + char **key_purpose_oids; + int crl_next_update; + int crl_number; + int crq_extensions; + char *proxy_policy_language; + char **ocsp_uris; + char **ca_issuers_uris; } cfg_ctx; cfg_ctx cfg; -void -cfg_init (void) +void cfg_init(void) { - memset (&cfg, 0, sizeof (cfg)); - cfg.path_len = -1; - cfg.serial = -1; + memset(&cfg, 0, sizeof(cfg)); + cfg.path_len = -1; + cfg.serial = -1; } #define READ_MULTI_LINE(name, s_name) \ @@ -179,1624 +177,1518 @@ cfg_init (void) s_name = atoi(val->v.strVal); \ } -int -template_parse (const char *template) +int template_parse(const char *template) { - /* Parsing return code */ - int ret; - unsigned int i; - tOptionValue const * pov; - const tOptionValue* val; - char tmpstr[256]; - - pov = configFileLoad(template); - if (pov == NULL) - { - perror("configFileLoad"); - fprintf(stderr, "Error loading template: %s\n", template); - exit(1); - } - - /* Option variables */ - val = optionGetValue(pov, "organization"); - if (val != NULL && val->valType == OPARG_TYPE_STRING) - cfg.organization = strdup(val->v.strVal); - - val = optionGetValue(pov, "unit"); - if (val != NULL && val->valType == OPARG_TYPE_STRING) - cfg.unit = strdup(val->v.strVal); - - val = optionGetValue(pov, "locality"); - if (val != NULL && val->valType == OPARG_TYPE_STRING) - cfg.locality = strdup(val->v.strVal); - - val = optionGetValue(pov, "state"); - if (val != NULL && val->valType == OPARG_TYPE_STRING) - cfg.state = strdup(val->v.strVal); - - val = optionGetValue(pov, "dn"); - if (val != NULL && val->valType == OPARG_TYPE_STRING) - cfg.dn = strdup(val->v.strVal); - - val = optionGetValue(pov, "cn"); - if (val != NULL && val->valType == OPARG_TYPE_STRING) - cfg.cn = strdup(val->v.strVal); - - val = optionGetValue(pov, "uid"); - if (val != NULL && val->valType == OPARG_TYPE_STRING) - cfg.uid = strdup(val->v.strVal); - - val = optionGetValue(pov, "challenge_password"); - if (val != NULL && val->valType == OPARG_TYPE_STRING) - cfg.challenge_password = strdup(val->v.strVal); - - val = optionGetValue(pov, "password"); - if (val != NULL && val->valType == OPARG_TYPE_STRING) - cfg.password = strdup(val->v.strVal); - - val = optionGetValue(pov, "pkcs9_email"); - if (val != NULL && val->valType == OPARG_TYPE_STRING) - cfg.pkcs9_email = strdup(val->v.strVal); - - val = optionGetValue(pov, "country"); - if (val != NULL && val->valType == OPARG_TYPE_STRING) - cfg.country = strdup(val->v.strVal); - - for (i=0;i<MAX_POLICIES;i++) - { - snprintf(tmpstr, sizeof(tmpstr), "policy%d", i+1); - val = optionGetValue(pov, tmpstr); - if (val != NULL && val->valType == OPARG_TYPE_STRING) - cfg.policy_oid[i] = strdup(val->v.strVal); - - if (cfg.policy_oid[i] != NULL) - { - snprintf(tmpstr, sizeof(tmpstr), "policy%d_url", i+1); - val = optionGetValue(pov, tmpstr); - if (val != NULL && val->valType == OPARG_TYPE_STRING) - cfg.policy_url[i] = strdup(val->v.strVal); - - snprintf(tmpstr, sizeof(tmpstr), "policy%d_txt", i+1); - val = optionGetValue(pov, tmpstr); - if (val != NULL && val->valType == OPARG_TYPE_STRING) - { - cfg.policy_txt[i] = strdup(val->v.strVal); - } - } - } - - READ_MULTI_LINE("dc", cfg.dc); - READ_MULTI_LINE("dns_name", cfg.dns_name); - READ_MULTI_LINE("uri", cfg.uri); - - READ_MULTI_LINE("ip_address", cfg.ip_addr); - READ_MULTI_LINE("email", cfg.email); - READ_MULTI_LINE("key_purpose_oid", cfg.key_purpose_oids); - - READ_MULTI_LINE_TOKENIZED("dn_oid", cfg.dn_oid); - - val = optionGetValue(pov, "crl_dist_points"); - if (val != NULL && val->valType == OPARG_TYPE_STRING) - cfg.crl_dist_points = strdup(val->v.strVal); - - val = optionGetValue(pov, "pkcs12_key_name"); - if (val != NULL && val->valType == OPARG_TYPE_STRING) - cfg.pkcs12_key_name = strdup(val->v.strVal); - - - READ_NUMERIC("serial", cfg.serial); - READ_NUMERIC("expiration_days", cfg.expiration_days); - READ_NUMERIC("crl_next_update", cfg.crl_next_update); - READ_NUMERIC("crl_number", cfg.crl_number); - READ_NUMERIC("path_len", cfg.path_len); - - val = optionGetValue(pov, "proxy_policy_language"); - if (val != NULL && val->valType == OPARG_TYPE_STRING) - cfg.proxy_policy_language = strdup(val->v.strVal); - - READ_MULTI_LINE("ocsp_uri", cfg.ocsp_uris); - READ_MULTI_LINE("ca_issuers_uri", cfg.ca_issuers_uris); - - READ_BOOLEAN("ca", cfg.ca); - READ_BOOLEAN("honor_crq_extensions", cfg.crq_extensions); - READ_BOOLEAN("tls_www_client", cfg.tls_www_client); - READ_BOOLEAN("tls_www_server", cfg.tls_www_server); - READ_BOOLEAN("signing_key", cfg.signing_key); - READ_BOOLEAN("encryption_key", cfg.encryption_key); - READ_BOOLEAN("cert_signing_key", cfg.cert_sign_key); - READ_BOOLEAN("crl_signing_key", cfg.crl_sign_key); - READ_BOOLEAN("code_signing_key", cfg.code_sign_key); - READ_BOOLEAN("ocsp_signing_key", cfg.ocsp_sign_key); - READ_BOOLEAN("time_stamping_key", cfg.time_stamping_key); - READ_BOOLEAN("ipsec_ike_key", cfg.ipsec_ike_key); - - optionUnloadNested(pov); - - return 0; + /* Parsing return code */ + int ret; + unsigned int i; + tOptionValue const *pov; + const tOptionValue *val; + char tmpstr[256]; + + pov = configFileLoad(template); + if (pov == NULL) { + perror("configFileLoad"); + fprintf(stderr, "Error loading template: %s\n", template); + exit(1); + } + + /* Option variables */ + val = optionGetValue(pov, "organization"); + if (val != NULL && val->valType == OPARG_TYPE_STRING) + cfg.organization = strdup(val->v.strVal); + + val = optionGetValue(pov, "unit"); + if (val != NULL && val->valType == OPARG_TYPE_STRING) + cfg.unit = strdup(val->v.strVal); + + val = optionGetValue(pov, "locality"); + if (val != NULL && val->valType == OPARG_TYPE_STRING) + cfg.locality = strdup(val->v.strVal); + + val = optionGetValue(pov, "state"); + if (val != NULL && val->valType == OPARG_TYPE_STRING) + cfg.state = strdup(val->v.strVal); + + val = optionGetValue(pov, "dn"); + if (val != NULL && val->valType == OPARG_TYPE_STRING) + cfg.dn = strdup(val->v.strVal); + + val = optionGetValue(pov, "cn"); + if (val != NULL && val->valType == OPARG_TYPE_STRING) + cfg.cn = strdup(val->v.strVal); + + val = optionGetValue(pov, "uid"); + if (val != NULL && val->valType == OPARG_TYPE_STRING) + cfg.uid = strdup(val->v.strVal); + + val = optionGetValue(pov, "challenge_password"); + if (val != NULL && val->valType == OPARG_TYPE_STRING) + cfg.challenge_password = strdup(val->v.strVal); + + val = optionGetValue(pov, "password"); + if (val != NULL && val->valType == OPARG_TYPE_STRING) + cfg.password = strdup(val->v.strVal); + + val = optionGetValue(pov, "pkcs9_email"); + if (val != NULL && val->valType == OPARG_TYPE_STRING) + cfg.pkcs9_email = strdup(val->v.strVal); + + val = optionGetValue(pov, "country"); + if (val != NULL && val->valType == OPARG_TYPE_STRING) + cfg.country = strdup(val->v.strVal); + + for (i = 0; i < MAX_POLICIES; i++) { + snprintf(tmpstr, sizeof(tmpstr), "policy%d", i + 1); + val = optionGetValue(pov, tmpstr); + if (val != NULL && val->valType == OPARG_TYPE_STRING) + cfg.policy_oid[i] = strdup(val->v.strVal); + + if (cfg.policy_oid[i] != NULL) { + snprintf(tmpstr, sizeof(tmpstr), "policy%d_url", + i + 1); + val = optionGetValue(pov, tmpstr); + if (val != NULL + && val->valType == OPARG_TYPE_STRING) + cfg.policy_url[i] = strdup(val->v.strVal); + + snprintf(tmpstr, sizeof(tmpstr), "policy%d_txt", + i + 1); + val = optionGetValue(pov, tmpstr); + if (val != NULL + && val->valType == OPARG_TYPE_STRING) { + cfg.policy_txt[i] = strdup(val->v.strVal); + } + } + } + + READ_MULTI_LINE("dc", cfg.dc); + READ_MULTI_LINE("dns_name", cfg.dns_name); + READ_MULTI_LINE("uri", cfg.uri); + + READ_MULTI_LINE("ip_address", cfg.ip_addr); + READ_MULTI_LINE("email", cfg.email); + READ_MULTI_LINE("key_purpose_oid", cfg.key_purpose_oids); + + READ_MULTI_LINE_TOKENIZED("dn_oid", cfg.dn_oid); + + val = optionGetValue(pov, "crl_dist_points"); + if (val != NULL && val->valType == OPARG_TYPE_STRING) + cfg.crl_dist_points = strdup(val->v.strVal); + + val = optionGetValue(pov, "pkcs12_key_name"); + if (val != NULL && val->valType == OPARG_TYPE_STRING) + cfg.pkcs12_key_name = strdup(val->v.strVal); + + + READ_NUMERIC("serial", cfg.serial); + READ_NUMERIC("expiration_days", cfg.expiration_days); + READ_NUMERIC("crl_next_update", cfg.crl_next_update); + READ_NUMERIC("crl_number", cfg.crl_number); + READ_NUMERIC("path_len", cfg.path_len); + + val = optionGetValue(pov, "proxy_policy_language"); + if (val != NULL && val->valType == OPARG_TYPE_STRING) + cfg.proxy_policy_language = strdup(val->v.strVal); + + READ_MULTI_LINE("ocsp_uri", cfg.ocsp_uris); + READ_MULTI_LINE("ca_issuers_uri", cfg.ca_issuers_uris); + + READ_BOOLEAN("ca", cfg.ca); + READ_BOOLEAN("honor_crq_extensions", cfg.crq_extensions); + READ_BOOLEAN("tls_www_client", cfg.tls_www_client); + READ_BOOLEAN("tls_www_server", cfg.tls_www_server); + READ_BOOLEAN("signing_key", cfg.signing_key); + READ_BOOLEAN("encryption_key", cfg.encryption_key); + READ_BOOLEAN("cert_signing_key", cfg.cert_sign_key); + READ_BOOLEAN("crl_signing_key", cfg.crl_sign_key); + READ_BOOLEAN("code_signing_key", cfg.code_sign_key); + READ_BOOLEAN("ocsp_signing_key", cfg.ocsp_sign_key); + READ_BOOLEAN("time_stamping_key", cfg.time_stamping_key); + READ_BOOLEAN("ipsec_ike_key", cfg.ipsec_ike_key); + + optionUnloadNested(pov); + + return 0; } #define IS_NEWLINE(x) ((x[0] == '\n') || (x[0] == '\r')) void -read_crt_set (gnutls_x509_crt_t crt, const char *input_str, const char *oid) +read_crt_set(gnutls_x509_crt_t crt, const char *input_str, const char *oid) { - char input[128]; - int ret; - - fputs (input_str, stderr); - if (fgets (input, sizeof (input), stdin) == NULL) - return; - - if (IS_NEWLINE(input)) - return; - - ret = - gnutls_x509_crt_set_dn_by_oid (crt, oid, 0, input, strlen (input) - 1); - if (ret < 0) - { - fprintf (stderr, "set_dn: %s\n", gnutls_strerror (ret)); - exit (1); - } + char input[128]; + int ret; + + fputs(input_str, stderr); + if (fgets(input, sizeof(input), stdin) == NULL) + return; + + if (IS_NEWLINE(input)) + return; + + ret = + gnutls_x509_crt_set_dn_by_oid(crt, oid, 0, input, + strlen(input) - 1); + if (ret < 0) { + fprintf(stderr, "set_dn: %s\n", gnutls_strerror(ret)); + exit(1); + } } void -read_crq_set (gnutls_x509_crq_t crq, const char *input_str, const char *oid) +read_crq_set(gnutls_x509_crq_t crq, const char *input_str, const char *oid) { - char input[128]; - int ret; - - fputs (input_str, stderr); - if (fgets (input, sizeof (input), stdin) == NULL) - return; - - if (IS_NEWLINE(input)) - return; - - ret = - gnutls_x509_crq_set_dn_by_oid (crq, oid, 0, input, strlen (input) - 1); - if (ret < 0) - { - fprintf (stderr, "set_dn: %s\n", gnutls_strerror (ret)); - exit (1); - } + char input[128]; + int ret; + + fputs(input_str, stderr); + if (fgets(input, sizeof(input), stdin) == NULL) + return; + + if (IS_NEWLINE(input)) + return; + + ret = + gnutls_x509_crq_set_dn_by_oid(crq, oid, 0, input, + strlen(input) - 1); + if (ret < 0) { + fprintf(stderr, "set_dn: %s\n", gnutls_strerror(ret)); + exit(1); + } } /* The input_str should contain %d or %u to print the default. */ -static int -read_int_with_default (const char *input_str, int def) +static int read_int_with_default(const char *input_str, int def) { - char *endptr; - long l, len; - static char input[128]; + char *endptr; + long l, len; + static char input[128]; - fprintf (stderr, input_str, def); - if (fgets (input, sizeof (input), stdin) == NULL) - return def; + fprintf(stderr, input_str, def); + if (fgets(input, sizeof(input), stdin) == NULL) + return def; - if (IS_NEWLINE(input)) - return def; + if (IS_NEWLINE(input)) + return def; - len = strlen (input); + len = strlen(input); - l = strtol (input, &endptr, 0); + l = strtol(input, &endptr, 0); - if (*endptr != '\0' && *endptr != '\r' && *endptr != '\n') - { - fprintf (stderr, "Trailing garbage ignored: `%s'\n", endptr); - return 0; - } + if (*endptr != '\0' && *endptr != '\r' && *endptr != '\n') { + fprintf(stderr, "Trailing garbage ignored: `%s'\n", + endptr); + return 0; + } - if (l <= INT_MIN || l >= INT_MAX) - { - fprintf (stderr, "Integer out of range: `%s'\n", input); - return 0; - } + if (l <= INT_MIN || l >= INT_MAX) { + fprintf(stderr, "Integer out of range: `%s'\n", input); + return 0; + } - if (input == endptr) - l = def; + if (input == endptr) + l = def; - return (int) l; + return (int) l; } -int -read_int (const char *input_str) +int read_int(const char *input_str) { - return read_int_with_default (input_str, 0); + return read_int_with_default(input_str, 0); } -const char * -read_str (const char *input_str) +const char *read_str(const char *input_str) { - static char input[128]; - int len; + static char input[128]; + int len; - fputs (input_str, stderr); - if (fgets (input, sizeof (input), stdin) == NULL) - return NULL; + fputs(input_str, stderr); + if (fgets(input, sizeof(input), stdin) == NULL) + return NULL; - if (IS_NEWLINE(input)) - return NULL; + if (IS_NEWLINE(input)) + return NULL; - len = strlen (input); - if ((len > 0) && (input[len - 1] == '\n')) - input[len - 1] = 0; - if (input[0] == 0) - return NULL; + len = strlen(input); + if ((len > 0) && (input[len - 1] == '\n')) + input[len - 1] = 0; + if (input[0] == 0) + return NULL; - return input; + return input; } /* Default is: * def: 0 -> no * def: 1 -> yes */ -int -read_yesno (const char *input_str, int def) +int read_yesno(const char *input_str, int def) { - char input[128]; - -restart: - fputs (input_str, stderr); - if (fgets (input, sizeof (input), stdin) == NULL) - return def; - - if (IS_NEWLINE(input)) - return def; - - if (input[0] == 'y' || input[0] == 'Y') - return 1; - else if (input[0] == 'n' || input[0] == 'N') - return 0; - else - goto restart; + char input[128]; + + restart: + fputs(input_str, stderr); + if (fgets(input, sizeof(input), stdin) == NULL) + return def; + + if (IS_NEWLINE(input)) + return def; + + if (input[0] == 'y' || input[0] == 'Y') + return 1; + else if (input[0] == 'n' || input[0] == 'N') + return 0; + else + goto restart; } /* Wrapper functions for non-interactive mode. */ -const char * -get_pass (void) +const char *get_pass(void) { - if (batch) - return cfg.password; - else - return getpass ("Enter password: "); + if (batch) + return cfg.password; + else + return getpass("Enter password: "); } -const char * -get_confirmed_pass (bool empty_ok) +const char *get_confirmed_pass(bool empty_ok) { - if (batch) - return cfg.password; - else - { - const char *pass = NULL; - char *copy = NULL; - - do - { - if (pass) - fprintf (stderr, "Password missmatch, try again.\n"); - - free (copy); - - pass = getpass ("Enter password: "); - copy = strdup (pass); - pass = getpass ("Confirm password: "); - } - while (strcmp (pass, copy) != 0 && !(empty_ok && *pass == '\0')); - - free (copy); - - return pass; - } + if (batch) + return cfg.password; + else { + const char *pass = NULL; + char *copy = NULL; + + do { + if (pass) + fprintf(stderr, + "Password missmatch, try again.\n"); + + free(copy); + + pass = getpass("Enter password: "); + copy = strdup(pass); + pass = getpass("Confirm password: "); + } + while (strcmp(pass, copy) != 0 + && !(empty_ok && *pass == '\0')); + + free(copy); + + return pass; + } } -const char * -get_challenge_pass (void) +const char *get_challenge_pass(void) { - if (batch) - return cfg.challenge_password; - else - return getpass ("Enter a challenge password: "); + if (batch) + return cfg.challenge_password; + else + return getpass("Enter a challenge password: "); } -const char * -get_crl_dist_point_url (void) +const char *get_crl_dist_point_url(void) { - if (batch) - return cfg.crl_dist_points; - else - return read_str ("Enter the URI of the CRL distribution point: "); + if (batch) + return cfg.crl_dist_points; + else + return + read_str + ("Enter the URI of the CRL distribution point: "); } -void -get_country_crt_set (gnutls_x509_crt_t crt) +void get_country_crt_set(gnutls_x509_crt_t crt) { - int ret; - - if (batch) - { - if (!cfg.country) - return; - ret = - gnutls_x509_crt_set_dn_by_oid (crt, - GNUTLS_OID_X520_COUNTRY_NAME, 0, - cfg.country, strlen (cfg.country)); - if (ret < 0) - { - fprintf (stderr, "set_dn: %s\n", gnutls_strerror (ret)); - exit (1); - } - } - else - { - read_crt_set (crt, "Country name (2 chars): ", - GNUTLS_OID_X520_COUNTRY_NAME); - } + int ret; + + if (batch) { + if (!cfg.country) + return; + ret = + gnutls_x509_crt_set_dn_by_oid(crt, + GNUTLS_OID_X520_COUNTRY_NAME, + 0, cfg.country, + strlen(cfg.country)); + if (ret < 0) { + fprintf(stderr, "set_dn: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } else { + read_crt_set(crt, "Country name (2 chars): ", + GNUTLS_OID_X520_COUNTRY_NAME); + } } -void -get_organization_crt_set (gnutls_x509_crt_t crt) +void get_organization_crt_set(gnutls_x509_crt_t crt) { - int ret; - - if (batch) - { - if (!cfg.organization) - return; - - ret = - gnutls_x509_crt_set_dn_by_oid (crt, - GNUTLS_OID_X520_ORGANIZATION_NAME, - 0, cfg.organization, - strlen (cfg.organization)); - if (ret < 0) - { - fprintf (stderr, "set_dn: %s\n", gnutls_strerror (ret)); - exit (1); - } - } - else - { - read_crt_set (crt, "Organization name: ", - GNUTLS_OID_X520_ORGANIZATION_NAME); - } + int ret; + + if (batch) { + if (!cfg.organization) + return; + + ret = + gnutls_x509_crt_set_dn_by_oid(crt, + GNUTLS_OID_X520_ORGANIZATION_NAME, + 0, cfg.organization, + strlen(cfg. + organization)); + if (ret < 0) { + fprintf(stderr, "set_dn: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } else { + read_crt_set(crt, "Organization name: ", + GNUTLS_OID_X520_ORGANIZATION_NAME); + } } -void -get_unit_crt_set (gnutls_x509_crt_t crt) +void get_unit_crt_set(gnutls_x509_crt_t crt) { - int ret; - - if (batch) - { - if (!cfg.unit) - return; - - ret = - gnutls_x509_crt_set_dn_by_oid (crt, - GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, - 0, cfg.unit, strlen (cfg.unit)); - if (ret < 0) - { - fprintf (stderr, "set_dn: %s\n", gnutls_strerror (ret)); - exit (1); - } - } - else - { - read_crt_set (crt, "Organizational unit name: ", - GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME); - } + int ret; + + if (batch) { + if (!cfg.unit) + return; + + ret = + gnutls_x509_crt_set_dn_by_oid(crt, + GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, + 0, cfg.unit, + strlen(cfg.unit)); + if (ret < 0) { + fprintf(stderr, "set_dn: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } else { + read_crt_set(crt, "Organizational unit name: ", + GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME); + } } -void -get_state_crt_set (gnutls_x509_crt_t crt) +void get_state_crt_set(gnutls_x509_crt_t crt) { - int ret; - - if (batch) - { - if (!cfg.state) - return; - ret = - gnutls_x509_crt_set_dn_by_oid (crt, - GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, - 0, cfg.state, strlen (cfg.state)); - if (ret < 0) - { - fprintf (stderr, "set_dn: %s\n", gnutls_strerror (ret)); - exit (1); - } - } - else - { - read_crt_set (crt, "State or province name: ", - GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME); - } + int ret; + + if (batch) { + if (!cfg.state) + return; + ret = + gnutls_x509_crt_set_dn_by_oid(crt, + GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, + 0, cfg.state, + strlen(cfg.state)); + if (ret < 0) { + fprintf(stderr, "set_dn: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } else { + read_crt_set(crt, "State or province name: ", + GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME); + } } -void -get_locality_crt_set (gnutls_x509_crt_t crt) +void get_locality_crt_set(gnutls_x509_crt_t crt) { - int ret; - - if (batch) - { - if (!cfg.locality) - return; - ret = - gnutls_x509_crt_set_dn_by_oid (crt, - GNUTLS_OID_X520_LOCALITY_NAME, 0, - cfg.locality, strlen (cfg.locality)); - if (ret < 0) - { - fprintf (stderr, "set_dn: %s\n", gnutls_strerror (ret)); - exit (1); - } - } - else - { - read_crt_set (crt, "Locality name: ", GNUTLS_OID_X520_LOCALITY_NAME); - } + int ret; + + if (batch) { + if (!cfg.locality) + return; + ret = + gnutls_x509_crt_set_dn_by_oid(crt, + GNUTLS_OID_X520_LOCALITY_NAME, + 0, cfg.locality, + strlen(cfg.locality)); + if (ret < 0) { + fprintf(stderr, "set_dn: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } else { + read_crt_set(crt, "Locality name: ", + GNUTLS_OID_X520_LOCALITY_NAME); + } } -void -get_cn_crt_set (gnutls_x509_crt_t crt) +void get_cn_crt_set(gnutls_x509_crt_t crt) { - int ret; - - if (batch) - { - if (!cfg.cn) - return; - ret = - gnutls_x509_crt_set_dn_by_oid (crt, GNUTLS_OID_X520_COMMON_NAME, - 0, cfg.cn, strlen (cfg.cn)); - if (ret < 0) - { - fprintf (stderr, "set_dn_by_oid: %s\n", gnutls_strerror (ret)); - exit (1); - } - } - else - { - read_crt_set (crt, "Common name: ", GNUTLS_OID_X520_COMMON_NAME); - } + int ret; + + if (batch) { + if (!cfg.cn) + return; + ret = + gnutls_x509_crt_set_dn_by_oid(crt, + GNUTLS_OID_X520_COMMON_NAME, + 0, cfg.cn, + strlen(cfg.cn)); + if (ret < 0) { + fprintf(stderr, "set_dn_by_oid: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } else { + read_crt_set(crt, "Common name: ", + GNUTLS_OID_X520_COMMON_NAME); + } } -void -get_dn_crt_set (gnutls_x509_crt_t crt) +void get_dn_crt_set(gnutls_x509_crt_t crt) { - int ret; - const char* err; - - if (batch) - { - if (!cfg.dn) - return; - ret = - gnutls_x509_crt_set_dn (crt, cfg.dn, &err); - if (ret < 0) - { - fprintf (stderr, "set_dn: %s at: %s\n", gnutls_strerror (ret), err); - exit (1); - } - } + int ret; + const char *err; + + if (batch) { + if (!cfg.dn) + return; + ret = gnutls_x509_crt_set_dn(crt, cfg.dn, &err); + if (ret < 0) { + fprintf(stderr, "set_dn: %s at: %s\n", + gnutls_strerror(ret), err); + exit(1); + } + } } -void -get_uid_crt_set (gnutls_x509_crt_t crt) +void get_uid_crt_set(gnutls_x509_crt_t crt) { - int ret; - - if (batch) - { - if (!cfg.uid) - return; - ret = gnutls_x509_crt_set_dn_by_oid (crt, GNUTLS_OID_LDAP_UID, 0, - cfg.uid, strlen (cfg.uid)); - if (ret < 0) - { - fprintf (stderr, "set_dn: %s\n", gnutls_strerror (ret)); - exit (1); - } - } - else - { - read_crt_set (crt, "UID: ", GNUTLS_OID_LDAP_UID); - } + int ret; + + if (batch) { + if (!cfg.uid) + return; + ret = + gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_LDAP_UID, + 0, cfg.uid, + strlen(cfg.uid)); + if (ret < 0) { + fprintf(stderr, "set_dn: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } else { + read_crt_set(crt, "UID: ", GNUTLS_OID_LDAP_UID); + } } -void -get_oid_crt_set (gnutls_x509_crt_t crt) +void get_oid_crt_set(gnutls_x509_crt_t crt) { - int ret, i; - - if (batch) - { - if (!cfg.dn_oid) - return; - for (i = 0; cfg.dn_oid[i] != NULL; i += 2) - { - if (cfg.dn_oid[i + 1] == NULL) - { - fprintf (stderr, "dn_oid: %s does not have an argument.\n", - cfg.dn_oid[i]); - exit (1); - } - ret = gnutls_x509_crt_set_dn_by_oid (crt, cfg.dn_oid[i], 0, - cfg.dn_oid[i + 1], - strlen (cfg.dn_oid[i + 1])); - - if (ret < 0) - { - fprintf (stderr, "set_dn_oid: %s\n", gnutls_strerror (ret)); - exit (1); - } - } - } + int ret, i; + + if (batch) { + if (!cfg.dn_oid) + return; + for (i = 0; cfg.dn_oid[i] != NULL; i += 2) { + if (cfg.dn_oid[i + 1] == NULL) { + fprintf(stderr, + "dn_oid: %s does not have an argument.\n", + cfg.dn_oid[i]); + exit(1); + } + ret = + gnutls_x509_crt_set_dn_by_oid(crt, + cfg.dn_oid[i], 0, + cfg.dn_oid[i + + 1], + strlen(cfg. + dn_oid[i + + 1])); + + if (ret < 0) { + fprintf(stderr, "set_dn_oid: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } + } } -void -get_key_purpose_set (int type, void *crt) +void get_key_purpose_set(int type, void *crt) { - int ret, i; - - if (batch) - { - if (!cfg.key_purpose_oids) - return; - for (i = 0; cfg.key_purpose_oids[i] != NULL; i++) - { - if (type == TYPE_CRT) - ret = - gnutls_x509_crt_set_key_purpose_oid (crt, cfg.key_purpose_oids[i], 0); - else - ret = - gnutls_x509_crq_set_key_purpose_oid (crt, cfg.key_purpose_oids[i], 0); - - if (ret < 0) - { - fprintf (stderr, "set_key_purpose_oid (%s): %s\n", - cfg.key_purpose_oids[i], gnutls_strerror (ret)); - exit (1); - } - } - } + int ret, i; + + if (batch) { + if (!cfg.key_purpose_oids) + return; + for (i = 0; cfg.key_purpose_oids[i] != NULL; i++) { + if (type == TYPE_CRT) + ret = + gnutls_x509_crt_set_key_purpose_oid + (crt, cfg.key_purpose_oids[i], 0); + else + ret = + gnutls_x509_crq_set_key_purpose_oid + (crt, cfg.key_purpose_oids[i], 0); + + if (ret < 0) { + fprintf(stderr, + "set_key_purpose_oid (%s): %s\n", + cfg.key_purpose_oids[i], + gnutls_strerror(ret)); + exit(1); + } + } + } } -void -get_ocsp_issuer_set (gnutls_x509_crt_t crt) +void get_ocsp_issuer_set(gnutls_x509_crt_t crt) { - int ret, i; - gnutls_datum_t uri; - - if (batch) - { - if (!cfg.ocsp_uris) - return; - for (i = 0; cfg.ocsp_uris[i] != NULL; i++) - { - uri.data = cfg.ocsp_uris[i]; - uri.size = strlen(cfg.ocsp_uris[i]); - ret = - gnutls_x509_crt_set_authority_info_access (crt, GNUTLS_IA_OCSP_URI, - &uri); - if (ret < 0) - { - fprintf (stderr, "set OCSP URI (%s): %s\n", - cfg.ocsp_uris[i], gnutls_strerror (ret)); - exit (1); - } - } - } + int ret, i; + gnutls_datum_t uri; + + if (batch) { + if (!cfg.ocsp_uris) + return; + for (i = 0; cfg.ocsp_uris[i] != NULL; i++) { + uri.data = cfg.ocsp_uris[i]; + uri.size = strlen(cfg.ocsp_uris[i]); + ret = + gnutls_x509_crt_set_authority_info_access(crt, + GNUTLS_IA_OCSP_URI, + &uri); + if (ret < 0) { + fprintf(stderr, "set OCSP URI (%s): %s\n", + cfg.ocsp_uris[i], + gnutls_strerror(ret)); + exit(1); + } + } + } } -void -get_ca_issuers_set (gnutls_x509_crt_t crt) +void get_ca_issuers_set(gnutls_x509_crt_t crt) { - int ret, i; - gnutls_datum_t uri; - - if (batch) - { - if (!cfg.ca_issuers_uris) - return; - for (i = 0; cfg.ca_issuers_uris[i] != NULL; i++) - { - uri.data = cfg.ca_issuers_uris[i]; - uri.size = strlen(cfg.ca_issuers_uris[i]); - ret = - gnutls_x509_crt_set_authority_info_access (crt, GNUTLS_IA_CAISSUERS_URI, - &uri); - if (ret < 0) - { - fprintf (stderr, "set CA ISSUERS URI (%s): %s\n", - cfg.ca_issuers_uris[i], gnutls_strerror (ret)); - exit (1); - } - } - } + int ret, i; + gnutls_datum_t uri; + + if (batch) { + if (!cfg.ca_issuers_uris) + return; + for (i = 0; cfg.ca_issuers_uris[i] != NULL; i++) { + uri.data = cfg.ca_issuers_uris[i]; + uri.size = strlen(cfg.ca_issuers_uris[i]); + ret = + gnutls_x509_crt_set_authority_info_access(crt, + GNUTLS_IA_CAISSUERS_URI, + &uri); + if (ret < 0) { + fprintf(stderr, + "set CA ISSUERS URI (%s): %s\n", + cfg.ca_issuers_uris[i], + gnutls_strerror(ret)); + exit(1); + } + } + } } -void -get_pkcs9_email_crt_set (gnutls_x509_crt_t crt) +void get_pkcs9_email_crt_set(gnutls_x509_crt_t crt) { - int ret; - - if (batch) - { - if (!cfg.pkcs9_email) - return; - ret = gnutls_x509_crt_set_dn_by_oid (crt, GNUTLS_OID_PKCS9_EMAIL, 0, - cfg.pkcs9_email, - strlen (cfg.pkcs9_email)); - if (ret < 0) - { - fprintf (stderr, "set_dn: %s\n", gnutls_strerror (ret)); - exit (1); - } - } - else - { - read_crt_set (crt, "E-mail: ", GNUTLS_OID_PKCS9_EMAIL); - } + int ret; + + if (batch) { + if (!cfg.pkcs9_email) + return; + ret = + gnutls_x509_crt_set_dn_by_oid(crt, + GNUTLS_OID_PKCS9_EMAIL, + 0, cfg.pkcs9_email, + strlen(cfg.pkcs9_email)); + if (ret < 0) { + fprintf(stderr, "set_dn: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } else { + read_crt_set(crt, "E-mail: ", GNUTLS_OID_PKCS9_EMAIL); + } } -int -get_serial (void) +int get_serial(void) { - int default_serial = time (NULL); - - if (batch) - { - if (cfg.serial < 0) - return default_serial; - return cfg.serial; - } - else - { - return read_int_with_default - ("Enter the certificate's serial number in decimal (default: %u): ", - default_serial); - } + int default_serial = time(NULL); + + if (batch) { + if (cfg.serial < 0) + return default_serial; + return cfg.serial; + } else { + return read_int_with_default + ("Enter the certificate's serial number in decimal (default: %u): ", + default_serial); + } } -int -get_days (void) +int get_days(void) { - int days; - - if (batch) - { - if (cfg.expiration_days <= 0) - return 365; - else - return cfg.expiration_days; - } - else - { - do - { - days = read_int ("The certificate will expire in (days): "); - } - while (days == 0); - return days; - } + int days; + + if (batch) { + if (cfg.expiration_days <= 0) + return 365; + else + return cfg.expiration_days; + } else { + do { + days = + read_int + ("The certificate will expire in (days): "); + } + while (days == 0); + return days; + } } -int -get_ca_status (void) +int get_ca_status(void) { - if (batch) - { - return cfg.ca; - } - else - { - return - read_yesno ("Does the certificate belong to an authority? (y/N): ", 0); - } + if (batch) { + return cfg.ca; + } else { + return + read_yesno + ("Does the certificate belong to an authority? (y/N): ", + 0); + } } -int -get_crq_extensions_status (void) +int get_crq_extensions_status(void) { - if (batch) - { - return cfg.crq_extensions; - } - else - { - return - read_yesno - ("Do you want to honour the extensions from the request? (y/N): ", 0); - } + if (batch) { + return cfg.crq_extensions; + } else { + return + read_yesno + ("Do you want to honour the extensions from the request? (y/N): ", + 0); + } } -int -get_crl_number (void) +int get_crl_number(void) { - if (batch) - { - return cfg.crl_number; - } - else - { - return read_int_with_default ("CRL Number: ", 1); - } + if (batch) { + return cfg.crl_number; + } else { + return read_int_with_default("CRL Number: ", 1); + } } -int -get_path_len (void) +int get_path_len(void) { - if (batch) - { - return cfg.path_len; - } - else - { - return read_int_with_default - ("Path length constraint (decimal, %d for no constraint): ", -1); - } + if (batch) { + return cfg.path_len; + } else { + return read_int_with_default + ("Path length constraint (decimal, %d for no constraint): ", + -1); + } } -const char * -get_pkcs12_key_name (void) +const char *get_pkcs12_key_name(void) { - const char *name; - - if (batch) - { - if (!cfg.pkcs12_key_name) - return "Anonymous"; - return cfg.pkcs12_key_name; - } - else - { - do - { - name = read_str ("Enter a name for the key: "); - } - while (name == NULL); - } - return name; + const char *name; + + if (batch) { + if (!cfg.pkcs12_key_name) + return "Anonymous"; + return cfg.pkcs12_key_name; + } else { + do { + name = read_str("Enter a name for the key: "); + } + while (name == NULL); + } + return name; } -int -get_tls_client_status (void) +int get_tls_client_status(void) { - if (batch) - { - return cfg.tls_www_client; - } - else - { - return read_yesno ("Is this a TLS web client certificate? (y/N): ", 0); - } + if (batch) { + return cfg.tls_www_client; + } else { + return + read_yesno + ("Is this a TLS web client certificate? (y/N): ", 0); + } } -int -get_tls_server_status (void) +int get_tls_server_status(void) { - if (batch) - { - return cfg.tls_www_server; - } - else - { - return - read_yesno ("Is this a TLS web server certificate? (y/N): ", 0); - } + if (batch) { + return cfg.tls_www_server; + } else { + return + read_yesno + ("Is this a TLS web server certificate? (y/N): ", 0); + } } /* convert a printable IP to binary */ -static int -string_to_ip (unsigned char *ip, const char *str) +static int string_to_ip(unsigned char *ip, const char *str) { - int len = strlen (str); - int ret; + int len = strlen(str); + int ret; #if HAVE_IPV6 - if (strchr (str, ':') != NULL || len > 16) - { /* IPv6 */ - ret = inet_pton (AF_INET6, str, ip); - if (ret <= 0) - { - fprintf (stderr, "Error in IPv6 address %s\n", str); - exit (1); - } - - /* To be done */ - return 16; - } - else + if (strchr(str, ':') != NULL || len > 16) { /* IPv6 */ + ret = inet_pton(AF_INET6, str, ip); + if (ret <= 0) { + fprintf(stderr, "Error in IPv6 address %s\n", str); + exit(1); + } + + /* To be done */ + return 16; + } else #endif - { /* IPv4 */ - ret = inet_pton (AF_INET, str, ip); - if (ret <= 0) - { - fprintf (stderr, "Error in IPv4 address %s\n", str); - exit (1); - } - - return 4; - } + { /* IPv4 */ + ret = inet_pton(AF_INET, str, ip); + if (ret <= 0) { + fprintf(stderr, "Error in IPv4 address %s\n", str); + exit(1); + } + + return 4; + } } -void -get_ip_addr_set (int type, void *crt) +void get_ip_addr_set(int type, void *crt) { - int ret = 0, i; - unsigned char ip[16]; - int len; - - if (batch) - { - if (!cfg.ip_addr) - return; - - for (i = 0; cfg.ip_addr[i] != NULL; i++) - { - len = string_to_ip (ip, cfg.ip_addr[i]); - if (len <= 0) - { - fprintf (stderr, "Error parsing address: %s\n", cfg.ip_addr[i]); - exit (1); - } - - if (type == TYPE_CRT) - ret = - gnutls_x509_crt_set_subject_alt_name (crt, GNUTLS_SAN_IPADDRESS, - ip, len, - GNUTLS_FSAN_APPEND); - else - ret = - gnutls_x509_crq_set_subject_alt_name (crt, GNUTLS_SAN_IPADDRESS, - ip, len, - GNUTLS_FSAN_APPEND); - - if (ret < 0) - break; - } - } - else - { - const char *p; - - p = - read_str ("Enter the IP address of the subject of the certificate: "); - if (!p) - return; - - len = string_to_ip (ip, p); - if (len <= 0) - { - fprintf (stderr, "Error parsing address: %s\n", p); - exit (1); - } - - if (type == TYPE_CRT) - ret = gnutls_x509_crt_set_subject_alt_name (crt, GNUTLS_SAN_IPADDRESS, - ip, len, - GNUTLS_FSAN_APPEND); - else - ret = gnutls_x509_crq_set_subject_alt_name (crt, GNUTLS_SAN_IPADDRESS, - ip, len, - GNUTLS_FSAN_APPEND); - } - - if (ret < 0) - { - fprintf (stderr, "set_subject_alt_name: %s\n", gnutls_strerror (ret)); - exit (1); - } + int ret = 0, i; + unsigned char ip[16]; + int len; + + if (batch) { + if (!cfg.ip_addr) + return; + + for (i = 0; cfg.ip_addr[i] != NULL; i++) { + len = string_to_ip(ip, cfg.ip_addr[i]); + if (len <= 0) { + fprintf(stderr, + "Error parsing address: %s\n", + cfg.ip_addr[i]); + exit(1); + } + + if (type == TYPE_CRT) + ret = + gnutls_x509_crt_set_subject_alt_name + (crt, GNUTLS_SAN_IPADDRESS, ip, len, + GNUTLS_FSAN_APPEND); + else + ret = + gnutls_x509_crq_set_subject_alt_name + (crt, GNUTLS_SAN_IPADDRESS, ip, len, + GNUTLS_FSAN_APPEND); + + if (ret < 0) + break; + } + } else { + const char *p; + + p = read_str + ("Enter the IP address of the subject of the certificate: "); + if (!p) + return; + + len = string_to_ip(ip, p); + if (len <= 0) { + fprintf(stderr, "Error parsing address: %s\n", p); + exit(1); + } + + if (type == TYPE_CRT) + ret = + gnutls_x509_crt_set_subject_alt_name(crt, + GNUTLS_SAN_IPADDRESS, + ip, len, + GNUTLS_FSAN_APPEND); + else + ret = + gnutls_x509_crq_set_subject_alt_name(crt, + GNUTLS_SAN_IPADDRESS, + ip, len, + GNUTLS_FSAN_APPEND); + } + + if (ret < 0) { + fprintf(stderr, "set_subject_alt_name: %s\n", + gnutls_strerror(ret)); + exit(1); + } } -void -get_email_set (int type, void *crt) +void get_email_set(int type, void *crt) { - int ret = 0, i; - - if (batch) - { - if (!cfg.email) - return; - - for (i = 0; cfg.email[i] != NULL; i++) - { - if (type == TYPE_CRT) - ret = - gnutls_x509_crt_set_subject_alt_name (crt, - GNUTLS_SAN_RFC822NAME, - cfg.email[i], - strlen (cfg.email[i]), - GNUTLS_FSAN_APPEND); - else - ret = - gnutls_x509_crq_set_subject_alt_name (crt, - GNUTLS_SAN_RFC822NAME, - cfg.email[i], - strlen (cfg.email[i]), - GNUTLS_FSAN_APPEND); - - if (ret < 0) - break; - } - } - else - { - const char *p; - - p = read_str ("Enter the e-mail of the subject of the certificate: "); - if (!p) - return; - - if (type == TYPE_CRT) - ret = - gnutls_x509_crt_set_subject_alt_name (crt, GNUTLS_SAN_RFC822NAME, p, - strlen (p), - GNUTLS_FSAN_APPEND); - else - ret = - gnutls_x509_crq_set_subject_alt_name (crt, GNUTLS_SAN_RFC822NAME, p, - strlen (p), - GNUTLS_FSAN_APPEND); - } - - if (ret < 0) - { - fprintf (stderr, "set_subject_alt_name: %s\n", gnutls_strerror (ret)); - exit (1); - } + int ret = 0, i; + + if (batch) { + if (!cfg.email) + return; + + for (i = 0; cfg.email[i] != NULL; i++) { + if (type == TYPE_CRT) + ret = + gnutls_x509_crt_set_subject_alt_name + (crt, GNUTLS_SAN_RFC822NAME, + cfg.email[i], strlen(cfg.email[i]), + GNUTLS_FSAN_APPEND); + else + ret = + gnutls_x509_crq_set_subject_alt_name + (crt, GNUTLS_SAN_RFC822NAME, + cfg.email[i], strlen(cfg.email[i]), + GNUTLS_FSAN_APPEND); + + if (ret < 0) + break; + } + } else { + const char *p; + + p = read_str + ("Enter the e-mail of the subject of the certificate: "); + if (!p) + return; + + if (type == TYPE_CRT) + ret = + gnutls_x509_crt_set_subject_alt_name(crt, + GNUTLS_SAN_RFC822NAME, + p, + strlen(p), + GNUTLS_FSAN_APPEND); + else + ret = + gnutls_x509_crq_set_subject_alt_name(crt, + GNUTLS_SAN_RFC822NAME, + p, + strlen(p), + GNUTLS_FSAN_APPEND); + } + + if (ret < 0) { + fprintf(stderr, "set_subject_alt_name: %s\n", + gnutls_strerror(ret)); + exit(1); + } } -void -get_dc_set (int type, void *crt) +void get_dc_set(int type, void *crt) { - int ret = 0, i; - - if (batch) - { - if (!cfg.dc) - return; - - for (i = 0; cfg.dc[i] != NULL; i++) - { - if (type == TYPE_CRT) - ret = gnutls_x509_crt_set_dn_by_oid (crt, GNUTLS_OID_LDAP_DC, - 0, cfg.dc[i], strlen (cfg.dc[i])); - else - ret = gnutls_x509_crq_set_dn_by_oid (crt, GNUTLS_OID_LDAP_DC, - 0, cfg.dc[i], strlen (cfg.dc[i])); - - if (ret < 0) - break; - } - } - else - { - const char *p; - - do - { - p = read_str ("Enter the subject's domain component (DC): "); - if (!p) - return; - - if (type == TYPE_CRT) - ret = gnutls_x509_crt_set_dn_by_oid (crt, GNUTLS_OID_LDAP_DC, - 0, p, strlen (p)); - else - ret = gnutls_x509_crq_set_dn_by_oid (crt, GNUTLS_OID_LDAP_DC, - 0, p, strlen (p)); - } - while(p != NULL); - } - - if (ret < 0) - { - fprintf (stderr, "set_dn_by_oid: %s\n", gnutls_strerror (ret)); - exit (1); - } + int ret = 0, i; + + if (batch) { + if (!cfg.dc) + return; + + for (i = 0; cfg.dc[i] != NULL; i++) { + if (type == TYPE_CRT) + ret = + gnutls_x509_crt_set_dn_by_oid(crt, + GNUTLS_OID_LDAP_DC, + 0, + cfg. + dc[i], + strlen + (cfg. + dc[i])); + else + ret = + gnutls_x509_crq_set_dn_by_oid(crt, + GNUTLS_OID_LDAP_DC, + 0, + cfg. + dc[i], + strlen + (cfg. + dc[i])); + + if (ret < 0) + break; + } + } else { + const char *p; + + do { + p = read_str + ("Enter the subject's domain component (DC): "); + if (!p) + return; + + if (type == TYPE_CRT) + ret = + gnutls_x509_crt_set_dn_by_oid(crt, + GNUTLS_OID_LDAP_DC, + 0, p, + strlen + (p)); + else + ret = + gnutls_x509_crq_set_dn_by_oid(crt, + GNUTLS_OID_LDAP_DC, + 0, p, + strlen + (p)); + } + while (p != NULL); + } + + if (ret < 0) { + fprintf(stderr, "set_dn_by_oid: %s\n", + gnutls_strerror(ret)); + exit(1); + } } -void -get_dns_name_set (int type, void *crt) +void get_dns_name_set(int type, void *crt) { - int ret = 0, i; - - if (batch) - { - if (!cfg.dns_name) - return; - - for (i = 0; cfg.dns_name[i] != NULL; i++) - { - if (type == TYPE_CRT) - ret = - gnutls_x509_crt_set_subject_alt_name (crt, GNUTLS_SAN_DNSNAME, - cfg.dns_name[i], - strlen (cfg.dns_name[i]), - GNUTLS_FSAN_APPEND); - else - ret = - gnutls_x509_crq_set_subject_alt_name (crt, GNUTLS_SAN_DNSNAME, - cfg.dns_name[i], - strlen (cfg.dns_name[i]), - GNUTLS_FSAN_APPEND); - - if (ret < 0) - break; - } - } - else - { - const char *p; - - do - { - p = - read_str ("Enter a dnsName of the subject of the certificate: "); - if (!p) - return; - - if (type == TYPE_CRT) - ret = gnutls_x509_crt_set_subject_alt_name - (crt, GNUTLS_SAN_DNSNAME, p, strlen (p), GNUTLS_FSAN_APPEND); - else - ret = gnutls_x509_crq_set_subject_alt_name - (crt, GNUTLS_SAN_DNSNAME, p, strlen (p), GNUTLS_FSAN_APPEND); - } - while (p); - } - - if (ret < 0) - { - fprintf (stderr, "set_subject_alt_name: %s\n", gnutls_strerror (ret)); - exit (1); - } + int ret = 0, i; + + if (batch) { + if (!cfg.dns_name) + return; + + for (i = 0; cfg.dns_name[i] != NULL; i++) { + if (type == TYPE_CRT) + ret = + gnutls_x509_crt_set_subject_alt_name + (crt, GNUTLS_SAN_DNSNAME, + cfg.dns_name[i], + strlen(cfg.dns_name[i]), + GNUTLS_FSAN_APPEND); + else + ret = + gnutls_x509_crq_set_subject_alt_name + (crt, GNUTLS_SAN_DNSNAME, + cfg.dns_name[i], + strlen(cfg.dns_name[i]), + GNUTLS_FSAN_APPEND); + + if (ret < 0) + break; + } + } else { + const char *p; + + do { + p = read_str + ("Enter a dnsName of the subject of the certificate: "); + if (!p) + return; + + if (type == TYPE_CRT) + ret = gnutls_x509_crt_set_subject_alt_name + (crt, GNUTLS_SAN_DNSNAME, p, strlen(p), + GNUTLS_FSAN_APPEND); + else + ret = gnutls_x509_crq_set_subject_alt_name + (crt, GNUTLS_SAN_DNSNAME, p, strlen(p), + GNUTLS_FSAN_APPEND); + } + while (p); + } + + if (ret < 0) { + fprintf(stderr, "set_subject_alt_name: %s\n", + gnutls_strerror(ret)); + exit(1); + } } -void -get_policy_set (gnutls_x509_crt_t crt) +void get_policy_set(gnutls_x509_crt_t crt) { - int ret = 0, i; - gnutls_x509_policy_st policy; - - if (batch) - { - if (!cfg.policy_oid) - return; - - for (i = 0; cfg.policy_oid[i] != NULL; i++) - { - memset(&policy, 0, sizeof(policy)); - policy.oid = cfg.policy_oid[i]; - - if (cfg.policy_txt[i] != NULL) - { - policy.qualifier[policy.qualifiers].type = GNUTLS_X509_QUALIFIER_NOTICE; - policy.qualifier[policy.qualifiers].data = cfg.policy_txt[i]; - policy.qualifier[policy.qualifiers].size = strlen(cfg.policy_txt[i]); - policy.qualifiers++; - } - - if (cfg.policy_url[i] != NULL) - { - policy.qualifier[policy.qualifiers].type = GNUTLS_X509_QUALIFIER_URI; - policy.qualifier[policy.qualifiers].data = cfg.policy_url[i]; - policy.qualifier[policy.qualifiers].size = strlen(cfg.policy_url[i]); - policy.qualifiers++; - } - - ret = - gnutls_x509_crt_set_policy (crt, &policy, 0); - if (ret < 0) - break; - } - } - - if (ret < 0) - { - fprintf (stderr, "set_policy: %s\n", gnutls_strerror (ret)); - exit (1); - } + int ret = 0, i; + gnutls_x509_policy_st policy; + + if (batch) { + if (!cfg.policy_oid) + return; + + for (i = 0; cfg.policy_oid[i] != NULL; i++) { + memset(&policy, 0, sizeof(policy)); + policy.oid = cfg.policy_oid[i]; + + if (cfg.policy_txt[i] != NULL) { + policy.qualifier[policy.qualifiers].type = + GNUTLS_X509_QUALIFIER_NOTICE; + policy.qualifier[policy.qualifiers].data = + cfg.policy_txt[i]; + policy.qualifier[policy.qualifiers].size = + strlen(cfg.policy_txt[i]); + policy.qualifiers++; + } + + if (cfg.policy_url[i] != NULL) { + policy.qualifier[policy.qualifiers].type = + GNUTLS_X509_QUALIFIER_URI; + policy.qualifier[policy.qualifiers].data = + cfg.policy_url[i]; + policy.qualifier[policy.qualifiers].size = + strlen(cfg.policy_url[i]); + policy.qualifiers++; + } + + ret = gnutls_x509_crt_set_policy(crt, &policy, 0); + if (ret < 0) + break; + } + } + + if (ret < 0) { + fprintf(stderr, "set_policy: %s\n", gnutls_strerror(ret)); + exit(1); + } } -void -get_uri_set (int type, void *crt) +void get_uri_set(int type, void *crt) { - int ret = 0, i; - - if (batch) - { - if (!cfg.uri) - return; - - for (i = 0; cfg.uri[i] != NULL; i++) - { - if (type == TYPE_CRT) - ret = - gnutls_x509_crt_set_subject_alt_name (crt, GNUTLS_SAN_URI, - cfg.uri[i], - strlen (cfg.uri[i]), - GNUTLS_FSAN_APPEND); - else - ret = - gnutls_x509_crq_set_subject_alt_name (crt, GNUTLS_SAN_URI, - cfg.uri[i], - strlen (cfg.uri[i]), - GNUTLS_FSAN_APPEND); - - if (ret < 0) - break; - } - } - else - { - const char *p; - - do - { - p = - read_str ("Enter a URI of the subject of the certificate: "); - if (!p) - return; - - if (type == TYPE_CRT) - ret = gnutls_x509_crt_set_subject_alt_name - (crt, GNUTLS_SAN_URI, p, strlen (p), GNUTLS_FSAN_APPEND); - else - ret = gnutls_x509_crq_set_subject_alt_name - (crt, GNUTLS_SAN_URI, p, strlen (p), GNUTLS_FSAN_APPEND); - } - while (p); - } - - if (ret < 0) - { - fprintf (stderr, "set_subject_alt_name: %s\n", gnutls_strerror (ret)); - exit (1); - } + int ret = 0, i; + + if (batch) { + if (!cfg.uri) + return; + + for (i = 0; cfg.uri[i] != NULL; i++) { + if (type == TYPE_CRT) + ret = + gnutls_x509_crt_set_subject_alt_name + (crt, GNUTLS_SAN_URI, cfg.uri[i], + strlen(cfg.uri[i]), + GNUTLS_FSAN_APPEND); + else + ret = + gnutls_x509_crq_set_subject_alt_name + (crt, GNUTLS_SAN_URI, cfg.uri[i], + strlen(cfg.uri[i]), + GNUTLS_FSAN_APPEND); + + if (ret < 0) + break; + } + } else { + const char *p; + + do { + p = read_str + ("Enter a URI of the subject of the certificate: "); + if (!p) + return; + + if (type == TYPE_CRT) + ret = gnutls_x509_crt_set_subject_alt_name + (crt, GNUTLS_SAN_URI, p, strlen(p), + GNUTLS_FSAN_APPEND); + else + ret = gnutls_x509_crq_set_subject_alt_name + (crt, GNUTLS_SAN_URI, p, strlen(p), + GNUTLS_FSAN_APPEND); + } + while (p); + } + + if (ret < 0) { + fprintf(stderr, "set_subject_alt_name: %s\n", + gnutls_strerror(ret)); + exit(1); + } } -int -get_sign_status (int server) +int get_sign_status(int server) { - const char *msg; - - if (batch) - { - return cfg.signing_key; - } - else - { - if (server) - msg = - "Will the certificate be used for signing (DHE and RSA-EXPORT ciphersuites)? (Y/n): "; - else - msg = - "Will the certificate be used for signing (required for TLS)? (Y/n): "; - return read_yesno (msg, 1); - } + const char *msg; + + if (batch) { + return cfg.signing_key; + } else { + if (server) + msg = + "Will the certificate be used for signing (DHE and RSA-EXPORT ciphersuites)? (Y/n): "; + else + msg = + "Will the certificate be used for signing (required for TLS)? (Y/n): "; + return read_yesno(msg, 1); + } } -int -get_encrypt_status (int server) +int get_encrypt_status(int server) { - const char *msg; - - if (batch) - { - return cfg.encryption_key; - } - else - { - if (server) - msg = - "Will the certificate be used for encryption (RSA ciphersuites)? (Y/n): "; - else - msg = - "Will the certificate be used for encryption (not required for TLS)? (Y/n): "; - return read_yesno (msg, 1); - } + const char *msg; + + if (batch) { + return cfg.encryption_key; + } else { + if (server) + msg = + "Will the certificate be used for encryption (RSA ciphersuites)? (Y/n): "; + else + msg = + "Will the certificate be used for encryption (not required for TLS)? (Y/n): "; + return read_yesno(msg, 1); + } } -int -get_cert_sign_status (void) +int get_cert_sign_status(void) { - if (batch) - { - return cfg.cert_sign_key; - } - else - { - return - read_yesno - ("Will the certificate be used to sign other certificates? (y/N): ", 0); - } + if (batch) { + return cfg.cert_sign_key; + } else { + return + read_yesno + ("Will the certificate be used to sign other certificates? (y/N): ", + 0); + } } -int -get_crl_sign_status (void) +int get_crl_sign_status(void) { - if (batch) - { - return cfg.crl_sign_key; - } - else - { - return - read_yesno ("Will the certificate be used to sign CRLs? (y/N): ", 0); - } + if (batch) { + return cfg.crl_sign_key; + } else { + return + read_yesno + ("Will the certificate be used to sign CRLs? (y/N): ", + 0); + } } -int -get_code_sign_status (void) +int get_code_sign_status(void) { - if (batch) - { - return cfg.code_sign_key; - } - else - { - return - read_yesno ("Will the certificate be used to sign code? (y/N): ", 0); - } + if (batch) { + return cfg.code_sign_key; + } else { + return + read_yesno + ("Will the certificate be used to sign code? (y/N): ", + 0); + } } -int -get_ocsp_sign_status (void) +int get_ocsp_sign_status(void) { - if (batch) - { - return cfg.ocsp_sign_key; - } - else - { - return - read_yesno - ("Will the certificate be used to sign OCSP requests? (y/N): ", 0); - } + if (batch) { + return cfg.ocsp_sign_key; + } else { + return + read_yesno + ("Will the certificate be used to sign OCSP requests? (y/N): ", + 0); + } } -int -get_time_stamp_status (void) +int get_time_stamp_status(void) { - if (batch) - { - return cfg.time_stamping_key; - } - else - { - return - read_yesno - ("Will the certificate be used for time stamping? (y/N): ", 0); - } + if (batch) { + return cfg.time_stamping_key; + } else { + return + read_yesno + ("Will the certificate be used for time stamping? (y/N): ", + 0); + } } -int -get_ipsec_ike_status (void) +int get_ipsec_ike_status(void) { - if (batch) - { - return cfg.ipsec_ike_key; - } - else - { - return - read_yesno - ("Will the certificate be used for IPsec IKE operations? (y/N): ", 0); - } + if (batch) { + return cfg.ipsec_ike_key; + } else { + return + read_yesno + ("Will the certificate be used for IPsec IKE operations? (y/N): ", + 0); + } } -int -get_crl_next_update (void) +int get_crl_next_update(void) { - int days; - - if (batch) - { - if (cfg.crl_next_update <= 0) - return 365; - else - return cfg.crl_next_update; - } - else - { - do - { - days = read_int ("The next CRL will be issued in (days): "); - } - while (days == 0); - return days; - } + int days; + + if (batch) { + if (cfg.crl_next_update <= 0) + return 365; + else + return cfg.crl_next_update; + } else { + do { + days = + read_int + ("The next CRL will be issued in (days): "); + } + while (days == 0); + return days; + } } -const char * -get_proxy_policy (char **policy, size_t * policylen) +const char *get_proxy_policy(char **policy, size_t * policylen) { - const char *ret; - - if (batch) - { - ret = cfg.proxy_policy_language; - if (!ret) - ret = "1.3.6.1.5.5.7.21.1"; - } - else - { - do - { - ret = read_str ("Enter the OID of the proxy policy language: "); - } - while (ret == NULL); - } - - *policy = NULL; - *policylen = 0; - - if (strcmp (ret, "1.3.6.1.5.5.7.21.1") != 0 && - strcmp (ret, "1.3.6.1.5.5.7.21.2") != 0) - { - fprintf (stderr, "Reading non-standard proxy policy not supported.\n"); - } - - return ret; + const char *ret; + + if (batch) { + ret = cfg.proxy_policy_language; + if (!ret) + ret = "1.3.6.1.5.5.7.21.1"; + } else { + do { + ret = + read_str + ("Enter the OID of the proxy policy language: "); + } + while (ret == NULL); + } + + *policy = NULL; + *policylen = 0; + + if (strcmp(ret, "1.3.6.1.5.5.7.21.1") != 0 && + strcmp(ret, "1.3.6.1.5.5.7.21.2") != 0) { + fprintf(stderr, + "Reading non-standard proxy policy not supported.\n"); + } + + return ret; } /* CRQ stuff. */ -void -get_country_crq_set (gnutls_x509_crq_t crq) +void get_country_crq_set(gnutls_x509_crq_t crq) { - int ret; - - if (batch) - { - if (!cfg.country) - return; - ret = - gnutls_x509_crq_set_dn_by_oid (crq, - GNUTLS_OID_X520_COUNTRY_NAME, 0, - cfg.country, strlen (cfg.country)); - if (ret < 0) - { - fprintf (stderr, "set_dn: %s\n", gnutls_strerror (ret)); - exit (1); - } - } - else - { - read_crq_set (crq, "Country name (2 chars): ", - GNUTLS_OID_X520_COUNTRY_NAME); - } + int ret; + + if (batch) { + if (!cfg.country) + return; + ret = + gnutls_x509_crq_set_dn_by_oid(crq, + GNUTLS_OID_X520_COUNTRY_NAME, + 0, cfg.country, + strlen(cfg.country)); + if (ret < 0) { + fprintf(stderr, "set_dn: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } else { + read_crq_set(crq, "Country name (2 chars): ", + GNUTLS_OID_X520_COUNTRY_NAME); + } } -void -get_organization_crq_set (gnutls_x509_crq_t crq) +void get_organization_crq_set(gnutls_x509_crq_t crq) { - int ret; - - if (batch) - { - if (!cfg.organization) - return; - - ret = - gnutls_x509_crq_set_dn_by_oid (crq, - GNUTLS_OID_X520_ORGANIZATION_NAME, - 0, cfg.organization, - strlen (cfg.organization)); - if (ret < 0) - { - fprintf (stderr, "set_dn: %s\n", gnutls_strerror (ret)); - exit (1); - } - } - else - { - read_crq_set (crq, "Organization name: ", - GNUTLS_OID_X520_ORGANIZATION_NAME); - } + int ret; + + if (batch) { + if (!cfg.organization) + return; + + ret = + gnutls_x509_crq_set_dn_by_oid(crq, + GNUTLS_OID_X520_ORGANIZATION_NAME, + 0, cfg.organization, + strlen(cfg. + organization)); + if (ret < 0) { + fprintf(stderr, "set_dn: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } else { + read_crq_set(crq, "Organization name: ", + GNUTLS_OID_X520_ORGANIZATION_NAME); + } } -void -get_unit_crq_set (gnutls_x509_crq_t crq) +void get_unit_crq_set(gnutls_x509_crq_t crq) { - int ret; - - if (batch) - { - if (!cfg.unit) - return; - - ret = - gnutls_x509_crq_set_dn_by_oid (crq, - GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, - 0, cfg.unit, strlen (cfg.unit)); - if (ret < 0) - { - fprintf (stderr, "set_dn: %s\n", gnutls_strerror (ret)); - exit (1); - } - } - else - { - read_crq_set (crq, "Organizational unit name: ", - GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME); - } + int ret; + + if (batch) { + if (!cfg.unit) + return; + + ret = + gnutls_x509_crq_set_dn_by_oid(crq, + GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, + 0, cfg.unit, + strlen(cfg.unit)); + if (ret < 0) { + fprintf(stderr, "set_dn: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } else { + read_crq_set(crq, "Organizational unit name: ", + GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME); + } } -void -get_state_crq_set (gnutls_x509_crq_t crq) +void get_state_crq_set(gnutls_x509_crq_t crq) { - int ret; - - if (batch) - { - if (!cfg.state) - return; - ret = - gnutls_x509_crq_set_dn_by_oid (crq, - GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, - 0, cfg.state, strlen (cfg.state)); - if (ret < 0) - { - fprintf (stderr, "set_dn: %s\n", gnutls_strerror (ret)); - exit (1); - } - } - else - { - read_crq_set (crq, "State or province name: ", - GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME); - } + int ret; + + if (batch) { + if (!cfg.state) + return; + ret = + gnutls_x509_crq_set_dn_by_oid(crq, + GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, + 0, cfg.state, + strlen(cfg.state)); + if (ret < 0) { + fprintf(stderr, "set_dn: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } else { + read_crq_set(crq, "State or province name: ", + GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME); + } } -void -get_locality_crq_set (gnutls_x509_crq_t crq) +void get_locality_crq_set(gnutls_x509_crq_t crq) { - int ret; - - if (batch) - { - if (!cfg.locality) - return; - ret = - gnutls_x509_crq_set_dn_by_oid (crq, - GNUTLS_OID_X520_LOCALITY_NAME, 0, - cfg.locality, strlen (cfg.locality)); - if (ret < 0) - { - fprintf (stderr, "set_dn: %s\n", gnutls_strerror (ret)); - exit (1); - } - } - else - { - read_crq_set (crq, "Locality name: ", GNUTLS_OID_X520_LOCALITY_NAME); - } + int ret; + + if (batch) { + if (!cfg.locality) + return; + ret = + gnutls_x509_crq_set_dn_by_oid(crq, + GNUTLS_OID_X520_LOCALITY_NAME, + 0, cfg.locality, + strlen(cfg.locality)); + if (ret < 0) { + fprintf(stderr, "set_dn: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } else { + read_crq_set(crq, "Locality name: ", + GNUTLS_OID_X520_LOCALITY_NAME); + } } -void -get_dn_crq_set (gnutls_x509_crq_t crq) +void get_dn_crq_set(gnutls_x509_crq_t crq) { - int ret; - const char* err; - - if (batch) - { - if (!cfg.dn) - return; - ret = - gnutls_x509_crq_set_dn (crq, cfg.dn, &err); - if (ret < 0) - { - fprintf (stderr, "set_dn: %s at: %s\n", gnutls_strerror (ret), err); - exit (1); - } - } + int ret; + const char *err; + + if (batch) { + if (!cfg.dn) + return; + ret = gnutls_x509_crq_set_dn(crq, cfg.dn, &err); + if (ret < 0) { + fprintf(stderr, "set_dn: %s at: %s\n", + gnutls_strerror(ret), err); + exit(1); + } + } } -void -get_cn_crq_set (gnutls_x509_crq_t crq) +void get_cn_crq_set(gnutls_x509_crq_t crq) { - int ret; - - if (batch) - { - if (!cfg.cn) - return; - ret = - gnutls_x509_crq_set_dn_by_oid (crq, GNUTLS_OID_X520_COMMON_NAME, - 0, cfg.cn, strlen (cfg.cn)); - if (ret < 0) - { - fprintf (stderr, "set_dn: %s\n", gnutls_strerror (ret)); - exit (1); - } - } - else - { - read_crq_set (crq, "Common name: ", GNUTLS_OID_X520_COMMON_NAME); - } + int ret; + + if (batch) { + if (!cfg.cn) + return; + ret = + gnutls_x509_crq_set_dn_by_oid(crq, + GNUTLS_OID_X520_COMMON_NAME, + 0, cfg.cn, + strlen(cfg.cn)); + if (ret < 0) { + fprintf(stderr, "set_dn: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } else { + read_crq_set(crq, "Common name: ", + GNUTLS_OID_X520_COMMON_NAME); + } } -void -get_uid_crq_set (gnutls_x509_crq_t crq) +void get_uid_crq_set(gnutls_x509_crq_t crq) { - int ret; - - if (batch) - { - if (!cfg.uid) - return; - ret = gnutls_x509_crq_set_dn_by_oid (crq, GNUTLS_OID_LDAP_UID, 0, - cfg.uid, strlen (cfg.uid)); - if (ret < 0) - { - fprintf (stderr, "set_dn: %s\n", gnutls_strerror (ret)); - exit (1); - } - } - else - { - read_crq_set (crq, "UID: ", GNUTLS_OID_LDAP_UID); - } + int ret; + + if (batch) { + if (!cfg.uid) + return; + ret = + gnutls_x509_crq_set_dn_by_oid(crq, GNUTLS_OID_LDAP_UID, + 0, cfg.uid, + strlen(cfg.uid)); + if (ret < 0) { + fprintf(stderr, "set_dn: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } else { + read_crq_set(crq, "UID: ", GNUTLS_OID_LDAP_UID); + } } -void -get_oid_crq_set (gnutls_x509_crq_t crq) +void get_oid_crq_set(gnutls_x509_crq_t crq) { - int ret, i; - - if (batch) - { - if (!cfg.dn_oid) - return; - for (i = 0; cfg.dn_oid[i] != NULL; i += 2) - { - if (cfg.dn_oid[i + 1] == NULL) - { - fprintf (stderr, "dn_oid: %s does not have an argument.\n", - cfg.dn_oid[i]); - exit (1); - } - ret = gnutls_x509_crq_set_dn_by_oid (crq, cfg.dn_oid[i], 0, - cfg.dn_oid[i + 1], - strlen (cfg.dn_oid[i + 1])); - - if (ret < 0) - { - fprintf (stderr, "set_dn_oid: %s\n", gnutls_strerror (ret)); - exit (1); - } - } - } + int ret, i; + + if (batch) { + if (!cfg.dn_oid) + return; + for (i = 0; cfg.dn_oid[i] != NULL; i += 2) { + if (cfg.dn_oid[i + 1] == NULL) { + fprintf(stderr, + "dn_oid: %s does not have an argument.\n", + cfg.dn_oid[i]); + exit(1); + } + ret = + gnutls_x509_crq_set_dn_by_oid(crq, + cfg.dn_oid[i], 0, + cfg.dn_oid[i + + 1], + strlen(cfg. + dn_oid[i + + 1])); + + if (ret < 0) { + fprintf(stderr, "set_dn_oid: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } + } } diff --git a/src/certtool-cfg.h b/src/certtool-cfg.h index 98f42993d2..7617900002 100644 --- a/src/certtool-cfg.h +++ b/src/certtool-cfg.h @@ -23,66 +23,66 @@ #include <stdbool.h> #include <gnutls/x509.h> -void cfg_init (void); -int template_parse (const char *template); +void cfg_init(void); +int template_parse(const char *template); -void read_crt_set (gnutls_x509_crt_t crt, const char *input_str, - const char *oid); -void read_crq_set (gnutls_x509_crq_t crq, const char *input_str, - const char *oid); -int read_int (const char *input_str); -const char *read_str (const char *input_str); -int read_yesno (const char *input_str, int def); +void read_crt_set(gnutls_x509_crt_t crt, const char *input_str, + const char *oid); +void read_crq_set(gnutls_x509_crq_t crq, const char *input_str, + const char *oid); +int read_int(const char *input_str); +const char *read_str(const char *input_str); +int read_yesno(const char *input_str, int def); -const char *get_pass (void); -const char *get_confirmed_pass (bool empty_ok); -const char *get_challenge_pass (void); -const char *get_crl_dist_point_url (void); -void get_country_crt_set (gnutls_x509_crt_t crt); -void get_organization_crt_set (gnutls_x509_crt_t crt); -void get_unit_crt_set (gnutls_x509_crt_t crt); -void get_state_crt_set (gnutls_x509_crt_t crt); -void get_locality_crt_set (gnutls_x509_crt_t crt); -void get_cn_crt_set (gnutls_x509_crt_t crt); -void get_dn_crt_set (gnutls_x509_crt_t crt); -void get_dn_crq_set (gnutls_x509_crq_t crt); -void get_uid_crt_set (gnutls_x509_crt_t crt); -void get_pkcs9_email_crt_set (gnutls_x509_crt_t crt); -void get_oid_crt_set (gnutls_x509_crt_t crt); -void get_key_purpose_set (int type, void *crt); -int get_serial (void); -int get_days (void); -int get_ca_status (void); -int get_crl_number (void); -int get_path_len (void); -int get_crq_extensions_status (void); -const char *get_pkcs12_key_name (void); -int get_tls_client_status (void); -int get_tls_server_status (void); -int get_crl_next_update (void); -int get_time_stamp_status (void); -int get_ocsp_sign_status (void); -int get_code_sign_status (void); -int get_crl_sign_status (void); -int get_cert_sign_status (void); -int get_encrypt_status (int server); -int get_sign_status (int server); -void get_ip_addr_set (int type, void *crt); -void get_dns_name_set (int type, void *crt); -void get_policy_set (gnutls_x509_crt_t); -void get_uri_set (int type, void *crt); -void get_email_set (int type, void *crt); -int get_ipsec_ike_status (void); -void get_dc_set (int type, void *crt); -void get_ca_issuers_set (gnutls_x509_crt_t crt); -void get_ocsp_issuer_set (gnutls_x509_crt_t crt); +const char *get_pass(void); +const char *get_confirmed_pass(bool empty_ok); +const char *get_challenge_pass(void); +const char *get_crl_dist_point_url(void); +void get_country_crt_set(gnutls_x509_crt_t crt); +void get_organization_crt_set(gnutls_x509_crt_t crt); +void get_unit_crt_set(gnutls_x509_crt_t crt); +void get_state_crt_set(gnutls_x509_crt_t crt); +void get_locality_crt_set(gnutls_x509_crt_t crt); +void get_cn_crt_set(gnutls_x509_crt_t crt); +void get_dn_crt_set(gnutls_x509_crt_t crt); +void get_dn_crq_set(gnutls_x509_crq_t crt); +void get_uid_crt_set(gnutls_x509_crt_t crt); +void get_pkcs9_email_crt_set(gnutls_x509_crt_t crt); +void get_oid_crt_set(gnutls_x509_crt_t crt); +void get_key_purpose_set(int type, void *crt); +int get_serial(void); +int get_days(void); +int get_ca_status(void); +int get_crl_number(void); +int get_path_len(void); +int get_crq_extensions_status(void); +const char *get_pkcs12_key_name(void); +int get_tls_client_status(void); +int get_tls_server_status(void); +int get_crl_next_update(void); +int get_time_stamp_status(void); +int get_ocsp_sign_status(void); +int get_code_sign_status(void); +int get_crl_sign_status(void); +int get_cert_sign_status(void); +int get_encrypt_status(int server); +int get_sign_status(int server); +void get_ip_addr_set(int type, void *crt); +void get_dns_name_set(int type, void *crt); +void get_policy_set(gnutls_x509_crt_t); +void get_uri_set(int type, void *crt); +void get_email_set(int type, void *crt); +int get_ipsec_ike_status(void); +void get_dc_set(int type, void *crt); +void get_ca_issuers_set(gnutls_x509_crt_t crt); +void get_ocsp_issuer_set(gnutls_x509_crt_t crt); -void get_cn_crq_set (gnutls_x509_crq_t crq); -void get_uid_crq_set (gnutls_x509_crq_t crq); -void get_locality_crq_set (gnutls_x509_crq_t crq); -void get_state_crq_set (gnutls_x509_crq_t crq); -void get_unit_crq_set (gnutls_x509_crq_t crq); -void get_organization_crq_set (gnutls_x509_crq_t crq); -void get_country_crq_set (gnutls_x509_crq_t crq); -void get_oid_crq_set (gnutls_x509_crq_t crq); -const char *get_proxy_policy (char **policy, size_t * policylen); +void get_cn_crq_set(gnutls_x509_crq_t crq); +void get_uid_crq_set(gnutls_x509_crq_t crq); +void get_locality_crq_set(gnutls_x509_crq_t crq); +void get_state_crq_set(gnutls_x509_crq_t crq); +void get_unit_crq_set(gnutls_x509_crq_t crq); +void get_organization_crq_set(gnutls_x509_crq_t crq); +void get_country_crq_set(gnutls_x509_crq_t crq); +void get_oid_crq_set(gnutls_x509_crq_t crq); +const char *get_proxy_policy(char **policy, size_t * policylen); diff --git a/src/certtool-common.c b/src/certtool-common.c index 2b0c4c744d..48455065b3 100644 --- a/src/certtool-common.c +++ b/src/certtool-common.c @@ -46,289 +46,274 @@ #include <read-file.h> unsigned char buffer[64 * 1024]; -const int buffer_size = sizeof (buffer); +const int buffer_size = sizeof(buffer); -FILE * -safe_open_rw (const char *file, int privkey_op) +FILE *safe_open_rw(const char *file, int privkey_op) { - mode_t omask = 0; - FILE *fh; + mode_t omask = 0; + FILE *fh; - if (privkey_op != 0) - { - omask = umask (S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); - } + if (privkey_op != 0) { + omask = umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + } - fh = fopen (file, "wb"); + fh = fopen(file, "wb"); - if (privkey_op != 0) - { - umask (omask); - } + if (privkey_op != 0) { + umask(omask); + } - return fh; + return fh; } -gnutls_datum_t * -load_secret_key (int mand, common_info_st * info) +gnutls_datum_t *load_secret_key(int mand, common_info_st * info) { - char raw_key[64]; - size_t raw_key_size = sizeof (raw_key); - static gnutls_datum_t key; - gnutls_datum_t hex_key; - int ret; - - if (info->verbose) - fprintf (stderr, "Loading secret key...\n"); - - if (info->secret_key == NULL) - { - if (mand) - { - fprintf (stderr, "missing --secret-key"); - exit(1); - } - else - return NULL; - } - - hex_key.data = (void *) info->secret_key; - hex_key.size = strlen (info->secret_key); - - ret = gnutls_hex_decode (&hex_key, raw_key, &raw_key_size); - if (ret < 0) - { - fprintf (stderr, "hex_decode: %s", gnutls_strerror (ret)); - exit(1); - } - - key.data = (void*)raw_key; - key.size = raw_key_size; - - return &key; + char raw_key[64]; + size_t raw_key_size = sizeof(raw_key); + static gnutls_datum_t key; + gnutls_datum_t hex_key; + int ret; + + if (info->verbose) + fprintf(stderr, "Loading secret key...\n"); + + if (info->secret_key == NULL) { + if (mand) { + fprintf(stderr, "missing --secret-key"); + exit(1); + } else + return NULL; + } + + hex_key.data = (void *) info->secret_key; + hex_key.size = strlen(info->secret_key); + + ret = gnutls_hex_decode(&hex_key, raw_key, &raw_key_size); + if (ret < 0) { + fprintf(stderr, "hex_decode: %s", gnutls_strerror(ret)); + exit(1); + } + + key.data = (void *) raw_key; + key.size = raw_key_size; + + return &key; } -const char* get_password(common_info_st * cinfo, unsigned int *flags, int confirm) +const char *get_password(common_info_st * cinfo, unsigned int *flags, + int confirm) { - if (cinfo->null_password) - { - if (flags) *flags |= GNUTLS_PKCS_NULL_PASSWORD; - return NULL; - } - else if (cinfo->password) - { - if (cinfo->password[0] == 0 && flags) - *flags |= GNUTLS_PKCS_PLAIN; - return cinfo->password; - } - else - { - if (confirm) - return get_confirmed_pass (true); - else - return get_pass (); - } + if (cinfo->null_password) { + if (flags) + *flags |= GNUTLS_PKCS_NULL_PASSWORD; + return NULL; + } else if (cinfo->password) { + if (cinfo->password[0] == 0 && flags) + *flags |= GNUTLS_PKCS_PLAIN; + return cinfo->password; + } else { + if (confirm) + return get_confirmed_pass(true); + else + return get_pass(); + } } -static gnutls_privkey_t _load_privkey(gnutls_datum_t *dat, common_info_st * info) +static gnutls_privkey_t _load_privkey(gnutls_datum_t * dat, + common_info_st * info) { -int ret; -gnutls_privkey_t key; -unsigned int flags = 0; -const char* pass; - - ret = gnutls_privkey_init (&key); - if (ret < 0) - { - fprintf (stderr, "privkey_init: %s", gnutls_strerror (ret)); - exit(1); - } - - ret = gnutls_privkey_import_x509_raw (key, dat, info->incert_format, NULL, 0); - if (ret == GNUTLS_E_DECRYPTION_FAILED) - { - pass = get_password (info, &flags, 0); - ret = gnutls_privkey_import_x509_raw (key, dat, info->incert_format, pass, flags); - } - - if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) - { - fprintf (stderr, - "import error: could not find a valid PEM header; " - "check if your key is PKCS #12 encoded"); - exit(1); - } - - if (ret < 0) - { - fprintf (stderr, "importing --load-privkey: %s: %s", - info->privkey, gnutls_strerror (ret)); - exit(1); - } - - return key; + int ret; + gnutls_privkey_t key; + unsigned int flags = 0; + const char *pass; + + ret = gnutls_privkey_init(&key); + if (ret < 0) { + fprintf(stderr, "privkey_init: %s", gnutls_strerror(ret)); + exit(1); + } + + ret = + gnutls_privkey_import_x509_raw(key, dat, info->incert_format, + NULL, 0); + if (ret == GNUTLS_E_DECRYPTION_FAILED) { + pass = get_password(info, &flags, 0); + ret = + gnutls_privkey_import_x509_raw(key, dat, + info->incert_format, + pass, flags); + } + + if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) { + fprintf(stderr, + "import error: could not find a valid PEM header; " + "check if your key is PKCS #12 encoded"); + exit(1); + } + + if (ret < 0) { + fprintf(stderr, "importing --load-privkey: %s: %s", + info->privkey, gnutls_strerror(ret)); + exit(1); + } + + return key; } -static gnutls_privkey_t _load_url_privkey(const char* url) +static gnutls_privkey_t _load_url_privkey(const char *url) { -int ret; -gnutls_privkey_t key; - - ret = gnutls_privkey_init (&key); - if (ret < 0) - { - fprintf (stderr, "privkey_init: %s", gnutls_strerror (ret)); - exit(1); - } - - ret = gnutls_privkey_import_url(key, url, 0); - if (ret < 0) - { - fprintf (stderr, "importing key: %s: %s", - url, gnutls_strerror (ret)); - exit(1); - } - - return key; + int ret; + gnutls_privkey_t key; + + ret = gnutls_privkey_init(&key); + if (ret < 0) { + fprintf(stderr, "privkey_init: %s", gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_privkey_import_url(key, url, 0); + if (ret < 0) { + fprintf(stderr, "importing key: %s: %s", + url, gnutls_strerror(ret)); + exit(1); + } + + return key; } -static gnutls_pubkey_t _load_url_pubkey(const char* url) +static gnutls_pubkey_t _load_url_pubkey(const char *url) { -int ret; -gnutls_pubkey_t pubkey; -unsigned int obj_flags = 0; - - ret = gnutls_pubkey_init (&pubkey); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - ret = gnutls_pubkey_import_url (pubkey, url, obj_flags); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s: %s\n", __func__, __LINE__, - gnutls_strerror (ret), url); - exit (1); - } - - return pubkey; + int ret; + gnutls_pubkey_t pubkey; + unsigned int obj_flags = 0; + + ret = gnutls_pubkey_init(&pubkey); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, + gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_pubkey_import_url(pubkey, url, obj_flags); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s: %s\n", __func__, + __LINE__, gnutls_strerror(ret), url); + exit(1); + } + + return pubkey; } /* Load the private key. * @mand should be non zero if it is required to read a private key. */ -gnutls_privkey_t -load_private_key (int mand, common_info_st * info) +gnutls_privkey_t load_private_key(int mand, common_info_st * info) { - gnutls_privkey_t key; - gnutls_datum_t dat; - size_t size; + gnutls_privkey_t key; + gnutls_datum_t dat; + size_t size; - if (!info->privkey && !mand) - return NULL; + if (!info->privkey && !mand) + return NULL; - if (info->privkey == NULL) - { - fprintf (stderr, "missing --load-privkey"); - exit(1); - } + if (info->privkey == NULL) { + fprintf(stderr, "missing --load-privkey"); + exit(1); + } - if (gnutls_url_is_supported(info->privkey) != 0) - return _load_url_privkey(info->privkey); + if (gnutls_url_is_supported(info->privkey) != 0) + return _load_url_privkey(info->privkey); - dat.data = (void*)read_binary_file (info->privkey, &size); - dat.size = size; + dat.data = (void *) read_binary_file(info->privkey, &size); + dat.size = size; - if (!dat.data) - { - fprintf (stderr, "reading --load-privkey: %s", info->privkey); - exit(1); - } + if (!dat.data) { + fprintf(stderr, "reading --load-privkey: %s", + info->privkey); + exit(1); + } - key = _load_privkey(&dat, info); + key = _load_privkey(&dat, info); - free (dat.data); + free(dat.data); - return key; + return key; } /* Load the private key. * @mand should be non zero if it is required to read a private key. */ gnutls_x509_privkey_t -load_x509_private_key (int mand, common_info_st * info) +load_x509_private_key(int mand, common_info_st * info) { - gnutls_x509_privkey_t key; - int ret; - gnutls_datum_t dat; - size_t size; - unsigned int flags = 0; - const char* pass; - - if (!info->privkey && !mand) - return NULL; - - if (info->privkey == NULL) - { - fprintf (stderr, "missing --load-privkey"); - exit(1); - } - - ret = gnutls_x509_privkey_init (&key); - if (ret < 0) - { - fprintf( stderr, "privkey_init: %s", gnutls_strerror (ret)); - exit(1); - } - - dat.data = (void*)read_binary_file (info->privkey, &size); - dat.size = size; - - if (!dat.data) - { - fprintf (stderr, "reading --load-privkey: %s", info->privkey); - exit(1); - } - - if (info->pkcs8) - { - pass = get_password (info, &flags, 0); - ret = - gnutls_x509_privkey_import_pkcs8 (key, &dat, info->incert_format, - pass, flags); - } - else - { - ret = gnutls_x509_privkey_import2 (key, &dat, info->incert_format, NULL, 0); - if (ret == GNUTLS_E_DECRYPTION_FAILED) - { - pass = get_password (info, &flags, 0); - ret = gnutls_x509_privkey_import2 (key, &dat, info->incert_format, pass, flags); - } - } - - free (dat.data); - - if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) - { - fprintf (stderr, - "import error: could not find a valid PEM header; " - "check if your key is PEM encoded"); - exit(1); - } - - if (ret < 0) - { - fprintf( stderr, "importing --load-privkey: %s: %s", - info->privkey, gnutls_strerror (ret)); - exit(1); - } - - return key; + gnutls_x509_privkey_t key; + int ret; + gnutls_datum_t dat; + size_t size; + unsigned int flags = 0; + const char *pass; + + if (!info->privkey && !mand) + return NULL; + + if (info->privkey == NULL) { + fprintf(stderr, "missing --load-privkey"); + exit(1); + } + + ret = gnutls_x509_privkey_init(&key); + if (ret < 0) { + fprintf(stderr, "privkey_init: %s", gnutls_strerror(ret)); + exit(1); + } + + dat.data = (void *) read_binary_file(info->privkey, &size); + dat.size = size; + + if (!dat.data) { + fprintf(stderr, "reading --load-privkey: %s", + info->privkey); + exit(1); + } + + if (info->pkcs8) { + pass = get_password(info, &flags, 0); + ret = + gnutls_x509_privkey_import_pkcs8(key, &dat, + info->incert_format, + pass, flags); + } else { + ret = + gnutls_x509_privkey_import2(key, &dat, + info->incert_format, NULL, + 0); + if (ret == GNUTLS_E_DECRYPTION_FAILED) { + pass = get_password(info, &flags, 0); + ret = + gnutls_x509_privkey_import2(key, &dat, + info-> + incert_format, + pass, flags); + } + } + + free(dat.data); + + if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) { + fprintf(stderr, + "import error: could not find a valid PEM header; " + "check if your key is PEM encoded"); + exit(1); + } + + if (ret < 0) { + fprintf(stderr, "importing --load-privkey: %s: %s", + info->privkey, gnutls_strerror(ret)); + exit(1); + } + + return key; } @@ -336,720 +321,676 @@ load_x509_private_key (int mand, common_info_st * info) * If mand is non zero then a certificate is mandatory. Otherwise * null will be returned if the certificate loading fails. */ -gnutls_x509_crt_t -load_cert (int mand, common_info_st * info) +gnutls_x509_crt_t load_cert(int mand, common_info_st * info) { - gnutls_x509_crt_t *crt; - size_t size; + gnutls_x509_crt_t *crt; + size_t size; - crt = load_cert_list (mand, &size, info); + crt = load_cert_list(mand, &size, info); - return crt ? crt[0] : NULL; + return crt ? crt[0] : NULL; } #define MAX_CERTS 256 /* Loads a certificate list */ -gnutls_x509_crt_t * -load_cert_list (int mand, size_t * crt_size, common_info_st * info) +gnutls_x509_crt_t *load_cert_list(int mand, size_t * crt_size, + common_info_st * info) { - FILE *fd; - static gnutls_x509_crt_t crt[MAX_CERTS]; - char *ptr; - int ret, i; - gnutls_datum_t dat; - size_t size; - int ptr_size; - - *crt_size = 0; - if (info->verbose) - fprintf (stderr, "Loading certificate list...\n"); - - if (info->cert == NULL) - { - if (mand) - { - fprintf (stderr, "missing --load-certificate"); - exit(1); - } - else - return NULL; - } - - fd = fopen (info->cert, "r"); - if (fd == NULL) - { - fprintf (stderr, "%s", info->cert); - exit(1); - } - - size = fread (buffer, 1, sizeof (buffer) - 1, fd); - buffer[size] = 0; - - fclose (fd); - - ptr = (void*)buffer; - ptr_size = size; - - for (i = 0; i < MAX_CERTS; i++) - { - ret = gnutls_x509_crt_init (&crt[i]); - if (ret < 0) - { - fprintf(stderr, "crt_init: %s", gnutls_strerror (ret)); - exit(1); - } - - dat.data = (void*)ptr; - dat.size = ptr_size; - - ret = gnutls_x509_crt_import (crt[i], &dat, info->incert_format); - if (ret < 0 && *crt_size > 0) - break; - if (ret < 0) - { - fprintf(stderr, "crt_import: %s", gnutls_strerror (ret)); - exit(1); - } - - ptr = strstr (ptr, "---END"); - if (ptr == NULL) - break; - ptr++; - - ptr_size = size; - ptr_size -= - (unsigned int) ((unsigned char *) ptr - (unsigned char *) buffer); - - if (ptr_size < 0) - break; - - (*crt_size)++; - } - if (info->verbose) - fprintf (stderr, "Loaded %d certificates.\n", (int) *crt_size); - - return crt; + FILE *fd; + static gnutls_x509_crt_t crt[MAX_CERTS]; + char *ptr; + int ret, i; + gnutls_datum_t dat; + size_t size; + int ptr_size; + + *crt_size = 0; + if (info->verbose) + fprintf(stderr, "Loading certificate list...\n"); + + if (info->cert == NULL) { + if (mand) { + fprintf(stderr, "missing --load-certificate"); + exit(1); + } else + return NULL; + } + + fd = fopen(info->cert, "r"); + if (fd == NULL) { + fprintf(stderr, "%s", info->cert); + exit(1); + } + + size = fread(buffer, 1, sizeof(buffer) - 1, fd); + buffer[size] = 0; + + fclose(fd); + + ptr = (void *) buffer; + ptr_size = size; + + for (i = 0; i < MAX_CERTS; i++) { + ret = gnutls_x509_crt_init(&crt[i]); + if (ret < 0) { + fprintf(stderr, "crt_init: %s", + gnutls_strerror(ret)); + exit(1); + } + + dat.data = (void *) ptr; + dat.size = ptr_size; + + ret = + gnutls_x509_crt_import(crt[i], &dat, + info->incert_format); + if (ret < 0 && *crt_size > 0) + break; + if (ret < 0) { + fprintf(stderr, "crt_import: %s", + gnutls_strerror(ret)); + exit(1); + } + + ptr = strstr(ptr, "---END"); + if (ptr == NULL) + break; + ptr++; + + ptr_size = size; + ptr_size -= + (unsigned int) ((unsigned char *) ptr - + (unsigned char *) buffer); + + if (ptr_size < 0) + break; + + (*crt_size)++; + } + if (info->verbose) + fprintf(stderr, "Loaded %d certificates.\n", + (int) *crt_size); + + return crt; } /* Load the Certificate Request. */ -gnutls_x509_crq_t -load_request (common_info_st * info) +gnutls_x509_crq_t load_request(common_info_st * info) { - gnutls_x509_crq_t crq; - int ret; - gnutls_datum_t dat; - size_t size; - - if (!info->request) - return NULL; - - ret = gnutls_x509_crq_init (&crq); - if (ret < 0) - { - fprintf(stderr, "crq_init: %s", gnutls_strerror (ret)); - exit(1); - } - - dat.data = (void*)read_binary_file (info->request, &size); - dat.size = size; - - if (!dat.data) - { - fprintf (stderr, "reading --load-request: %s", info->request); - exit(1); - } - - ret = gnutls_x509_crq_import (crq, &dat, info->incert_format); - if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) - { - fprintf(stderr, - "import error: could not find a valid PEM header"); - exit(1); - } - - free (dat.data); - if (ret < 0) - { - fprintf(stderr, "importing --load-request: %s: %s", - info->request, gnutls_strerror (ret)); - exit(1); - } - return crq; + gnutls_x509_crq_t crq; + int ret; + gnutls_datum_t dat; + size_t size; + + if (!info->request) + return NULL; + + ret = gnutls_x509_crq_init(&crq); + if (ret < 0) { + fprintf(stderr, "crq_init: %s", gnutls_strerror(ret)); + exit(1); + } + + dat.data = (void *) read_binary_file(info->request, &size); + dat.size = size; + + if (!dat.data) { + fprintf(stderr, "reading --load-request: %s", + info->request); + exit(1); + } + + ret = gnutls_x509_crq_import(crq, &dat, info->incert_format); + if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) { + fprintf(stderr, + "import error: could not find a valid PEM header"); + exit(1); + } + + free(dat.data); + if (ret < 0) { + fprintf(stderr, "importing --load-request: %s: %s", + info->request, gnutls_strerror(ret)); + exit(1); + } + return crq; } /* Load the CA's private key. */ -gnutls_privkey_t -load_ca_private_key (common_info_st * info) +gnutls_privkey_t load_ca_private_key(common_info_st * info) { - gnutls_privkey_t key; - gnutls_datum_t dat; - size_t size; + gnutls_privkey_t key; + gnutls_datum_t dat; + size_t size; - if (info->ca_privkey == NULL) - { - fprintf(stderr, "missing --load-ca-privkey"); - exit(1); - } + if (info->ca_privkey == NULL) { + fprintf(stderr, "missing --load-ca-privkey"); + exit(1); + } - if (gnutls_url_is_supported(info->ca_privkey) != 0) - return _load_url_privkey(info->ca_privkey); + if (gnutls_url_is_supported(info->ca_privkey) != 0) + return _load_url_privkey(info->ca_privkey); - dat.data = (void*)read_binary_file (info->ca_privkey, &size); - dat.size = size; + dat.data = (void *) read_binary_file(info->ca_privkey, &size); + dat.size = size; - if (!dat.data) - { - fprintf (stderr, "reading --load-ca-privkey: %s", - info->ca_privkey); - exit(1); - } + if (!dat.data) { + fprintf(stderr, "reading --load-ca-privkey: %s", + info->ca_privkey); + exit(1); + } - key = _load_privkey(&dat, info); + key = _load_privkey(&dat, info); - free (dat.data); + free(dat.data); - return key; + return key; } /* Loads the CA's certificate */ -gnutls_x509_crt_t -load_ca_cert (common_info_st * info) +gnutls_x509_crt_t load_ca_cert(common_info_st * info) { - gnutls_x509_crt_t crt; - int ret; - gnutls_datum_t dat; - size_t size; - - if (info->ca == NULL) - { - fprintf(stderr, "missing --load-ca-certificate"); - exit(1); - } - - ret = gnutls_x509_crt_init (&crt); - if (ret < 0) - { - fprintf(stderr, "crt_init: %s", gnutls_strerror (ret)); - exit(1); - } - - dat.data = (void*)read_binary_file (info->ca, &size); - dat.size = size; - - if (!dat.data) - { - fprintf( stderr, "reading --load-ca-certificate: %s", - info->ca); - exit(1); - } - - ret = gnutls_x509_crt_import (crt, &dat, info->incert_format); - free (dat.data); - if (ret < 0) - { - fprintf(stderr, "importing --load-ca-certificate: %s: %s", - info->ca, gnutls_strerror (ret)); - exit(1); - } - - return crt; + gnutls_x509_crt_t crt; + int ret; + gnutls_datum_t dat; + size_t size; + + if (info->ca == NULL) { + fprintf(stderr, "missing --load-ca-certificate"); + exit(1); + } + + ret = gnutls_x509_crt_init(&crt); + if (ret < 0) { + fprintf(stderr, "crt_init: %s", gnutls_strerror(ret)); + exit(1); + } + + dat.data = (void *) read_binary_file(info->ca, &size); + dat.size = size; + + if (!dat.data) { + fprintf(stderr, "reading --load-ca-certificate: %s", + info->ca); + exit(1); + } + + ret = gnutls_x509_crt_import(crt, &dat, info->incert_format); + free(dat.data); + if (ret < 0) { + fprintf(stderr, "importing --load-ca-certificate: %s: %s", + info->ca, gnutls_strerror(ret)); + exit(1); + } + + return crt; } /* Load a public key. * @mand should be non zero if it is required to read a public key. */ -gnutls_pubkey_t -load_pubkey (int mand, common_info_st * info) +gnutls_pubkey_t load_pubkey(int mand, common_info_st * info) { - gnutls_pubkey_t key; - int ret; - gnutls_datum_t dat; - size_t size; - - if (!info->pubkey && !mand) - return NULL; - - if (info->pubkey == NULL) - { - fprintf(stderr, "missing --load-pubkey"); - exit(1); - } - - if (gnutls_url_is_supported(info->pubkey) != 0) - return _load_url_pubkey(info->pubkey); - - ret = gnutls_pubkey_init (&key); - if (ret < 0) - { - fprintf(stderr, "privkey_init: %s", gnutls_strerror (ret)); - exit(1); - } - - dat.data = (void*)read_binary_file (info->pubkey, &size); - dat.size = size; - - if (!dat.data) - { - fprintf( stderr, "reading --load-pubkey: %s", info->pubkey); - exit(1); - } - - ret = gnutls_pubkey_import (key, &dat, info->incert_format); - - free (dat.data); - - if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) - { - fprintf(stderr, - "import error: could not find a valid PEM header; " - "check if your key has the PUBLIC KEY header"); - exit(1); - } - - if (ret < 0) - { - fprintf(stderr, "importing --load-pubkey: %s: %s", - info->pubkey, gnutls_strerror (ret)); - exit(1); - } - - return key; + gnutls_pubkey_t key; + int ret; + gnutls_datum_t dat; + size_t size; + + if (!info->pubkey && !mand) + return NULL; + + if (info->pubkey == NULL) { + fprintf(stderr, "missing --load-pubkey"); + exit(1); + } + + if (gnutls_url_is_supported(info->pubkey) != 0) + return _load_url_pubkey(info->pubkey); + + ret = gnutls_pubkey_init(&key); + if (ret < 0) { + fprintf(stderr, "privkey_init: %s", gnutls_strerror(ret)); + exit(1); + } + + dat.data = (void *) read_binary_file(info->pubkey, &size); + dat.size = size; + + if (!dat.data) { + fprintf(stderr, "reading --load-pubkey: %s", info->pubkey); + exit(1); + } + + ret = gnutls_pubkey_import(key, &dat, info->incert_format); + + free(dat.data); + + if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) { + fprintf(stderr, + "import error: could not find a valid PEM header; " + "check if your key has the PUBLIC KEY header"); + exit(1); + } + + if (ret < 0) { + fprintf(stderr, "importing --load-pubkey: %s: %s", + info->pubkey, gnutls_strerror(ret)); + exit(1); + } + + return key; } -gnutls_pubkey_t load_public_key_or_import(int mand, gnutls_privkey_t privkey, common_info_st * info) +gnutls_pubkey_t load_public_key_or_import(int mand, + gnutls_privkey_t privkey, + common_info_st * info) { -gnutls_pubkey_t pubkey; -int ret; - - ret = gnutls_pubkey_init(&pubkey); - if (ret < 0) - { - fprintf(stderr, "gnutls_pubkey_init: %s", - gnutls_strerror (ret)); - exit(1); - } - - if (!privkey || (ret = gnutls_pubkey_import_privkey(pubkey, privkey, 0, 0)) < 0) - { /* could not get (e.g. on PKCS #11 */ - gnutls_pubkey_deinit(pubkey); - return load_pubkey(mand, info); - } - - return pubkey; + gnutls_pubkey_t pubkey; + int ret; + + ret = gnutls_pubkey_init(&pubkey); + if (ret < 0) { + fprintf(stderr, "gnutls_pubkey_init: %s", + gnutls_strerror(ret)); + exit(1); + } + + if (!privkey || (ret = gnutls_pubkey_import_privkey(pubkey, privkey, 0, 0)) < 0) { /* could not get (e.g. on PKCS #11 */ + gnutls_pubkey_deinit(pubkey); + return load_pubkey(mand, info); + } + + return pubkey; } int -get_bits (gnutls_pk_algorithm_t key_type, int info_bits, const char* info_sec_param, int warn) +get_bits(gnutls_pk_algorithm_t key_type, int info_bits, + const char *info_sec_param, int warn) { - int bits; - - if (info_bits != 0) - { - static int warned = 0; - - if (warned == 0 && warn != 0) - { - warned = 1; - fprintf (stderr, - "** Note: Please use the --sec-param instead of --bits\n"); - } - bits = info_bits; - } - else - { - if (info_sec_param) - { - bits = - gnutls_sec_param_to_pk_bits (key_type, - str_to_sec_param (info_sec_param)); - } - else - bits = - gnutls_sec_param_to_pk_bits (key_type, GNUTLS_SEC_PARAM_NORMAL); - } - - return bits; + int bits; + + if (info_bits != 0) { + static int warned = 0; + + if (warned == 0 && warn != 0) { + warned = 1; + fprintf(stderr, + "** Note: Please use the --sec-param instead of --bits\n"); + } + bits = info_bits; + } else { + if (info_sec_param) { + bits = + gnutls_sec_param_to_pk_bits(key_type, + str_to_sec_param + (info_sec_param)); + } else + bits = + gnutls_sec_param_to_pk_bits(key_type, + GNUTLS_SEC_PARAM_NORMAL); + } + + return bits; } -gnutls_sec_param_t str_to_sec_param (const char *str) +gnutls_sec_param_t str_to_sec_param(const char *str) { - if (strcasecmp (str, "low") == 0) - { - return GNUTLS_SEC_PARAM_LOW; - } - else if (strcasecmp (str, "legacy") == 0) - { - return GNUTLS_SEC_PARAM_LEGACY; - } - else if (strcasecmp (str, "normal") == 0) - { - return GNUTLS_SEC_PARAM_NORMAL; - } - else if (strcasecmp (str, "high") == 0) - { - return GNUTLS_SEC_PARAM_HIGH; - } - else if (strcasecmp (str, "ultra") == 0) - { - return GNUTLS_SEC_PARAM_ULTRA; - } - else - { - fprintf (stderr, "Unknown security parameter string: %s\n", str); - exit (1); - } + if (strcasecmp(str, "low") == 0) { + return GNUTLS_SEC_PARAM_LOW; + } else if (strcasecmp(str, "legacy") == 0) { + return GNUTLS_SEC_PARAM_LEGACY; + } else if (strcasecmp(str, "normal") == 0) { + return GNUTLS_SEC_PARAM_NORMAL; + } else if (strcasecmp(str, "high") == 0) { + return GNUTLS_SEC_PARAM_HIGH; + } else if (strcasecmp(str, "ultra") == 0) { + return GNUTLS_SEC_PARAM_ULTRA; + } else { + fprintf(stderr, "Unknown security parameter string: %s\n", + str); + exit(1); + } } #define SPACE "\t" static void -print_hex_datum (FILE* outfile, gnutls_datum_t * dat, int cprint) +print_hex_datum(FILE * outfile, gnutls_datum_t * dat, int cprint) { - unsigned int j; - - if (cprint != 0) - { - fprintf (outfile, "\n" SPACE"\""); - for (j = 0; j < dat->size; j++) - { - fprintf (outfile, "\\x%.2x", (unsigned char) dat->data[j]); - if ((j + 1) % 15 == 0) - fprintf (outfile, "\"\n" SPACE"\""); - } - fprintf (outfile, "\";\n\n"); - - return; - } - - fprintf (outfile, "\n" SPACE); - for (j = 0; j < dat->size; j++) - { - fprintf (outfile, "%.2x:", (unsigned char) dat->data[j]); - if ((j + 1) % 15 == 0) - fprintf (outfile, "\n" SPACE); - } - fprintf (outfile, "\n\n"); + unsigned int j; + + if (cprint != 0) { + fprintf(outfile, "\n" SPACE "\""); + for (j = 0; j < dat->size; j++) { + fprintf(outfile, "\\x%.2x", + (unsigned char) dat->data[j]); + if ((j + 1) % 15 == 0) + fprintf(outfile, "\"\n" SPACE "\""); + } + fprintf(outfile, "\";\n\n"); + + return; + } + + fprintf(outfile, "\n" SPACE); + for (j = 0; j < dat->size; j++) { + fprintf(outfile, "%.2x:", (unsigned char) dat->data[j]); + if ((j + 1) % 15 == 0) + fprintf(outfile, "\n" SPACE); + } + fprintf(outfile, "\n\n"); } -static void print_head(FILE* out, const char* txt, unsigned int size, int cprint) +static void print_head(FILE * out, const char *txt, unsigned int size, + int cprint) { -unsigned i; -char* p, * ntxt; - - if (cprint != 0) - { - if (size > 0) - asprintf(&ntxt, "const unsigned char %s[%u] =", txt, size); - else - asprintf(&ntxt, "const unsigned char %s[] =\n", txt); - - p = strstr(ntxt, "char"); - p += 5; - - for (i=0;i<strlen(txt);i++) - if (p[i] == ' ') p[i] = '_'; - - fprintf(out, "%s", ntxt); - free(ntxt); - - return; - } - fprintf(out, "%s:", txt); + unsigned i; + char *p, *ntxt; + + if (cprint != 0) { + if (size > 0) + asprintf(&ntxt, "const unsigned char %s[%u] =", + txt, size); + else + asprintf(&ntxt, "const unsigned char %s[] =\n", + txt); + + p = strstr(ntxt, "char"); + p += 5; + + for (i = 0; i < strlen(txt); i++) + if (p[i] == ' ') + p[i] = '_'; + + fprintf(out, "%s", ntxt); + free(ntxt); + + return; + } + fprintf(out, "%s:", txt); } void -print_dsa_pkey (FILE* outfile, gnutls_datum_t * x, gnutls_datum_t * y, gnutls_datum_t * p, - gnutls_datum_t * q, gnutls_datum_t * g, int cprint) +print_dsa_pkey(FILE * outfile, gnutls_datum_t * x, gnutls_datum_t * y, + gnutls_datum_t * p, gnutls_datum_t * q, gnutls_datum_t * g, + int cprint) { - if (x) - { - print_head (outfile, "private key", x->size, cprint); - print_hex_datum (outfile, x, cprint); - } - print_head (outfile, "public key", y->size, cprint); - print_hex_datum (outfile, y, cprint); - print_head (outfile, "p", p->size, cprint); - print_hex_datum (outfile, p, cprint); - print_head (outfile, "q", q->size, cprint); - print_hex_datum (outfile, q, cprint); - print_head (outfile, "g", g->size, cprint); - print_hex_datum (outfile, g, cprint); + if (x) { + print_head(outfile, "private key", x->size, cprint); + print_hex_datum(outfile, x, cprint); + } + print_head(outfile, "public key", y->size, cprint); + print_hex_datum(outfile, y, cprint); + print_head(outfile, "p", p->size, cprint); + print_hex_datum(outfile, p, cprint); + print_head(outfile, "q", q->size, cprint); + print_hex_datum(outfile, q, cprint); + print_head(outfile, "g", g->size, cprint); + print_hex_datum(outfile, g, cprint); } void -print_ecc_pkey (FILE* outfile, gnutls_ecc_curve_t curve, gnutls_datum_t* k, - gnutls_datum_t * x, gnutls_datum_t * y, int cprint) +print_ecc_pkey(FILE * outfile, gnutls_ecc_curve_t curve, + gnutls_datum_t * k, gnutls_datum_t * x, gnutls_datum_t * y, + int cprint) { - if (cprint != 0) - fprintf (outfile, "/* curve: %s */\n", gnutls_ecc_curve_get_name(curve)); - else - fprintf (outfile, "curve:\t%s\n", gnutls_ecc_curve_get_name(curve)); - - if (k) - { - print_head (outfile, "private key", k->size, cprint); - print_hex_datum (outfile, k, cprint); - } - print_head (outfile, "x", x->size, cprint); - print_hex_datum (outfile, x, cprint); - print_head (outfile, "y", y->size, cprint); - print_hex_datum (outfile, y, cprint); + if (cprint != 0) + fprintf(outfile, "/* curve: %s */\n", + gnutls_ecc_curve_get_name(curve)); + else + fprintf(outfile, "curve:\t%s\n", + gnutls_ecc_curve_get_name(curve)); + + if (k) { + print_head(outfile, "private key", k->size, cprint); + print_hex_datum(outfile, k, cprint); + } + print_head(outfile, "x", x->size, cprint); + print_hex_datum(outfile, x, cprint); + print_head(outfile, "y", y->size, cprint); + print_hex_datum(outfile, y, cprint); } void -print_rsa_pkey (FILE* outfile, gnutls_datum_t * m, gnutls_datum_t * e, gnutls_datum_t * d, - gnutls_datum_t * p, gnutls_datum_t * q, gnutls_datum_t * u, - gnutls_datum_t * exp1, gnutls_datum_t * exp2, int cprint) +print_rsa_pkey(FILE * outfile, gnutls_datum_t * m, gnutls_datum_t * e, + gnutls_datum_t * d, gnutls_datum_t * p, gnutls_datum_t * q, + gnutls_datum_t * u, gnutls_datum_t * exp1, + gnutls_datum_t * exp2, int cprint) { - print_head (outfile, "modulus", m->size, cprint); - print_hex_datum (outfile, m, cprint); - print_head (outfile, "public exponent", e->size, cprint); - print_hex_datum (outfile, e, cprint); - if (d) - { - print_head (outfile, "private exponent", d->size, cprint); - print_hex_datum (outfile, d, cprint); - print_head (outfile, "prime1", p->size, cprint); - print_hex_datum (outfile, p, cprint); - print_head (outfile, "prime2", q->size, cprint); - print_hex_datum (outfile, q, cprint); - print_head (outfile, "coefficient", u->size, cprint); - print_hex_datum (outfile, u, cprint); - if (exp1 && exp2) - { - print_head (outfile, "exp1", exp1->size, cprint); - print_hex_datum (outfile, exp1, cprint); - print_head (outfile, "exp2", exp2->size, cprint); - print_hex_datum (outfile, exp2, cprint); - } - } + print_head(outfile, "modulus", m->size, cprint); + print_hex_datum(outfile, m, cprint); + print_head(outfile, "public exponent", e->size, cprint); + print_hex_datum(outfile, e, cprint); + if (d) { + print_head(outfile, "private exponent", d->size, cprint); + print_hex_datum(outfile, d, cprint); + print_head(outfile, "prime1", p->size, cprint); + print_hex_datum(outfile, p, cprint); + print_head(outfile, "prime2", q->size, cprint); + print_hex_datum(outfile, q, cprint); + print_head(outfile, "coefficient", u->size, cprint); + print_hex_datum(outfile, u, cprint); + if (exp1 && exp2) { + print_head(outfile, "exp1", exp1->size, cprint); + print_hex_datum(outfile, exp1, cprint); + print_head(outfile, "exp2", exp2->size, cprint); + print_hex_datum(outfile, exp2, cprint); + } + } } -void _pubkey_info(FILE* outfile, gnutls_certificate_print_formats_t format, gnutls_pubkey_t pubkey) +void _pubkey_info(FILE * outfile, + gnutls_certificate_print_formats_t format, + gnutls_pubkey_t pubkey) { -gnutls_datum_t data; -int ret; -size_t size; - - ret = gnutls_pubkey_print(pubkey, format, &data); - if (ret < 0) - { - fprintf(stderr, "pubkey_print error: %s", gnutls_strerror (ret)); - exit(1); - } - - fprintf (outfile, "%s\n", data.data); - gnutls_free (data.data); - - size = buffer_size; - ret = gnutls_pubkey_export (pubkey, GNUTLS_X509_FMT_PEM, buffer, &size); - if (ret < 0) - { - fprintf(stderr, "export error: %s", gnutls_strerror (ret)); - exit(1); - } - - fprintf (outfile, "\n%s\n", buffer); + gnutls_datum_t data; + int ret; + size_t size; + + ret = gnutls_pubkey_print(pubkey, format, &data); + if (ret < 0) { + fprintf(stderr, "pubkey_print error: %s", + gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "%s\n", data.data); + gnutls_free(data.data); + + size = buffer_size; + ret = + gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_PEM, buffer, + &size); + if (ret < 0) { + fprintf(stderr, "export error: %s", gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "\n%s\n", buffer); } static void -print_dh_info (FILE* outfile, gnutls_datum_t * p, gnutls_datum_t * g, unsigned int q_bits, int cprint) +print_dh_info(FILE * outfile, gnutls_datum_t * p, gnutls_datum_t * g, + unsigned int q_bits, int cprint) { - if (q_bits > 0) - { - if (cprint != 0) - fprintf (outfile, "\n /* recommended key length: %d bytes */\n\n", (7+q_bits)/8); - else - fprintf (outfile, "\nRecommended key length: %d bits\n\n", q_bits); - } + if (q_bits > 0) { + if (cprint != 0) + fprintf(outfile, + "\n /* recommended key length: %d bytes */\n\n", + (7 + q_bits) / 8); + else + fprintf(outfile, + "\nRecommended key length: %d bits\n\n", + q_bits); + } - print_head (outfile, "generator", g->size, cprint); - print_hex_datum (outfile, g, cprint); + print_head(outfile, "generator", g->size, cprint); + print_hex_datum(outfile, g, cprint); - print_head (outfile, "prime", p->size, cprint); - print_hex_datum (outfile, p, cprint); + print_head(outfile, "prime", p->size, cprint); + print_hex_datum(outfile, p, cprint); } -void dh_info (FILE* infile, FILE* outfile, common_info_st * ci) +void dh_info(FILE * infile, FILE * outfile, common_info_st * ci) { - gnutls_datum_t params; - size_t size; - int ret; - gnutls_dh_params_t dh_params; - gnutls_datum_t p, g; - unsigned int q_bits = 0; - - if (gnutls_dh_params_init (&dh_params) < 0) - { - fprintf (stderr, "Error in dh parameter initialization\n"); - exit (1); - } - - params.data = (void*)fread_file (infile, &size); - params.size = size; - - ret = - gnutls_dh_params_import_pkcs3 (dh_params, ¶ms, ci->incert_format); - if (ret < 0) - { - fprintf (stderr, "Error parsing dh params: %s\n", gnutls_strerror (ret)); - exit (1); - } - - ret = gnutls_dh_params_export_raw (dh_params, &p, &g, &q_bits); - if (ret < 0) - { - fprintf (stderr, "Error exporting parameters: %s\n", - gnutls_strerror (ret)); - exit (1); - } - - if (ci->outcert_format == GNUTLS_X509_FMT_PEM) - print_dh_info (outfile, &p, &g, q_bits, ci->cprint); - - if (!ci->cprint) - { /* generate a PKCS#3 structure */ - size_t len = buffer_size; - - ret = gnutls_dh_params_export_pkcs3 (dh_params, ci->outcert_format, - buffer, &len); - - if (ret == 0) - { - if (ci->outcert_format == GNUTLS_X509_FMT_PEM) - { - fprintf (outfile, "\n%s", buffer); - } - else - { - fwrite (buffer, 1, len, outfile); - } - } - else - { - fprintf (stderr, "Error: %s\n", gnutls_strerror (ret)); - } - } - - gnutls_dh_params_deinit(dh_params); + gnutls_datum_t params; + size_t size; + int ret; + gnutls_dh_params_t dh_params; + gnutls_datum_t p, g; + unsigned int q_bits = 0; + + if (gnutls_dh_params_init(&dh_params) < 0) { + fprintf(stderr, "Error in dh parameter initialization\n"); + exit(1); + } + + params.data = (void *) fread_file(infile, &size); + params.size = size; + + ret = + gnutls_dh_params_import_pkcs3(dh_params, ¶ms, + ci->incert_format); + if (ret < 0) { + fprintf(stderr, "Error parsing dh params: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_dh_params_export_raw(dh_params, &p, &g, &q_bits); + if (ret < 0) { + fprintf(stderr, "Error exporting parameters: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + if (ci->outcert_format == GNUTLS_X509_FMT_PEM) + print_dh_info(outfile, &p, &g, q_bits, ci->cprint); + + if (!ci->cprint) { /* generate a PKCS#3 structure */ + size_t len = buffer_size; + + ret = + gnutls_dh_params_export_pkcs3(dh_params, + ci->outcert_format, + buffer, &len); + + if (ret == 0) { + if (ci->outcert_format == GNUTLS_X509_FMT_PEM) { + fprintf(outfile, "\n%s", buffer); + } else { + fwrite(buffer, 1, len, outfile); + } + } else { + fprintf(stderr, "Error: %s\n", + gnutls_strerror(ret)); + } + } + + gnutls_dh_params_deinit(dh_params); } /* If how is zero then the included parameters are used. */ -int -generate_prime (FILE* outfile, int how, common_info_st * info) +int generate_prime(FILE * outfile, int how, common_info_st * info) { - int ret; - gnutls_dh_params_t dh_params; - gnutls_datum_t p, g; - int bits = get_bits (GNUTLS_PK_DH, info->bits, info->sec_param, 1); - unsigned int q_bits = 0; - - gnutls_dh_params_init (&dh_params); - - if (how != 0) - { - fprintf (stderr, "Generating DH parameters (%d bits)...\n", bits); - fprintf (stderr, "(might take long time)\n"); - } - else - fprintf (stderr, "Retrieving DH parameters...\n"); - - if (how != 0) - { - ret = gnutls_dh_params_generate2 (dh_params, bits); - if (ret < 0) - { - fprintf (stderr, "Error generating parameters: %s\n", - gnutls_strerror (ret)); - exit (1); - } - - ret = gnutls_dh_params_export_raw (dh_params, &p, &g, &q_bits); - if (ret < 0) - { - fprintf (stderr, "Error exporting parameters: %s\n", - gnutls_strerror (ret)); - exit (1); - } - } - else - { + int ret; + gnutls_dh_params_t dh_params; + gnutls_datum_t p, g; + int bits = get_bits(GNUTLS_PK_DH, info->bits, info->sec_param, 1); + unsigned int q_bits = 0; + + gnutls_dh_params_init(&dh_params); + + if (how != 0) { + fprintf(stderr, "Generating DH parameters (%d bits)...\n", + bits); + fprintf(stderr, "(might take long time)\n"); + } else + fprintf(stderr, "Retrieving DH parameters...\n"); + + if (how != 0) { + ret = gnutls_dh_params_generate2(dh_params, bits); + if (ret < 0) { + fprintf(stderr, + "Error generating parameters: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + ret = + gnutls_dh_params_export_raw(dh_params, &p, &g, + &q_bits); + if (ret < 0) { + fprintf(stderr, "Error exporting parameters: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } else { #ifdef ENABLE_SRP - if (bits <= 1024) - { - p = gnutls_srp_1024_group_prime; - g = gnutls_srp_1024_group_generator; - bits = 1024; - } - else if (bits <= 1536) - { - p = gnutls_srp_1536_group_prime; - g = gnutls_srp_1536_group_generator; - bits = 1536; - } - else if (bits <= 2048) - { - p = gnutls_srp_2048_group_prime; - g = gnutls_srp_2048_group_generator; - bits = 2048; - } - else if (bits <= 3072) - { - p = gnutls_srp_3072_group_prime; - g = gnutls_srp_3072_group_generator; - bits = 3072; - } - else - { - p = gnutls_srp_4096_group_prime; - g = gnutls_srp_4096_group_generator; - bits = 4096; - } - - ret = gnutls_dh_params_import_raw (dh_params, &p, &g); - if (ret < 0) - { - fprintf (stderr, "Error exporting parameters: %s\n", - gnutls_strerror (ret)); - exit (1); - } + if (bits <= 1024) { + p = gnutls_srp_1024_group_prime; + g = gnutls_srp_1024_group_generator; + bits = 1024; + } else if (bits <= 1536) { + p = gnutls_srp_1536_group_prime; + g = gnutls_srp_1536_group_generator; + bits = 1536; + } else if (bits <= 2048) { + p = gnutls_srp_2048_group_prime; + g = gnutls_srp_2048_group_generator; + bits = 2048; + } else if (bits <= 3072) { + p = gnutls_srp_3072_group_prime; + g = gnutls_srp_3072_group_generator; + bits = 3072; + } else { + p = gnutls_srp_4096_group_prime; + g = gnutls_srp_4096_group_generator; + bits = 4096; + } + + ret = gnutls_dh_params_import_raw(dh_params, &p, &g); + if (ret < 0) { + fprintf(stderr, "Error exporting parameters: %s\n", + gnutls_strerror(ret)); + exit(1); + } #else - fprintf (stderr, "Parameters unavailable as SRP is disabled.\n"); - exit (1); + fprintf(stderr, + "Parameters unavailable as SRP is disabled.\n"); + exit(1); #endif - } + } - print_dh_info (outfile, &p, &g, q_bits, info->cprint); + print_dh_info(outfile, &p, &g, q_bits, info->cprint); - if (!info->cprint) - { /* generate a PKCS#3 structure */ - size_t len = buffer_size; + if (!info->cprint) { /* generate a PKCS#3 structure */ + size_t len = buffer_size; - ret = gnutls_dh_params_export_pkcs3 (dh_params, GNUTLS_X509_FMT_PEM, - buffer, &len); + ret = + gnutls_dh_params_export_pkcs3(dh_params, + GNUTLS_X509_FMT_PEM, + buffer, &len); - if (ret == 0) - { - fprintf (outfile, "\n%s", buffer); - } - else - { - fprintf (stderr, "Error: %s\n", gnutls_strerror (ret)); - } + if (ret == 0) { + fprintf(outfile, "\n%s", buffer); + } else { + fprintf(stderr, "Error: %s\n", + gnutls_strerror(ret)); + } - } + } - gnutls_dh_params_deinit(dh_params); + gnutls_dh_params_deinit(dh_params); - return 0; + return 0; } - diff --git a/src/certtool-common.h b/src/certtool-common.h index 35d1c2fbd2..b300988487 100644 --- a/src/certtool-common.h +++ b/src/certtool-common.h @@ -27,75 +27,82 @@ #define TYPE_CRT 1 #define TYPE_CRQ 2 -void certtool_version (void); +void certtool_version(void); #include <gnutls/x509.h> #include <gnutls/abstract.h> -typedef struct common_info -{ - const char *secret_key; - const char *privkey; - const char *pubkey; - int pkcs8; - int incert_format; - int outcert_format; - const char *cert; - - const char *request; - const char *ca; - const char *ca_privkey; - int bits; - const char* sec_param; - const char* pkcs_cipher; - const char* password; - int null_password; - unsigned int crq_extensions; - unsigned int v1_cert; - - int cprint; - - unsigned int verbose; +typedef struct common_info { + const char *secret_key; + const char *privkey; + const char *pubkey; + int pkcs8; + int incert_format; + int outcert_format; + const char *cert; + + const char *request; + const char *ca; + const char *ca_privkey; + int bits; + const char *sec_param; + const char *pkcs_cipher; + const char *password; + int null_password; + unsigned int crq_extensions; + unsigned int v1_cert; + + int cprint; + + unsigned int verbose; } common_info_st; -gnutls_pubkey_t load_public_key_or_import(int mand, gnutls_privkey_t privkey, common_info_st * info); -gnutls_privkey_t load_private_key (int mand, common_info_st * info); -gnutls_x509_privkey_t load_x509_private_key (int mand, common_info_st * info); -gnutls_x509_privkey_t *load_privkey_list (int mand, size_t * privkey_size, - common_info_st * info); -gnutls_x509_crq_t load_request (common_info_st * info); -gnutls_privkey_t load_ca_private_key (common_info_st * info); -gnutls_x509_crt_t load_ca_cert (common_info_st * info); -gnutls_x509_crt_t load_cert (int mand, common_info_st * info); -gnutls_datum_t *load_secret_key (int mand, common_info_st * info); -gnutls_pubkey_t load_pubkey (int mand, common_info_st * info); -gnutls_x509_crt_t *load_cert_list (int mand, size_t * size, - common_info_st * info); -int get_bits (gnutls_pk_algorithm_t key_type, int info_bits, const char* info_sec_param, int warn); - -gnutls_sec_param_t str_to_sec_param (const char *str); +gnutls_pubkey_t load_public_key_or_import(int mand, + gnutls_privkey_t privkey, + common_info_st * info); +gnutls_privkey_t load_private_key(int mand, common_info_st * info); +gnutls_x509_privkey_t load_x509_private_key(int mand, + common_info_st * info); +gnutls_x509_privkey_t *load_privkey_list(int mand, size_t * privkey_size, + common_info_st * info); +gnutls_x509_crq_t load_request(common_info_st * info); +gnutls_privkey_t load_ca_private_key(common_info_st * info); +gnutls_x509_crt_t load_ca_cert(common_info_st * info); +gnutls_x509_crt_t load_cert(int mand, common_info_st * info); +gnutls_datum_t *load_secret_key(int mand, common_info_st * info); +gnutls_pubkey_t load_pubkey(int mand, common_info_st * info); +gnutls_x509_crt_t *load_cert_list(int mand, size_t * size, + common_info_st * info); +int get_bits(gnutls_pk_algorithm_t key_type, int info_bits, + const char *info_sec_param, int warn); + +gnutls_sec_param_t str_to_sec_param(const char *str); /* prime.c */ -int generate_prime (FILE* outfile, int how, common_info_st * info); -void dh_info (FILE* infile, FILE* outfile, common_info_st * ci); - -gnutls_x509_privkey_t * load_privkey_list (int mand, size_t * privkey_size, common_info_st * info); - -void _pubkey_info(FILE* outfile, gnutls_certificate_print_formats_t, gnutls_pubkey_t pubkey); -void -print_ecc_pkey (FILE* outfile, gnutls_ecc_curve_t curve, gnutls_datum_t* k, gnutls_datum_t * x, - gnutls_datum_t * y, int cprint); -void -print_rsa_pkey (FILE* outfile, gnutls_datum_t * m, gnutls_datum_t * e, gnutls_datum_t * d, - gnutls_datum_t * p, gnutls_datum_t * q, gnutls_datum_t * u, - gnutls_datum_t * exp1, gnutls_datum_t * exp2, int cprint); -void -print_dsa_pkey (FILE* outfile, gnutls_datum_t * x, gnutls_datum_t * y, gnutls_datum_t * p, - gnutls_datum_t * q, gnutls_datum_t * g, int cprint); - -FILE *safe_open_rw (const char *file, int privkey_op); - -const char* get_password(common_info_st * cinfo, unsigned int *flags, int confirm); +int generate_prime(FILE * outfile, int how, common_info_st * info); +void dh_info(FILE * infile, FILE * outfile, common_info_st * ci); + +gnutls_x509_privkey_t *load_privkey_list(int mand, size_t * privkey_size, + common_info_st * info); + +void _pubkey_info(FILE * outfile, gnutls_certificate_print_formats_t, + gnutls_pubkey_t pubkey); +void print_ecc_pkey(FILE * outfile, gnutls_ecc_curve_t curve, + gnutls_datum_t * k, gnutls_datum_t * x, + gnutls_datum_t * y, int cprint); +void print_rsa_pkey(FILE * outfile, gnutls_datum_t * m, gnutls_datum_t * e, + gnutls_datum_t * d, gnutls_datum_t * p, + gnutls_datum_t * q, gnutls_datum_t * u, + gnutls_datum_t * exp1, gnutls_datum_t * exp2, + int cprint); +void print_dsa_pkey(FILE * outfile, gnutls_datum_t * x, gnutls_datum_t * y, + gnutls_datum_t * p, gnutls_datum_t * q, + gnutls_datum_t * g, int cprint); + +FILE *safe_open_rw(const char *file, int privkey_op); + +const char *get_password(common_info_st * cinfo, unsigned int *flags, + int confirm); extern unsigned char buffer[]; extern const int buffer_size; diff --git a/src/certtool-extras.c b/src/certtool-extras.c index ee89434f7f..649b5eb668 100644 --- a/src/certtool-extras.c +++ b/src/certtool-extras.c @@ -46,89 +46,91 @@ /* Loads a x509 private key list */ -gnutls_x509_privkey_t * -load_privkey_list (int mand, size_t * privkey_size, common_info_st * info) +gnutls_x509_privkey_t *load_privkey_list(int mand, size_t * privkey_size, + common_info_st * info) { - static gnutls_x509_privkey_t key[MAX_KEYS]; - char *ptr; - int ret, i; - gnutls_datum_t dat, file_data; - int ptr_size; - unsigned int flags = 0; - const char* pass; - - *privkey_size = 0; - fprintf (stderr, "Loading private key list...\n"); - - if (info->privkey == NULL) - { - if (mand) - { - fprintf( stderr, "missing --load-privkey"); - exit(1); - } - else - return NULL; - } - - ret = gnutls_load_file(info->privkey, &file_data); - if (ret < 0) - { - fprintf (stderr, "%s", info->privkey); - exit(1); - } - - ptr = (void*)file_data.data; - ptr_size = file_data.size; - - for (i = 0; i < MAX_KEYS; i++) - { - ret = gnutls_x509_privkey_init (&key[i]); - if (ret < 0) - { - fprintf( stderr, "privkey_init: %s", gnutls_strerror (ret)); - exit(1); - } - - dat.data = (void*)ptr; - dat.size = ptr_size; - - ret = gnutls_x509_privkey_import2 (key[i], &dat, info->incert_format, NULL, 0); - if (ret == GNUTLS_E_DECRYPTION_FAILED) - { - pass = get_password (info, &flags, 0); - ret = gnutls_x509_privkey_import2 (key[i], &dat, info->incert_format, pass, flags); - } - - if (ret < 0 && *privkey_size > 0) - break; - if (ret < 0) - { - fprintf( stderr, "privkey_import: %s", gnutls_strerror (ret)); - exit(1); - } - - (*privkey_size)++; - - if (info->incert_format != GNUTLS_X509_FMT_PEM) - break; - - ptr = strstr (ptr, "---END"); - if (ptr == NULL) - break; - ptr++; - - ptr_size = file_data.size; - ptr_size -= - (unsigned int) ((unsigned char *) ptr - (unsigned char *) buffer); - - if (ptr_size < 0) - break; - - } - - gnutls_free(file_data.data); - fprintf (stderr, "Loaded %d private keys.\n", (int) *privkey_size); - - return key; + static gnutls_x509_privkey_t key[MAX_KEYS]; + char *ptr; + int ret, i; + gnutls_datum_t dat, file_data; + int ptr_size; + unsigned int flags = 0; + const char *pass; + + *privkey_size = 0; + fprintf(stderr, "Loading private key list...\n"); + + if (info->privkey == NULL) { + if (mand) { + fprintf(stderr, "missing --load-privkey"); + exit(1); + } else + return NULL; + } + + ret = gnutls_load_file(info->privkey, &file_data); + if (ret < 0) { + fprintf(stderr, "%s", info->privkey); + exit(1); + } + + ptr = (void *) file_data.data; + ptr_size = file_data.size; + + for (i = 0; i < MAX_KEYS; i++) { + ret = gnutls_x509_privkey_init(&key[i]); + if (ret < 0) { + fprintf(stderr, "privkey_init: %s", + gnutls_strerror(ret)); + exit(1); + } + + dat.data = (void *) ptr; + dat.size = ptr_size; + + ret = + gnutls_x509_privkey_import2(key[i], &dat, + info->incert_format, NULL, + 0); + if (ret == GNUTLS_E_DECRYPTION_FAILED) { + pass = get_password(info, &flags, 0); + ret = + gnutls_x509_privkey_import2(key[i], &dat, + info-> + incert_format, + pass, flags); + } + + if (ret < 0 && *privkey_size > 0) + break; + if (ret < 0) { + fprintf(stderr, "privkey_import: %s", + gnutls_strerror(ret)); + exit(1); + } + + (*privkey_size)++; + + if (info->incert_format != GNUTLS_X509_FMT_PEM) + break; + + ptr = strstr(ptr, "---END"); + if (ptr == NULL) + break; + ptr++; + + ptr_size = file_data.size; + ptr_size -= + (unsigned int) ((unsigned char *) ptr - + (unsigned char *) buffer); + + if (ptr_size < 0) + break; + + } + + gnutls_free(file_data.data); + fprintf(stderr, "Loaded %d private keys.\n", (int) *privkey_size); + + return key; } diff --git a/src/certtool.c b/src/certtool.c index 1e0aab2aee..9f0c74443f 100644 --- a/src/certtool.c +++ b/src/certtool.c @@ -47,29 +47,29 @@ #include "certtool-args.h" #include "certtool-common.h" -static void privkey_info_int (common_info_st*, gnutls_x509_privkey_t key); -static void print_crl_info (gnutls_x509_crl_t crl, FILE * out); -void pkcs7_info (void); -void crq_info (void); -void smime_to_pkcs7 (void); -void pkcs12_info (common_info_st*); -void generate_pkcs12 (common_info_st *); -void generate_pkcs8 (common_info_st *); -static void verify_chain (void); -void verify_crl (common_info_st * cinfo); -void pubkey_info (gnutls_x509_crt_t crt, common_info_st *); -void pgp_privkey_info (void); -void pgp_ring_info (void); -void certificate_info (int, common_info_st *); -void pgp_certificate_info (void); -void crl_info (void); -void privkey_info (common_info_st*); -static void cmd_parser (int argc, char **argv); -void generate_self_signed (common_info_st *); -void generate_request (common_info_st *); -static void print_certificate_info (gnutls_x509_crt_t crt, FILE * out, - unsigned int all); -static void verify_certificate (common_info_st * cinfo); +static void privkey_info_int(common_info_st *, gnutls_x509_privkey_t key); +static void print_crl_info(gnutls_x509_crl_t crl, FILE * out); +void pkcs7_info(void); +void crq_info(void); +void smime_to_pkcs7(void); +void pkcs12_info(common_info_st *); +void generate_pkcs12(common_info_st *); +void generate_pkcs8(common_info_st *); +static void verify_chain(void); +void verify_crl(common_info_st * cinfo); +void pubkey_info(gnutls_x509_crt_t crt, common_info_st *); +void pgp_privkey_info(void); +void pgp_ring_info(void); +void certificate_info(int, common_info_st *); +void pgp_certificate_info(void); +void crl_info(void); +void privkey_info(common_info_st *); +static void cmd_parser(int argc, char **argv); +void generate_self_signed(common_info_st *); +void generate_request(common_info_st *); +static void print_certificate_info(gnutls_x509_crt_t crt, FILE * out, + unsigned int all); +static void verify_certificate(common_info_st * cinfo); FILE *outfile; FILE *infile; @@ -83,1546 +83,1488 @@ gnutls_certificate_print_formats_t full_format = GNUTLS_CRT_PRINT_FULL; int batch; -static void -tls_log_func (int level, const char *str) +static void tls_log_func(int level, const char *str) { - fprintf (stderr, "|<%d>| %s", level, str); + fprintf(stderr, "|<%d>| %s", level, str); } -int -main (int argc, char **argv) +int main(int argc, char **argv) { - cfg_init (); - cmd_parser (argc, argv); + cfg_init(); + cmd_parser(argc, argv); - return 0; + return 0; } static gnutls_x509_privkey_t -generate_private_key_int (common_info_st * cinfo) +generate_private_key_int(common_info_st * cinfo) { - gnutls_x509_privkey_t key; - int ret, key_type, bits; - - key_type = req_key_type; - - ret = gnutls_x509_privkey_init (&key); - if (ret < 0) - { - fprintf(stderr, "privkey_init: %s", gnutls_strerror (ret)); - exit(1); - } - - bits = get_bits (key_type, cinfo->bits, cinfo->sec_param, 1); - - fprintf (stderr, "Generating a %d bit %s private key...\n", - bits, gnutls_pk_algorithm_get_name (key_type)); - - if (bits > 1024 && key_type == GNUTLS_PK_DSA) - fprintf (stderr, - "Note that DSA keys with size over 1024 may cause incompatibility problems when used with earlier than TLS 1.2 versions.\n\n"); - - ret = gnutls_x509_privkey_generate (key, key_type, bits, 0); - if (ret < 0) - { - fprintf(stderr, "privkey_generate: %s", gnutls_strerror (ret)); - exit(1); - } - - ret = gnutls_x509_privkey_verify_params (key); - if (ret < 0) - { - fprintf(stderr, "privkey_verify_params: %s", gnutls_strerror (ret)); - exit(1); - } - - return key; + gnutls_x509_privkey_t key; + int ret, key_type, bits; + + key_type = req_key_type; + + ret = gnutls_x509_privkey_init(&key); + if (ret < 0) { + fprintf(stderr, "privkey_init: %s", gnutls_strerror(ret)); + exit(1); + } + + bits = get_bits(key_type, cinfo->bits, cinfo->sec_param, 1); + + fprintf(stderr, "Generating a %d bit %s private key...\n", + bits, gnutls_pk_algorithm_get_name(key_type)); + + if (bits > 1024 && key_type == GNUTLS_PK_DSA) + fprintf(stderr, + "Note that DSA keys with size over 1024 may cause incompatibility problems when used with earlier than TLS 1.2 versions.\n\n"); + + ret = gnutls_x509_privkey_generate(key, key_type, bits, 0); + if (ret < 0) { + fprintf(stderr, "privkey_generate: %s", + gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_x509_privkey_verify_params(key); + if (ret < 0) { + fprintf(stderr, "privkey_verify_params: %s", + gnutls_strerror(ret)); + exit(1); + } + + return key; } -static int -cipher_to_flags (const char *cipher) +static int cipher_to_flags(const char *cipher) { - if (cipher == NULL) - { - return GNUTLS_PKCS_USE_PKCS12_ARCFOUR; - } - else if (strcasecmp (cipher, "3des") == 0) - { - return GNUTLS_PKCS_USE_PBES2_3DES; - } - else if (strcasecmp (cipher, "3des-pkcs12") == 0) - { - return GNUTLS_PKCS_USE_PKCS12_3DES; - } - else if (strcasecmp (cipher, "arcfour") == 0) - { - return GNUTLS_PKCS_USE_PKCS12_ARCFOUR; - } - else if (strcasecmp (cipher, "aes-128") == 0) - { - return GNUTLS_PKCS_USE_PBES2_AES_128; - } - else if (strcasecmp (cipher, "aes-192") == 0) - { - return GNUTLS_PKCS_USE_PBES2_AES_192; - } - else if (strcasecmp (cipher, "aes-256") == 0) - { - return GNUTLS_PKCS_USE_PBES2_AES_256; - } - else if (strcasecmp (cipher, "rc2-40") == 0) - { - return GNUTLS_PKCS_USE_PKCS12_RC2_40; - } - - fprintf(stderr, "unknown cipher %s\n", cipher); - exit(1); + if (cipher == NULL) { + return GNUTLS_PKCS_USE_PKCS12_ARCFOUR; + } else if (strcasecmp(cipher, "3des") == 0) { + return GNUTLS_PKCS_USE_PBES2_3DES; + } else if (strcasecmp(cipher, "3des-pkcs12") == 0) { + return GNUTLS_PKCS_USE_PKCS12_3DES; + } else if (strcasecmp(cipher, "arcfour") == 0) { + return GNUTLS_PKCS_USE_PKCS12_ARCFOUR; + } else if (strcasecmp(cipher, "aes-128") == 0) { + return GNUTLS_PKCS_USE_PBES2_AES_128; + } else if (strcasecmp(cipher, "aes-192") == 0) { + return GNUTLS_PKCS_USE_PBES2_AES_192; + } else if (strcasecmp(cipher, "aes-256") == 0) { + return GNUTLS_PKCS_USE_PBES2_AES_256; + } else if (strcasecmp(cipher, "rc2-40") == 0) { + return GNUTLS_PKCS_USE_PKCS12_RC2_40; + } + + fprintf(stderr, "unknown cipher %s\n", cipher); + exit(1); } static void -print_private_key (common_info_st* cinfo, gnutls_x509_privkey_t key) +print_private_key(common_info_st * cinfo, gnutls_x509_privkey_t key) { - int ret; - size_t size; - - if (!key) - return; - - - if (!cinfo->pkcs8) - { - /* Only print private key parameters when an unencrypted - * format is used */ - if (outcert_format == GNUTLS_X509_FMT_PEM) - privkey_info_int(cinfo, key); - - size = buffer_size; - ret = gnutls_x509_privkey_export (key, outcert_format, - buffer, &size); - if (ret < 0) - { - fprintf(stderr, "privkey_export: %s", gnutls_strerror (ret)); - exit(1); - } - } - else - { - unsigned int flags = 0; - const char *pass; - - pass = get_password(cinfo, &flags, 0); - flags |= cipher_to_flags (cinfo->pkcs_cipher); - - size = buffer_size; - ret = - gnutls_x509_privkey_export_pkcs8 (key, outcert_format, pass, - flags, buffer, &size); - if (ret < 0) - { - fprintf(stderr, "privkey_export_pkcs8: %s", - gnutls_strerror (ret)); - exit(1); - } - } - - fwrite (buffer, 1, size, outfile); + int ret; + size_t size; + + if (!key) + return; + + + if (!cinfo->pkcs8) { + /* Only print private key parameters when an unencrypted + * format is used */ + if (outcert_format == GNUTLS_X509_FMT_PEM) + privkey_info_int(cinfo, key); + + size = buffer_size; + ret = gnutls_x509_privkey_export(key, outcert_format, + buffer, &size); + if (ret < 0) { + fprintf(stderr, "privkey_export: %s", + gnutls_strerror(ret)); + exit(1); + } + } else { + unsigned int flags = 0; + const char *pass; + + pass = get_password(cinfo, &flags, 0); + flags |= cipher_to_flags(cinfo->pkcs_cipher); + + size = buffer_size; + ret = + gnutls_x509_privkey_export_pkcs8(key, outcert_format, + pass, flags, buffer, + &size); + if (ret < 0) { + fprintf(stderr, "privkey_export_pkcs8: %s", + gnutls_strerror(ret)); + exit(1); + } + } + + fwrite(buffer, 1, size, outfile); } -static void -generate_private_key (common_info_st* cinfo) +static void generate_private_key(common_info_st * cinfo) { - gnutls_x509_privkey_t key; + gnutls_x509_privkey_t key; - key = generate_private_key_int (cinfo); + key = generate_private_key_int(cinfo); - print_private_key (cinfo, key); + print_private_key(cinfo, key); - gnutls_x509_privkey_deinit (key); + gnutls_x509_privkey_deinit(key); } static gnutls_x509_crt_t -generate_certificate (gnutls_privkey_t * ret_key, - gnutls_x509_crt_t ca_crt, int proxy, - common_info_st * cinfo) +generate_certificate(gnutls_privkey_t * ret_key, + gnutls_x509_crt_t ca_crt, int proxy, + common_info_st * cinfo) { - gnutls_x509_crt_t crt; - gnutls_privkey_t key = NULL; - gnutls_pubkey_t pubkey; - size_t size; - int ret; - int client; - int days, result, ca_status = 0, is_ike = 0, path_len; - time_t secs, now; - int vers; - unsigned int usage = 0, server; - gnutls_x509_crq_t crq; /* request */ - - ret = gnutls_x509_crt_init (&crt); - if (ret < 0) - { - fprintf(stderr, "crt_init: %s", gnutls_strerror (ret)); - exit(1); - } - - crq = load_request (cinfo); - - if (crq == NULL) - { - - key = load_private_key (0, cinfo); - - pubkey = load_public_key_or_import (1, key, cinfo); - - if (!batch) - fprintf (stderr, - "Please enter the details of the certificate's distinguished name. " - "Just press enter to ignore a field.\n"); - - /* set the DN. - */ - if (proxy) - { - result = gnutls_x509_crt_set_proxy_dn (crt, ca_crt, 0, NULL, 0); - if (result < 0) - { - fprintf(stderr, "set_proxy_dn: %s", - gnutls_strerror (result)); - exit(1); - } - - get_dn_crt_set (crt); - get_cn_crt_set (crt); - } - else - { - get_dn_crt_set (crt); - - get_cn_crt_set (crt); - get_uid_crt_set (crt); - get_unit_crt_set (crt); - get_organization_crt_set (crt); - get_locality_crt_set (crt); - get_state_crt_set (crt); - get_country_crt_set (crt); - get_dc_set (TYPE_CRT, crt); - - get_oid_crt_set (crt); - get_key_purpose_set (TYPE_CRT, crt); - - if (!batch) - fprintf (stderr, - "This field should not be used in new certificates.\n"); - - get_pkcs9_email_crt_set (crt); - } - - result = gnutls_x509_crt_set_pubkey (crt, pubkey); - if (result < 0) - { - fprintf(stderr, "set_key: %s", gnutls_strerror (result)); - exit(1); - } - } - else - { - result = gnutls_x509_crt_set_crq (crt, crq); - if (result < 0) - { - fprintf(stderr, "set_crq: %s", gnutls_strerror (result)); - exit(1); - } - } - - - { - int serial = get_serial (); - char bin_serial[5]; - - bin_serial[4] = serial & 0xff; - bin_serial[3] = (serial >> 8) & 0xff; - bin_serial[2] = (serial >> 16) & 0xff; - bin_serial[1] = (serial >> 24) & 0xff; - bin_serial[0] = 0; - - result = gnutls_x509_crt_set_serial (crt, bin_serial, 5); - if (result < 0) - { - fprintf(stderr, "serial: %s", gnutls_strerror (result)); - exit(1); - } - } - - if (!batch) - fprintf (stderr, "\n\nActivation/Expiration time.\n"); - - gnutls_x509_crt_set_activation_time (crt, time (NULL)); - - now = time(NULL); - - do - { - days = get_days (); - secs = days * 24 * 60 * 60 + now; - } - while (secs < now || (unsigned)(secs-now)/(24*60*60) != (unsigned)days); - - result = - gnutls_x509_crt_set_expiration_time (crt, secs); - if (result < 0) - { - fprintf(stderr, "set_expiration: %s", gnutls_strerror (result)); - exit(1); - } - - if (!batch) - fprintf (stderr, "\n\nExtensions.\n"); - - /* do not allow extensions on a v1 certificate */ - if (crq && get_crq_extensions_status () != 0) - { - result = gnutls_x509_crt_set_crq_extensions (crt, crq); - if (result < 0) - { - fprintf(stderr, "set_crq: %s", gnutls_strerror (result)); - exit(1); - } - } - - /* append additional extensions */ - if (cinfo->v1_cert == 0) - { - - if (proxy) - { - const char *policylanguage; - char *policy; - size_t policylen; - int proxypathlen = get_path_len (); - - if (!batch) - { - printf ("1.3.6.1.5.5.7.21.1 ::= id-ppl-inheritALL\n"); - printf ("1.3.6.1.5.5.7.21.2 ::= id-ppl-independent\n"); - } - - policylanguage = get_proxy_policy (&policy, &policylen); - - result = - gnutls_x509_crt_set_proxy (crt, proxypathlen, policylanguage, - policy, policylen); - if (result < 0) - { - fprintf(stderr, "set_proxy: %s", - gnutls_strerror (result)); - exit(1); - } - } - - if (!proxy) - ca_status = get_ca_status (); - if (ca_status) - path_len = get_path_len (); - else - path_len = -1; - - result = - gnutls_x509_crt_set_basic_constraints (crt, ca_status, path_len); - if (result < 0) - { - fprintf(stderr, "basic_constraints: %s", - gnutls_strerror (result)); - exit(1); - } - - client = get_tls_client_status (); - if (client != 0) - { - result = gnutls_x509_crt_set_key_purpose_oid (crt, - GNUTLS_KP_TLS_WWW_CLIENT, - 0); - if (result < 0) - { - fprintf(stderr, "key_kp: %s", gnutls_strerror (result)); - exit(1); - } - } - - is_ike = get_ipsec_ike_status (); - server = get_tls_server_status (); - - get_dns_name_set (TYPE_CRT, crt); - get_uri_set (TYPE_CRT, crt); - get_ip_addr_set (TYPE_CRT, crt); - get_policy_set (crt); - - if (server != 0) - { - result = 0; - - result = - gnutls_x509_crt_set_key_purpose_oid (crt, - GNUTLS_KP_TLS_WWW_SERVER, 0); - if (result < 0) - { - fprintf(stderr, "key_kp: %s", gnutls_strerror (result)); - exit(1); - } - } - else if (!proxy) - { - get_email_set (TYPE_CRT, crt); - } - - if (!ca_status || server) - { - int pk; - - - pk = gnutls_x509_crt_get_pk_algorithm (crt, NULL); - - if (pk == GNUTLS_PK_RSA) - { /* DSA and ECDSA keys can only sign. */ - result = get_sign_status (server); - if (result) - usage |= GNUTLS_KEY_DIGITAL_SIGNATURE; - - result = get_encrypt_status (server); - if (result) - usage |= GNUTLS_KEY_KEY_ENCIPHERMENT; - } - else - usage |= GNUTLS_KEY_DIGITAL_SIGNATURE; - - if (is_ike) - { - result = - gnutls_x509_crt_set_key_purpose_oid (crt, - GNUTLS_KP_IPSEC_IKE, 0); - if (result < 0) - { - fprintf(stderr, "key_kp: %s", - gnutls_strerror (result)); - exit(1); - } - } - } - - - if (ca_status) - { - result = get_cert_sign_status (); - if (result) - usage |= GNUTLS_KEY_KEY_CERT_SIGN; - - result = get_crl_sign_status (); - if (result) - usage |= GNUTLS_KEY_CRL_SIGN; - - result = get_code_sign_status (); - if (result) - { - result = - gnutls_x509_crt_set_key_purpose_oid (crt, - GNUTLS_KP_CODE_SIGNING, - 0); - if (result < 0) - { - fprintf(stderr, "key_kp: %s", - gnutls_strerror (result)); - exit(1); - } - } - - result = get_ocsp_sign_status (); - if (result) - { - result = - gnutls_x509_crt_set_key_purpose_oid (crt, - GNUTLS_KP_OCSP_SIGNING, - 0); - if (result < 0) - { - fprintf(stderr, "key_kp: %s", - gnutls_strerror (result)); - exit(1); - } - } - - result = get_time_stamp_status (); - if (result) - { - result = - gnutls_x509_crt_set_key_purpose_oid (crt, - GNUTLS_KP_TIME_STAMPING, - 0); - if (result < 0) - { - fprintf(stderr, "key_kp: %s", - gnutls_strerror (result)); - exit(1); - } - } - } - get_ocsp_issuer_set(crt); - get_ca_issuers_set(crt); - - if (usage != 0) - { - /* http://tools.ietf.org/html/rfc4945#section-5.1.3.2: if any KU is - set, then either digitalSignature or the nonRepudiation bits in the - KeyUsage extension MUST for all IKE certs */ - if (is_ike && (get_sign_status (server) != 1)) - usage |= GNUTLS_KEY_NON_REPUDIATION; - result = gnutls_x509_crt_set_key_usage (crt, usage); - if (result < 0) - { - fprintf(stderr, "key_usage: %s", - gnutls_strerror (result)); - exit(1); - } - } - - /* Subject Key ID. - */ - size = buffer_size; - result = gnutls_x509_crt_get_key_id (crt, 0, buffer, &size); - if (result >= 0) - { - result = gnutls_x509_crt_set_subject_key_id (crt, buffer, size); - if (result < 0) - { - fprintf(stderr, "set_subject_key_id: %s", - gnutls_strerror (result)); - exit(1); - } - } - - /* Authority Key ID. - */ - if (ca_crt != NULL) - { - size = buffer_size; - result = gnutls_x509_crt_get_subject_key_id (ca_crt, buffer, - &size, NULL); - if (result < 0) - { - size = 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); - if (result < 0) - { - fprintf(stderr, "set_authority_key_id: %s", - gnutls_strerror (result)); - exit(1); - } - } - } - } - - /* Version. - */ - if (cinfo->v1_cert != 0) - vers = 1; - else - vers = 3; - result = gnutls_x509_crt_set_version (crt, vers); - if (result < 0) - { - fprintf(stderr, "set_version: %s", gnutls_strerror (result)); - exit(1); - } - - *ret_key = key; - return crt; + gnutls_x509_crt_t crt; + gnutls_privkey_t key = NULL; + gnutls_pubkey_t pubkey; + size_t size; + int ret; + int client; + int days, result, ca_status = 0, is_ike = 0, path_len; + time_t secs, now; + int vers; + unsigned int usage = 0, server; + gnutls_x509_crq_t crq; /* request */ + + ret = gnutls_x509_crt_init(&crt); + if (ret < 0) { + fprintf(stderr, "crt_init: %s", gnutls_strerror(ret)); + exit(1); + } + + crq = load_request(cinfo); + + if (crq == NULL) { + + key = load_private_key(0, cinfo); + + pubkey = load_public_key_or_import(1, key, cinfo); + + if (!batch) + fprintf(stderr, + "Please enter the details of the certificate's distinguished name. " + "Just press enter to ignore a field.\n"); + + /* set the DN. + */ + if (proxy) { + result = + gnutls_x509_crt_set_proxy_dn(crt, ca_crt, 0, + NULL, 0); + if (result < 0) { + fprintf(stderr, "set_proxy_dn: %s", + gnutls_strerror(result)); + exit(1); + } + + get_dn_crt_set(crt); + get_cn_crt_set(crt); + } else { + get_dn_crt_set(crt); + + get_cn_crt_set(crt); + get_uid_crt_set(crt); + get_unit_crt_set(crt); + get_organization_crt_set(crt); + get_locality_crt_set(crt); + get_state_crt_set(crt); + get_country_crt_set(crt); + get_dc_set(TYPE_CRT, crt); + + get_oid_crt_set(crt); + get_key_purpose_set(TYPE_CRT, crt); + + if (!batch) + fprintf(stderr, + "This field should not be used in new certificates.\n"); + + get_pkcs9_email_crt_set(crt); + } + + result = gnutls_x509_crt_set_pubkey(crt, pubkey); + if (result < 0) { + fprintf(stderr, "set_key: %s", + gnutls_strerror(result)); + exit(1); + } + } else { + result = gnutls_x509_crt_set_crq(crt, crq); + if (result < 0) { + fprintf(stderr, "set_crq: %s", + gnutls_strerror(result)); + exit(1); + } + } + + + { + int serial = get_serial(); + char bin_serial[5]; + + bin_serial[4] = serial & 0xff; + bin_serial[3] = (serial >> 8) & 0xff; + bin_serial[2] = (serial >> 16) & 0xff; + bin_serial[1] = (serial >> 24) & 0xff; + bin_serial[0] = 0; + + result = gnutls_x509_crt_set_serial(crt, bin_serial, 5); + if (result < 0) { + fprintf(stderr, "serial: %s", + gnutls_strerror(result)); + exit(1); + } + } + + if (!batch) + fprintf(stderr, "\n\nActivation/Expiration time.\n"); + + gnutls_x509_crt_set_activation_time(crt, time(NULL)); + + now = time(NULL); + + do { + days = get_days(); + secs = days * 24 * 60 * 60 + now; + } + while (secs < now + || (unsigned) (secs - now) / (24 * 60 * 60) != + (unsigned) days); + + result = gnutls_x509_crt_set_expiration_time(crt, secs); + if (result < 0) { + fprintf(stderr, "set_expiration: %s", + gnutls_strerror(result)); + exit(1); + } + + if (!batch) + fprintf(stderr, "\n\nExtensions.\n"); + + /* do not allow extensions on a v1 certificate */ + if (crq && get_crq_extensions_status() != 0) { + result = gnutls_x509_crt_set_crq_extensions(crt, crq); + if (result < 0) { + fprintf(stderr, "set_crq: %s", + gnutls_strerror(result)); + exit(1); + } + } + + /* append additional extensions */ + if (cinfo->v1_cert == 0) { + + if (proxy) { + const char *policylanguage; + char *policy; + size_t policylen; + int proxypathlen = get_path_len(); + + if (!batch) { + printf + ("1.3.6.1.5.5.7.21.1 ::= id-ppl-inheritALL\n"); + printf + ("1.3.6.1.5.5.7.21.2 ::= id-ppl-independent\n"); + } + + policylanguage = + get_proxy_policy(&policy, &policylen); + + result = + gnutls_x509_crt_set_proxy(crt, proxypathlen, + policylanguage, + policy, policylen); + if (result < 0) { + fprintf(stderr, "set_proxy: %s", + gnutls_strerror(result)); + exit(1); + } + } + + if (!proxy) + ca_status = get_ca_status(); + if (ca_status) + path_len = get_path_len(); + else + path_len = -1; + + result = + gnutls_x509_crt_set_basic_constraints(crt, ca_status, + path_len); + if (result < 0) { + fprintf(stderr, "basic_constraints: %s", + gnutls_strerror(result)); + exit(1); + } + + client = get_tls_client_status(); + if (client != 0) { + result = gnutls_x509_crt_set_key_purpose_oid(crt, + GNUTLS_KP_TLS_WWW_CLIENT, + 0); + if (result < 0) { + fprintf(stderr, "key_kp: %s", + gnutls_strerror(result)); + exit(1); + } + } + + is_ike = get_ipsec_ike_status(); + server = get_tls_server_status(); + + get_dns_name_set(TYPE_CRT, crt); + get_uri_set(TYPE_CRT, crt); + get_ip_addr_set(TYPE_CRT, crt); + get_policy_set(crt); + + if (server != 0) { + result = 0; + + result = + gnutls_x509_crt_set_key_purpose_oid(crt, + GNUTLS_KP_TLS_WWW_SERVER, + 0); + if (result < 0) { + fprintf(stderr, "key_kp: %s", + gnutls_strerror(result)); + exit(1); + } + } else if (!proxy) { + get_email_set(TYPE_CRT, crt); + } + + if (!ca_status || server) { + int pk; + + + pk = gnutls_x509_crt_get_pk_algorithm(crt, NULL); + + if (pk == GNUTLS_PK_RSA) { /* DSA and ECDSA keys can only sign. */ + result = get_sign_status(server); + if (result) + usage |= + GNUTLS_KEY_DIGITAL_SIGNATURE; + + result = get_encrypt_status(server); + if (result) + usage |= + GNUTLS_KEY_KEY_ENCIPHERMENT; + } else + usage |= GNUTLS_KEY_DIGITAL_SIGNATURE; + + if (is_ike) { + result = + gnutls_x509_crt_set_key_purpose_oid + (crt, GNUTLS_KP_IPSEC_IKE, 0); + if (result < 0) { + fprintf(stderr, "key_kp: %s", + gnutls_strerror(result)); + exit(1); + } + } + } + + + if (ca_status) { + result = get_cert_sign_status(); + if (result) + usage |= GNUTLS_KEY_KEY_CERT_SIGN; + + result = get_crl_sign_status(); + if (result) + usage |= GNUTLS_KEY_CRL_SIGN; + + result = get_code_sign_status(); + if (result) { + result = + gnutls_x509_crt_set_key_purpose_oid + (crt, GNUTLS_KP_CODE_SIGNING, 0); + if (result < 0) { + fprintf(stderr, "key_kp: %s", + gnutls_strerror(result)); + exit(1); + } + } + + result = get_ocsp_sign_status(); + if (result) { + result = + gnutls_x509_crt_set_key_purpose_oid + (crt, GNUTLS_KP_OCSP_SIGNING, 0); + if (result < 0) { + fprintf(stderr, "key_kp: %s", + gnutls_strerror(result)); + exit(1); + } + } + + result = get_time_stamp_status(); + if (result) { + result = + gnutls_x509_crt_set_key_purpose_oid + (crt, GNUTLS_KP_TIME_STAMPING, 0); + if (result < 0) { + fprintf(stderr, "key_kp: %s", + gnutls_strerror(result)); + exit(1); + } + } + } + get_ocsp_issuer_set(crt); + get_ca_issuers_set(crt); + + if (usage != 0) { + /* http://tools.ietf.org/html/rfc4945#section-5.1.3.2: if any KU is + set, then either digitalSignature or the nonRepudiation bits in the + KeyUsage extension MUST for all IKE certs */ + if (is_ike && (get_sign_status(server) != 1)) + usage |= GNUTLS_KEY_NON_REPUDIATION; + result = gnutls_x509_crt_set_key_usage(crt, usage); + if (result < 0) { + fprintf(stderr, "key_usage: %s", + gnutls_strerror(result)); + exit(1); + } + } + + /* Subject Key ID. + */ + size = buffer_size; + result = gnutls_x509_crt_get_key_id(crt, 0, buffer, &size); + if (result >= 0) { + result = + gnutls_x509_crt_set_subject_key_id(crt, buffer, + size); + if (result < 0) { + fprintf(stderr, "set_subject_key_id: %s", + gnutls_strerror(result)); + exit(1); + } + } + + /* Authority Key ID. + */ + if (ca_crt != NULL) { + size = buffer_size; + result = + gnutls_x509_crt_get_subject_key_id(ca_crt, + buffer, + &size, + NULL); + if (result < 0) { + size = 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); + if (result < 0) { + fprintf(stderr, + "set_authority_key_id: %s", + gnutls_strerror(result)); + exit(1); + } + } + } + } + + /* Version. + */ + if (cinfo->v1_cert != 0) + vers = 1; + else + vers = 3; + result = gnutls_x509_crt_set_version(crt, vers); + if (result < 0) { + fprintf(stderr, "set_version: %s", + gnutls_strerror(result)); + exit(1); + } + + *ret_key = key; + return crt; } static gnutls_x509_crl_t -generate_crl (gnutls_x509_crt_t ca_crt, common_info_st * cinfo) +generate_crl(gnutls_x509_crt_t ca_crt, common_info_st * cinfo) { - gnutls_x509_crl_t crl; - gnutls_x509_crt_t *crts; - size_t size; - int days, result; - unsigned int i; - time_t now = time (NULL); - - result = gnutls_x509_crl_init (&crl); - if (result < 0) - { - fprintf(stderr, "crl_init: %s", gnutls_strerror (result)); - exit(1); - } - - crts = load_cert_list (0, &size, cinfo); - - for (i = 0; i < size; i++) - { - result = gnutls_x509_crl_set_crt (crl, crts[i], now); - if (result < 0) - { - fprintf(stderr, "crl_set_crt: %s", gnutls_strerror (result)); - exit(1); - } - } - - result = gnutls_x509_crl_set_this_update (crl, now); - if (result < 0) - { - fprintf(stderr, "this_update: %s", gnutls_strerror (result)); - exit(1); - } - - fprintf (stderr, "Update times.\n"); - days = get_crl_next_update (); - - result = gnutls_x509_crl_set_next_update (crl, now + days * 24 * 60 * 60); - if (result < 0) - { - fprintf(stderr, "next_update: %s", gnutls_strerror (result)); - exit(1); - } - - result = gnutls_x509_crl_set_version (crl, 2); - if (result < 0) - { - fprintf(stderr, "set_version: %s", gnutls_strerror (result)); - exit(1); - } - - /* Authority Key ID. - */ - if (ca_crt != NULL) - { - size = buffer_size; - result = gnutls_x509_crt_get_subject_key_id (ca_crt, buffer, - &size, NULL); - if (result < 0) - { - size = buffer_size; - result = gnutls_x509_crt_get_key_id (ca_crt, 0, buffer, &size); - } - if (result >= 0) - { - result = gnutls_x509_crl_set_authority_key_id (crl, buffer, size); - if (result < 0) - { - fprintf(stderr, "set_authority_key_id: %s", - gnutls_strerror (result)); - exit(1); - } - - } - } - - { - unsigned int number = get_crl_number (); - char bin_number[5]; - - bin_number[4] = number & 0xff; - bin_number[3] = (number >> 8) & 0xff; - bin_number[2] = (number >> 16) & 0xff; - bin_number[1] = (number >> 24) & 0xff; - bin_number[0] = 0; - - result = gnutls_x509_crl_set_number (crl, bin_number, 5); - if (result < 0) - { - fprintf(stderr, "set_number: %s", gnutls_strerror (result)); - exit(1); - } - } - - return crl; + gnutls_x509_crl_t crl; + gnutls_x509_crt_t *crts; + size_t size; + int days, result; + unsigned int i; + time_t now = time(NULL); + + result = gnutls_x509_crl_init(&crl); + if (result < 0) { + fprintf(stderr, "crl_init: %s", gnutls_strerror(result)); + exit(1); + } + + crts = load_cert_list(0, &size, cinfo); + + for (i = 0; i < size; i++) { + result = gnutls_x509_crl_set_crt(crl, crts[i], now); + if (result < 0) { + fprintf(stderr, "crl_set_crt: %s", + gnutls_strerror(result)); + exit(1); + } + } + + result = gnutls_x509_crl_set_this_update(crl, now); + if (result < 0) { + fprintf(stderr, "this_update: %s", + gnutls_strerror(result)); + exit(1); + } + + fprintf(stderr, "Update times.\n"); + days = get_crl_next_update(); + + result = + gnutls_x509_crl_set_next_update(crl, + now + days * 24 * 60 * 60); + if (result < 0) { + fprintf(stderr, "next_update: %s", + gnutls_strerror(result)); + exit(1); + } + + result = gnutls_x509_crl_set_version(crl, 2); + if (result < 0) { + fprintf(stderr, "set_version: %s", + gnutls_strerror(result)); + exit(1); + } + + /* Authority Key ID. + */ + if (ca_crt != NULL) { + size = buffer_size; + result = gnutls_x509_crt_get_subject_key_id(ca_crt, buffer, + &size, NULL); + if (result < 0) { + size = buffer_size; + result = + gnutls_x509_crt_get_key_id(ca_crt, 0, buffer, + &size); + } + if (result >= 0) { + result = + gnutls_x509_crl_set_authority_key_id(crl, + buffer, + size); + if (result < 0) { + fprintf(stderr, "set_authority_key_id: %s", + gnutls_strerror(result)); + exit(1); + } + + } + } + + { + unsigned int number = get_crl_number(); + char bin_number[5]; + + bin_number[4] = number & 0xff; + bin_number[3] = (number >> 8) & 0xff; + bin_number[2] = (number >> 16) & 0xff; + bin_number[1] = (number >> 24) & 0xff; + bin_number[0] = 0; + + result = gnutls_x509_crl_set_number(crl, bin_number, 5); + if (result < 0) { + fprintf(stderr, "set_number: %s", + gnutls_strerror(result)); + exit(1); + } + } + + return crl; } -static gnutls_digest_algorithm_t -get_dig_for_pub (gnutls_pubkey_t pubkey) +static gnutls_digest_algorithm_t get_dig_for_pub(gnutls_pubkey_t pubkey) { - gnutls_digest_algorithm_t dig; - int result; - unsigned int mand; - - result = gnutls_pubkey_get_preferred_hash_algorithm (pubkey, &dig, &mand); - if (result < 0) - { - { - fprintf(stderr, "crt_get_preferred_hash_algorithm: %s", - gnutls_strerror (result)); - exit(1); - } - } - - /* if algorithm allows alternatives */ - if (mand == 0 && default_dig != GNUTLS_DIG_UNKNOWN) - dig = default_dig; - - return dig; + gnutls_digest_algorithm_t dig; + int result; + unsigned int mand; + + result = + gnutls_pubkey_get_preferred_hash_algorithm(pubkey, &dig, + &mand); + if (result < 0) { + { + fprintf(stderr, + "crt_get_preferred_hash_algorithm: %s", + gnutls_strerror(result)); + exit(1); + } + } + + /* if algorithm allows alternatives */ + if (mand == 0 && default_dig != GNUTLS_DIG_UNKNOWN) + dig = default_dig; + + return dig; } -static gnutls_digest_algorithm_t -get_dig (gnutls_x509_crt_t crt) +static gnutls_digest_algorithm_t get_dig(gnutls_x509_crt_t crt) { - gnutls_digest_algorithm_t dig; - gnutls_pubkey_t pubkey; - int result; + gnutls_digest_algorithm_t dig; + gnutls_pubkey_t pubkey; + int result; - gnutls_pubkey_init(&pubkey); + gnutls_pubkey_init(&pubkey); - result = gnutls_pubkey_import_x509(pubkey, crt, 0); - if (result < 0) - { - { - fprintf(stderr, "gnutls_pubkey_import_x509: %s", - gnutls_strerror (result)); - exit(1); - } - } + result = gnutls_pubkey_import_x509(pubkey, crt, 0); + if (result < 0) { + { + fprintf(stderr, "gnutls_pubkey_import_x509: %s", + gnutls_strerror(result)); + exit(1); + } + } - dig = get_dig_for_pub (pubkey); + dig = get_dig_for_pub(pubkey); - gnutls_pubkey_deinit(pubkey); + gnutls_pubkey_deinit(pubkey); - return dig; + return dig; } -void -generate_self_signed (common_info_st * cinfo) +void generate_self_signed(common_info_st * cinfo) { - gnutls_x509_crt_t crt; - gnutls_privkey_t key; - size_t size; - int result; - const char *uri; - - fprintf (stderr, "Generating a self signed certificate...\n"); - - crt = generate_certificate (&key, NULL, 0, cinfo); - - if (!key) - key = load_private_key (1, cinfo); - - uri = get_crl_dist_point_url (); - if (uri) - { - result = gnutls_x509_crt_set_crl_dist_points (crt, GNUTLS_SAN_URI, - uri, - 0 /* all reasons */ ); - if (result < 0) - { - fprintf(stderr, "crl_dist_points: %s", - gnutls_strerror (result)); - exit(1); - } - } - - print_certificate_info (crt, stderr, 0); - - fprintf (stderr, "\n\nSigning certificate...\n"); - - result = gnutls_x509_crt_privkey_sign (crt, crt, key, get_dig (crt), 0); - if (result < 0) - { - fprintf(stderr, "crt_sign: %s", gnutls_strerror (result)); - exit(1); - } - - size = buffer_size; - result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size); - if (result < 0) - { - fprintf(stderr, "crt_export: %s", gnutls_strerror (result)); - exit(1); - } - - fwrite (buffer, 1, size, outfile); - - gnutls_x509_crt_deinit (crt); - gnutls_privkey_deinit (key); + gnutls_x509_crt_t crt; + gnutls_privkey_t key; + size_t size; + int result; + const char *uri; + + fprintf(stderr, "Generating a self signed certificate...\n"); + + crt = generate_certificate(&key, NULL, 0, cinfo); + + if (!key) + key = load_private_key(1, cinfo); + + uri = get_crl_dist_point_url(); + if (uri) { + result = + gnutls_x509_crt_set_crl_dist_points(crt, + GNUTLS_SAN_URI, + uri, + 0 /* all reasons */ + ); + if (result < 0) { + fprintf(stderr, "crl_dist_points: %s", + gnutls_strerror(result)); + exit(1); + } + } + + print_certificate_info(crt, stderr, 0); + + fprintf(stderr, "\n\nSigning certificate...\n"); + + result = + gnutls_x509_crt_privkey_sign(crt, crt, key, get_dig(crt), 0); + if (result < 0) { + fprintf(stderr, "crt_sign: %s", gnutls_strerror(result)); + exit(1); + } + + size = buffer_size; + result = + gnutls_x509_crt_export(crt, outcert_format, buffer, &size); + if (result < 0) { + fprintf(stderr, "crt_export: %s", gnutls_strerror(result)); + exit(1); + } + + fwrite(buffer, 1, size, outfile); + + gnutls_x509_crt_deinit(crt); + gnutls_privkey_deinit(key); } -static void -generate_signed_certificate (common_info_st * cinfo) +static void generate_signed_certificate(common_info_st * cinfo) { - gnutls_x509_crt_t crt; - gnutls_privkey_t key; - size_t size; - int result; - gnutls_privkey_t ca_key; - gnutls_x509_crt_t ca_crt; - - fprintf (stderr, "Generating a signed certificate...\n"); - - ca_key = load_ca_private_key (cinfo); - ca_crt = load_ca_cert (cinfo); - - crt = generate_certificate (&key, ca_crt, 0, cinfo); - - /* Copy the CRL distribution points. - */ - gnutls_x509_crt_cpy_crl_dist_points (crt, ca_crt); - /* it doesn't matter if we couldn't copy the CRL dist points. - */ - - print_certificate_info (crt, stderr, 0); - - fprintf (stderr, "\n\nSigning certificate...\n"); - - result = gnutls_x509_crt_privkey_sign (crt, ca_crt, ca_key, get_dig (ca_crt), 0); - if (result < 0) - { - fprintf(stderr, "crt_sign: %s", gnutls_strerror (result)); - exit(1); - } - - size = buffer_size; - result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size); - if (result < 0) - { - fprintf(stderr, "crt_export: %s", gnutls_strerror (result)); - exit(1); - } - - fwrite (buffer, 1, size, outfile); - - gnutls_x509_crt_deinit (crt); - gnutls_privkey_deinit (key); - gnutls_privkey_deinit(ca_key); + gnutls_x509_crt_t crt; + gnutls_privkey_t key; + size_t size; + int result; + gnutls_privkey_t ca_key; + gnutls_x509_crt_t ca_crt; + + fprintf(stderr, "Generating a signed certificate...\n"); + + ca_key = load_ca_private_key(cinfo); + ca_crt = load_ca_cert(cinfo); + + crt = generate_certificate(&key, ca_crt, 0, cinfo); + + /* Copy the CRL distribution points. + */ + gnutls_x509_crt_cpy_crl_dist_points(crt, ca_crt); + /* it doesn't matter if we couldn't copy the CRL dist points. + */ + + print_certificate_info(crt, stderr, 0); + + fprintf(stderr, "\n\nSigning certificate...\n"); + + result = + gnutls_x509_crt_privkey_sign(crt, ca_crt, ca_key, + get_dig(ca_crt), 0); + if (result < 0) { + fprintf(stderr, "crt_sign: %s", gnutls_strerror(result)); + exit(1); + } + + size = buffer_size; + result = + gnutls_x509_crt_export(crt, outcert_format, buffer, &size); + if (result < 0) { + fprintf(stderr, "crt_export: %s", gnutls_strerror(result)); + exit(1); + } + + fwrite(buffer, 1, size, outfile); + + gnutls_x509_crt_deinit(crt); + gnutls_privkey_deinit(key); + gnutls_privkey_deinit(ca_key); } -static void -generate_proxy_certificate (common_info_st * cinfo) +static void generate_proxy_certificate(common_info_st * cinfo) { - gnutls_x509_crt_t crt, eecrt; - gnutls_privkey_t key, eekey; - size_t size; - int result; + gnutls_x509_crt_t crt, eecrt; + gnutls_privkey_t key, eekey; + size_t size; + int result; - fprintf (stderr, "Generating a proxy certificate...\n"); + fprintf(stderr, "Generating a proxy certificate...\n"); - eekey = load_ca_private_key (cinfo); - eecrt = load_cert (1, cinfo); + eekey = load_ca_private_key(cinfo); + eecrt = load_cert(1, cinfo); - crt = generate_certificate (&key, eecrt, 1, cinfo); + crt = generate_certificate(&key, eecrt, 1, cinfo); - print_certificate_info (crt, stderr, 0); + print_certificate_info(crt, stderr, 0); - fprintf (stderr, "\n\nSigning certificate...\n"); + fprintf(stderr, "\n\nSigning certificate...\n"); - result = gnutls_x509_crt_privkey_sign (crt, eecrt, eekey, get_dig (eecrt), 0); - if (result < 0) - { - fprintf(stderr, "crt_sign: %s", gnutls_strerror (result)); - exit(1); - } + result = + gnutls_x509_crt_privkey_sign(crt, eecrt, eekey, get_dig(eecrt), + 0); + if (result < 0) { + fprintf(stderr, "crt_sign: %s", gnutls_strerror(result)); + exit(1); + } - size = buffer_size; - result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size); - if (result < 0) - { - fprintf(stderr, "crt_export: %s", gnutls_strerror (result)); - exit(1); - } + size = buffer_size; + result = + gnutls_x509_crt_export(crt, outcert_format, buffer, &size); + if (result < 0) { + fprintf(stderr, "crt_export: %s", gnutls_strerror(result)); + exit(1); + } - fwrite (buffer, 1, size, outfile); + fwrite(buffer, 1, size, outfile); - gnutls_x509_crt_deinit (eecrt); - gnutls_x509_crt_deinit (crt); - gnutls_privkey_deinit (key); - gnutls_privkey_deinit (eekey); + gnutls_x509_crt_deinit(eecrt); + gnutls_x509_crt_deinit(crt); + gnutls_privkey_deinit(key); + gnutls_privkey_deinit(eekey); } -static void -generate_signed_crl (common_info_st * cinfo) +static void generate_signed_crl(common_info_st * cinfo) { - gnutls_x509_crl_t crl; - int result; - gnutls_privkey_t ca_key; - gnutls_x509_crt_t ca_crt; - - fprintf (stderr, "Generating a signed CRL...\n"); - - ca_key = load_ca_private_key (cinfo); - ca_crt = load_ca_cert (cinfo); - crl = generate_crl (ca_crt, cinfo); - - fprintf (stderr, "\n"); - result = gnutls_x509_crl_privkey_sign(crl, ca_crt, ca_key, get_dig (ca_crt), 0); - if (result < 0) - { - fprintf(stderr, "crl_privkey_sign: %s", gnutls_strerror (result)); - exit(1); - } - - print_crl_info (crl, stderr); - - gnutls_privkey_deinit( ca_key); - gnutls_x509_crl_deinit (crl); + gnutls_x509_crl_t crl; + int result; + gnutls_privkey_t ca_key; + gnutls_x509_crt_t ca_crt; + + fprintf(stderr, "Generating a signed CRL...\n"); + + ca_key = load_ca_private_key(cinfo); + ca_crt = load_ca_cert(cinfo); + crl = generate_crl(ca_crt, cinfo); + + fprintf(stderr, "\n"); + result = + gnutls_x509_crl_privkey_sign(crl, ca_crt, ca_key, + get_dig(ca_crt), 0); + if (result < 0) { + fprintf(stderr, "crl_privkey_sign: %s", + gnutls_strerror(result)); + exit(1); + } + + print_crl_info(crl, stderr); + + gnutls_privkey_deinit(ca_key); + gnutls_x509_crl_deinit(crl); } -static void -update_signed_certificate (common_info_st * cinfo) +static void update_signed_certificate(common_info_st * cinfo) { - gnutls_x509_crt_t crt; - size_t size; - int result; - gnutls_privkey_t ca_key; - gnutls_x509_crt_t ca_crt; - int days; - time_t tim = time (NULL); - - fprintf (stderr, "Generating a signed certificate...\n"); - - ca_key = load_ca_private_key (cinfo); - ca_crt = load_ca_cert (cinfo); - crt = load_cert (1, cinfo); - - fprintf (stderr, "Activation/Expiration time.\n"); - gnutls_x509_crt_set_activation_time (crt, tim); - - days = get_days (); - - result = - gnutls_x509_crt_set_expiration_time (crt, tim + ((time_t) days) * 24 * 60 * 60); - if (result < 0) - { - fprintf(stderr, "set_expiration: %s", gnutls_strerror (result)); - exit(1); - } - - fprintf (stderr, "\n\nSigning certificate...\n"); - - result = gnutls_x509_crt_privkey_sign (crt, ca_crt, ca_key, get_dig (ca_crt), 0); - if (result < 0) - { - fprintf(stderr, "crt_sign: %s", gnutls_strerror (result)); - exit(1); - } - - size = buffer_size; - result = gnutls_x509_crt_export (crt, outcert_format, buffer, &size); - if (result < 0) - { - fprintf(stderr, "crt_export: %s", gnutls_strerror (result)); - exit(1); - } - - fwrite (buffer, 1, size, outfile); - - gnutls_x509_crt_deinit (crt); + gnutls_x509_crt_t crt; + size_t size; + int result; + gnutls_privkey_t ca_key; + gnutls_x509_crt_t ca_crt; + int days; + time_t tim = time(NULL); + + fprintf(stderr, "Generating a signed certificate...\n"); + + ca_key = load_ca_private_key(cinfo); + ca_crt = load_ca_cert(cinfo); + crt = load_cert(1, cinfo); + + fprintf(stderr, "Activation/Expiration time.\n"); + gnutls_x509_crt_set_activation_time(crt, tim); + + days = get_days(); + + result = + gnutls_x509_crt_set_expiration_time(crt, + tim + + ((time_t) days) * 24 * 60 * + 60); + if (result < 0) { + fprintf(stderr, "set_expiration: %s", + gnutls_strerror(result)); + exit(1); + } + + fprintf(stderr, "\n\nSigning certificate...\n"); + + result = + gnutls_x509_crt_privkey_sign(crt, ca_crt, ca_key, + get_dig(ca_crt), 0); + if (result < 0) { + fprintf(stderr, "crt_sign: %s", gnutls_strerror(result)); + exit(1); + } + + size = buffer_size; + result = + gnutls_x509_crt_export(crt, outcert_format, buffer, &size); + if (result < 0) { + fprintf(stderr, "crt_export: %s", gnutls_strerror(result)); + exit(1); + } + + fwrite(buffer, 1, size, outfile); + + gnutls_x509_crt_deinit(crt); } -static void -cmd_parser (int argc, char **argv) +static void cmd_parser(int argc, char **argv) { - int ret, privkey_op = 0; - common_info_st cinfo; - - optionProcess( &certtoolOptions, argc, argv); - - if (HAVE_OPT(GENERATE_PRIVKEY) || HAVE_OPT(GENERATE_REQUEST) || - HAVE_OPT(KEY_INFO) || HAVE_OPT(PGP_KEY_INFO)) - privkey_op = 1; - - if (HAVE_OPT(HEX_NUMBERS)) - full_format = GNUTLS_CRT_PRINT_FULL_NUMBERS; - - if (HAVE_OPT(OUTFILE)) - { - outfile = safe_open_rw (OPT_ARG(OUTFILE), privkey_op); - if (outfile == NULL) - { - fprintf(stderr, "%s", OPT_ARG(OUTFILE)); - exit(1); - } - } - else - outfile = stdout; - - if (HAVE_OPT(INFILE)) - { - infile = fopen (OPT_ARG(INFILE), "rb"); - if (infile == NULL) - { - fprintf(stderr, "%s", OPT_ARG(INFILE)); - exit(1); - } - } - else - infile = stdin; - - if (HAVE_OPT(INDER) || HAVE_OPT(INRAW)) - incert_format = GNUTLS_X509_FMT_DER; - else - incert_format = GNUTLS_X509_FMT_PEM; - - if (HAVE_OPT(OUTDER) || HAVE_OPT(OUTRAW)) - outcert_format = GNUTLS_X509_FMT_DER; - else - outcert_format = GNUTLS_X509_FMT_PEM; - - if (HAVE_OPT(DSA)) - req_key_type = GNUTLS_PK_DSA; - else if (HAVE_OPT(ECC)) - req_key_type = GNUTLS_PK_ECC; - else - req_key_type = GNUTLS_PK_RSA; - - default_dig = GNUTLS_DIG_UNKNOWN; - if (HAVE_OPT(HASH)) - { - if (strcasecmp (OPT_ARG(HASH), "md5") == 0) - { - fprintf (stderr, - "Warning: MD5 is broken, and should not be used any more for digital signatures.\n"); - default_dig = GNUTLS_DIG_MD5; - } - else if (strcasecmp (OPT_ARG(HASH), "sha1") == 0) - default_dig = GNUTLS_DIG_SHA1; - else if (strcasecmp (OPT_ARG(HASH), "sha256") == 0) - default_dig = GNUTLS_DIG_SHA256; - else if (strcasecmp (OPT_ARG(HASH), "sha224") == 0) - default_dig = GNUTLS_DIG_SHA224; - else if (strcasecmp (OPT_ARG(HASH), "sha384") == 0) - default_dig = GNUTLS_DIG_SHA384; - else if (strcasecmp (OPT_ARG(HASH), "sha512") == 0) - default_dig = GNUTLS_DIG_SHA512; - else if (strcasecmp (OPT_ARG(HASH), "rmd160") == 0) - default_dig = GNUTLS_DIG_RMD160; - else - { - fprintf(stderr, "invalid hash: %s", OPT_ARG(HASH)); - exit(1); - } - } - - batch = 0; - if (HAVE_OPT(TEMPLATE)) - { - batch = 1; - template_parse (OPT_ARG(TEMPLATE)); - } - - gnutls_global_set_log_function (tls_log_func); - - if (HAVE_OPT(DEBUG)) - { - gnutls_global_set_log_level (OPT_VALUE_DEBUG); - printf ("Setting log level to %d\n", (int)OPT_VALUE_DEBUG); - } - - if ((ret = gnutls_global_init ()) < 0) - { - fprintf(stderr, "global_init: %s", gnutls_strerror (ret)); - exit(1); - } - + int ret, privkey_op = 0; + common_info_st cinfo; + + optionProcess(&certtoolOptions, argc, argv); + + if (HAVE_OPT(GENERATE_PRIVKEY) || HAVE_OPT(GENERATE_REQUEST) || + HAVE_OPT(KEY_INFO) || HAVE_OPT(PGP_KEY_INFO)) + privkey_op = 1; + + if (HAVE_OPT(HEX_NUMBERS)) + full_format = GNUTLS_CRT_PRINT_FULL_NUMBERS; + + if (HAVE_OPT(OUTFILE)) { + outfile = safe_open_rw(OPT_ARG(OUTFILE), privkey_op); + if (outfile == NULL) { + fprintf(stderr, "%s", OPT_ARG(OUTFILE)); + exit(1); + } + } else + outfile = stdout; + + if (HAVE_OPT(INFILE)) { + infile = fopen(OPT_ARG(INFILE), "rb"); + if (infile == NULL) { + fprintf(stderr, "%s", OPT_ARG(INFILE)); + exit(1); + } + } else + infile = stdin; + + if (HAVE_OPT(INDER) || HAVE_OPT(INRAW)) + incert_format = GNUTLS_X509_FMT_DER; + else + incert_format = GNUTLS_X509_FMT_PEM; + + if (HAVE_OPT(OUTDER) || HAVE_OPT(OUTRAW)) + outcert_format = GNUTLS_X509_FMT_DER; + else + outcert_format = GNUTLS_X509_FMT_PEM; + + if (HAVE_OPT(DSA)) + req_key_type = GNUTLS_PK_DSA; + else if (HAVE_OPT(ECC)) + req_key_type = GNUTLS_PK_ECC; + else + req_key_type = GNUTLS_PK_RSA; + + default_dig = GNUTLS_DIG_UNKNOWN; + if (HAVE_OPT(HASH)) { + if (strcasecmp(OPT_ARG(HASH), "md5") == 0) { + fprintf(stderr, + "Warning: MD5 is broken, and should not be used any more for digital signatures.\n"); + default_dig = GNUTLS_DIG_MD5; + } else if (strcasecmp(OPT_ARG(HASH), "sha1") == 0) + default_dig = GNUTLS_DIG_SHA1; + else if (strcasecmp(OPT_ARG(HASH), "sha256") == 0) + default_dig = GNUTLS_DIG_SHA256; + else if (strcasecmp(OPT_ARG(HASH), "sha224") == 0) + default_dig = GNUTLS_DIG_SHA224; + else if (strcasecmp(OPT_ARG(HASH), "sha384") == 0) + default_dig = GNUTLS_DIG_SHA384; + else if (strcasecmp(OPT_ARG(HASH), "sha512") == 0) + default_dig = GNUTLS_DIG_SHA512; + else if (strcasecmp(OPT_ARG(HASH), "rmd160") == 0) + default_dig = GNUTLS_DIG_RMD160; + else { + fprintf(stderr, "invalid hash: %s", OPT_ARG(HASH)); + exit(1); + } + } + + batch = 0; + if (HAVE_OPT(TEMPLATE)) { + batch = 1; + template_parse(OPT_ARG(TEMPLATE)); + } + + gnutls_global_set_log_function(tls_log_func); + + if (HAVE_OPT(DEBUG)) { + gnutls_global_set_log_level(OPT_VALUE_DEBUG); + printf("Setting log level to %d\n", (int) OPT_VALUE_DEBUG); + } + + if ((ret = gnutls_global_init()) < 0) { + fprintf(stderr, "global_init: %s", gnutls_strerror(ret)); + exit(1); + } #ifdef ENABLE_PKCS11 - pkcs11_common(); + pkcs11_common(); #endif - memset (&cinfo, 0, sizeof (cinfo)); - - if (HAVE_OPT(VERBOSE)) - cinfo.verbose = 1; - - cinfo.cprint = HAVE_OPT(CPRINT); - - if (HAVE_OPT(LOAD_PRIVKEY)) - cinfo.privkey = OPT_ARG(LOAD_PRIVKEY); - - cinfo.v1_cert = HAVE_OPT(V1); - if (HAVE_OPT(NO_CRQ_EXTENSIONS)) - cinfo.crq_extensions = 0; - else cinfo.crq_extensions = 1; - - if (HAVE_OPT(LOAD_PUBKEY)) - cinfo.pubkey = OPT_ARG(LOAD_PUBKEY); - - cinfo.pkcs8 = HAVE_OPT(PKCS8); - cinfo.incert_format = incert_format; - cinfo.outcert_format = outcert_format; - - if (HAVE_OPT(LOAD_CERTIFICATE)) - cinfo.cert = OPT_ARG(LOAD_CERTIFICATE); - - if (HAVE_OPT(LOAD_REQUEST)) - cinfo.request = OPT_ARG(LOAD_REQUEST); - - if (HAVE_OPT(LOAD_CA_CERTIFICATE)) - cinfo.ca = OPT_ARG(LOAD_CA_CERTIFICATE); - - if (HAVE_OPT(LOAD_CA_PRIVKEY)) - cinfo.ca_privkey = OPT_ARG(LOAD_CA_PRIVKEY); - - if (HAVE_OPT(BITS)) - cinfo.bits = OPT_VALUE_BITS; - - if (HAVE_OPT(SEC_PARAM)) - cinfo.sec_param = OPT_ARG(SEC_PARAM); - - if (HAVE_OPT(PKCS_CIPHER)) - cinfo.pkcs_cipher = OPT_ARG(PKCS_CIPHER); - - if (HAVE_OPT(PASSWORD)) - { - cinfo.password = OPT_ARG(PASSWORD); - if (HAVE_OPT(GENERATE_PRIVKEY) && cinfo.pkcs8 == 0) - { - fprintf(stderr, "Assuming PKCS #8 format...\n"); - cinfo.pkcs8 = 1; - } - } - - if (HAVE_OPT(NULL_PASSWORD)) - { - cinfo.null_password = 1; - cinfo.password = ""; - } - - if (HAVE_OPT(GENERATE_SELF_SIGNED)) - generate_self_signed (&cinfo); - else if (HAVE_OPT(GENERATE_CERTIFICATE)) - generate_signed_certificate (&cinfo); - else if (HAVE_OPT(GENERATE_PROXY)) - generate_proxy_certificate (&cinfo); - else if (HAVE_OPT(GENERATE_CRL)) - generate_signed_crl (&cinfo); - else if (HAVE_OPT(UPDATE_CERTIFICATE)) - update_signed_certificate (&cinfo); - else if (HAVE_OPT(GENERATE_PRIVKEY)) - generate_private_key (&cinfo); - else if (HAVE_OPT(GENERATE_REQUEST)) - generate_request (&cinfo); - else if (HAVE_OPT(VERIFY_CHAIN)) - verify_chain (); - else if (HAVE_OPT(VERIFY)) - verify_certificate (&cinfo); - else if (HAVE_OPT(VERIFY_CRL)) - verify_crl (&cinfo); - else if (HAVE_OPT(CERTIFICATE_INFO)) - certificate_info (0, &cinfo); - else if (HAVE_OPT(DH_INFO)) - dh_info (infile, outfile, &cinfo); - else if (HAVE_OPT(CERTIFICATE_PUBKEY)) - certificate_info (1, &cinfo); - else if (HAVE_OPT(KEY_INFO)) - privkey_info (&cinfo); - else if (HAVE_OPT(PUBKEY_INFO)) - pubkey_info (NULL, &cinfo); - else if (HAVE_OPT(TO_P12)) - generate_pkcs12 (&cinfo); - else if (HAVE_OPT(P12_INFO)) - pkcs12_info (&cinfo); - else if (HAVE_OPT(GENERATE_DH_PARAMS)) - generate_prime (outfile, 1, &cinfo); - else if (HAVE_OPT(GET_DH_PARAMS)) - generate_prime (outfile, 0, &cinfo); - else if (HAVE_OPT(CRL_INFO)) - crl_info (); - else if (HAVE_OPT(P7_INFO)) - pkcs7_info (); - else if (HAVE_OPT(SMIME_TO_P7)) - smime_to_pkcs7 (); - else if (HAVE_OPT(TO_P8)) - generate_pkcs8 (&cinfo); + memset(&cinfo, 0, sizeof(cinfo)); + + if (HAVE_OPT(VERBOSE)) + cinfo.verbose = 1; + + cinfo.cprint = HAVE_OPT(CPRINT); + + if (HAVE_OPT(LOAD_PRIVKEY)) + cinfo.privkey = OPT_ARG(LOAD_PRIVKEY); + + cinfo.v1_cert = HAVE_OPT(V1); + if (HAVE_OPT(NO_CRQ_EXTENSIONS)) + cinfo.crq_extensions = 0; + else + cinfo.crq_extensions = 1; + + if (HAVE_OPT(LOAD_PUBKEY)) + cinfo.pubkey = OPT_ARG(LOAD_PUBKEY); + + cinfo.pkcs8 = HAVE_OPT(PKCS8); + cinfo.incert_format = incert_format; + cinfo.outcert_format = outcert_format; + + if (HAVE_OPT(LOAD_CERTIFICATE)) + cinfo.cert = OPT_ARG(LOAD_CERTIFICATE); + + if (HAVE_OPT(LOAD_REQUEST)) + cinfo.request = OPT_ARG(LOAD_REQUEST); + + if (HAVE_OPT(LOAD_CA_CERTIFICATE)) + cinfo.ca = OPT_ARG(LOAD_CA_CERTIFICATE); + + if (HAVE_OPT(LOAD_CA_PRIVKEY)) + cinfo.ca_privkey = OPT_ARG(LOAD_CA_PRIVKEY); + + if (HAVE_OPT(BITS)) + cinfo.bits = OPT_VALUE_BITS; + + if (HAVE_OPT(SEC_PARAM)) + cinfo.sec_param = OPT_ARG(SEC_PARAM); + + if (HAVE_OPT(PKCS_CIPHER)) + cinfo.pkcs_cipher = OPT_ARG(PKCS_CIPHER); + + if (HAVE_OPT(PASSWORD)) { + cinfo.password = OPT_ARG(PASSWORD); + if (HAVE_OPT(GENERATE_PRIVKEY) && cinfo.pkcs8 == 0) { + fprintf(stderr, "Assuming PKCS #8 format...\n"); + cinfo.pkcs8 = 1; + } + } + + if (HAVE_OPT(NULL_PASSWORD)) { + cinfo.null_password = 1; + cinfo.password = ""; + } + + if (HAVE_OPT(GENERATE_SELF_SIGNED)) + generate_self_signed(&cinfo); + else if (HAVE_OPT(GENERATE_CERTIFICATE)) + generate_signed_certificate(&cinfo); + else if (HAVE_OPT(GENERATE_PROXY)) + generate_proxy_certificate(&cinfo); + else if (HAVE_OPT(GENERATE_CRL)) + generate_signed_crl(&cinfo); + else if (HAVE_OPT(UPDATE_CERTIFICATE)) + update_signed_certificate(&cinfo); + else if (HAVE_OPT(GENERATE_PRIVKEY)) + generate_private_key(&cinfo); + else if (HAVE_OPT(GENERATE_REQUEST)) + generate_request(&cinfo); + else if (HAVE_OPT(VERIFY_CHAIN)) + verify_chain(); + else if (HAVE_OPT(VERIFY)) + verify_certificate(&cinfo); + else if (HAVE_OPT(VERIFY_CRL)) + verify_crl(&cinfo); + else if (HAVE_OPT(CERTIFICATE_INFO)) + certificate_info(0, &cinfo); + else if (HAVE_OPT(DH_INFO)) + dh_info(infile, outfile, &cinfo); + else if (HAVE_OPT(CERTIFICATE_PUBKEY)) + certificate_info(1, &cinfo); + else if (HAVE_OPT(KEY_INFO)) + privkey_info(&cinfo); + else if (HAVE_OPT(PUBKEY_INFO)) + pubkey_info(NULL, &cinfo); + else if (HAVE_OPT(TO_P12)) + generate_pkcs12(&cinfo); + else if (HAVE_OPT(P12_INFO)) + pkcs12_info(&cinfo); + else if (HAVE_OPT(GENERATE_DH_PARAMS)) + generate_prime(outfile, 1, &cinfo); + else if (HAVE_OPT(GET_DH_PARAMS)) + generate_prime(outfile, 0, &cinfo); + else if (HAVE_OPT(CRL_INFO)) + crl_info(); + else if (HAVE_OPT(P7_INFO)) + pkcs7_info(); + else if (HAVE_OPT(SMIME_TO_P7)) + smime_to_pkcs7(); + else if (HAVE_OPT(TO_P8)) + generate_pkcs8(&cinfo); #ifdef ENABLE_OPENPGP - else if (HAVE_OPT(PGP_CERTIFICATE_INFO)) - pgp_certificate_info (); - else if (HAVE_OPT(PGP_KEY_INFO)) - pgp_privkey_info (); - else if (HAVE_OPT(PGP_RING_INFO)) - pgp_ring_info (); + else if (HAVE_OPT(PGP_CERTIFICATE_INFO)) + pgp_certificate_info(); + else if (HAVE_OPT(PGP_KEY_INFO)) + pgp_privkey_info(); + else if (HAVE_OPT(PGP_RING_INFO)) + pgp_ring_info(); #endif - else if (HAVE_OPT(CRQ_INFO)) - crq_info (); - else - USAGE(1); + else if (HAVE_OPT(CRQ_INFO)) + crq_info(); + else + USAGE(1); - fclose (outfile); + fclose(outfile); #ifdef ENABLE_PKCS11 - gnutls_pkcs11_deinit (); + gnutls_pkcs11_deinit(); #endif - gnutls_global_deinit (); + gnutls_global_deinit(); } #define MAX_CRTS 500 -void -certificate_info (int pubkey, common_info_st * cinfo) +void certificate_info(int pubkey, common_info_st * cinfo) { - gnutls_x509_crt_t crt[MAX_CRTS]; - size_t size; - int ret, i, count; - gnutls_datum_t pem; - unsigned int crt_num; - - pem.data = (void*)fread_file (infile, &size); - pem.size = size; - - crt_num = MAX_CRTS; - ret = - gnutls_x509_crt_list_import (crt, &crt_num, &pem, incert_format, - GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED); - if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) - { - fprintf( stderr, "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, - incert_format, 0); - } - if (ret < 0) - { - fprintf(stderr, "import error: %s", gnutls_strerror (ret)); - exit(1); - } - - free (pem.data); - - count = ret; - - if (count > 1 && outcert_format == GNUTLS_X509_FMT_DER) - { - fprintf( stderr, "cannot output multiple certificates in DER format; " - "using PEM instead"); - outcert_format = GNUTLS_X509_FMT_PEM; - } - - for (i = 0; i < count; i++) - { - if (i > 0) - fprintf (outfile, "\n"); - - if (outcert_format == GNUTLS_X509_FMT_PEM) - print_certificate_info (crt[i], outfile, 1); - - if (pubkey) - pubkey_info (crt[i], cinfo); - else - { - size = buffer_size; - ret = gnutls_x509_crt_export (crt[i], outcert_format, buffer, - &size); - if (ret < 0) - { - fprintf(stderr, "export error: %s", gnutls_strerror (ret)); - exit(1); - } - - fwrite (buffer, 1, size, outfile); - } - - gnutls_x509_crt_deinit (crt[i]); - } + gnutls_x509_crt_t crt[MAX_CRTS]; + size_t size; + int ret, i, count; + gnutls_datum_t pem; + unsigned int crt_num; + + pem.data = (void *) fread_file(infile, &size); + pem.size = size; + + crt_num = MAX_CRTS; + ret = + gnutls_x509_crt_list_import(crt, &crt_num, &pem, incert_format, + GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED); + if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { + fprintf(stderr, "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, + incert_format, 0); + } + if (ret < 0) { + fprintf(stderr, "import error: %s", gnutls_strerror(ret)); + exit(1); + } + + free(pem.data); + + count = ret; + + if (count > 1 && outcert_format == GNUTLS_X509_FMT_DER) { + fprintf(stderr, + "cannot output multiple certificates in DER format; " + "using PEM instead"); + outcert_format = GNUTLS_X509_FMT_PEM; + } + + for (i = 0; i < count; i++) { + if (i > 0) + fprintf(outfile, "\n"); + + if (outcert_format == GNUTLS_X509_FMT_PEM) + print_certificate_info(crt[i], outfile, 1); + + if (pubkey) + pubkey_info(crt[i], cinfo); + else { + size = buffer_size; + ret = + gnutls_x509_crt_export(crt[i], outcert_format, + buffer, &size); + if (ret < 0) { + fprintf(stderr, "export error: %s", + gnutls_strerror(ret)); + exit(1); + } + + fwrite(buffer, 1, size, outfile); + } + + gnutls_x509_crt_deinit(crt[i]); + } } #ifdef ENABLE_OPENPGP -void -pgp_certificate_info (void) +void pgp_certificate_info(void) { - gnutls_openpgp_crt_t crt; - size_t size; - int ret; - gnutls_datum_t pem, out_data; - unsigned int verify_status; - - pem.data = (void*)fread_file (infile, &size); - pem.size = size; - - ret = gnutls_openpgp_crt_init (&crt); - if (ret < 0) - { - fprintf(stderr, "openpgp_crt_init: %s", gnutls_strerror (ret)); - exit(1); - } - - ret = gnutls_openpgp_crt_import (crt, &pem, incert_format); - - if (ret < 0) - { - fprintf(stderr, "import error: %s", gnutls_strerror (ret)); - exit(1); - } - - free (pem.data); - - if (outcert_format == GNUTLS_OPENPGP_FMT_BASE64) - { - ret = gnutls_openpgp_crt_print (crt, 0, &out_data); - - if (ret == 0) - { - fprintf (outfile, "%s\n", out_data.data); - gnutls_free (out_data.data); - } - } - - - ret = gnutls_openpgp_crt_verify_self (crt, 0, &verify_status); - if (ret < 0) - { - { - fprintf(stderr, "verify signature error: %s", - gnutls_strerror (ret)); - exit(1); - } - } - - if (verify_status & GNUTLS_CERT_INVALID) - { - fprintf (outfile, "Self Signature verification: failed\n\n"); - } - else - { - fprintf (outfile, "Self Signature verification: ok (%x)\n\n", - verify_status); - } - - size = buffer_size; - ret = gnutls_openpgp_crt_export (crt, outcert_format, buffer, &size); - if (ret < 0) - { - fprintf(stderr, "export error: %s", gnutls_strerror (ret)); - exit(1); - } - - fprintf (outfile, "%s\n", buffer); - gnutls_openpgp_crt_deinit (crt); + gnutls_openpgp_crt_t crt; + size_t size; + int ret; + gnutls_datum_t pem, out_data; + unsigned int verify_status; + + pem.data = (void *) fread_file(infile, &size); + pem.size = size; + + ret = gnutls_openpgp_crt_init(&crt); + if (ret < 0) { + fprintf(stderr, "openpgp_crt_init: %s", + gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_openpgp_crt_import(crt, &pem, incert_format); + + if (ret < 0) { + fprintf(stderr, "import error: %s", gnutls_strerror(ret)); + exit(1); + } + + free(pem.data); + + if (outcert_format == GNUTLS_OPENPGP_FMT_BASE64) { + ret = gnutls_openpgp_crt_print(crt, 0, &out_data); + + if (ret == 0) { + fprintf(outfile, "%s\n", out_data.data); + gnutls_free(out_data.data); + } + } + + + ret = gnutls_openpgp_crt_verify_self(crt, 0, &verify_status); + if (ret < 0) { + { + fprintf(stderr, "verify signature error: %s", + gnutls_strerror(ret)); + exit(1); + } + } + + if (verify_status & GNUTLS_CERT_INVALID) { + fprintf(outfile, + "Self Signature verification: failed\n\n"); + } else { + fprintf(outfile, + "Self Signature verification: ok (%x)\n\n", + verify_status); + } + + size = buffer_size; + ret = + gnutls_openpgp_crt_export(crt, outcert_format, buffer, &size); + if (ret < 0) { + fprintf(stderr, "export error: %s", gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "%s\n", buffer); + gnutls_openpgp_crt_deinit(crt); } -void -pgp_privkey_info (void) +void pgp_privkey_info(void) { - gnutls_openpgp_privkey_t key; - unsigned char keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - size_t size; - int ret, i, subkeys, bits = 0; - gnutls_datum_t pem; - const char *cprint; - - size = fread (buffer, 1, buffer_size - 1, infile); - buffer[size] = 0; - - gnutls_openpgp_privkey_init (&key); - - pem.data = buffer; - pem.size = size; - - ret = gnutls_openpgp_privkey_import (key, &pem, incert_format, - NULL, 0); - - if (ret < 0) - { - fprintf(stderr, "import error: %s", gnutls_strerror (ret)); - exit(1); - } - - /* Public key algorithm - */ - subkeys = gnutls_openpgp_privkey_get_subkey_count (key); - if (subkeys < 0) - { - fprintf(stderr, "privkey_get_subkey_count: %s", - gnutls_strerror (subkeys)); - exit(1); - } - - 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); - fprintf (outfile, "%s\n", cprint ? cprint : "Unknown"); - fprintf (outfile, "\tKey Security Level: %s\n", - gnutls_sec_param_get_name (gnutls_openpgp_privkey_sec_param - (key))); - - /* 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 (outfile, &m, &e, &d, &p, &q, &u, NULL, NULL, HAVE_OPT(CPRINT)); - - bits = m.size * 8; - } - 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 (outfile, &x, &y, &p, &q, &g, HAVE_OPT(CPRINT)); - - bits = y.size * 8; - } - - fprintf (outfile, "\n"); - - size = buffer_size; - 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, 8)); - } - - size = buffer_size; - if (i == -1) - ret = gnutls_openpgp_privkey_get_fingerprint (key, buffer, &size); - else - ret = gnutls_openpgp_privkey_get_subkey_fingerprint (key, i, buffer, &size); - - if (ret < 0) - { - fprintf (stderr, "Error in fingerprint calculation: %s\n", - gnutls_strerror (ret)); - } - else - { - gnutls_datum_t art; - - fprintf (outfile, "Fingerprint: %s\n", raw_to_string (buffer, size)); - - ret = gnutls_random_art(GNUTLS_RANDOM_ART_OPENSSH, cprint, bits, buffer, size, &art); - if (ret >= 0) - { - fprintf (outfile, "Fingerprint's random art:\n%s\n\n", art.data); - gnutls_free(art.data); - } - } - } - - size = buffer_size; - ret = gnutls_openpgp_privkey_export (key, GNUTLS_OPENPGP_FMT_BASE64, - NULL, 0, buffer, &size); - if (ret < 0) - { - fprintf(stderr, "export error: %s", gnutls_strerror (ret)); - exit(1); - } - - fprintf (outfile, "\n%s\n", buffer); - - gnutls_openpgp_privkey_deinit (key); + gnutls_openpgp_privkey_t key; + unsigned char keyid[GNUTLS_OPENPGP_KEYID_SIZE]; + size_t size; + int ret, i, subkeys, bits = 0; + gnutls_datum_t pem; + const char *cprint; + + size = fread(buffer, 1, buffer_size - 1, infile); + buffer[size] = 0; + + gnutls_openpgp_privkey_init(&key); + + pem.data = buffer; + pem.size = size; + + ret = gnutls_openpgp_privkey_import(key, &pem, incert_format, + NULL, 0); + + if (ret < 0) { + fprintf(stderr, "import error: %s", gnutls_strerror(ret)); + exit(1); + } + + /* Public key algorithm + */ + subkeys = gnutls_openpgp_privkey_get_subkey_count(key); + if (subkeys < 0) { + fprintf(stderr, "privkey_get_subkey_count: %s", + gnutls_strerror(subkeys)); + exit(1); + } + + 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); + fprintf(outfile, "%s\n", cprint ? cprint : "Unknown"); + fprintf(outfile, "\tKey Security Level: %s\n", + gnutls_sec_param_get_name + (gnutls_openpgp_privkey_sec_param(key))); + + /* 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(outfile, &m, &e, &d, &p, &q, + &u, NULL, NULL, + HAVE_OPT(CPRINT)); + + bits = m.size * 8; + } 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(outfile, &x, &y, &p, &q, &g, + HAVE_OPT(CPRINT)); + + bits = y.size * 8; + } + + fprintf(outfile, "\n"); + + size = buffer_size; + 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, 8)); + } + + size = buffer_size; + if (i == -1) + ret = + gnutls_openpgp_privkey_get_fingerprint(key, + buffer, + &size); + else + ret = + gnutls_openpgp_privkey_get_subkey_fingerprint + (key, i, buffer, &size); + + if (ret < 0) { + fprintf(stderr, + "Error in fingerprint calculation: %s\n", + gnutls_strerror(ret)); + } else { + gnutls_datum_t art; + + fprintf(outfile, "Fingerprint: %s\n", + raw_to_string(buffer, size)); + + ret = + gnutls_random_art(GNUTLS_RANDOM_ART_OPENSSH, + cprint, bits, buffer, size, + &art); + if (ret >= 0) { + fprintf(outfile, + "Fingerprint's random art:\n%s\n\n", + art.data); + gnutls_free(art.data); + } + } + } + + size = buffer_size; + ret = gnutls_openpgp_privkey_export(key, GNUTLS_OPENPGP_FMT_BASE64, + NULL, 0, buffer, &size); + if (ret < 0) { + fprintf(stderr, "export error: %s", gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "\n%s\n", buffer); + + gnutls_openpgp_privkey_deinit(key); } -void -pgp_ring_info (void) +void pgp_ring_info(void) { - gnutls_openpgp_keyring_t ring; - gnutls_openpgp_crt_t crt; - size_t size; - int ret, i, count; - gnutls_datum_t pem; - - pem.data = (void*)fread_file (infile, &size); - pem.size = size; - - ret = gnutls_openpgp_keyring_init (&ring); - if (ret < 0) - { - fprintf(stderr, "openpgp_keyring_init: %s", - gnutls_strerror (ret)); - exit(1); - } - - ret = gnutls_openpgp_keyring_import (ring, &pem, incert_format); - - if (ret < 0) - { - fprintf(stderr, "import error: %s", gnutls_strerror (ret)); - exit(1); - } - - free (pem.data); - - count = gnutls_openpgp_keyring_get_crt_count (ring); - if (count >= 0) - fprintf (outfile, "Keyring contains %d OpenPGP certificates\n\n", count); - else - { - fprintf(stderr, "keyring error: %s", gnutls_strerror (count)); - exit(1); - } - - for (i = 0; i < count; i++) - { - ret = gnutls_openpgp_keyring_get_crt (ring, i, &crt); - if (ret < 0) - { - fprintf(stderr, "export error: %s", gnutls_strerror (ret)); - exit(1); - } - - size = buffer_size; - ret = gnutls_openpgp_crt_export (crt, outcert_format, - buffer, &size); - if (ret < 0) - { - fprintf(stderr, "export error: %s", gnutls_strerror (ret)); - exit(1); - } - - fwrite (buffer, 1, size, outfile); - fprintf (outfile, "\n\n"); - - gnutls_openpgp_crt_deinit (crt); - - - } - - gnutls_openpgp_keyring_deinit (ring); + gnutls_openpgp_keyring_t ring; + gnutls_openpgp_crt_t crt; + size_t size; + int ret, i, count; + gnutls_datum_t pem; + + pem.data = (void *) fread_file(infile, &size); + pem.size = size; + + ret = gnutls_openpgp_keyring_init(&ring); + if (ret < 0) { + fprintf(stderr, "openpgp_keyring_init: %s", + gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_openpgp_keyring_import(ring, &pem, incert_format); + + if (ret < 0) { + fprintf(stderr, "import error: %s", gnutls_strerror(ret)); + exit(1); + } + + free(pem.data); + + count = gnutls_openpgp_keyring_get_crt_count(ring); + if (count >= 0) + fprintf(outfile, + "Keyring contains %d OpenPGP certificates\n\n", + count); + else { + fprintf(stderr, "keyring error: %s", + gnutls_strerror(count)); + exit(1); + } + + for (i = 0; i < count; i++) { + ret = gnutls_openpgp_keyring_get_crt(ring, i, &crt); + if (ret < 0) { + fprintf(stderr, "export error: %s", + gnutls_strerror(ret)); + exit(1); + } + + size = buffer_size; + ret = gnutls_openpgp_crt_export(crt, outcert_format, + buffer, &size); + if (ret < 0) { + fprintf(stderr, "export error: %s", + gnutls_strerror(ret)); + exit(1); + } + + fwrite(buffer, 1, size, outfile); + fprintf(outfile, "\n\n"); + + gnutls_openpgp_crt_deinit(crt); + + + } + + gnutls_openpgp_keyring_deinit(ring); } @@ -1631,660 +1573,644 @@ pgp_ring_info (void) 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 data; - int ret; - - if (all) - ret = gnutls_x509_crt_print (crt, full_format, &data); - else - ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_UNSIGNED_FULL, &data); - if (ret == 0) - { - fprintf (out, "%s\n", data.data); - gnutls_free (data.data); - } - - if (out == stderr && batch == 0) /* interactive */ - if (read_yesno ("Is the above information ok? (y/N): ", 0) == 0) - { - exit (1); - } + gnutls_datum_t data; + int ret; + + if (all) + ret = gnutls_x509_crt_print(crt, full_format, &data); + else + ret = + gnutls_x509_crt_print(crt, + GNUTLS_CRT_PRINT_UNSIGNED_FULL, + &data); + if (ret == 0) { + fprintf(out, "%s\n", data.data); + gnutls_free(data.data); + } + + if (out == stderr && batch == 0) /* interactive */ + if (read_yesno("Is the above information ok? (y/N): ", 0) + == 0) { + exit(1); + } } -static void -print_crl_info (gnutls_x509_crl_t crl, FILE * out) +static void print_crl_info(gnutls_x509_crl_t crl, FILE * out) { - gnutls_datum_t data; - int ret; - size_t size; - - ret = gnutls_x509_crl_print (crl, full_format, &data); - if (ret < 0) - { - fprintf(stderr, "crl_print: %s", gnutls_strerror (ret)); - exit(1); - } - - fprintf (out, "%s\n", data.data); - - gnutls_free (data.data); - - size = buffer_size; - ret = gnutls_x509_crl_export (crl, GNUTLS_X509_FMT_PEM, buffer, &size); - if (ret < 0) - { - fprintf(stderr, "crl_export: %s", gnutls_strerror (ret)); - exit(1); - } - - fwrite (buffer, 1, size, outfile); + gnutls_datum_t data; + int ret; + size_t size; + + ret = gnutls_x509_crl_print(crl, full_format, &data); + if (ret < 0) { + fprintf(stderr, "crl_print: %s", gnutls_strerror(ret)); + exit(1); + } + + fprintf(out, "%s\n", data.data); + + gnutls_free(data.data); + + size = buffer_size; + ret = + gnutls_x509_crl_export(crl, GNUTLS_X509_FMT_PEM, buffer, + &size); + if (ret < 0) { + fprintf(stderr, "crl_export: %s", gnutls_strerror(ret)); + exit(1); + } + + fwrite(buffer, 1, size, outfile); } -void -crl_info (void) +void crl_info(void) { - gnutls_x509_crl_t crl; - int ret; - size_t size; - gnutls_datum_t pem; - - ret = gnutls_x509_crl_init (&crl); - if (ret < 0) - { - fprintf(stderr, "crl_init: %s", gnutls_strerror (ret)); - exit(1); - } - - pem.data = (void*)fread_file (infile, &size); - pem.size = size; - - if (!pem.data) - { - fprintf(stderr, "%s", infile ? "file" : - "standard input"); - exit(1); - } - - ret = gnutls_x509_crl_import (crl, &pem, incert_format); - - free (pem.data); - if (ret < 0) - { - fprintf(stderr, "import error: %s", gnutls_strerror (ret)); - exit(1); - } - - print_crl_info (crl, outfile); - - gnutls_x509_crl_deinit (crl); + gnutls_x509_crl_t crl; + int ret; + size_t size; + gnutls_datum_t pem; + + ret = gnutls_x509_crl_init(&crl); + if (ret < 0) { + fprintf(stderr, "crl_init: %s", gnutls_strerror(ret)); + exit(1); + } + + pem.data = (void *) fread_file(infile, &size); + pem.size = size; + + if (!pem.data) { + fprintf(stderr, "%s", infile ? "file" : "standard input"); + exit(1); + } + + ret = gnutls_x509_crl_import(crl, &pem, incert_format); + + free(pem.data); + if (ret < 0) { + fprintf(stderr, "import error: %s", gnutls_strerror(ret)); + exit(1); + } + + print_crl_info(crl, outfile); + + gnutls_x509_crl_deinit(crl); } -static void -print_crq_info (gnutls_x509_crq_t crq, FILE * out) +static void print_crq_info(gnutls_x509_crq_t crq, FILE * out) { - gnutls_datum_t data; - int ret; - size_t size; - - if (outcert_format == GNUTLS_X509_FMT_PEM) - { - ret = gnutls_x509_crq_print (crq, full_format, &data); - if (ret < 0) - { - fprintf(stderr, "crq_print: %s", gnutls_strerror (ret)); - exit(1); - } - - fprintf (out, "%s\n", data.data); - - gnutls_free (data.data); - } - - ret = gnutls_x509_crq_verify(crq, 0); - if (ret < 0) - { - fprintf(out, "Self signature: FAILED\n\n"); - } - else - { - fprintf(out, "Self signature: verified\n\n"); - } - - size = buffer_size; - ret = gnutls_x509_crq_export (crq, outcert_format, buffer, &size); - if (ret < 0) - { - fprintf(stderr, "crq_export: %s", gnutls_strerror (ret)); - exit(1); - } - - fwrite (buffer, 1, size, outfile); + gnutls_datum_t data; + int ret; + size_t size; + + if (outcert_format == GNUTLS_X509_FMT_PEM) { + ret = gnutls_x509_crq_print(crq, full_format, &data); + if (ret < 0) { + fprintf(stderr, "crq_print: %s", + gnutls_strerror(ret)); + exit(1); + } + + fprintf(out, "%s\n", data.data); + + gnutls_free(data.data); + } + + ret = gnutls_x509_crq_verify(crq, 0); + if (ret < 0) { + fprintf(out, "Self signature: FAILED\n\n"); + } else { + fprintf(out, "Self signature: verified\n\n"); + } + + size = buffer_size; + ret = gnutls_x509_crq_export(crq, outcert_format, buffer, &size); + if (ret < 0) { + fprintf(stderr, "crq_export: %s", gnutls_strerror(ret)); + exit(1); + } + + fwrite(buffer, 1, size, outfile); } -void -crq_info (void) +void crq_info(void) { - gnutls_x509_crq_t crq; - int ret; - size_t size; - gnutls_datum_t pem; - - ret = gnutls_x509_crq_init (&crq); - if (ret < 0) - { - fprintf(stderr, "crq_init: %s", gnutls_strerror (ret)); - exit(1); - } - - pem.data = (void*)fread_file (infile, &size); - pem.size = size; - - if (!pem.data) - { - fprintf(stderr, "%s", infile ? "file" : - "standard input"); - exit(1); - } - - ret = gnutls_x509_crq_import (crq, &pem, incert_format); - - free (pem.data); - if (ret < 0) - { - fprintf(stderr, "import error: %s", gnutls_strerror (ret)); - exit(1); - } - - print_crq_info (crq, outfile); - - gnutls_x509_crq_deinit (crq); + gnutls_x509_crq_t crq; + int ret; + size_t size; + gnutls_datum_t pem; + + ret = gnutls_x509_crq_init(&crq); + if (ret < 0) { + fprintf(stderr, "crq_init: %s", gnutls_strerror(ret)); + exit(1); + } + + pem.data = (void *) fread_file(infile, &size); + pem.size = size; + + if (!pem.data) { + fprintf(stderr, "%s", infile ? "file" : "standard input"); + exit(1); + } + + ret = gnutls_x509_crq_import(crq, &pem, incert_format); + + free(pem.data); + if (ret < 0) { + fprintf(stderr, "import error: %s", gnutls_strerror(ret)); + exit(1); + } + + print_crq_info(crq, outfile); + + gnutls_x509_crq_deinit(crq); } -static void privkey_info_int (common_info_st* cinfo, gnutls_x509_privkey_t key) +static void privkey_info_int(common_info_st * cinfo, + gnutls_x509_privkey_t key) { -int ret, key_type; -unsigned int bits = 0; -size_t size; -const char *cprint; - - /* Public key algorithm - */ - fprintf (outfile, "Public Key Info:\n"); - ret = gnutls_x509_privkey_get_pk_algorithm2 (key, &bits); - fprintf (outfile, "\tPublic Key Algorithm: "); - - key_type = ret; - - cprint = gnutls_pk_algorithm_get_name (key_type); - fprintf (outfile, "%s\n", cprint ? cprint : "Unknown"); - fprintf (outfile, "\tKey Security Level: %s (%u bits)\n\n", - gnutls_sec_param_get_name (gnutls_x509_privkey_sec_param (key)), bits); - - /* Print the raw public and private keys - */ - if (key_type == GNUTLS_PK_RSA) - { - gnutls_datum_t m, e, d, p, q, u, exp1, exp2; - - ret = - gnutls_x509_privkey_export_rsa_raw2 (key, &m, &e, &d, &p, &q, &u, - &exp1, &exp2); - if (ret < 0) - fprintf (stderr, "Error in key RSA data export: %s\n", - gnutls_strerror (ret)); - else - { - print_rsa_pkey (outfile, &m, &e, &d, &p, &q, &u, &exp1, &exp2, HAVE_OPT(CPRINT)); - - gnutls_free (m.data); - gnutls_free (e.data); - gnutls_free (d.data); - gnutls_free (p.data); - gnutls_free (q.data); - gnutls_free (u.data); - gnutls_free (exp1.data); - gnutls_free (exp2.data); - } - } - else if (key_type == GNUTLS_PK_DSA) - { - gnutls_datum_t p, q, g, y, x; - - 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)); - else - { - print_dsa_pkey (outfile, &x, &y, &p, &q, &g, HAVE_OPT(CPRINT)); - - gnutls_free (x.data); - gnutls_free (y.data); - gnutls_free (p.data); - gnutls_free (q.data); - gnutls_free (g.data); - } - } - else if (key_type == GNUTLS_PK_EC) - { - gnutls_datum_t y, x, k; - gnutls_ecc_curve_t curve; - - ret = gnutls_x509_privkey_export_ecc_raw (key, &curve, &x, &y, &k); - if (ret < 0) - fprintf (stderr, "Error in key ECC data export: %s\n", - gnutls_strerror (ret)); - else - { - print_ecc_pkey (outfile, curve, &k, &x, &y, HAVE_OPT(CPRINT)); - - gnutls_free (x.data); - gnutls_free (y.data); - gnutls_free (k.data); - } - } - - fprintf (outfile, "\n"); - - size = buffer_size; - if ((ret = gnutls_x509_privkey_get_key_id (key, 0, buffer, &size)) < 0) - { - fprintf (stderr, "Error in key id calculation: %s\n", - gnutls_strerror (ret)); - } - else - { - gnutls_datum_t art; - - fprintf (outfile, "Public Key ID: %s\n", raw_to_string (buffer, size)); - - ret = gnutls_random_art(GNUTLS_RANDOM_ART_OPENSSH, cprint, bits, buffer, size, &art); - if (ret >= 0) - { - fprintf (outfile, "Public key's random art:\n%s\n", art.data); - gnutls_free(art.data); - } - } - fprintf (outfile, "\n"); + int ret, key_type; + unsigned int bits = 0; + size_t size; + const char *cprint; + + /* Public key algorithm + */ + fprintf(outfile, "Public Key Info:\n"); + ret = gnutls_x509_privkey_get_pk_algorithm2(key, &bits); + fprintf(outfile, "\tPublic Key Algorithm: "); + + key_type = ret; + + cprint = gnutls_pk_algorithm_get_name(key_type); + fprintf(outfile, "%s\n", cprint ? cprint : "Unknown"); + fprintf(outfile, "\tKey Security Level: %s (%u bits)\n\n", + gnutls_sec_param_get_name(gnutls_x509_privkey_sec_param + (key)), bits); + + /* Print the raw public and private keys + */ + if (key_type == GNUTLS_PK_RSA) { + gnutls_datum_t m, e, d, p, q, u, exp1, exp2; + + ret = + gnutls_x509_privkey_export_rsa_raw2(key, &m, &e, &d, + &p, &q, &u, &exp1, + &exp2); + if (ret < 0) + fprintf(stderr, + "Error in key RSA data export: %s\n", + gnutls_strerror(ret)); + else { + print_rsa_pkey(outfile, &m, &e, &d, &p, &q, &u, + &exp1, &exp2, HAVE_OPT(CPRINT)); + + gnutls_free(m.data); + gnutls_free(e.data); + gnutls_free(d.data); + gnutls_free(p.data); + gnutls_free(q.data); + gnutls_free(u.data); + gnutls_free(exp1.data); + gnutls_free(exp2.data); + } + } else if (key_type == GNUTLS_PK_DSA) { + gnutls_datum_t p, q, g, y, x; + + 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)); + else { + print_dsa_pkey(outfile, &x, &y, &p, &q, &g, + HAVE_OPT(CPRINT)); + + gnutls_free(x.data); + gnutls_free(y.data); + gnutls_free(p.data); + gnutls_free(q.data); + gnutls_free(g.data); + } + } else if (key_type == GNUTLS_PK_EC) { + gnutls_datum_t y, x, k; + gnutls_ecc_curve_t curve; + + ret = + gnutls_x509_privkey_export_ecc_raw(key, &curve, &x, &y, + &k); + if (ret < 0) + fprintf(stderr, + "Error in key ECC data export: %s\n", + gnutls_strerror(ret)); + else { + print_ecc_pkey(outfile, curve, &k, &x, &y, + HAVE_OPT(CPRINT)); + + gnutls_free(x.data); + gnutls_free(y.data); + gnutls_free(k.data); + } + } + + fprintf(outfile, "\n"); + + size = buffer_size; + if ((ret = + gnutls_x509_privkey_get_key_id(key, 0, buffer, &size)) < 0) { + fprintf(stderr, "Error in key id calculation: %s\n", + gnutls_strerror(ret)); + } else { + gnutls_datum_t art; + + fprintf(outfile, "Public Key ID: %s\n", + raw_to_string(buffer, size)); + + ret = + gnutls_random_art(GNUTLS_RANDOM_ART_OPENSSH, cprint, + bits, buffer, size, &art); + if (ret >= 0) { + fprintf(outfile, "Public key's random art:\n%s\n", + art.data); + gnutls_free(art.data); + } + } + fprintf(outfile, "\n"); } -void -privkey_info (common_info_st* cinfo) +void privkey_info(common_info_st * cinfo) { - gnutls_x509_privkey_t key; - size_t size; - int ret; - gnutls_datum_t pem; - const char *pass; - unsigned int flags = 0; - - size = fread (buffer, 1, buffer_size - 1, infile); - buffer[size] = 0; - - gnutls_x509_privkey_init (&key); - - pem.data = buffer; - pem.size = size; - - ret = gnutls_x509_privkey_import2 (key, &pem, incert_format, NULL, 0); - - /* If we failed to import the certificate previously try PKCS #8 */ - if (ret == GNUTLS_E_DECRYPTION_FAILED) - { - fprintf(stderr, "Encrypted structure detected...\n"); - pass = get_password(cinfo, &flags, 0); - - ret = gnutls_x509_privkey_import2 (key, &pem, - incert_format, pass, flags); - } - if (ret < 0) - { - fprintf(stderr, "import error: %s", gnutls_strerror (ret)); - exit(1); - } - - if (outcert_format == GNUTLS_X509_FMT_PEM) - privkey_info_int (cinfo, key); - - ret = gnutls_x509_privkey_verify_params (key); - if (ret < 0) - fprintf (outfile, "\n** Private key parameters validation failed **\n\n"); - - size = buffer_size; - ret = gnutls_x509_privkey_export (key, outcert_format, buffer, &size); - if (ret < 0) - { - fprintf(stderr, "export error: %s", gnutls_strerror (ret)); - exit(1); - } - - fwrite (buffer, 1, size, outfile); - - gnutls_x509_privkey_deinit (key); + gnutls_x509_privkey_t key; + size_t size; + int ret; + gnutls_datum_t pem; + const char *pass; + unsigned int flags = 0; + + size = fread(buffer, 1, buffer_size - 1, infile); + buffer[size] = 0; + + gnutls_x509_privkey_init(&key); + + pem.data = buffer; + pem.size = size; + + ret = + gnutls_x509_privkey_import2(key, &pem, incert_format, NULL, 0); + + /* If we failed to import the certificate previously try PKCS #8 */ + if (ret == GNUTLS_E_DECRYPTION_FAILED) { + fprintf(stderr, "Encrypted structure detected...\n"); + pass = get_password(cinfo, &flags, 0); + + ret = gnutls_x509_privkey_import2(key, &pem, + incert_format, pass, + flags); + } + if (ret < 0) { + fprintf(stderr, "import error: %s", gnutls_strerror(ret)); + exit(1); + } + + if (outcert_format == GNUTLS_X509_FMT_PEM) + privkey_info_int(cinfo, key); + + ret = gnutls_x509_privkey_verify_params(key); + if (ret < 0) + fprintf(outfile, + "\n** Private key parameters validation failed **\n\n"); + + size = buffer_size; + ret = + gnutls_x509_privkey_export(key, outcert_format, buffer, &size); + if (ret < 0) { + fprintf(stderr, "export error: %s", gnutls_strerror(ret)); + exit(1); + } + + fwrite(buffer, 1, size, outfile); + + gnutls_x509_privkey_deinit(key); } /* Generate a PKCS #10 certificate request. */ -void -generate_request (common_info_st * cinfo) +void generate_request(common_info_st * cinfo) { - gnutls_x509_crq_t crq; - gnutls_x509_privkey_t xkey; - gnutls_pubkey_t pubkey; - gnutls_privkey_t pkey; - int ret, ca_status, path_len, pk; - const char *pass; - unsigned int usage = 0; - - fprintf (stderr, "Generating a PKCS #10 certificate request...\n"); - - ret = gnutls_x509_crq_init (&crq); - if (ret < 0) - { - fprintf(stderr, "crq_init: %s", gnutls_strerror (ret)); - exit(1); - } - - - /* Load the private key. - */ - pkey = load_private_key (0, cinfo); - if (!pkey) - { - ret = gnutls_privkey_init (&pkey); - if (ret < 0) - { - fprintf(stderr, "privkey_init: %s", gnutls_strerror (ret)); - exit(1); - } - - xkey = generate_private_key_int (cinfo); - - print_private_key (cinfo, xkey); - - ret = gnutls_privkey_import_x509(pkey, xkey, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE); - if (ret < 0) - { - fprintf(stderr, "privkey_import_x509: %s", gnutls_strerror (ret)); - exit(1); - } - } - - pubkey = load_public_key_or_import (1, pkey, cinfo); - - pk = gnutls_pubkey_get_pk_algorithm (pubkey, NULL); - - /* Set the DN. - */ - get_dn_crq_set (crq); - - get_cn_crq_set (crq); - get_unit_crq_set (crq); - get_organization_crq_set (crq); - get_locality_crq_set (crq); - get_state_crq_set (crq); - get_country_crq_set (crq); - - get_dc_set (TYPE_CRQ, crq); - get_uid_crq_set (crq); - get_oid_crq_set (crq); - - get_dns_name_set (TYPE_CRQ, crq); - get_uri_set (TYPE_CRQ, crq); - get_ip_addr_set (TYPE_CRQ, crq); - get_email_set (TYPE_CRQ, crq); - - pass = get_challenge_pass (); - - if (pass != NULL && pass[0] != 0) - { - ret = gnutls_x509_crq_set_challenge_password (crq, pass); - if (ret < 0) - { - fprintf(stderr, "set_pass: %s", gnutls_strerror (ret)); - exit(1); - } - } - - if (cinfo->crq_extensions != 0) - { - ca_status = get_ca_status (); - if (ca_status) - path_len = get_path_len (); - else - path_len = -1; - - ret = gnutls_x509_crq_set_basic_constraints (crq, ca_status, path_len); - if (ret < 0) - { - fprintf(stderr, "set_basic_constraints: %s", - gnutls_strerror (ret)); - exit(1); - } - - if (pk == GNUTLS_PK_RSA) - { - ret = get_sign_status (1); - if (ret) - usage |= GNUTLS_KEY_DIGITAL_SIGNATURE; - - /* Only ask for an encryption certificate - * if it is an RSA one */ - ret = get_encrypt_status (1); - if (ret) - usage |= GNUTLS_KEY_KEY_ENCIPHERMENT; - else - usage |= GNUTLS_KEY_DIGITAL_SIGNATURE; - } - else /* DSA and ECDSA are always signing */ - usage |= GNUTLS_KEY_DIGITAL_SIGNATURE; - - if (ca_status) - { - ret = get_cert_sign_status (); - if (ret) - usage |= GNUTLS_KEY_KEY_CERT_SIGN; - - ret = get_crl_sign_status (); - if (ret) - usage |= GNUTLS_KEY_CRL_SIGN; - - ret = get_code_sign_status (); - if (ret) - { - ret = gnutls_x509_crq_set_key_purpose_oid - (crq, GNUTLS_KP_CODE_SIGNING, 0); - if (ret < 0) - { - fprintf(stderr, "key_kp: %s", gnutls_strerror (ret)); - exit(1); - } - } - - ret = get_ocsp_sign_status (); - if (ret) - { - ret = gnutls_x509_crq_set_key_purpose_oid - (crq, GNUTLS_KP_OCSP_SIGNING, 0); - if (ret < 0) - { - fprintf(stderr, "key_kp: %s", gnutls_strerror (ret)); - exit(1); - } - } - - ret = get_time_stamp_status (); - if (ret) - { - ret = gnutls_x509_crq_set_key_purpose_oid - (crq, GNUTLS_KP_TIME_STAMPING, 0); - if (ret < 0) - { - fprintf(stderr, "key_kp: %s", gnutls_strerror (ret)); - exit(1); - } - } - - ret = get_ipsec_ike_status (); - if (ret) - { - ret = gnutls_x509_crq_set_key_purpose_oid - (crq, GNUTLS_KP_IPSEC_IKE, 0); - if (ret < 0) - { - fprintf(stderr, "key_kp: %s", gnutls_strerror (ret)); - exit(1); - } - } - } - - ret = gnutls_x509_crq_set_key_usage (crq, usage); - if (ret < 0) - { - fprintf(stderr, "key_usage: %s", gnutls_strerror (ret)); - exit(1); - } - - ret = get_tls_client_status (); - if (ret != 0) - { - ret = gnutls_x509_crq_set_key_purpose_oid - (crq, GNUTLS_KP_TLS_WWW_CLIENT, 0); - if (ret < 0) - { - fprintf(stderr, "key_kp: %s", gnutls_strerror (ret)); - exit(1); - } - } - - ret = get_tls_server_status (); - if (ret != 0) - { - ret = gnutls_x509_crq_set_key_purpose_oid - (crq, GNUTLS_KP_TLS_WWW_SERVER, 0); - if (ret < 0) - { - fprintf(stderr, "key_kp: %s", gnutls_strerror (ret)); - exit(1); - } - } - - get_key_purpose_set (TYPE_CRQ, crq); - } - - ret = gnutls_x509_crq_set_pubkey (crq, pubkey); - if (ret < 0) - { - fprintf(stderr, "set_key: %s", gnutls_strerror (ret)); - exit(1); - } - - ret = gnutls_x509_crq_privkey_sign (crq, pkey, get_dig_for_pub (pubkey), 0); - if (ret < 0) - { - fprintf(stderr, "sign: %s", gnutls_strerror (ret)); - exit(1); - } - - print_crq_info (crq, outfile); - - gnutls_x509_crq_deinit (crq); - gnutls_privkey_deinit( pkey); - gnutls_pubkey_deinit( pubkey); + gnutls_x509_crq_t crq; + gnutls_x509_privkey_t xkey; + gnutls_pubkey_t pubkey; + gnutls_privkey_t pkey; + int ret, ca_status, path_len, pk; + const char *pass; + unsigned int usage = 0; + + fprintf(stderr, "Generating a PKCS #10 certificate request...\n"); + + ret = gnutls_x509_crq_init(&crq); + if (ret < 0) { + fprintf(stderr, "crq_init: %s", gnutls_strerror(ret)); + exit(1); + } + + + /* Load the private key. + */ + pkey = load_private_key(0, cinfo); + if (!pkey) { + ret = gnutls_privkey_init(&pkey); + if (ret < 0) { + fprintf(stderr, "privkey_init: %s", + gnutls_strerror(ret)); + exit(1); + } + + xkey = generate_private_key_int(cinfo); + + print_private_key(cinfo, xkey); + + ret = + gnutls_privkey_import_x509(pkey, xkey, + GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE); + if (ret < 0) { + fprintf(stderr, "privkey_import_x509: %s", + gnutls_strerror(ret)); + exit(1); + } + } + + pubkey = load_public_key_or_import(1, pkey, cinfo); + + pk = gnutls_pubkey_get_pk_algorithm(pubkey, NULL); + + /* Set the DN. + */ + get_dn_crq_set(crq); + + get_cn_crq_set(crq); + get_unit_crq_set(crq); + get_organization_crq_set(crq); + get_locality_crq_set(crq); + get_state_crq_set(crq); + get_country_crq_set(crq); + + get_dc_set(TYPE_CRQ, crq); + get_uid_crq_set(crq); + get_oid_crq_set(crq); + + get_dns_name_set(TYPE_CRQ, crq); + get_uri_set(TYPE_CRQ, crq); + get_ip_addr_set(TYPE_CRQ, crq); + get_email_set(TYPE_CRQ, crq); + + pass = get_challenge_pass(); + + if (pass != NULL && pass[0] != 0) { + ret = gnutls_x509_crq_set_challenge_password(crq, pass); + if (ret < 0) { + fprintf(stderr, "set_pass: %s", + gnutls_strerror(ret)); + exit(1); + } + } + + if (cinfo->crq_extensions != 0) { + ca_status = get_ca_status(); + if (ca_status) + path_len = get_path_len(); + else + path_len = -1; + + ret = + gnutls_x509_crq_set_basic_constraints(crq, ca_status, + path_len); + if (ret < 0) { + fprintf(stderr, "set_basic_constraints: %s", + gnutls_strerror(ret)); + exit(1); + } + + if (pk == GNUTLS_PK_RSA) { + ret = get_sign_status(1); + if (ret) + usage |= GNUTLS_KEY_DIGITAL_SIGNATURE; + + /* Only ask for an encryption certificate + * if it is an RSA one */ + ret = get_encrypt_status(1); + if (ret) + usage |= GNUTLS_KEY_KEY_ENCIPHERMENT; + else + usage |= GNUTLS_KEY_DIGITAL_SIGNATURE; + } else /* DSA and ECDSA are always signing */ + usage |= GNUTLS_KEY_DIGITAL_SIGNATURE; + + if (ca_status) { + ret = get_cert_sign_status(); + if (ret) + usage |= GNUTLS_KEY_KEY_CERT_SIGN; + + ret = get_crl_sign_status(); + if (ret) + usage |= GNUTLS_KEY_CRL_SIGN; + + ret = get_code_sign_status(); + if (ret) { + ret = gnutls_x509_crq_set_key_purpose_oid + (crq, GNUTLS_KP_CODE_SIGNING, 0); + if (ret < 0) { + fprintf(stderr, "key_kp: %s", + gnutls_strerror(ret)); + exit(1); + } + } + + ret = get_ocsp_sign_status(); + if (ret) { + ret = gnutls_x509_crq_set_key_purpose_oid + (crq, GNUTLS_KP_OCSP_SIGNING, 0); + if (ret < 0) { + fprintf(stderr, "key_kp: %s", + gnutls_strerror(ret)); + exit(1); + } + } + + ret = get_time_stamp_status(); + if (ret) { + ret = gnutls_x509_crq_set_key_purpose_oid + (crq, GNUTLS_KP_TIME_STAMPING, 0); + if (ret < 0) { + fprintf(stderr, "key_kp: %s", + gnutls_strerror(ret)); + exit(1); + } + } + + ret = get_ipsec_ike_status(); + if (ret) { + ret = gnutls_x509_crq_set_key_purpose_oid + (crq, GNUTLS_KP_IPSEC_IKE, 0); + if (ret < 0) { + fprintf(stderr, "key_kp: %s", + gnutls_strerror(ret)); + exit(1); + } + } + } + + ret = gnutls_x509_crq_set_key_usage(crq, usage); + if (ret < 0) { + fprintf(stderr, "key_usage: %s", + gnutls_strerror(ret)); + exit(1); + } + + ret = get_tls_client_status(); + if (ret != 0) { + ret = gnutls_x509_crq_set_key_purpose_oid + (crq, GNUTLS_KP_TLS_WWW_CLIENT, 0); + if (ret < 0) { + fprintf(stderr, "key_kp: %s", + gnutls_strerror(ret)); + exit(1); + } + } + + ret = get_tls_server_status(); + if (ret != 0) { + ret = gnutls_x509_crq_set_key_purpose_oid + (crq, GNUTLS_KP_TLS_WWW_SERVER, 0); + if (ret < 0) { + fprintf(stderr, "key_kp: %s", + gnutls_strerror(ret)); + exit(1); + } + } + + get_key_purpose_set(TYPE_CRQ, crq); + } + + ret = gnutls_x509_crq_set_pubkey(crq, pubkey); + if (ret < 0) { + fprintf(stderr, "set_key: %s", gnutls_strerror(ret)); + exit(1); + } + + ret = + gnutls_x509_crq_privkey_sign(crq, pkey, + get_dig_for_pub(pubkey), 0); + if (ret < 0) { + fprintf(stderr, "sign: %s", gnutls_strerror(ret)); + exit(1); + } + + print_crq_info(crq, outfile); + + gnutls_x509_crq_deinit(crq); + gnutls_privkey_deinit(pkey); + gnutls_pubkey_deinit(pubkey); } -static void print_verification_res (FILE* outfile, unsigned int output); +static void print_verification_res(FILE * outfile, unsigned int output); static int detailed_verification(gnutls_x509_crt_t cert, - gnutls_x509_crt_t issuer, gnutls_x509_crl_t crl, - unsigned int verification_output) + gnutls_x509_crt_t issuer, + gnutls_x509_crl_t crl, + unsigned int verification_output) { - char name[512]; - char tmp[255]; - char issuer_name[512]; - size_t name_size; - size_t issuer_name_size; - int ret; - - issuer_name_size = sizeof (issuer_name); - ret = - gnutls_x509_crt_get_issuer_dn (cert, issuer_name, &issuer_name_size); - if (ret < 0) - { - fprintf(stderr, "gnutls_x509_crt_get_issuer_dn: %s", gnutls_strerror (ret)); - exit(1); - } - - name_size = sizeof (name); - ret = - gnutls_x509_crt_get_dn (cert, name, &name_size); - if (ret < 0) - { - fprintf(stderr, "gnutls_x509_crt_get_dn: %s", gnutls_strerror (ret)); - exit(1); - } - - fprintf (outfile, "\tSubject: %s\n", name); - fprintf (outfile, "\tIssuer: %s\n", issuer_name); - - if (issuer != NULL) - { - issuer_name_size = sizeof (issuer_name); - ret = - gnutls_x509_crt_get_dn (issuer, issuer_name, &issuer_name_size); - if (ret < 0) - { - fprintf(stderr, "gnutls_x509_crt_get_issuer_dn: %s", gnutls_strerror (ret)); - exit(1); - } - - fprintf (outfile, "\tChecked against: %s\n", issuer_name); - } - - if (crl != NULL) - { - gnutls_datum_t data; - - issuer_name_size = sizeof (issuer_name); - ret = - gnutls_x509_crl_get_issuer_dn (crl, issuer_name, &issuer_name_size); - if (ret < 0) - { - fprintf(stderr, "gnutls_x509_crl_get_issuer_dn: %s", gnutls_strerror (ret)); - exit(1); - } - - name_size = sizeof(tmp); - ret = gnutls_x509_crl_get_number(crl, tmp, &name_size, NULL); - if (ret < 0) - strcpy(name, "unnumbered"); - else - { - data.data = (void*)tmp; - data.size = name_size; - - name_size = sizeof(name); - ret = gnutls_hex_encode(&data, name, &name_size); - if (ret < 0) - { - fprintf(stderr, "gnutls_hex_encode: %s", gnutls_strerror (ret)); - exit(1); - } - } - fprintf (outfile, "\tChecked against CRL[%s] of: %s\n", name, issuer_name); - } - - fprintf (outfile, "\tOutput: "); - print_verification_res(outfile, verification_output); - - fputs("\n\n", outfile); - - return 0; + char name[512]; + char tmp[255]; + char issuer_name[512]; + size_t name_size; + size_t issuer_name_size; + int ret; + + issuer_name_size = sizeof(issuer_name); + ret = + gnutls_x509_crt_get_issuer_dn(cert, issuer_name, + &issuer_name_size); + if (ret < 0) { + fprintf(stderr, "gnutls_x509_crt_get_issuer_dn: %s", + gnutls_strerror(ret)); + exit(1); + } + + name_size = sizeof(name); + ret = gnutls_x509_crt_get_dn(cert, name, &name_size); + if (ret < 0) { + fprintf(stderr, "gnutls_x509_crt_get_dn: %s", + gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "\tSubject: %s\n", name); + fprintf(outfile, "\tIssuer: %s\n", issuer_name); + + if (issuer != NULL) { + issuer_name_size = sizeof(issuer_name); + ret = + gnutls_x509_crt_get_dn(issuer, issuer_name, + &issuer_name_size); + if (ret < 0) { + fprintf(stderr, + "gnutls_x509_crt_get_issuer_dn: %s", + gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "\tChecked against: %s\n", issuer_name); + } + + if (crl != NULL) { + gnutls_datum_t data; + + issuer_name_size = sizeof(issuer_name); + ret = + gnutls_x509_crl_get_issuer_dn(crl, issuer_name, + &issuer_name_size); + if (ret < 0) { + fprintf(stderr, + "gnutls_x509_crl_get_issuer_dn: %s", + gnutls_strerror(ret)); + exit(1); + } + + name_size = sizeof(tmp); + ret = + gnutls_x509_crl_get_number(crl, tmp, &name_size, NULL); + if (ret < 0) + strcpy(name, "unnumbered"); + else { + data.data = (void *) tmp; + data.size = name_size; + + name_size = sizeof(name); + ret = gnutls_hex_encode(&data, name, &name_size); + if (ret < 0) { + fprintf(stderr, "gnutls_hex_encode: %s", + gnutls_strerror(ret)); + exit(1); + } + } + fprintf(outfile, "\tChecked against CRL[%s] of: %s\n", + name, issuer_name); + } + + fprintf(outfile, "\tOutput: "); + print_verification_res(outfile, verification_output); + + fputs("\n\n", outfile); + + return 0; } /* Will verify a certificate chain. If no CA certificates @@ -2292,307 +2218,296 @@ static int detailed_verification(gnutls_x509_crt_t cert, * chain is used as a CA. */ static int -_verify_x509_mem (const void *cert, int cert_size, const void* ca, int ca_size) +_verify_x509_mem(const void *cert, int cert_size, const void *ca, + int ca_size) { - int ret; - gnutls_datum_t tmp; - gnutls_x509_crt_t *x509_cert_list = NULL; - gnutls_x509_crt_t *x509_ca_list = NULL; - gnutls_x509_crl_t *x509_crl_list = NULL; - unsigned int x509_ncerts, x509_ncrls = 0, x509_ncas = 0; - gnutls_x509_trust_list_t list; - unsigned int output; - - ret = gnutls_x509_trust_list_init(&list, 0); - if (ret < 0) - { - fprintf(stderr, "gnutls_x509_trust_list_init: %s", - gnutls_strerror (ret)); - exit(1); - } - - if (ca == NULL) - { - tmp.data = (void*)cert; - tmp.size = cert_size; - } - else - { - tmp.data = (void*)ca; - tmp.size = ca_size; - - /* Load CAs */ - ret = gnutls_x509_crt_list_import2( &x509_ca_list, &x509_ncas, &tmp, - GNUTLS_X509_FMT_PEM, 0); - if (ret < 0 || x509_ncas < 1) - { - fprintf(stderr, "error parsing CAs: %s", - gnutls_strerror (ret)); - exit(1); - } - } - - ret = gnutls_x509_crl_list_import2( &x509_crl_list, &x509_ncrls, &tmp, - GNUTLS_X509_FMT_PEM, 0); - if (ret < 0) - { - x509_crl_list = NULL; - x509_ncrls = 0; - } - - tmp.data = (void*)cert; - tmp.size = cert_size; - - /* ignore errors. CRLs might not be given */ - ret = gnutls_x509_crt_list_import2( &x509_cert_list, &x509_ncerts, &tmp, - GNUTLS_X509_FMT_PEM, 0); - if (ret < 0 || x509_ncerts < 1) - { - fprintf(stderr, "error parsing CRTs: %s", - gnutls_strerror (ret)); - exit(1); - } - - if (ca == NULL) - { - x509_ca_list = &x509_cert_list[x509_ncerts - 1]; - x509_ncas = 1; - } - - fprintf(stdout, "Loaded %d certificates, %d CAs and %d CRLs\n\n", - x509_ncerts, x509_ncas, x509_ncrls); - - ret = gnutls_x509_trust_list_add_cas(list, x509_ca_list, x509_ncas, 0); - if (ret < 0) - { - fprintf(stderr, "gnutls_x509_trust_add_cas: %s", - gnutls_strerror (ret)); - exit(1); - } - - ret = gnutls_x509_trust_list_add_crls(list, x509_crl_list, x509_ncrls, 0, 0); - if (ret < 0) - { - fprintf(stderr, "gnutls_x509_trust_add_crls: %s", - gnutls_strerror (ret)); - exit(1); - } - - gnutls_free(x509_crl_list); - - ret = gnutls_x509_trust_list_verify_crt (list, x509_cert_list, x509_ncerts, - GNUTLS_VERIFY_DO_NOT_ALLOW_SAME|GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT, &output, - detailed_verification); - if (ret < 0) - { - fprintf(stderr, "gnutls_x509_trusted_list_verify_crt: %s", - gnutls_strerror (ret)); - exit(1); - } - - fprintf (outfile, "Chain verification output: "); - print_verification_res(outfile, output); - - fprintf (outfile, "\n\n"); - - gnutls_free(x509_cert_list); - gnutls_x509_trust_list_deinit(list, 1); - - if (output != 0) - exit(EXIT_FAILURE); - - return 0; + int ret; + gnutls_datum_t tmp; + gnutls_x509_crt_t *x509_cert_list = NULL; + gnutls_x509_crt_t *x509_ca_list = NULL; + gnutls_x509_crl_t *x509_crl_list = NULL; + unsigned int x509_ncerts, x509_ncrls = 0, x509_ncas = 0; + gnutls_x509_trust_list_t list; + unsigned int output; + + ret = gnutls_x509_trust_list_init(&list, 0); + if (ret < 0) { + fprintf(stderr, "gnutls_x509_trust_list_init: %s", + gnutls_strerror(ret)); + exit(1); + } + + if (ca == NULL) { + tmp.data = (void *) cert; + tmp.size = cert_size; + } else { + tmp.data = (void *) ca; + tmp.size = ca_size; + + /* Load CAs */ + ret = + gnutls_x509_crt_list_import2(&x509_ca_list, &x509_ncas, + &tmp, GNUTLS_X509_FMT_PEM, + 0); + if (ret < 0 || x509_ncas < 1) { + fprintf(stderr, "error parsing CAs: %s", + gnutls_strerror(ret)); + exit(1); + } + } + + ret = + gnutls_x509_crl_list_import2(&x509_crl_list, &x509_ncrls, &tmp, + GNUTLS_X509_FMT_PEM, 0); + if (ret < 0) { + x509_crl_list = NULL; + x509_ncrls = 0; + } + + tmp.data = (void *) cert; + tmp.size = cert_size; + + /* ignore errors. CRLs might not be given */ + ret = + gnutls_x509_crt_list_import2(&x509_cert_list, &x509_ncerts, + &tmp, GNUTLS_X509_FMT_PEM, 0); + if (ret < 0 || x509_ncerts < 1) { + fprintf(stderr, "error parsing CRTs: %s", + gnutls_strerror(ret)); + exit(1); + } + + if (ca == NULL) { + x509_ca_list = &x509_cert_list[x509_ncerts - 1]; + x509_ncas = 1; + } + + fprintf(stdout, "Loaded %d certificates, %d CAs and %d CRLs\n\n", + x509_ncerts, x509_ncas, x509_ncrls); + + ret = + gnutls_x509_trust_list_add_cas(list, x509_ca_list, x509_ncas, + 0); + if (ret < 0) { + fprintf(stderr, "gnutls_x509_trust_add_cas: %s", + gnutls_strerror(ret)); + exit(1); + } + + ret = + gnutls_x509_trust_list_add_crls(list, x509_crl_list, + x509_ncrls, 0, 0); + if (ret < 0) { + fprintf(stderr, "gnutls_x509_trust_add_crls: %s", + gnutls_strerror(ret)); + exit(1); + } + + gnutls_free(x509_crl_list); + + ret = + gnutls_x509_trust_list_verify_crt(list, x509_cert_list, + x509_ncerts, + GNUTLS_VERIFY_DO_NOT_ALLOW_SAME + | + GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT, + &output, + detailed_verification); + if (ret < 0) { + fprintf(stderr, "gnutls_x509_trusted_list_verify_crt: %s", + gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "Chain verification output: "); + print_verification_res(outfile, output); + + fprintf(outfile, "\n\n"); + + gnutls_free(x509_cert_list); + gnutls_x509_trust_list_deinit(list, 1); + + if (output != 0) + exit(EXIT_FAILURE); + + return 0; } -static void -print_verification_res (FILE* outfile, unsigned int output) +static void print_verification_res(FILE * outfile, unsigned int output) { - gnutls_datum_t pout; - int ret; - - if (output) - { - fprintf (outfile, "Not verified."); - } - else - { - fprintf (outfile, "Verified."); - } - - ret = gnutls_certificate_verification_status_print( output, GNUTLS_CRT_X509, &pout, 0); - if (ret < 0) - { - fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); - exit(EXIT_FAILURE); - } - - fprintf (outfile, " %s", pout.data); - gnutls_free(pout.data); + gnutls_datum_t pout; + int ret; + + if (output) { + fprintf(outfile, "Not verified."); + } else { + fprintf(outfile, "Verified."); + } + + ret = + gnutls_certificate_verification_status_print(output, + GNUTLS_CRT_X509, + &pout, 0); + if (ret < 0) { + fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); + exit(EXIT_FAILURE); + } + + fprintf(outfile, " %s", pout.data); + gnutls_free(pout.data); } -static void -verify_chain (void) +static void verify_chain(void) { - char *buf; - size_t size; + char *buf; + size_t size; - buf = (void*)fread_file (infile, &size); - if (buf == NULL) - { - fprintf(stderr, "reading chain"); - exit(1); - } + buf = (void *) fread_file(infile, &size); + if (buf == NULL) { + fprintf(stderr, "reading chain"); + exit(1); + } - buf[size] = 0; + buf[size] = 0; - _verify_x509_mem (buf, size, NULL, 0); + _verify_x509_mem(buf, size, NULL, 0); } -static void -verify_certificate (common_info_st * cinfo) +static void verify_certificate(common_info_st * cinfo) { - char *cert; - char *cas; - size_t cert_size, ca_size; - FILE * ca_file = fopen(cinfo->ca, "r"); - - if (ca_file == NULL) - { - fprintf(stderr, "opening CA file"); - exit(1); - } - - cert = (void*)fread_file (infile, &cert_size); - if (cert == NULL) - { - fprintf(stderr, "reading certificate chain"); - exit(1); - } - - cert[cert_size] = 0; - - cas = (void*)fread_file (ca_file, &ca_size); - if (cas == NULL) - { - fprintf(stderr, "reading CA list"); - exit(1); - } - - cas[ca_size] = 0; - fclose(ca_file); - - _verify_x509_mem (cert, cert_size, cas, ca_size); + char *cert; + char *cas; + size_t cert_size, ca_size; + FILE *ca_file = fopen(cinfo->ca, "r"); + + if (ca_file == NULL) { + fprintf(stderr, "opening CA file"); + exit(1); + } + + cert = (void *) fread_file(infile, &cert_size); + if (cert == NULL) { + fprintf(stderr, "reading certificate chain"); + exit(1); + } + + cert[cert_size] = 0; + + cas = (void *) fread_file(ca_file, &ca_size); + if (cas == NULL) { + fprintf(stderr, "reading CA list"); + exit(1); + } + + cas[ca_size] = 0; + fclose(ca_file); + + _verify_x509_mem(cert, cert_size, cas, ca_size); } -void -verify_crl (common_info_st * cinfo) +void verify_crl(common_info_st * cinfo) { - size_t size, dn_size; - char dn[128]; - unsigned int output; - int ret; - gnutls_datum_t pem, pout; - gnutls_x509_crl_t crl; - gnutls_x509_crt_t issuer; - - issuer = load_ca_cert (cinfo); - - fprintf (outfile, "\nCA certificate:\n"); - - dn_size = sizeof (dn); - ret = gnutls_x509_crt_get_dn (issuer, dn, &dn_size); - if (ret < 0) - { - fprintf(stderr, "crt_get_dn: %s", gnutls_strerror (ret)); - exit(1); - } - - fprintf (outfile, "\tSubject: %s\n\n", dn); - - ret = gnutls_x509_crl_init (&crl); - if (ret < 0) - { - fprintf(stderr, "crl_init: %s", gnutls_strerror (ret)); - exit(1); - } - - pem.data = (void*)fread_file (infile, &size); - pem.size = size; - - ret = gnutls_x509_crl_import (crl, &pem, incert_format); - free (pem.data); - if (ret < 0) - { - fprintf(stderr, "import error: %s", gnutls_strerror (ret)); - exit(1); - } - - print_crl_info (crl, outfile); - - fprintf (outfile, "Verification output: "); - ret = gnutls_x509_crl_verify (crl, &issuer, 1, 0, &output); - if (ret < 0) - { - fprintf(stderr, "verification error: %s", gnutls_strerror (ret)); - exit(1); - } - - if (output) - { - fprintf (outfile, "Not verified. "); - } - else - { - fprintf (outfile, "Verified."); - } - - ret = gnutls_certificate_verification_status_print( output, GNUTLS_CRT_X509, &pout, 0); - if (ret < 0) - { - fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); - exit(EXIT_FAILURE); - } - - fprintf (outfile, " %s", pout.data); - gnutls_free(pout.data); - - fprintf (outfile, "\n"); + size_t size, dn_size; + char dn[128]; + unsigned int output; + int ret; + gnutls_datum_t pem, pout; + gnutls_x509_crl_t crl; + gnutls_x509_crt_t issuer; + + issuer = load_ca_cert(cinfo); + + fprintf(outfile, "\nCA certificate:\n"); + + dn_size = sizeof(dn); + ret = gnutls_x509_crt_get_dn(issuer, dn, &dn_size); + if (ret < 0) { + fprintf(stderr, "crt_get_dn: %s", gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "\tSubject: %s\n\n", dn); + + ret = gnutls_x509_crl_init(&crl); + if (ret < 0) { + fprintf(stderr, "crl_init: %s", gnutls_strerror(ret)); + exit(1); + } + + pem.data = (void *) fread_file(infile, &size); + pem.size = size; + + ret = gnutls_x509_crl_import(crl, &pem, incert_format); + free(pem.data); + if (ret < 0) { + fprintf(stderr, "import error: %s", gnutls_strerror(ret)); + exit(1); + } + + print_crl_info(crl, outfile); + + fprintf(outfile, "Verification output: "); + ret = gnutls_x509_crl_verify(crl, &issuer, 1, 0, &output); + if (ret < 0) { + fprintf(stderr, "verification error: %s", + gnutls_strerror(ret)); + exit(1); + } + + if (output) { + fprintf(outfile, "Not verified. "); + } else { + fprintf(outfile, "Verified."); + } + + ret = + gnutls_certificate_verification_status_print(output, + GNUTLS_CRT_X509, + &pout, 0); + if (ret < 0) { + fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); + exit(EXIT_FAILURE); + } + + fprintf(outfile, " %s", pout.data); + gnutls_free(pout.data); + + fprintf(outfile, "\n"); } -void -generate_pkcs8 (common_info_st * cinfo) +void generate_pkcs8(common_info_st * cinfo) { - gnutls_x509_privkey_t key; - int result; - size_t size; - unsigned int flags = 0; - const char *password; + gnutls_x509_privkey_t key; + int result; + size_t size; + unsigned int flags = 0; + const char *password; - fprintf (stderr, "Generating a PKCS #8 key structure...\n"); + fprintf(stderr, "Generating a PKCS #8 key structure...\n"); - key = load_x509_private_key (1, cinfo); + key = load_x509_private_key(1, cinfo); - password = get_password(cinfo, &flags, 1); + password = get_password(cinfo, &flags, 1); - flags |= cipher_to_flags (cinfo->pkcs_cipher); + flags |= cipher_to_flags(cinfo->pkcs_cipher); - size = buffer_size; - result = - gnutls_x509_privkey_export_pkcs8 (key, outcert_format, - password, flags, buffer, &size); + size = buffer_size; + result = + gnutls_x509_privkey_export_pkcs8(key, outcert_format, + password, flags, buffer, + &size); - if (result < 0) - { - fprintf(stderr, "key_export: %s", gnutls_strerror (result)); - exit(1); - } + if (result < 0) { + fprintf(stderr, "key_export: %s", gnutls_strerror(result)); + exit(1); + } - fwrite (buffer, 1, size, outfile); + fwrite(buffer, 1, size, outfile); } @@ -2600,651 +2515,628 @@ generate_pkcs8 (common_info_st * cinfo) #include <gnutls/pkcs12.h> #include <unistd.h> -void -generate_pkcs12 (common_info_st * cinfo) +void generate_pkcs12(common_info_st * cinfo) { - gnutls_pkcs12_t pkcs12; - gnutls_x509_crt_t *crts; - gnutls_x509_privkey_t *keys; - int result; - size_t size; - gnutls_datum_t data; - const char *pass; - const char *name; - unsigned int flags = 0, i; - gnutls_datum_t key_id; - unsigned char _key_id[32]; - int indx; - size_t ncrts; - size_t nkeys; - - fprintf (stderr, "Generating a PKCS #12 structure...\n"); - - keys = load_privkey_list (0, &nkeys, cinfo); - crts = load_cert_list (0, &ncrts, cinfo); - - name = get_pkcs12_key_name (); - - result = gnutls_pkcs12_init (&pkcs12); - if (result < 0) - { - fprintf(stderr, "pkcs12_init: %s", gnutls_strerror (result)); - exit(1); - } - - pass = get_password(cinfo, &flags, 1); - flags |= cipher_to_flags (cinfo->pkcs_cipher); - - for (i = 0; i < ncrts; i++) - { - gnutls_pkcs12_bag_t bag; - - result = gnutls_pkcs12_bag_init (&bag); - if (result < 0) - { - fprintf(stderr, "bag_init: %s", gnutls_strerror (result)); - exit(1); - } - - result = gnutls_pkcs12_bag_set_crt (bag, crts[i]); - if (result < 0) - { - fprintf(stderr, "set_crt[%d]: %s", i, - gnutls_strerror (result)); - exit(1); - } - - indx = result; - - if (i==0) /* only the first certificate gets the friendly name */ - { - result = gnutls_pkcs12_bag_set_friendly_name (bag, indx, name); - if (result < 0) - { - fprintf(stderr, "bag_set_friendly_name: %s", - gnutls_strerror (result)); - exit(1); - } - } - - size = sizeof (_key_id); - result = gnutls_x509_crt_get_key_id (crts[i], 0, _key_id, &size); - if (result < 0) - { - fprintf(stderr, "key_id[%d]: %s", i, - gnutls_strerror (result)); - exit(1); - } - - key_id.data = _key_id; - key_id.size = size; - - result = gnutls_pkcs12_bag_set_key_id (bag, indx, &key_id); - if (result < 0) - { - fprintf(stderr, "bag_set_key_id: %s", - gnutls_strerror (result)); - exit(1); - } - - result = gnutls_pkcs12_bag_encrypt (bag, pass, flags); - if (result < 0) - { - fprintf(stderr, "bag_encrypt: %s", gnutls_strerror (result)); - exit(1); - } - - result = gnutls_pkcs12_set_bag (pkcs12, bag); - if (result < 0) - { - fprintf(stderr, "set_bag: %s", gnutls_strerror (result)); - exit(1); - } - } - - for (i = 0; i < nkeys; i++) - { - gnutls_pkcs12_bag_t kbag; - - result = gnutls_pkcs12_bag_init (&kbag); - if (result < 0) - { - fprintf(stderr, "bag_init: %s", gnutls_strerror (result)); - exit(1); - } - - size = buffer_size; - result = - gnutls_x509_privkey_export_pkcs8 (keys[i], GNUTLS_X509_FMT_DER, - pass, flags, buffer, &size); - if (result < 0) - { - fprintf(stderr, "key_export[%d]: %s", i, gnutls_strerror (result)); - exit(1); - } - - data.data = buffer; - data.size = size; - result = - gnutls_pkcs12_bag_set_data (kbag, - GNUTLS_BAG_PKCS8_ENCRYPTED_KEY, &data); - if (result < 0) - { - fprintf(stderr, "bag_set_data: %s", gnutls_strerror (result)); - exit(1); - } - - indx = result; - - result = gnutls_pkcs12_bag_set_friendly_name (kbag, indx, name); - if (result < 0) - { - fprintf(stderr, "bag_set_friendly_name: %s", - gnutls_strerror (result)); - exit(1); - } - - size = sizeof (_key_id); - result = gnutls_x509_privkey_get_key_id (keys[i], 0, _key_id, &size); - if (result < 0) - { - fprintf(stderr, "key_id[%d]: %s", i, gnutls_strerror (result)); - exit(1); - } - - key_id.data = _key_id; - key_id.size = size; - - result = gnutls_pkcs12_bag_set_key_id (kbag, indx, &key_id); - if (result < 0) - { - fprintf(stderr, "bag_set_key_id: %s", - gnutls_strerror (result)); - exit(1); - } - - result = gnutls_pkcs12_set_bag (pkcs12, kbag); - if (result < 0) - { - fprintf(stderr, "set_bag: %s", gnutls_strerror (result)); - exit(1); - } - } - - result = gnutls_pkcs12_generate_mac (pkcs12, pass); - if (result < 0) - { - fprintf(stderr, "generate_mac: %s", gnutls_strerror (result)); - exit(1); - } - - size = buffer_size; - result = gnutls_pkcs12_export (pkcs12, outcert_format, buffer, &size); - if (result < 0) - { - fprintf(stderr, "pkcs12_export: %s", gnutls_strerror (result)); - exit(1); - } - - fwrite (buffer, 1, size, outfile); + gnutls_pkcs12_t pkcs12; + gnutls_x509_crt_t *crts; + gnutls_x509_privkey_t *keys; + int result; + size_t size; + gnutls_datum_t data; + const char *pass; + const char *name; + unsigned int flags = 0, i; + gnutls_datum_t key_id; + unsigned char _key_id[32]; + int indx; + size_t ncrts; + size_t nkeys; + + fprintf(stderr, "Generating a PKCS #12 structure...\n"); + + keys = load_privkey_list(0, &nkeys, cinfo); + crts = load_cert_list(0, &ncrts, cinfo); + + name = get_pkcs12_key_name(); + + result = gnutls_pkcs12_init(&pkcs12); + if (result < 0) { + fprintf(stderr, "pkcs12_init: %s", + gnutls_strerror(result)); + exit(1); + } + + pass = get_password(cinfo, &flags, 1); + flags |= cipher_to_flags(cinfo->pkcs_cipher); + + for (i = 0; i < ncrts; i++) { + gnutls_pkcs12_bag_t bag; + + result = gnutls_pkcs12_bag_init(&bag); + if (result < 0) { + fprintf(stderr, "bag_init: %s", + gnutls_strerror(result)); + exit(1); + } + + result = gnutls_pkcs12_bag_set_crt(bag, crts[i]); + if (result < 0) { + fprintf(stderr, "set_crt[%d]: %s", i, + gnutls_strerror(result)); + exit(1); + } + + indx = result; + + if (i == 0) { /* only the first certificate gets the friendly name */ + result = + gnutls_pkcs12_bag_set_friendly_name(bag, indx, + name); + if (result < 0) { + fprintf(stderr, + "bag_set_friendly_name: %s", + gnutls_strerror(result)); + exit(1); + } + } + + size = sizeof(_key_id); + result = + gnutls_x509_crt_get_key_id(crts[i], 0, _key_id, &size); + if (result < 0) { + fprintf(stderr, "key_id[%d]: %s", i, + gnutls_strerror(result)); + exit(1); + } + + key_id.data = _key_id; + key_id.size = size; + + result = gnutls_pkcs12_bag_set_key_id(bag, indx, &key_id); + if (result < 0) { + fprintf(stderr, "bag_set_key_id: %s", + gnutls_strerror(result)); + exit(1); + } + + result = gnutls_pkcs12_bag_encrypt(bag, pass, flags); + if (result < 0) { + fprintf(stderr, "bag_encrypt: %s", + gnutls_strerror(result)); + exit(1); + } + + result = gnutls_pkcs12_set_bag(pkcs12, bag); + if (result < 0) { + fprintf(stderr, "set_bag: %s", + gnutls_strerror(result)); + exit(1); + } + } + + for (i = 0; i < nkeys; i++) { + gnutls_pkcs12_bag_t kbag; + + result = gnutls_pkcs12_bag_init(&kbag); + if (result < 0) { + fprintf(stderr, "bag_init: %s", + gnutls_strerror(result)); + exit(1); + } + + size = buffer_size; + result = + gnutls_x509_privkey_export_pkcs8(keys[i], + GNUTLS_X509_FMT_DER, + pass, flags, buffer, + &size); + if (result < 0) { + fprintf(stderr, "key_export[%d]: %s", i, + gnutls_strerror(result)); + exit(1); + } + + data.data = buffer; + data.size = size; + result = + gnutls_pkcs12_bag_set_data(kbag, + GNUTLS_BAG_PKCS8_ENCRYPTED_KEY, + &data); + if (result < 0) { + fprintf(stderr, "bag_set_data: %s", + gnutls_strerror(result)); + exit(1); + } + + indx = result; + + result = + gnutls_pkcs12_bag_set_friendly_name(kbag, indx, name); + if (result < 0) { + fprintf(stderr, "bag_set_friendly_name: %s", + gnutls_strerror(result)); + exit(1); + } + + size = sizeof(_key_id); + result = + gnutls_x509_privkey_get_key_id(keys[i], 0, _key_id, + &size); + if (result < 0) { + fprintf(stderr, "key_id[%d]: %s", i, + gnutls_strerror(result)); + exit(1); + } + + key_id.data = _key_id; + key_id.size = size; + + result = gnutls_pkcs12_bag_set_key_id(kbag, indx, &key_id); + if (result < 0) { + fprintf(stderr, "bag_set_key_id: %s", + gnutls_strerror(result)); + exit(1); + } + + result = gnutls_pkcs12_set_bag(pkcs12, kbag); + if (result < 0) { + fprintf(stderr, "set_bag: %s", + gnutls_strerror(result)); + exit(1); + } + } + + result = gnutls_pkcs12_generate_mac(pkcs12, pass); + if (result < 0) { + fprintf(stderr, "generate_mac: %s", + gnutls_strerror(result)); + exit(1); + } + + size = buffer_size; + result = + gnutls_pkcs12_export(pkcs12, outcert_format, buffer, &size); + if (result < 0) { + fprintf(stderr, "pkcs12_export: %s", + gnutls_strerror(result)); + exit(1); + } + + fwrite(buffer, 1, size, outfile); } -static const char * -BAGTYPE (gnutls_pkcs12_bag_type_t x) +static const char *BAGTYPE(gnutls_pkcs12_bag_type_t x) { - switch (x) - { - case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY: - return "PKCS #8 Encrypted key"; - case GNUTLS_BAG_EMPTY: - return "Empty"; - case GNUTLS_BAG_PKCS8_KEY: - return "PKCS #8 Key"; - case GNUTLS_BAG_CERTIFICATE: - return "Certificate"; - case GNUTLS_BAG_ENCRYPTED: - return "Encrypted"; - case GNUTLS_BAG_CRL: - return "CRL"; - case GNUTLS_BAG_SECRET: - return "Secret"; - default: - return "Unknown"; - } + switch (x) { + case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY: + return "PKCS #8 Encrypted key"; + case GNUTLS_BAG_EMPTY: + return "Empty"; + case GNUTLS_BAG_PKCS8_KEY: + return "PKCS #8 Key"; + case GNUTLS_BAG_CERTIFICATE: + return "Certificate"; + case GNUTLS_BAG_ENCRYPTED: + return "Encrypted"; + case GNUTLS_BAG_CRL: + return "CRL"; + case GNUTLS_BAG_SECRET: + return "Secret"; + default: + return "Unknown"; + } } -static void -print_bag_data (gnutls_pkcs12_bag_t bag) +static void print_bag_data(gnutls_pkcs12_bag_t bag) { - int result; - int count, i, type; - gnutls_datum_t cdata, id; - const char *str, *name; - gnutls_datum_t out; - - count = gnutls_pkcs12_bag_get_count (bag); - if (count < 0) - { - fprintf(stderr, "get_count: %s", gnutls_strerror (count)); - exit(1); - } - - fprintf (outfile, "\tElements: %d\n", count); - - for (i = 0; i < count; i++) - { - type = gnutls_pkcs12_bag_get_type (bag, i); - if (type < 0) - { - fprintf(stderr, "get_type: %s", gnutls_strerror (type)); - exit(1); - } - - fprintf (stderr, "\tType: %s\n", BAGTYPE (type)); - - name = NULL; - result = gnutls_pkcs12_bag_get_friendly_name (bag, i, (char **) &name); - if (result < 0) - { - fprintf(stderr, "get_friendly_name: %s", - gnutls_strerror (type)); - exit(1); - } - - if (name) - fprintf (outfile, "\tFriendly name: %s\n", name); - - id.data = NULL; - id.size = 0; - result = gnutls_pkcs12_bag_get_key_id (bag, i, &id); - if (result < 0) - { - fprintf(stderr, "get_key_id: %s", gnutls_strerror (type)); - exit(1); - } - - if (id.size > 0) - 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) - { - fprintf(stderr, "get_data: %s", gnutls_strerror (result)); - exit(1); - } - - switch (type) - { - case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY: - str = "ENCRYPTED PRIVATE KEY"; - break; - case GNUTLS_BAG_PKCS8_KEY: - str = "PRIVATE KEY"; - break; - case GNUTLS_BAG_CERTIFICATE: - str = "CERTIFICATE"; - break; - case GNUTLS_BAG_CRL: - str = "CRL"; - break; - case GNUTLS_BAG_ENCRYPTED: - case GNUTLS_BAG_EMPTY: - default: - str = NULL; - } - - if (str != NULL) - { - gnutls_pem_base64_encode_alloc (str, &cdata, &out); - fprintf (outfile, "%s\n", out.data); - - gnutls_free (out.data); - } - - } + int result; + int count, i, type; + gnutls_datum_t cdata, id; + const char *str, *name; + gnutls_datum_t out; + + count = gnutls_pkcs12_bag_get_count(bag); + if (count < 0) { + fprintf(stderr, "get_count: %s", gnutls_strerror(count)); + exit(1); + } + + fprintf(outfile, "\tElements: %d\n", count); + + for (i = 0; i < count; i++) { + type = gnutls_pkcs12_bag_get_type(bag, i); + if (type < 0) { + fprintf(stderr, "get_type: %s", + gnutls_strerror(type)); + exit(1); + } + + fprintf(stderr, "\tType: %s\n", BAGTYPE(type)); + + name = NULL; + result = + gnutls_pkcs12_bag_get_friendly_name(bag, i, + (char **) &name); + if (result < 0) { + fprintf(stderr, "get_friendly_name: %s", + gnutls_strerror(type)); + exit(1); + } + + if (name) + fprintf(outfile, "\tFriendly name: %s\n", name); + + id.data = NULL; + id.size = 0; + result = gnutls_pkcs12_bag_get_key_id(bag, i, &id); + if (result < 0) { + fprintf(stderr, "get_key_id: %s", + gnutls_strerror(type)); + exit(1); + } + + if (id.size > 0) + 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) { + fprintf(stderr, "get_data: %s", + gnutls_strerror(result)); + exit(1); + } + + switch (type) { + case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY: + str = "ENCRYPTED PRIVATE KEY"; + break; + case GNUTLS_BAG_PKCS8_KEY: + str = "PRIVATE KEY"; + break; + case GNUTLS_BAG_CERTIFICATE: + str = "CERTIFICATE"; + break; + case GNUTLS_BAG_CRL: + str = "CRL"; + break; + case GNUTLS_BAG_ENCRYPTED: + case GNUTLS_BAG_EMPTY: + default: + str = NULL; + } + + if (str != NULL) { + gnutls_pem_base64_encode_alloc(str, &cdata, &out); + fprintf(outfile, "%s\n", out.data); + + gnutls_free(out.data); + } + + } } -void -pkcs12_info (common_info_st* cinfo) +void pkcs12_info(common_info_st * cinfo) { - gnutls_pkcs12_t pkcs12; - gnutls_pkcs12_bag_t bag; - int result; - size_t size; - gnutls_datum_t data; - const char *pass; - int indx, fail = 0; - - result = gnutls_pkcs12_init (&pkcs12); - if (result < 0) - { - fprintf(stderr, "p12_init: %s", gnutls_strerror (result)); - exit(1); - } - - data.data = (void*)fread_file (infile, &size); - data.size = size; - - result = gnutls_pkcs12_import (pkcs12, &data, incert_format, 0); - free (data.data); - if (result < 0) - { - fprintf(stderr, "p12_import: %s", gnutls_strerror (result)); - exit(1); - } - - pass = get_password(cinfo, NULL, 0); - - result = gnutls_pkcs12_verify_mac (pkcs12, pass); - if (result < 0) - { - fail = 1; - fprintf (stderr, "verify_mac: %s", gnutls_strerror (result)); - } - - for (indx = 0;; indx++) - { - result = gnutls_pkcs12_bag_init (&bag); - if (result < 0) - { - fprintf(stderr, "bag_init: %s", gnutls_strerror (result)); - exit(1); - } - - result = gnutls_pkcs12_get_bag (pkcs12, indx, bag); - if (result < 0) - break; - - result = gnutls_pkcs12_bag_get_count (bag); - if (result < 0) - { - fprintf(stderr, "bag_count: %s", gnutls_strerror (result)); - exit(1); - } - - fprintf (outfile, "BAG #%d\n", indx); - - result = gnutls_pkcs12_bag_get_type (bag, 0); - if (result < 0) - { - fprintf(stderr, "bag_init: %s", gnutls_strerror (result)); - exit(1); - } - - if (result == GNUTLS_BAG_ENCRYPTED) - { - fprintf (stderr, "\tType: %s\n", BAGTYPE (result)); - fprintf (stderr, "\n\tDecrypting...\n"); - - result = gnutls_pkcs12_bag_decrypt (bag, pass); - - if (result < 0) - { - fail = 1; - fprintf(stderr, "bag_decrypt: %s", gnutls_strerror (result)); - continue; - } - - result = gnutls_pkcs12_bag_get_count (bag); - if (result < 0) - { - fprintf(stderr, "encrypted bag_count: %s", - gnutls_strerror (result)); - exit(1); - } - } - - print_bag_data (bag); - - gnutls_pkcs12_bag_deinit (bag); - } - - if (fail) - { - fprintf(stderr, "There were errors parsing the structure\n"); - exit(1); - } + gnutls_pkcs12_t pkcs12; + gnutls_pkcs12_bag_t bag; + int result; + size_t size; + gnutls_datum_t data; + const char *pass; + int indx, fail = 0; + + result = gnutls_pkcs12_init(&pkcs12); + if (result < 0) { + fprintf(stderr, "p12_init: %s", gnutls_strerror(result)); + exit(1); + } + + data.data = (void *) fread_file(infile, &size); + data.size = size; + + result = gnutls_pkcs12_import(pkcs12, &data, incert_format, 0); + free(data.data); + if (result < 0) { + fprintf(stderr, "p12_import: %s", gnutls_strerror(result)); + exit(1); + } + + pass = get_password(cinfo, NULL, 0); + + result = gnutls_pkcs12_verify_mac(pkcs12, pass); + if (result < 0) { + fail = 1; + fprintf(stderr, "verify_mac: %s", gnutls_strerror(result)); + } + + for (indx = 0;; indx++) { + result = gnutls_pkcs12_bag_init(&bag); + if (result < 0) { + fprintf(stderr, "bag_init: %s", + gnutls_strerror(result)); + exit(1); + } + + result = gnutls_pkcs12_get_bag(pkcs12, indx, bag); + if (result < 0) + break; + + result = gnutls_pkcs12_bag_get_count(bag); + if (result < 0) { + fprintf(stderr, "bag_count: %s", + gnutls_strerror(result)); + exit(1); + } + + fprintf(outfile, "BAG #%d\n", indx); + + result = gnutls_pkcs12_bag_get_type(bag, 0); + if (result < 0) { + fprintf(stderr, "bag_init: %s", + gnutls_strerror(result)); + exit(1); + } + + if (result == GNUTLS_BAG_ENCRYPTED) { + fprintf(stderr, "\tType: %s\n", BAGTYPE(result)); + fprintf(stderr, "\n\tDecrypting...\n"); + + result = gnutls_pkcs12_bag_decrypt(bag, pass); + + if (result < 0) { + fail = 1; + fprintf(stderr, "bag_decrypt: %s", + gnutls_strerror(result)); + continue; + } + + result = gnutls_pkcs12_bag_get_count(bag); + if (result < 0) { + fprintf(stderr, "encrypted bag_count: %s", + gnutls_strerror(result)); + exit(1); + } + } + + print_bag_data(bag); + + gnutls_pkcs12_bag_deinit(bag); + } + + if (fail) { + fprintf(stderr, + "There were errors parsing the structure\n"); + exit(1); + } } -void -pkcs7_info (void) +void pkcs7_info(void) { - gnutls_pkcs7_t pkcs7; - int result; - size_t size; - gnutls_datum_t data, b64; - int indx, count; - - result = gnutls_pkcs7_init (&pkcs7); - if (result < 0) - { - fprintf(stderr, "p7_init: %s", gnutls_strerror (result)); - exit(1); - } - - data.data = (void*)fread_file (infile, &size); - data.size = size; - - result = gnutls_pkcs7_import (pkcs7, &data, incert_format); - free (data.data); - if (result < 0) - { - fprintf(stderr, "import error: %s", gnutls_strerror (result)); - exit(1); - } - - /* Read and print the certificates. - */ - result = gnutls_pkcs7_get_crt_count (pkcs7); - if (result < 0) - { - fprintf(stderr, "p7_crt_count: %s", gnutls_strerror (result)); - exit(1); - } - - count = result; - - if (count > 0) - fprintf (outfile, "Number of certificates: %u\n", count); - - for (indx = 0; indx < count; indx++) - { - fputs ("\n", outfile); - - size = buffer_size; - result = gnutls_pkcs7_get_crt_raw (pkcs7, indx, buffer, &size); - if (result < 0) - break; - - data.data = buffer; - data.size = size; - - result = gnutls_pem_base64_encode_alloc ("CERTIFICATE", &data, &b64); - if (result < 0) - { - fprintf(stderr, "encoding: %s", gnutls_strerror (result)); - exit(1); - } - - fputs ((void*)b64.data, outfile); - gnutls_free (b64.data); - } - - /* Read the CRLs now. - */ - result = gnutls_pkcs7_get_crl_count (pkcs7); - if (result < 0) - { - fprintf(stderr, "p7_crl_count: %s", gnutls_strerror (result)); - exit(1); - } - - count = result; - - if (count > 0) - fprintf (outfile, "\nNumber of CRLs: %u\n", count); - - for (indx = 0; indx < count; indx++) - { - fputs ("\n", outfile); - - size = buffer_size; - result = gnutls_pkcs7_get_crl_raw (pkcs7, indx, buffer, &size); - if (result < 0) - break; - - data.data = buffer; - data.size = size; - - result = gnutls_pem_base64_encode_alloc ("X509 CRL", &data, &b64); - if (result < 0) - { - fprintf(stderr, "encoding: %s", gnutls_strerror (result)); - exit(1); - } - - fputs ((void*)b64.data, outfile); - gnutls_free (b64.data); - } + gnutls_pkcs7_t pkcs7; + int result; + size_t size; + gnutls_datum_t data, b64; + int indx, count; + + result = gnutls_pkcs7_init(&pkcs7); + if (result < 0) { + fprintf(stderr, "p7_init: %s", gnutls_strerror(result)); + exit(1); + } + + data.data = (void *) fread_file(infile, &size); + data.size = size; + + result = gnutls_pkcs7_import(pkcs7, &data, incert_format); + free(data.data); + if (result < 0) { + fprintf(stderr, "import error: %s", + gnutls_strerror(result)); + exit(1); + } + + /* Read and print the certificates. + */ + result = gnutls_pkcs7_get_crt_count(pkcs7); + if (result < 0) { + fprintf(stderr, "p7_crt_count: %s", + gnutls_strerror(result)); + exit(1); + } + + count = result; + + if (count > 0) + fprintf(outfile, "Number of certificates: %u\n", count); + + for (indx = 0; indx < count; indx++) { + fputs("\n", outfile); + + size = buffer_size; + result = + gnutls_pkcs7_get_crt_raw(pkcs7, indx, buffer, &size); + if (result < 0) + break; + + data.data = buffer; + data.size = size; + + result = + gnutls_pem_base64_encode_alloc("CERTIFICATE", &data, + &b64); + if (result < 0) { + fprintf(stderr, "encoding: %s", + gnutls_strerror(result)); + exit(1); + } + + fputs((void *) b64.data, outfile); + gnutls_free(b64.data); + } + + /* Read the CRLs now. + */ + result = gnutls_pkcs7_get_crl_count(pkcs7); + if (result < 0) { + fprintf(stderr, "p7_crl_count: %s", + gnutls_strerror(result)); + exit(1); + } + + count = result; + + if (count > 0) + fprintf(outfile, "\nNumber of CRLs: %u\n", count); + + for (indx = 0; indx < count; indx++) { + fputs("\n", outfile); + + size = buffer_size; + result = + gnutls_pkcs7_get_crl_raw(pkcs7, indx, buffer, &size); + if (result < 0) + break; + + data.data = buffer; + data.size = size; + + result = + gnutls_pem_base64_encode_alloc("X509 CRL", &data, + &b64); + if (result < 0) { + fprintf(stderr, "encoding: %s", + gnutls_strerror(result)); + exit(1); + } + + fputs((void *) b64.data, outfile); + gnutls_free(b64.data); + } } -void -smime_to_pkcs7 (void) +void smime_to_pkcs7(void) { - size_t linesize = 0; - char *lineptr = NULL; - ssize_t len; - - /* Find body. FIXME: Handle non-b64 Content-Transfer-Encoding. - Reject non-S/MIME tagged Content-Type's? */ - do - { - len = getline (&lineptr, &linesize, infile); - if (len == -1) - { - fprintf(stderr, "cannot find RFC 2822 header/body separator"); - exit(1); - } - } - while (strcmp (lineptr, "\r\n") != 0 && strcmp (lineptr, "\n") != 0); - - do - { - len = getline (&lineptr, &linesize, infile); - if (len == -1) - { - fprintf(stderr, "message has RFC 2822 header but no body"); - exit(1); - } - } - while (strcmp (lineptr, "\r\n") == 0 && strcmp (lineptr, "\n") == 0); - - fprintf (outfile, "%s", "-----BEGIN PKCS7-----\n"); - - do - { - while (len > 0 - && (lineptr[len - 1] == '\r' || lineptr[len - 1] == '\n')) - lineptr[--len] = '\0'; - if (strcmp (lineptr, "") != 0) - fprintf (outfile, "%s\n", lineptr); - len = getline (&lineptr, &linesize, infile); - } - while (len != -1); - - fprintf (outfile, "%s", "-----END PKCS7-----\n"); - - free (lineptr); + size_t linesize = 0; + char *lineptr = NULL; + ssize_t len; + + /* Find body. FIXME: Handle non-b64 Content-Transfer-Encoding. + Reject non-S/MIME tagged Content-Type's? */ + do { + len = getline(&lineptr, &linesize, infile); + if (len == -1) { + fprintf(stderr, + "cannot find RFC 2822 header/body separator"); + exit(1); + } + } + while (strcmp(lineptr, "\r\n") != 0 && strcmp(lineptr, "\n") != 0); + + do { + len = getline(&lineptr, &linesize, infile); + if (len == -1) { + fprintf(stderr, + "message has RFC 2822 header but no body"); + exit(1); + } + } + while (strcmp(lineptr, "\r\n") == 0 && strcmp(lineptr, "\n") == 0); + + fprintf(outfile, "%s", "-----BEGIN PKCS7-----\n"); + + do { + while (len > 0 + && (lineptr[len - 1] == '\r' + || lineptr[len - 1] == '\n')) + lineptr[--len] = '\0'; + if (strcmp(lineptr, "") != 0) + fprintf(outfile, "%s\n", lineptr); + len = getline(&lineptr, &linesize, infile); + } + while (len != -1); + + fprintf(outfile, "%s", "-----END PKCS7-----\n"); + + free(lineptr); } -void -pubkey_info (gnutls_x509_crt_t crt, common_info_st * cinfo) +void pubkey_info(gnutls_x509_crt_t crt, common_info_st * cinfo) { - gnutls_pubkey_t pubkey; - gnutls_privkey_t privkey = NULL; - gnutls_x509_crq_t crq = NULL; - int ret; - size_t size; - - ret = gnutls_pubkey_init (&pubkey); - if (ret < 0) - { - fprintf(stderr, "pubkey_init: %s", gnutls_strerror (ret)); - exit(1); - } - - if (crt == NULL) - { - crt = load_cert (0, cinfo); - } - - if (crq == NULL) - { - crq = load_request (cinfo); - } - - if (crt != NULL) - { - ret = gnutls_pubkey_import_x509 (pubkey, crt, 0); - if (ret < 0) - { - fprintf(stderr, "pubkey_import_x509: %s", - gnutls_strerror (ret)); - exit(1); - } - } - else if (crq != NULL) - { - ret = gnutls_pubkey_import_x509_crq (pubkey, crq, 0); - if (ret < 0) - { - fprintf(stderr, "pubkey_import_x509_crq: %s", - gnutls_strerror (ret)); - exit(1); - } - } - else - { - privkey = load_private_key (0, cinfo); - - if (privkey != NULL) - { - ret = gnutls_pubkey_import_privkey(pubkey, privkey, 0, 0); - if (ret < 0) - { - fprintf(stderr, "pubkey_import_privkey: %s", - gnutls_strerror (ret)); - exit(1); - } - } - else - { - gnutls_pubkey_deinit(pubkey); - pubkey = load_pubkey (1, cinfo); - } - } - - if (outcert_format == GNUTLS_X509_FMT_DER) - { - size = buffer_size; - ret = gnutls_pubkey_export (pubkey, outcert_format, buffer, &size); - if (ret < 0) - { - fprintf(stderr, "export error: %s", gnutls_strerror (ret)); - exit(1); - } - - fwrite (buffer, 1, size, outfile); - - gnutls_pubkey_deinit (pubkey); - - return; - } - - /* PEM */ - - _pubkey_info(outfile, full_format, pubkey); - gnutls_pubkey_deinit (pubkey); + gnutls_pubkey_t pubkey; + gnutls_privkey_t privkey = NULL; + gnutls_x509_crq_t crq = NULL; + int ret; + size_t size; + + ret = gnutls_pubkey_init(&pubkey); + if (ret < 0) { + fprintf(stderr, "pubkey_init: %s", gnutls_strerror(ret)); + exit(1); + } + + if (crt == NULL) { + crt = load_cert(0, cinfo); + } + + if (crq == NULL) { + crq = load_request(cinfo); + } + + if (crt != NULL) { + ret = gnutls_pubkey_import_x509(pubkey, crt, 0); + if (ret < 0) { + fprintf(stderr, "pubkey_import_x509: %s", + gnutls_strerror(ret)); + exit(1); + } + } else if (crq != NULL) { + ret = gnutls_pubkey_import_x509_crq(pubkey, crq, 0); + if (ret < 0) { + fprintf(stderr, "pubkey_import_x509_crq: %s", + gnutls_strerror(ret)); + exit(1); + } + } else { + privkey = load_private_key(0, cinfo); + + if (privkey != NULL) { + ret = + gnutls_pubkey_import_privkey(pubkey, privkey, + 0, 0); + if (ret < 0) { + fprintf(stderr, + "pubkey_import_privkey: %s", + gnutls_strerror(ret)); + exit(1); + } + } else { + gnutls_pubkey_deinit(pubkey); + pubkey = load_pubkey(1, cinfo); + } + } + + if (outcert_format == GNUTLS_X509_FMT_DER) { + size = buffer_size; + ret = + gnutls_pubkey_export(pubkey, outcert_format, buffer, + &size); + if (ret < 0) { + fprintf(stderr, "export error: %s", + gnutls_strerror(ret)); + exit(1); + } + + fwrite(buffer, 1, size, outfile); + + gnutls_pubkey_deinit(pubkey); + + return; + } + + /* PEM */ + + _pubkey_info(outfile, full_format, pubkey); + gnutls_pubkey_deinit(pubkey); } diff --git a/src/cli-debug.c b/src/cli-debug.c index a32a75519b..ab09f971e8 100644 --- a/src/cli-debug.c +++ b/src/cli-debug.c @@ -27,9 +27,9 @@ #include <gnutls/gnutls.h> #include <sys/time.h> #if HAVE_SYS_SOCKET_H -# include <sys/socket.h> +#include <sys/socket.h> #elif HAVE_WS2TCPIP_H -# include <ws2tcpip.h> +#include <ws2tcpip.h> #endif #include <tests.h> #include <common.h> @@ -40,7 +40,7 @@ /* Gnulib portability files. */ #include "sockets.h" -static void cmd_parser (int argc, char **argv); +static void cmd_parser(int argc, char **argv); #define ERR(err,s) if (err==-1) {perror(s);return(1);} #define MAX_BUF 4096 @@ -65,293 +65,296 @@ extern int tls1_ok; extern int tls1_1_ok; extern int ssl3_ok; -static void -tls_log_func (int level, const char *str) +static void tls_log_func(int level, const char *str) { - fprintf (stderr, "|<%d>| %s", level, str); + fprintf(stderr, "|<%d>| %s", level, str); } -typedef test_code_t (*TEST_FUNC) (gnutls_session_t); +typedef test_code_t(*TEST_FUNC) (gnutls_session_t); -typedef struct -{ - const char *test_name; - TEST_FUNC func; - const char *suc_str; - const char *fail_str; - const char *unsure_str; +typedef struct { + const char *test_name; + TEST_FUNC func; + const char *suc_str; + const char *fail_str; + const char *unsure_str; } TLS_TEST; static const TLS_TEST tls_tests[] = { - {"for SSL 3.0 support", test_ssl3, "yes", "no", "dunno"}, - {"whether \%COMPAT is required", test_record_padding, "no", "yes", "dunno"}, - {"for TLS 1.0 support", test_tls1, "yes", "no", "dunno"}, - {"for TLS 1.1 support", test_tls1_1, "yes", "no", "dunno"}, - {"fallback from TLS 1.1 to", test_tls1_1_fallback, "TLS 1.0", "failed", - "SSL 3.0"}, - {"for TLS 1.2 support", test_tls1_2, "yes", "no", "dunno"}, - /* The following tests will disable TLS 1.x if the server is - * buggy */ - {"whether we need to disable TLS 1.2", test_tls_disable2, "no", "yes", - "dunno"}, - {"whether we need to disable TLS 1.1", test_tls_disable1, "no", "yes", - "dunno"}, - {"whether we need to disable TLS 1.0", test_tls_disable0, "no", "yes", - "dunno"}, - {"for Safe renegotiation support", test_safe_renegotiation, "yes", "no", - "dunno"}, - {"for Safe renegotiation support (SCSV)", test_safe_renegotiation_scsv, - "yes", "no", "dunno"}, - {"for HTTPS server name", test_server, "", "failed", "not checked"}, - {"for version rollback bug in RSA PMS", test_rsa_pms, "no", "yes", - "dunno"}, - {"for version rollback bug in Client Hello", test_version_rollback, - "no", "yes", "dunno"}, - - - {"whether the server ignores the RSA PMS version", - test_rsa_pms_version_check, "yes", "no", "dunno"}, - {"whether the server can accept Hello Extensions", - test_hello_extension, "yes", "no", "dunno"}, - {"whether the server can accept HeartBeat Extension", test_heartbeat_extension, "yes", "no", "dunno"}, - {"whether the server can accept small records (512 bytes)", - test_small_records, "yes", "no", "dunno"}, - {"whether the server can accept cipher suites not in SSL 3.0 spec", - test_unknown_ciphersuites, "yes", "no", "dunno"}, - {"whether the server can accept a bogus TLS record version in the client hello", test_version_oob, "yes", "no", "dunno"}, - {"for certificate information", test_certificate, "", "", ""}, - {"for trusted CAs", test_server_cas, "", "", ""}, - {"whether the server understands TLS closure alerts", test_bye, "yes", - "no", "partially"}, - /* the fact that is after the closure alert test does matter. - */ - {"whether the server supports session resumption", - test_session_resume2, "yes", "no", "dunno"}, + {"for SSL 3.0 support", test_ssl3, "yes", "no", "dunno"}, + {"whether \%COMPAT is required", test_record_padding, "no", "yes", + "dunno"}, + {"for TLS 1.0 support", test_tls1, "yes", "no", "dunno"}, + {"for TLS 1.1 support", test_tls1_1, "yes", "no", "dunno"}, + {"fallback from TLS 1.1 to", test_tls1_1_fallback, "TLS 1.0", + "failed", + "SSL 3.0"}, + {"for TLS 1.2 support", test_tls1_2, "yes", "no", "dunno"}, + /* The following tests will disable TLS 1.x if the server is + * buggy */ + {"whether we need to disable TLS 1.2", test_tls_disable2, "no", + "yes", + "dunno"}, + {"whether we need to disable TLS 1.1", test_tls_disable1, "no", + "yes", + "dunno"}, + {"whether we need to disable TLS 1.0", test_tls_disable0, "no", + "yes", + "dunno"}, + {"for Safe renegotiation support", test_safe_renegotiation, "yes", + "no", + "dunno"}, + {"for Safe renegotiation support (SCSV)", + test_safe_renegotiation_scsv, + "yes", "no", "dunno"}, + {"for HTTPS server name", test_server, "", "failed", + "not checked"}, + {"for version rollback bug in RSA PMS", test_rsa_pms, "no", "yes", + "dunno"}, + {"for version rollback bug in Client Hello", test_version_rollback, + "no", "yes", "dunno"}, + + + {"whether the server ignores the RSA PMS version", + test_rsa_pms_version_check, "yes", "no", "dunno"}, + {"whether the server can accept Hello Extensions", + test_hello_extension, "yes", "no", "dunno"}, + {"whether the server can accept HeartBeat Extension", + test_heartbeat_extension, "yes", "no", "dunno"}, + {"whether the server can accept small records (512 bytes)", + test_small_records, "yes", "no", "dunno"}, + {"whether the server can accept cipher suites not in SSL 3.0 spec", + test_unknown_ciphersuites, "yes", "no", "dunno"}, + {"whether the server can accept a bogus TLS record version in the client hello", test_version_oob, "yes", "no", "dunno"}, + {"for certificate information", test_certificate, "", "", ""}, + {"for trusted CAs", test_server_cas, "", "", ""}, + {"whether the server understands TLS closure alerts", test_bye, + "yes", + "no", "partially"}, + /* the fact that is after the closure alert test does matter. + */ + {"whether the server supports session resumption", + test_session_resume2, "yes", "no", "dunno"}, #ifdef ENABLE_ANON - {"for anonymous authentication support", test_anonymous, "yes", "no", - "dunno"}, - {"anonymous Diffie-Hellman group info", test_dhe_group, "", "N/A", - "N/A"}, + {"for anonymous authentication support", test_anonymous, "yes", + "no", + "dunno"}, + {"anonymous Diffie-Hellman group info", test_dhe_group, "", "N/A", + "N/A"}, #endif - {"for ephemeral Diffie-Hellman support", test_dhe, "yes", "no", - "dunno"}, - {"ephemeral Diffie-Hellman group info", test_dhe_group, "", "N/A", - "N/A"}, - {"for ephemeral EC Diffie-Hellman support", test_ecdhe, "yes", "no", - "dunno"}, - {"ephemeral EC Diffie-Hellman group info", test_ecdhe_curve, "", "N/A", - "N/A"}, - {"for AES-GCM cipher support", test_aes_gcm, "yes", "no", - "dunno"}, - {"for AES-CBC cipher support", test_aes, "yes", "no", - "dunno"}, - {"for CAMELLIA cipher support", test_camellia, "yes", "no", - "dunno"}, - {"for 3DES-CBC cipher support", test_3des, "yes", "no", "dunno"}, - {"for ARCFOUR 128 cipher support", test_arcfour, "yes", "no", "dunno"}, - {"for MD5 MAC support", test_md5, "yes", "no", "dunno"}, - {"for SHA1 MAC support", test_sha, "yes", "no", "dunno"}, - {"for SHA256 MAC support", test_sha256, "yes", "no", "dunno"}, + {"for ephemeral Diffie-Hellman support", test_dhe, "yes", "no", + "dunno"}, + {"ephemeral Diffie-Hellman group info", test_dhe_group, "", "N/A", + "N/A"}, + {"for ephemeral EC Diffie-Hellman support", test_ecdhe, "yes", + "no", + "dunno"}, + {"ephemeral EC Diffie-Hellman group info", test_ecdhe_curve, "", + "N/A", + "N/A"}, + {"for AES-GCM cipher support", test_aes_gcm, "yes", "no", + "dunno"}, + {"for AES-CBC cipher support", test_aes, "yes", "no", + "dunno"}, + {"for CAMELLIA cipher support", test_camellia, "yes", "no", + "dunno"}, + {"for 3DES-CBC cipher support", test_3des, "yes", "no", "dunno"}, + {"for ARCFOUR 128 cipher support", test_arcfour, "yes", "no", + "dunno"}, + {"for MD5 MAC support", test_md5, "yes", "no", "dunno"}, + {"for SHA1 MAC support", test_sha, "yes", "no", "dunno"}, + {"for SHA256 MAC support", test_sha256, "yes", "no", "dunno"}, #ifdef HAVE_LIBZ - {"for ZLIB compression support", test_zlib, "yes", - "no", "dunno"}, + {"for ZLIB compression support", test_zlib, "yes", + "no", "dunno"}, #endif - {"for max record size", test_max_record_size, "yes", - "no", "dunno"}, - {"for OpenPGP authentication support", test_openpgp1, - "yes", "no", "dunno"}, - {NULL, NULL, NULL, NULL, NULL} + {"for max record size", test_max_record_size, "yes", + "no", "dunno"}, + {"for OpenPGP authentication support", test_openpgp1, + "yes", "no", "dunno"}, + {NULL, NULL, NULL, NULL, NULL} }; static int tt = 0; const char *ip; -int -main (int argc, char **argv) +int main(int argc, char **argv) { - int err, ret; - int sd, i; - gnutls_session_t state; - char buffer[MAX_BUF + 1]; - char portname[6]; - struct addrinfo hints, *res, *ptr; + int err, ret; + int sd, i; + gnutls_session_t state; + char buffer[MAX_BUF + 1]; + char portname[6]; + struct addrinfo hints, *res, *ptr; - cmd_parser(argc, argv); + cmd_parser(argc, argv); #ifndef _WIN32 - signal (SIGPIPE, SIG_IGN); + signal(SIGPIPE, SIG_IGN); #endif - sockets_init (); - - if (gnutls_global_init () < 0) - { - fprintf (stderr, "global state initialization error\n"); - exit (1); - } - - gnutls_global_set_log_function (tls_log_func); - gnutls_global_set_log_level (debug); - - printf ("Resolving '%s'...\n", hostname); - /* get server name */ - memset (&hints, 0, sizeof (hints)); - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = 0; - snprintf (portname, sizeof (portname), "%d", port); - if ((err = getaddrinfo (hostname, portname, &hints, &res)) != 0) - { - fprintf (stderr, "Cannot resolve %s: %s\n", hostname, - gai_strerror (err)); - exit (1); - } - - /* X509 stuff */ - if (gnutls_certificate_allocate_credentials (&xcred) < 0) - { /* space for 2 certificates */ - fprintf (stderr, "memory error\n"); - exit (1); - } - - /* SRP stuff */ + sockets_init(); + + if (gnutls_global_init() < 0) { + fprintf(stderr, "global state initialization error\n"); + exit(1); + } + + gnutls_global_set_log_function(tls_log_func); + gnutls_global_set_log_level(debug); + + printf("Resolving '%s'...\n", hostname); + /* get server name */ + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = 0; + snprintf(portname, sizeof(portname), "%d", port); + if ((err = getaddrinfo(hostname, portname, &hints, &res)) != 0) { + fprintf(stderr, "Cannot resolve %s: %s\n", hostname, + gai_strerror(err)); + exit(1); + } + + /* X509 stuff */ + if (gnutls_certificate_allocate_credentials(&xcred) < 0) { /* space for 2 certificates */ + fprintf(stderr, "memory error\n"); + exit(1); + } + + /* SRP stuff */ #ifdef ENABLE_SRP - if (gnutls_srp_allocate_client_credentials (&srp_cred) < 0) - { - fprintf (stderr, "memory error\n"); - exit (1); - } + if (gnutls_srp_allocate_client_credentials(&srp_cred) < 0) { + fprintf(stderr, "memory error\n"); + exit(1); + } #endif #ifdef ENABLE_ANON - /* ANON stuff */ - if (gnutls_anon_allocate_client_credentials (&anon_cred) < 0) - { - fprintf (stderr, "memory error\n"); - exit (1); - } + /* ANON stuff */ + if (gnutls_anon_allocate_client_credentials(&anon_cred) < 0) { + fprintf(stderr, "memory error\n"); + exit(1); + } #endif - i = 0; - - do - { - - if (tls_tests[i].test_name == NULL) - break; /* finished */ - - /* if neither of SSL3 and TLSv1 are supported, exit - */ - if (i > 6 && tls1_1_ok == 0 && tls1_ok == 0 && ssl3_ok == 0) - { - fprintf (stderr, - "\nServer does not support any of SSL 3.0, TLS 1.0 and TLS 1.1\n"); - break; - } - - sd = -1; - for (ptr = res; ptr != NULL; ptr = ptr->ai_next) - { - sd = socket (ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); - if (sd == -1) - { - continue; - } - - getnameinfo (ptr->ai_addr, ptr->ai_addrlen, buffer, MAX_BUF, - NULL, 0, NI_NUMERICHOST); - if (tt == 0) - { - printf ("Connecting to '%s:%d'...\n", buffer, port); - tt = 1; - } - if ((err = connect (sd, ptr->ai_addr, ptr->ai_addrlen)) != 0) - { - close (sd); - sd = -1; - continue; - } - else - break; - } - ERR (err, "connect"); - - gnutls_init (&state, GNUTLS_CLIENT|GNUTLS_NO_EXTENSIONS); - - gnutls_transport_set_ptr (state, (gnutls_transport_ptr_t) - gl_fd_to_handle (sd)); - if (hostname && !isdigit(hostname[0]) && strchr(hostname, ':') == 0) - gnutls_server_name_set (state, GNUTLS_NAME_DNS, hostname, - strlen (hostname)); - - do - { - printf ("Checking %s...", tls_tests[i].test_name); - fflush(stdout); - - ret = tls_tests[i].func (state); - - if (ret == TEST_SUCCEED) - printf (" %s\n", tls_tests[i].suc_str); - else if (ret == TEST_FAILED) - printf (" %s\n", tls_tests[i].fail_str); - else if (ret == TEST_UNSURE) - printf (" %s\n", tls_tests[i].unsure_str); - else if (ret == TEST_IGNORE) - { - printf (" N/A\n"); - i++; - } - } - while (ret == TEST_IGNORE && tls_tests[i].test_name != NULL); - - gnutls_deinit (state); - - shutdown (sd, SHUT_RDWR); /* no more receptions */ - close (sd); - - i++; - } - while (1); - - freeaddrinfo (res); + i = 0; + + do { + + if (tls_tests[i].test_name == NULL) + break; /* finished */ + + /* if neither of SSL3 and TLSv1 are supported, exit + */ + if (i > 6 && tls1_1_ok == 0 && tls1_ok == 0 + && ssl3_ok == 0) { + fprintf(stderr, + "\nServer does not support any of SSL 3.0, TLS 1.0 and TLS 1.1\n"); + break; + } + + sd = -1; + for (ptr = res; ptr != NULL; ptr = ptr->ai_next) { + sd = socket(ptr->ai_family, ptr->ai_socktype, + ptr->ai_protocol); + if (sd == -1) { + continue; + } + + getnameinfo(ptr->ai_addr, ptr->ai_addrlen, buffer, + MAX_BUF, NULL, 0, NI_NUMERICHOST); + if (tt == 0) { + printf("Connecting to '%s:%d'...\n", + buffer, port); + tt = 1; + } + if ((err = + connect(sd, ptr->ai_addr, + ptr->ai_addrlen)) != 0) { + close(sd); + sd = -1; + continue; + } else + break; + } + ERR(err, "connect"); + + gnutls_init(&state, GNUTLS_CLIENT | GNUTLS_NO_EXTENSIONS); + + gnutls_transport_set_ptr(state, (gnutls_transport_ptr_t) + gl_fd_to_handle(sd)); + if (hostname && !isdigit(hostname[0]) + && strchr(hostname, ':') == 0) + gnutls_server_name_set(state, GNUTLS_NAME_DNS, + hostname, strlen(hostname)); + + do { + printf("Checking %s...", tls_tests[i].test_name); + fflush(stdout); + + ret = tls_tests[i].func(state); + + if (ret == TEST_SUCCEED) + printf(" %s\n", tls_tests[i].suc_str); + else if (ret == TEST_FAILED) + printf(" %s\n", tls_tests[i].fail_str); + else if (ret == TEST_UNSURE) + printf(" %s\n", tls_tests[i].unsure_str); + else if (ret == TEST_IGNORE) { + printf(" N/A\n"); + i++; + } + } + while (ret == TEST_IGNORE + && tls_tests[i].test_name != NULL); + + gnutls_deinit(state); + + shutdown(sd, SHUT_RDWR); /* no more receptions */ + close(sd); + + i++; + } + while (1); + + freeaddrinfo(res); #ifdef ENABLE_SRP - gnutls_srp_free_client_credentials (srp_cred); + gnutls_srp_free_client_credentials(srp_cred); #endif - gnutls_certificate_free_credentials (xcred); + gnutls_certificate_free_credentials(xcred); #ifdef ENABLE_ANON - gnutls_anon_free_client_credentials (anon_cred); + gnutls_anon_free_client_credentials(anon_cred); #endif - gnutls_global_deinit (); + gnutls_global_deinit(); - return 0; + return 0; } -static void cmd_parser (int argc, char **argv) +static void cmd_parser(int argc, char **argv) { - const char* rest = NULL; - int optct = optionProcess( &gnutls_cli_debugOptions, argc, argv); - argc -= optct; - argv += optct; - - if (rest == NULL && argc > 0) - rest = argv[0]; - - if (HAVE_OPT(PORT)) - port = OPT_VALUE_PORT; - else - port = 443; - - if (rest == NULL) - hostname = "localhost"; - else - hostname = rest; - - if (HAVE_OPT(DEBUG)) - debug = OPT_VALUE_DEBUG; - - if (HAVE_OPT(VERBOSE)) - verbose++; + const char *rest = NULL; + int optct = optionProcess(&gnutls_cli_debugOptions, argc, argv); + argc -= optct; + argv += optct; -} + if (rest == NULL && argc > 0) + rest = argv[0]; + + if (HAVE_OPT(PORT)) + port = OPT_VALUE_PORT; + else + port = 443; + + if (rest == NULL) + hostname = "localhost"; + else + hostname = rest; + if (HAVE_OPT(DEBUG)) + debug = OPT_VALUE_DEBUG; + + if (HAVE_OPT(VERBOSE)) + verbose++; + +} @@ -27,9 +27,9 @@ #include <sys/time.h> #include <sys/stat.h> #if HAVE_SYS_SOCKET_H -# include <sys/socket.h> +#include <sys/socket.h> #elif HAVE_WS2TCPIP_H -# include <ws2tcpip.h> +#include <ws2tcpip.h> #endif #include <sys/select.h> #include <unistd.h> @@ -68,7 +68,8 @@ #define MAX_BUF 4096 /* global stuff here */ -int resume, starttls, insecure, ranges, rehandshake, udp, mtu, inline_commands; +int resume, starttls, insecure, ranges, rehandshake, udp, mtu, + inline_commands; const char *hostname = NULL; const char *service = NULL; int record_max_size; @@ -90,8 +91,8 @@ static int x509ctype; static int disable_extensions; static int disable_sni; static unsigned int init_flags = GNUTLS_CLIENT; -static const char * priorities = NULL; -static const char * inline_commands_prefix; +static const char *priorities = NULL; +static const char *inline_commands_prefix; const char *psk_username = NULL; gnutls_datum_t psk_key = { NULL, 0 }; @@ -105,10 +106,10 @@ static gnutls_certificate_credentials_t xcred; /* prototypes */ -static void check_rehandshake (socket_st * socket, int ret); -static int do_handshake (socket_st * socket); -static void init_global_tls_stuff (void); -static int cert_verify_ocsp (gnutls_session_t session); +static void check_rehandshake(socket_st * socket, int ret); +static int do_handshake(socket_st * socket); +static void init_global_tls_stuff(void); +static int cert_verify_ocsp(gnutls_session_t session); #define MAX_CRT 6 static unsigned int x509_crt_size; @@ -118,427 +119,435 @@ static gnutls_privkey_t x509_key = NULL; static gnutls_pcert_st pgp_crt; static gnutls_privkey_t pgp_key = NULL; -static void -get_keyid (gnutls_openpgp_keyid_t keyid, const char *str) +static void get_keyid(gnutls_openpgp_keyid_t keyid, const char *str) { - size_t keyid_size = sizeof (keyid); - - if (strlen (str) != 16) - { - fprintf (stderr, - "The OpenPGP subkey ID has to be 16 hexadecimal characters.\n"); - exit (1); - } - - if (gnutls_hex2bin (str, strlen (str), keyid, &keyid_size) < 0) - { - fprintf (stderr, "Error converting hex string: %s.\n", str); - exit (1); - } - - return; + size_t keyid_size = sizeof(keyid); + + if (strlen(str) != 16) { + fprintf(stderr, + "The OpenPGP subkey ID has to be 16 hexadecimal characters.\n"); + exit(1); + } + + if (gnutls_hex2bin(str, strlen(str), keyid, &keyid_size) < 0) { + fprintf(stderr, "Error converting hex string: %s.\n", str); + exit(1); + } + + return; } /* Load the certificate and the private key. */ -static void -load_keys (void) +static void load_keys(void) { - unsigned int crt_num; - int ret; - unsigned int i; - gnutls_datum_t data = { NULL, 0 }; - gnutls_x509_crt_t crt_list[MAX_CRT]; - unsigned char keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - - if (x509_certfile != NULL && x509_keyfile != NULL) - { + unsigned int crt_num; + int ret; + unsigned int i; + gnutls_datum_t data = { NULL, 0 }; + gnutls_x509_crt_t crt_list[MAX_CRT]; + unsigned char keyid[GNUTLS_OPENPGP_KEYID_SIZE]; + + if (x509_certfile != NULL && x509_keyfile != NULL) { #ifdef ENABLE_PKCS11 - if (strncmp (x509_certfile, "pkcs11:", 7) == 0) - { - crt_num = 1; - gnutls_x509_crt_init (&crt_list[0]); - gnutls_x509_crt_set_pin_function(crt_list[0], pin_callback, NULL); - - ret = - gnutls_x509_crt_import_pkcs11_url (crt_list[0], x509_certfile, 0); - - if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) - ret = - gnutls_x509_crt_import_pkcs11_url (crt_list[0], x509_certfile, - GNUTLS_PKCS11_OBJ_FLAG_LOGIN); - - if (ret < 0) - { - fprintf (stderr, "*** Error loading cert file.\n"); - exit (1); - } - x509_crt_size = 1; - } - else -#endif /* ENABLE_PKCS11 */ - { - - ret = gnutls_load_file (x509_certfile, &data); - if (ret < 0) - { - fprintf (stderr, "*** Error loading cert file.\n"); - exit (1); - } - - crt_num = MAX_CRT; - ret = - gnutls_x509_crt_list_import (crt_list, &crt_num, &data, - x509ctype, - GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED); - if (ret < 0) - { - if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) - { - fprintf (stderr, - "*** Error loading cert file: Too many certs %d\n", - crt_num); - - } - else - { - fprintf (stderr, - "*** Error loading cert file: %s\n", - gnutls_strerror (ret)); - } - exit (1); - } - x509_crt_size = ret; - } - - for (i=0;i<x509_crt_size;i++) - { - ret = gnutls_pcert_import_x509(&x509_crt[i], crt_list[i], 0); - if (ret < 0) - { - fprintf(stderr, "*** Error importing crt to pcert: %s\n", - gnutls_strerror(ret)); - exit(1); - } - gnutls_x509_crt_deinit(crt_list[i]); - } - - gnutls_free (data.data); - - ret = gnutls_privkey_init(&x509_key); - if (ret < 0) - { - fprintf (stderr, "*** Error initializing key: %s\n", - gnutls_strerror (ret)); - exit (1); - } - - gnutls_privkey_set_pin_function(x509_key, pin_callback, NULL); - - if (gnutls_url_is_supported(x509_keyfile) != 0) - { - ret = - gnutls_privkey_import_url (x509_key, x509_keyfile, 0); - if (ret < 0) - { - fprintf (stderr, "*** Error loading url: %s\n", - gnutls_strerror (ret)); - exit (1); - } - } - else - { - ret = gnutls_load_file (x509_keyfile, &data); - if (ret < 0) - { - fprintf (stderr, "*** Error loading key file.\n"); - exit (1); - } - - ret = gnutls_privkey_import_x509_raw( x509_key, &data, x509ctype, NULL, 0); - if (ret < 0) - { - fprintf (stderr, "*** Error loading url: %s\n", - gnutls_strerror (ret)); - exit (1); - } - - gnutls_free(data.data); - } - - fprintf (stdout, "Processed %d client X.509 certificates...\n", - x509_crt_size); - } - + if (strncmp(x509_certfile, "pkcs11:", 7) == 0) { + crt_num = 1; + gnutls_x509_crt_init(&crt_list[0]); + gnutls_x509_crt_set_pin_function(crt_list[0], + pin_callback, + NULL); + + ret = + gnutls_x509_crt_import_pkcs11_url(crt_list[0], + x509_certfile, + 0); + + if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) + ret = + gnutls_x509_crt_import_pkcs11_url + (crt_list[0], x509_certfile, + GNUTLS_PKCS11_OBJ_FLAG_LOGIN); + + if (ret < 0) { + fprintf(stderr, + "*** Error loading cert file.\n"); + exit(1); + } + x509_crt_size = 1; + } else +#endif /* ENABLE_PKCS11 */ + { + + ret = gnutls_load_file(x509_certfile, &data); + if (ret < 0) { + fprintf(stderr, + "*** Error loading cert file.\n"); + exit(1); + } + + crt_num = MAX_CRT; + ret = + gnutls_x509_crt_list_import(crt_list, &crt_num, + &data, x509ctype, + GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED); + if (ret < 0) { + if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { + fprintf(stderr, + "*** Error loading cert file: Too many certs %d\n", + crt_num); + + } else { + fprintf(stderr, + "*** Error loading cert file: %s\n", + gnutls_strerror(ret)); + } + exit(1); + } + x509_crt_size = ret; + } + + for (i = 0; i < x509_crt_size; i++) { + ret = + gnutls_pcert_import_x509(&x509_crt[i], + crt_list[i], 0); + if (ret < 0) { + fprintf(stderr, + "*** Error importing crt to pcert: %s\n", + gnutls_strerror(ret)); + exit(1); + } + gnutls_x509_crt_deinit(crt_list[i]); + } + + gnutls_free(data.data); + + ret = gnutls_privkey_init(&x509_key); + if (ret < 0) { + fprintf(stderr, "*** Error initializing key: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + gnutls_privkey_set_pin_function(x509_key, pin_callback, + NULL); + + if (gnutls_url_is_supported(x509_keyfile) != 0) { + ret = + gnutls_privkey_import_url(x509_key, + x509_keyfile, 0); + if (ret < 0) { + fprintf(stderr, + "*** Error loading url: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } else { + ret = gnutls_load_file(x509_keyfile, &data); + if (ret < 0) { + fprintf(stderr, + "*** Error loading key file.\n"); + exit(1); + } + + ret = + gnutls_privkey_import_x509_raw(x509_key, &data, + x509ctype, NULL, + 0); + if (ret < 0) { + fprintf(stderr, + "*** Error loading url: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + gnutls_free(data.data); + } + + fprintf(stdout, + "Processed %d client X.509 certificates...\n", + x509_crt_size); + } #ifdef ENABLE_OPENPGP - if (HAVE_OPT(PGPSUBKEY)) - { - get_keyid (keyid, OPT_ARG(PGPSUBKEY)); - } - - if (pgp_certfile != NULL && pgp_keyfile != NULL) - { - gnutls_openpgp_crt_t tmp_pgp_crt; - - ret = gnutls_load_file (pgp_certfile, &data); - if (ret < 0) - { - fprintf (stderr, "*** Error loading PGP cert file.\n"); - exit (1); - } - - gnutls_openpgp_crt_init (&tmp_pgp_crt); - - ret = - gnutls_pcert_import_openpgp_raw (&pgp_crt, &data, GNUTLS_OPENPGP_FMT_BASE64, HAVE_OPT(PGPSUBKEY)?keyid:NULL, 0); - if (ret < 0) - { - fprintf (stderr, - "*** Error loading PGP cert file: %s\n", - gnutls_strerror (ret)); - exit (1); - } - - gnutls_free (data.data); - - ret = gnutls_privkey_init(&pgp_key); - if (ret < 0) - { - fprintf (stderr, "*** Error initializing key: %s\n", - gnutls_strerror (ret)); - exit (1); - } - - gnutls_privkey_set_pin_function(pgp_key, pin_callback, NULL); - - if (gnutls_url_is_supported (pgp_keyfile)) - { - ret = gnutls_privkey_import_url( pgp_key, pgp_keyfile, 0); - if (ret < 0) - { - fprintf (stderr, "*** Error loading url: %s\n", - gnutls_strerror (ret)); - exit (1); - } - } - else - { - ret = gnutls_load_file (pgp_keyfile, &data); - if (ret < 0) - { - fprintf (stderr, "*** Error loading key file.\n"); - exit (1); - } - - if (HAVE_OPT(PGPSUBKEY)) - ret = gnutls_privkey_import_openpgp_raw( pgp_key, &data, x509ctype, keyid, NULL); - else - ret = gnutls_privkey_import_openpgp_raw( pgp_key, &data, x509ctype, NULL, NULL); - if (ret < 0) - { - fprintf (stderr, "*** Error loading url: %s\n", - gnutls_strerror (ret)); - exit (1); - } - - gnutls_free(data.data); - } - - - fprintf (stdout, "Processed 1 client PGP certificate...\n"); - } + if (HAVE_OPT(PGPSUBKEY)) { + get_keyid(keyid, OPT_ARG(PGPSUBKEY)); + } + + if (pgp_certfile != NULL && pgp_keyfile != NULL) { + gnutls_openpgp_crt_t tmp_pgp_crt; + + ret = gnutls_load_file(pgp_certfile, &data); + if (ret < 0) { + fprintf(stderr, + "*** Error loading PGP cert file.\n"); + exit(1); + } + + gnutls_openpgp_crt_init(&tmp_pgp_crt); + + ret = + gnutls_pcert_import_openpgp_raw(&pgp_crt, &data, + GNUTLS_OPENPGP_FMT_BASE64, + HAVE_OPT(PGPSUBKEY) ? + keyid : NULL, 0); + if (ret < 0) { + fprintf(stderr, + "*** Error loading PGP cert file: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + gnutls_free(data.data); + + ret = gnutls_privkey_init(&pgp_key); + if (ret < 0) { + fprintf(stderr, "*** Error initializing key: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + gnutls_privkey_set_pin_function(pgp_key, pin_callback, + NULL); + + if (gnutls_url_is_supported(pgp_keyfile)) { + ret = + gnutls_privkey_import_url(pgp_key, pgp_keyfile, + 0); + if (ret < 0) { + fprintf(stderr, + "*** Error loading url: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } else { + ret = gnutls_load_file(pgp_keyfile, &data); + if (ret < 0) { + fprintf(stderr, + "*** Error loading key file.\n"); + exit(1); + } + + if (HAVE_OPT(PGPSUBKEY)) + ret = + gnutls_privkey_import_openpgp_raw + (pgp_key, &data, x509ctype, keyid, + NULL); + else + ret = + gnutls_privkey_import_openpgp_raw + (pgp_key, &data, x509ctype, NULL, + NULL); + if (ret < 0) { + fprintf(stderr, + "*** Error loading url: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + gnutls_free(data.data); + } + + + fprintf(stdout, "Processed 1 client PGP certificate...\n"); + } #endif } #define IS_NEWLINE(x) ((x[0] == '\n') || (x[0] == '\r')) -static int -read_yesno (const char *input_str) +static int read_yesno(const char *input_str) { - char input[128]; + char input[128]; - fputs (input_str, stderr); - if (fgets (input, sizeof (input), stdin) == NULL) - return 0; + fputs(input_str, stderr); + if (fgets(input, sizeof(input), stdin) == NULL) + return 0; - if (IS_NEWLINE(input)) - return 0; + if (IS_NEWLINE(input)) + return 0; - if (input[0] == 'y' || input[0] == 'Y') - return 1; + if (input[0] == 'y' || input[0] == 'Y') + return 1; - return 0; + return 0; } /* converts a textual service or port to * a service. */ -static const char* port_to_service(const char* sport) +static const char *port_to_service(const char *sport) { -unsigned int port; -struct servent * sr; - - port = atoi(sport); - if (port == 0) return sport; - - port = htons(port); - - sr = getservbyport(port, udp?"udp":"tcp"); - if (sr == NULL) - { - fprintf(stderr, "Warning: getservbyport() failed. Using port number as service.\n"); - return sport; - } - - return sr->s_name; + unsigned int port; + struct servent *sr; + + port = atoi(sport); + if (port == 0) + return sport; + + port = htons(port); + + sr = getservbyport(port, udp ? "udp" : "tcp"); + if (sr == NULL) { + fprintf(stderr, + "Warning: getservbyport() failed. Using port number as service.\n"); + return sport; + } + + return sr->s_name; } -static int service_to_port(const char* service) +static int service_to_port(const char *service) { -unsigned int port; -struct servent * sr; - - port = atoi(service); - if (port != 0) return port; - - sr = getservbyname(service, udp?"udp":"tcp"); - if (sr == NULL) - { - fprintf(stderr, "Warning: getservbyname() failed.\n"); - exit(1); - } - - return ntohs(sr->s_port); + unsigned int port; + struct servent *sr; + + port = atoi(service); + if (port != 0) + return port; + + sr = getservbyname(service, udp ? "udp" : "tcp"); + if (sr == NULL) { + fprintf(stderr, "Warning: getservbyname() failed.\n"); + exit(1); + } + + return ntohs(sr->s_port); } -static int -cert_verify_callback (gnutls_session_t session) +static int cert_verify_callback(gnutls_session_t session) { - int rc; - unsigned int status = 0; - int ssh = ENABLED_OPT(TOFU); + int rc; + unsigned int status = 0; + int ssh = ENABLED_OPT(TOFU); #ifdef HAVE_DANE - int dane = ENABLED_OPT(DANE); + int dane = ENABLED_OPT(DANE); #endif - int ca_verify = ENABLED_OPT(CA_VERIFICATION); - const char* txt_service; - - print_cert_info (session, verbose, print_cert); - - if (ca_verify) - { - rc = cert_verify(session, hostname); - if (rc == 0) - { - printf ("*** Verifying server certificate failed...\n"); - if (!insecure && !ssh) - return -1; - } - else if (ENABLED_OPT(OCSP) && gnutls_ocsp_status_request_is_checked(session, 0) == 0) - { /* off-line verification succeeded. Try OCSP */ - rc = cert_verify_ocsp(session); - if (rc == 0) - { - printf ("*** Verifying (with OCSP) server certificate failed...\n"); - if (!insecure && !ssh) - return -1; - } - else if (rc == -1) - printf("*** OCSP response ignored\n"); - } - } - - if (ssh) /* try ssh auth */ - { - unsigned int list_size; - const gnutls_datum_t * cert; - - cert = gnutls_certificate_get_peers(session, &list_size); - if (cert == NULL) - { - fprintf(stderr, "Cannot obtain peer's certificate!\n"); - return -1; - } - - txt_service = port_to_service(service); - - rc = gnutls_verify_stored_pubkey(NULL, NULL, hostname, txt_service, - GNUTLS_CRT_X509, cert, 0); - if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND) - { - print_cert_info_compact(session); - fprintf(stderr, "Host %s (%s) has never been contacted before.\n", hostname, txt_service); - if (status == 0) - fprintf(stderr, "Its certificate is valid for %s.\n", hostname); - - rc = read_yesno("Are you sure you want to trust it? (y/N): "); - if (rc == 0) - return -1; - } - else if (rc == GNUTLS_E_CERTIFICATE_KEY_MISMATCH) - { - print_cert_info_compact(session); - fprintf(stderr, "Warning: host %s is known and it is associated with a different key.\n", hostname); - fprintf(stderr, "It might be that the server has multiple keys, or an attacker replaced the key to eavesdrop this connection .\n"); - if (status == 0) - fprintf(stderr, "Its certificate is valid for %s.\n", hostname); - - rc = read_yesno("Do you trust the received key? (y/N): "); - if (rc == 0) - return -1; - } - else if (rc < 0) - { - fprintf(stderr, "gnutls_verify_stored_pubkey: %s\n", gnutls_strerror(rc)); - return -1; - } - - if (rc != 0) - { - rc = gnutls_store_pubkey(NULL, NULL, hostname, txt_service, - GNUTLS_CRT_X509, cert, 0, 0); - if (rc < 0) - fprintf(stderr, "Could not store key: %s\n", gnutls_strerror(rc)); - } - } - + int ca_verify = ENABLED_OPT(CA_VERIFICATION); + const char *txt_service; + + print_cert_info(session, verbose, print_cert); + + if (ca_verify) { + rc = cert_verify(session, hostname); + if (rc == 0) { + printf + ("*** Verifying server certificate failed...\n"); + if (!insecure && !ssh) + return -1; + } else if (ENABLED_OPT(OCSP) && gnutls_ocsp_status_request_is_checked(session, 0) == 0) { /* off-line verification succeeded. Try OCSP */ + rc = cert_verify_ocsp(session); + if (rc == 0) { + printf + ("*** Verifying (with OCSP) server certificate failed...\n"); + if (!insecure && !ssh) + return -1; + } else if (rc == -1) + printf("*** OCSP response ignored\n"); + } + } + + if (ssh) { /* try ssh auth */ + unsigned int list_size; + const gnutls_datum_t *cert; + + cert = gnutls_certificate_get_peers(session, &list_size); + if (cert == NULL) { + fprintf(stderr, + "Cannot obtain peer's certificate!\n"); + return -1; + } + + txt_service = port_to_service(service); + + rc = gnutls_verify_stored_pubkey(NULL, NULL, hostname, + txt_service, + GNUTLS_CRT_X509, cert, 0); + if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND) { + print_cert_info_compact(session); + fprintf(stderr, + "Host %s (%s) has never been contacted before.\n", + hostname, txt_service); + if (status == 0) + fprintf(stderr, + "Its certificate is valid for %s.\n", + hostname); + + rc = read_yesno + ("Are you sure you want to trust it? (y/N): "); + if (rc == 0) + return -1; + } else if (rc == GNUTLS_E_CERTIFICATE_KEY_MISMATCH) { + print_cert_info_compact(session); + fprintf(stderr, + "Warning: host %s is known and it is associated with a different key.\n", + hostname); + fprintf(stderr, + "It might be that the server has multiple keys, or an attacker replaced the key to eavesdrop this connection .\n"); + if (status == 0) + fprintf(stderr, + "Its certificate is valid for %s.\n", + hostname); + + rc = read_yesno + ("Do you trust the received key? (y/N): "); + if (rc == 0) + return -1; + } else if (rc < 0) { + fprintf(stderr, + "gnutls_verify_stored_pubkey: %s\n", + gnutls_strerror(rc)); + return -1; + } + + if (rc != 0) { + rc = gnutls_store_pubkey(NULL, NULL, hostname, + txt_service, + GNUTLS_CRT_X509, cert, 0, + 0); + if (rc < 0) + fprintf(stderr, + "Could not store key: %s\n", + gnutls_strerror(rc)); + } + } #ifdef HAVE_DANE - if (dane) /* try DANE auth */ - { - int port; - unsigned int sflags = ENABLED_OPT(LOCAL_DNS)?0:DANE_F_IGNORE_LOCAL_RESOLVER; - - port = service_to_port(service); - rc = dane_verify_session_crt( NULL, session, hostname, udp?"udp":"tcp", port, - sflags, 0, &status); - if (rc < 0) - { - fprintf(stderr, "*** DANE verification error: %s\n", dane_strerror(rc)); - if (!insecure) - return -1; - } - else - { - gnutls_datum_t out; - - rc = dane_verification_status_print( status, &out, 0); - if (rc < 0) - { - fprintf(stderr, "*** DANE error: %s\n", dane_strerror(rc)); - if (!insecure) - return -1; - } - - fprintf(stderr, "- DANE: %s\n", out.data); - gnutls_free(out.data); - } - - } + if (dane) { /* try DANE auth */ + int port; + unsigned int sflags = + ENABLED_OPT(LOCAL_DNS) ? 0 : + DANE_F_IGNORE_LOCAL_RESOLVER; + + port = service_to_port(service); + rc = dane_verify_session_crt(NULL, session, hostname, + udp ? "udp" : "tcp", port, + sflags, 0, &status); + if (rc < 0) { + fprintf(stderr, + "*** DANE verification error: %s\n", + dane_strerror(rc)); + if (!insecure) + return -1; + } else { + gnutls_datum_t out; + + rc = dane_verification_status_print(status, &out, + 0); + if (rc < 0) { + fprintf(stderr, "*** DANE error: %s\n", + dane_strerror(rc)); + if (!insecure) + return -1; + } + + fprintf(stderr, "- DANE: %s\n", out.data); + gnutls_free(out.data); + } + + } #endif - return 0; + return 0; } /* This callback should be associated with a session by calling @@ -547,242 +556,233 @@ cert_verify_callback (gnutls_session_t session) */ static int -cert_callback (gnutls_session_t session, - const gnutls_datum_t * req_ca_rdn, int nreqs, - const gnutls_pk_algorithm_t * sign_algos, - int sign_algos_length, gnutls_pcert_st **pcert, - unsigned int *pcert_length, gnutls_privkey_t * pkey) +cert_callback(gnutls_session_t session, + const gnutls_datum_t * req_ca_rdn, int nreqs, + const gnutls_pk_algorithm_t * sign_algos, + int sign_algos_length, gnutls_pcert_st ** pcert, + unsigned int *pcert_length, gnutls_privkey_t * pkey) { - char issuer_dn[256]; - int i, ret, cert_type; - size_t len; - - if (verbose) - { - /* Print the server's trusted CAs - */ - if (nreqs > 0) - printf ("- Server's trusted authorities:\n"); - else - printf ("- Server did not send us any trusted authorities names.\n"); - - /* print the names (if any) */ - for (i = 0; i < nreqs; i++) - { - len = sizeof (issuer_dn); - ret = gnutls_x509_rdn_get (&req_ca_rdn[i], issuer_dn, &len); - if (ret >= 0) - { - printf (" [%d]: ", i); - printf ("%s\n", issuer_dn); - } - } - } - - /* Select a certificate and return it. - * The certificate must be of any of the "sign algorithms" - * supported by the server. - */ - - cert_type = gnutls_certificate_type_get (session); - - *pcert_length = 0; - - if (cert_type == GNUTLS_CRT_X509) - { - if (x509_crt_size > 0) - { - if (x509_key != NULL) - { - *pkey = x509_key; - } - else - { - printf ("- Could not find a suitable key to send to server\n"); - return -1; - } - - *pcert_length = x509_crt_size; - *pcert = x509_crt; - } - - } - else if (cert_type == GNUTLS_CRT_OPENPGP) - { - if (pgp_key != NULL) - { - *pkey = pgp_key; - - *pcert_length = 1; - *pcert = &pgp_crt; - } - } - - printf ("- Successfully sent %u certificate(s) to server.\n", *pcert_length); - return 0; + char issuer_dn[256]; + int i, ret, cert_type; + size_t len; + + if (verbose) { + /* Print the server's trusted CAs + */ + if (nreqs > 0) + printf("- Server's trusted authorities:\n"); + else + printf + ("- Server did not send us any trusted authorities names.\n"); + + /* print the names (if any) */ + for (i = 0; i < nreqs; i++) { + len = sizeof(issuer_dn); + ret = + gnutls_x509_rdn_get(&req_ca_rdn[i], issuer_dn, + &len); + if (ret >= 0) { + printf(" [%d]: ", i); + printf("%s\n", issuer_dn); + } + } + } + + /* Select a certificate and return it. + * The certificate must be of any of the "sign algorithms" + * supported by the server. + */ + + cert_type = gnutls_certificate_type_get(session); + + *pcert_length = 0; + + if (cert_type == GNUTLS_CRT_X509) { + if (x509_crt_size > 0) { + if (x509_key != NULL) { + *pkey = x509_key; + } else { + printf + ("- Could not find a suitable key to send to server\n"); + return -1; + } + + *pcert_length = x509_crt_size; + *pcert = x509_crt; + } + + } else if (cert_type == GNUTLS_CRT_OPENPGP) { + if (pgp_key != NULL) { + *pkey = pgp_key; + + *pcert_length = 1; + *pcert = &pgp_crt; + } + } + + printf("- Successfully sent %u certificate(s) to server.\n", + *pcert_length); + return 0; } /* initializes a gnutls_session_t with some defaults. */ -static gnutls_session_t -init_tls_session (const char *hostname) +static gnutls_session_t init_tls_session(const char *hostname) { - const char *err; - int ret; - unsigned i; - gnutls_session_t session; - - if (priorities == NULL) - priorities = "NORMAL"; - - if (udp) - { - gnutls_init (&session, GNUTLS_DATAGRAM|init_flags); - if (mtu) - gnutls_dtls_set_mtu(session, mtu); - } - else - gnutls_init (&session, init_flags); - - if ((ret = gnutls_priority_set_direct (session, priorities, &err)) < 0) - { - if (ret == GNUTLS_E_INVALID_REQUEST) fprintf (stderr, "Syntax error at: %s\n", err); - else - fprintf(stderr, "Error in priorities: %s\n", gnutls_strerror(ret)); - exit (1); - } - - /* allow the use of private ciphersuites. - */ - if (disable_extensions == 0 && disable_sni == 0) - { - if (!isdigit(hostname[0]) && strchr(hostname, ':') == 0) - gnutls_server_name_set (session, GNUTLS_NAME_DNS, hostname, - strlen (hostname)); - } - - if (HAVE_OPT(DH_BITS)) - gnutls_dh_set_prime_bits( session, OPT_VALUE_DH_BITS); - - if (HAVE_OPT(ALPN)) - { - unsigned proto_n = STACKCT_OPT(ALPN); - char** protos = (void*)STACKLST_OPT(ALPN); - gnutls_datum_t p[proto_n]; - - for (i=0;i<proto_n;i++) - { - p[i].data = (void*)protos[i]; - p[i].size = strlen(protos[i]); - } - gnutls_alpn_set_protocols( session, p, proto_n, 0); - } - - gnutls_credentials_set (session, GNUTLS_CRD_ANON, anon_cred); - if (srp_cred) - gnutls_credentials_set (session, GNUTLS_CRD_SRP, srp_cred); - if (psk_cred) - gnutls_credentials_set (session, GNUTLS_CRD_PSK, psk_cred); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); - - gnutls_certificate_set_retrieve_function2 (xcred, cert_callback); - gnutls_certificate_set_verify_function (xcred, cert_verify_callback); - - /* send the fingerprint */ + const char *err; + int ret; + unsigned i; + gnutls_session_t session; + + if (priorities == NULL) + priorities = "NORMAL"; + + if (udp) { + gnutls_init(&session, GNUTLS_DATAGRAM | init_flags); + if (mtu) + gnutls_dtls_set_mtu(session, mtu); + } else + gnutls_init(&session, init_flags); + + if ((ret = + gnutls_priority_set_direct(session, priorities, &err)) < 0) { + if (ret == GNUTLS_E_INVALID_REQUEST) + fprintf(stderr, "Syntax error at: %s\n", err); + else + fprintf(stderr, "Error in priorities: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + /* allow the use of private ciphersuites. + */ + if (disable_extensions == 0 && disable_sni == 0) { + if (!isdigit(hostname[0]) && strchr(hostname, ':') == 0) + gnutls_server_name_set(session, GNUTLS_NAME_DNS, + hostname, strlen(hostname)); + } + + if (HAVE_OPT(DH_BITS)) + gnutls_dh_set_prime_bits(session, OPT_VALUE_DH_BITS); + + if (HAVE_OPT(ALPN)) { + unsigned proto_n = STACKCT_OPT(ALPN); + char **protos = (void *) STACKLST_OPT(ALPN); + gnutls_datum_t p[proto_n]; + + for (i = 0; i < proto_n; i++) { + p[i].data = (void *) protos[i]; + p[i].size = strlen(protos[i]); + } + gnutls_alpn_set_protocols(session, p, proto_n, 0); + } + + gnutls_credentials_set(session, GNUTLS_CRD_ANON, anon_cred); + if (srp_cred) + gnutls_credentials_set(session, GNUTLS_CRD_SRP, srp_cred); + if (psk_cred) + gnutls_credentials_set(session, GNUTLS_CRD_PSK, psk_cred); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + gnutls_certificate_set_retrieve_function2(xcred, cert_callback); + gnutls_certificate_set_verify_function(xcred, + cert_verify_callback); + + /* send the fingerprint */ #ifdef ENABLE_OPENPGP - if (fingerprint != 0) - gnutls_openpgp_send_cert (session, GNUTLS_OPENPGP_CERT_FINGERPRINT); + if (fingerprint != 0) + gnutls_openpgp_send_cert(session, + GNUTLS_OPENPGP_CERT_FINGERPRINT); #endif - /* use the max record size extension */ - if (record_max_size > 0 && disable_extensions == 0) - { - if (gnutls_record_set_max_size (session, record_max_size) < 0) - { - fprintf (stderr, - "Cannot set the maximum record size to %d.\n", - record_max_size); - fprintf (stderr, "Possible values: 512, 1024, 2048, 4096.\n"); - exit (1); - } - } - - if (HAVE_OPT(HEARTBEAT)) - gnutls_heartbeat_enable (session, GNUTLS_HB_PEER_ALLOWED_TO_SEND); + /* use the max record size extension */ + if (record_max_size > 0 && disable_extensions == 0) { + if (gnutls_record_set_max_size(session, record_max_size) < + 0) { + fprintf(stderr, + "Cannot set the maximum record size to %d.\n", + record_max_size); + fprintf(stderr, + "Possible values: 512, 1024, 2048, 4096.\n"); + exit(1); + } + } + + if (HAVE_OPT(HEARTBEAT)) + gnutls_heartbeat_enable(session, + GNUTLS_HB_PEER_ALLOWED_TO_SEND); #ifdef ENABLE_DTLS_SRTP - if (HAVE_OPT(SRTP_PROFILES)) - { - ret = gnutls_srtp_set_profile_direct (session, OPT_ARG(SRTP_PROFILES), &err); - if (ret == GNUTLS_E_INVALID_REQUEST) fprintf (stderr, "Syntax error at: %s\n", err); - else - fprintf(stderr, "Error in profiles: %s\n", gnutls_strerror(ret)); - exit (1); - } + if (HAVE_OPT(SRTP_PROFILES)) { + ret = + gnutls_srtp_set_profile_direct(session, + OPT_ARG(SRTP_PROFILES), + &err); + if (ret == GNUTLS_E_INVALID_REQUEST) + fprintf(stderr, "Syntax error at: %s\n", err); + else + fprintf(stderr, "Error in profiles: %s\n", + gnutls_strerror(ret)); + exit(1); + } #endif - return session; + return session; } -static void cmd_parser (int argc, char **argv); +static void cmd_parser(int argc, char **argv); /* Returns zero if the error code was successfully handled. */ -static int -handle_error (socket_st * hd, int err) +static int handle_error(socket_st * hd, int err) { - int alert, ret; - const char *err_type, *str; - - if (err >= 0 || err == GNUTLS_E_AGAIN || err == GNUTLS_E_INTERRUPTED) - return 0; - - if (gnutls_error_is_fatal (err) == 0) - { - ret = 0; - err_type = "Non fatal"; - } - else - { - ret = err; - err_type = "Fatal"; - } - - str = gnutls_strerror (err); - if (str == NULL) - str = str_unknown; - fprintf (stderr, "*** %s error: %s\n", err_type, str); - - if (err == GNUTLS_E_WARNING_ALERT_RECEIVED - || err == GNUTLS_E_FATAL_ALERT_RECEIVED) - { - alert = gnutls_alert_get (hd->session); - str = gnutls_alert_get_name (alert); - if (str == NULL) - str = str_unknown; - printf ("*** Received alert [%d]: %s\n", alert, str); - } - - check_rehandshake (hd, err); - - return ret; + int alert, ret; + const char *err_type, *str; + + if (err >= 0 || err == GNUTLS_E_AGAIN + || err == GNUTLS_E_INTERRUPTED) + return 0; + + if (gnutls_error_is_fatal(err) == 0) { + ret = 0; + err_type = "Non fatal"; + } else { + ret = err; + err_type = "Fatal"; + } + + str = gnutls_strerror(err); + if (str == NULL) + str = str_unknown; + fprintf(stderr, "*** %s error: %s\n", err_type, str); + + if (err == GNUTLS_E_WARNING_ALERT_RECEIVED + || err == GNUTLS_E_FATAL_ALERT_RECEIVED) { + alert = gnutls_alert_get(hd->session); + str = gnutls_alert_get_name(alert); + if (str == NULL) + str = str_unknown; + printf("*** Received alert [%d]: %s\n", alert, str); + } + + check_rehandshake(hd, err); + + return ret; } int starttls_alarmed = 0; #ifndef _WIN32 -static void -starttls_alarm (int signum) +static void starttls_alarm(int signum) { - starttls_alarmed = 1; + starttls_alarmed = 1; } #endif -static void -tls_log_func (int level, const char *str) +static void tls_log_func(int level, const char *str) { - fprintf (stderr, "|<%d>| %s", level, str); + fprintf(stderr, "|<%d>| %s", level, str); } #define IN_KEYBOARD 1 @@ -790,960 +790,906 @@ tls_log_func (int level, const char *str) #define IN_NONE 0 /* returns IN_KEYBOARD for keyboard input and IN_NET for network input */ -static int check_net_or_keyboard_input(socket_st* hd) +static int check_net_or_keyboard_input(socket_st * hd) { - int maxfd; - fd_set rset; - int err; - struct timeval tv; + int maxfd; + fd_set rset; + int err; + struct timeval tv; - do - { - FD_ZERO (&rset); - FD_SET (hd->fd, &rset); + do { + FD_ZERO(&rset); + FD_SET(hd->fd, &rset); #ifndef _WIN32 - FD_SET (fileno (stdin), &rset); - maxfd = MAX (fileno (stdin), hd->fd); + FD_SET(fileno(stdin), &rset); + maxfd = MAX(fileno(stdin), hd->fd); #else - maxfd = hd->fd; + maxfd = hd->fd; #endif - tv.tv_sec = 0; - tv.tv_usec = 50 * 1000; + tv.tv_sec = 0; + tv.tv_usec = 50 * 1000; - if (hd->secure == 1) - if (gnutls_record_check_pending(hd->session)) - return IN_NET; + if (hd->secure == 1) + if (gnutls_record_check_pending(hd->session)) + return IN_NET; - err = select (maxfd + 1, &rset, NULL, NULL, &tv); - if (err < 0) - continue; + err = select(maxfd + 1, &rset, NULL, NULL, &tv); + if (err < 0) + continue; - if (FD_ISSET (hd->fd, &rset)) - return IN_NET; + if (FD_ISSET(hd->fd, &rset)) + return IN_NET; #ifdef _WIN32 - { - int state; - state = WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 200); - - if (state == WAIT_OBJECT_0) - return IN_KEYBOARD; - } + { + int state; + state = + WaitForSingleObject(GetStdHandle + (STD_INPUT_HANDLE), 200); + + if (state == WAIT_OBJECT_0) + return IN_KEYBOARD; + } #else - if (FD_ISSET (fileno (stdin), &rset)) - return IN_KEYBOARD; + if (FD_ISSET(fileno(stdin), &rset)) + return IN_KEYBOARD; #endif - } - while(err == 0); - - return IN_NONE; + } + while (err == 0); + + return IN_NONE; } -static int try_rehandshake(socket_st *hd) +static int try_rehandshake(socket_st * hd) { - int ret; - - ret = do_handshake (hd); - if (ret < 0) - { - fprintf (stderr, "*** ReHandshake has failed\n"); - gnutls_perror (ret); - return ret; - } - else - { - printf ("- ReHandshake was completed\n"); - return 0; - } + int ret; + + ret = do_handshake(hd); + if (ret < 0) { + fprintf(stderr, "*** ReHandshake has failed\n"); + gnutls_perror(ret); + return ret; + } else { + printf("- ReHandshake was completed\n"); + return 0; + } } -static int try_resume (socket_st *hd) +static int try_resume(socket_st * hd) { - int ret; - - char *session_data; - size_t session_data_size = 0; - - gnutls_session_get_data (hd->session, NULL, &session_data_size); - session_data = (char *) malloc (session_data_size); - if (session_data == NULL) - return GNUTLS_E_MEMORY_ERROR; - - gnutls_session_get_data (hd->session, session_data, - &session_data_size); - - printf ("- Disconnecting\n"); - socket_bye (hd); - - printf ("\n\n- Connecting again- trying to resume previous session\n"); - socket_open (hd, hostname, service, udp); - - hd->session = init_tls_session (hostname); - gnutls_session_set_data (hd->session, session_data, session_data_size); - free (session_data); - - ret = do_handshake (hd); - if (ret < 0) - { - fprintf (stderr, "*** Resume handshake has failed\n"); - gnutls_perror (ret); - return ret; - } - - printf ("- Resume Handshake was completed\n"); - if (gnutls_session_is_resumed (hd->session) != 0) - printf ("*** This is a resumed session\n"); - - return 0; + int ret; + + char *session_data; + size_t session_data_size = 0; + + gnutls_session_get_data(hd->session, NULL, &session_data_size); + session_data = (char *) malloc(session_data_size); + if (session_data == NULL) + return GNUTLS_E_MEMORY_ERROR; + + gnutls_session_get_data(hd->session, session_data, + &session_data_size); + + printf("- Disconnecting\n"); + socket_bye(hd); + + printf + ("\n\n- Connecting again- trying to resume previous session\n"); + socket_open(hd, hostname, service, udp); + + hd->session = init_tls_session(hostname); + gnutls_session_set_data(hd->session, session_data, + session_data_size); + free(session_data); + + ret = do_handshake(hd); + if (ret < 0) { + fprintf(stderr, "*** Resume handshake has failed\n"); + gnutls_perror(ret); + return ret; + } + + printf("- Resume Handshake was completed\n"); + if (gnutls_session_is_resumed(hd->session) != 0) + printf("*** This is a resumed session\n"); + + return 0; } -static -bool parse_for_inline_commands_in_buffer (char *buffer, size_t bytes, - inline_cmds_st *inline_cmds) +static +bool parse_for_inline_commands_in_buffer(char *buffer, size_t bytes, + inline_cmds_st * inline_cmds) { - ssize_t local_bytes, match_bytes, prev_bytes_copied, ii, jj; - char *local_buffer_ptr, *ptr; - char inline_command_string[MAX_INLINE_COMMAND_BYTES]; - ssize_t l; - - inline_cmds->bytes_to_flush = 0; - inline_cmds->cmd_found = INLINE_COMMAND_NONE; - - if (inline_cmds->bytes_copied) - { - local_buffer_ptr = - &inline_cmds->inline_cmd_buffer[inline_cmds->bytes_copied]; - - local_bytes = - ((inline_cmds->bytes_copied + bytes) <= MAX_INLINE_COMMAND_BYTES) ? - (ssize_t)bytes : (MAX_INLINE_COMMAND_BYTES - inline_cmds->bytes_copied); - - memcpy (local_buffer_ptr, buffer, local_bytes); - prev_bytes_copied = inline_cmds->bytes_copied; - inline_cmds->new_buffer_ptr = buffer + local_bytes; - inline_cmds->bytes_copied += local_bytes; - local_buffer_ptr = inline_cmds->inline_cmd_buffer; - local_bytes = inline_cmds->bytes_copied; - } - else - { - prev_bytes_copied = 0; - local_buffer_ptr = buffer; - local_bytes = bytes; - inline_cmds->new_buffer_ptr = buffer + bytes; - } - - inline_cmds->current_ptr = local_buffer_ptr; - - if (local_buffer_ptr[0] == inline_commands_prefix[0] && inline_cmds->lf_found) - { - for (jj = 0; jj < NUM_INLINE_COMMANDS; jj ++) - { - if (inline_commands_prefix[0] != '^') /* refer inline_cmds.h for usage of ^ */ - { - strcpy (inline_command_string, inline_commands_def[jj].string); - inline_command_string[strlen(inline_commands_def[jj].string)] = '\0'; - inline_command_string[0] = inline_commands_prefix[0]; - /* Inline commands are delimited by the inline_commands_prefix[0] (default is ^). - The inline_commands_def[].string includes a trailing LF */ - inline_command_string[strlen(inline_commands_def[jj].string) - 2] = inline_commands_prefix[0]; - ptr = inline_command_string; - } - else - ptr = inline_commands_def[jj].string; - - l = strlen(ptr); - match_bytes = (local_bytes <= l) ? local_bytes : l; - if (strncmp (ptr, local_buffer_ptr, match_bytes) == 0) - { - if (match_bytes == (ssize_t)strlen (ptr)) - { - inline_cmds->new_buffer_ptr = buffer + match_bytes - prev_bytes_copied; - inline_cmds->cmd_found = inline_commands_def[jj].command; - inline_cmds->bytes_copied = 0; /* reset it */ - } - else - { - /* partial command */ - memcpy (&inline_cmds->inline_cmd_buffer[inline_cmds->bytes_copied], - buffer, bytes); - inline_cmds->bytes_copied += bytes; - } - return true; - } - /* else - if not a match, do nothing here */ - } /* for */ - } - - for (ii = prev_bytes_copied; ii < local_bytes; ii ++) - { - if (ii && local_buffer_ptr[ii] == inline_commands_prefix[0] && inline_cmds->lf_found) - { - /* possible inline command. First, let's flush bytes up to ^ */ - inline_cmds->new_buffer_ptr = buffer + ii - prev_bytes_copied; - inline_cmds->bytes_to_flush = ii; - inline_cmds->lf_found = true; - - /* bytes to flush starts at inline_cmds->current_ptr */ - return true; - } - else if (local_buffer_ptr[ii] == '\n') - { - inline_cmds->lf_found = true; - } - else - { - inline_cmds->lf_found = false; - } - } /* for */ - - inline_cmds->bytes_copied = 0; /* reset it */ - return false; /* not an inline command */ + ssize_t local_bytes, match_bytes, prev_bytes_copied, ii, jj; + char *local_buffer_ptr, *ptr; + char inline_command_string[MAX_INLINE_COMMAND_BYTES]; + ssize_t l; + + inline_cmds->bytes_to_flush = 0; + inline_cmds->cmd_found = INLINE_COMMAND_NONE; + + if (inline_cmds->bytes_copied) { + local_buffer_ptr = + &inline_cmds->inline_cmd_buffer[inline_cmds-> + bytes_copied]; + + local_bytes = + ((inline_cmds->bytes_copied + bytes) <= + MAX_INLINE_COMMAND_BYTES) ? (ssize_t) bytes + : (MAX_INLINE_COMMAND_BYTES - + inline_cmds->bytes_copied); + + memcpy(local_buffer_ptr, buffer, local_bytes); + prev_bytes_copied = inline_cmds->bytes_copied; + inline_cmds->new_buffer_ptr = buffer + local_bytes; + inline_cmds->bytes_copied += local_bytes; + local_buffer_ptr = inline_cmds->inline_cmd_buffer; + local_bytes = inline_cmds->bytes_copied; + } else { + prev_bytes_copied = 0; + local_buffer_ptr = buffer; + local_bytes = bytes; + inline_cmds->new_buffer_ptr = buffer + bytes; + } + + inline_cmds->current_ptr = local_buffer_ptr; + + if (local_buffer_ptr[0] == inline_commands_prefix[0] + && inline_cmds->lf_found) { + for (jj = 0; jj < NUM_INLINE_COMMANDS; jj++) { + if (inline_commands_prefix[0] != '^') { /* refer inline_cmds.h for usage of ^ */ + strcpy(inline_command_string, + inline_commands_def[jj].string); + inline_command_string[strlen + (inline_commands_def + [jj].string)] = + '\0'; + inline_command_string[0] = + inline_commands_prefix[0]; + /* Inline commands are delimited by the inline_commands_prefix[0] (default is ^). + The inline_commands_def[].string includes a trailing LF */ + inline_command_string[strlen + (inline_commands_def + [jj].string) - 2] = + inline_commands_prefix[0]; + ptr = inline_command_string; + } else + ptr = inline_commands_def[jj].string; + + l = strlen(ptr); + match_bytes = (local_bytes <= l) ? local_bytes : l; + if (strncmp(ptr, local_buffer_ptr, match_bytes) == + 0) { + if (match_bytes == (ssize_t) strlen(ptr)) { + inline_cmds->new_buffer_ptr = + buffer + match_bytes - + prev_bytes_copied; + inline_cmds->cmd_found = + inline_commands_def[jj]. + command; + inline_cmds->bytes_copied = 0; /* reset it */ + } else { + /* partial command */ + memcpy(&inline_cmds-> + inline_cmd_buffer + [inline_cmds->bytes_copied], + buffer, bytes); + inline_cmds->bytes_copied += bytes; + } + return true; + } + /* else - if not a match, do nothing here */ + } /* for */ + } + + for (ii = prev_bytes_copied; ii < local_bytes; ii++) { + if (ii && local_buffer_ptr[ii] == inline_commands_prefix[0] + && inline_cmds->lf_found) { + /* possible inline command. First, let's flush bytes up to ^ */ + inline_cmds->new_buffer_ptr = + buffer + ii - prev_bytes_copied; + inline_cmds->bytes_to_flush = ii; + inline_cmds->lf_found = true; + + /* bytes to flush starts at inline_cmds->current_ptr */ + return true; + } else if (local_buffer_ptr[ii] == '\n') { + inline_cmds->lf_found = true; + } else { + inline_cmds->lf_found = false; + } + } /* for */ + + inline_cmds->bytes_copied = 0; /* reset it */ + return false; /* not an inline command */ } static -int run_inline_command (inline_cmds_st *cmd, socket_st * hd) +int run_inline_command(inline_cmds_st * cmd, socket_st * hd) { - switch (cmd->cmd_found) - { - case INLINE_COMMAND_RESUME: - return try_resume (hd); - case INLINE_COMMAND_RENEGOTIATE: - return try_rehandshake (hd); - default: - return -1; - } + switch (cmd->cmd_found) { + case INLINE_COMMAND_RESUME: + return try_resume(hd); + case INLINE_COMMAND_RENEGOTIATE: + return try_rehandshake(hd); + default: + return -1; + } } static -int do_inline_command_processing (char *buffer_ptr, size_t curr_bytes, socket_st * hd, inline_cmds_st *inline_cmds) +int do_inline_command_processing(char *buffer_ptr, size_t curr_bytes, + socket_st * hd, + inline_cmds_st * inline_cmds) { - int skip_bytes, bytes; - bool inline_cmd_start_found; - - bytes = curr_bytes; - -continue_inline_processing: - /* parse_for_inline_commands_in_buffer hunts for start of an inline command - * sequence. The function maintains state information in inline_cmds. - */ - inline_cmd_start_found = parse_for_inline_commands_in_buffer (buffer_ptr, - bytes, inline_cmds); - if (!inline_cmd_start_found) - return bytes; - - /* inline_cmd_start_found is set */ - - if (inline_cmds->bytes_to_flush) - { - /* start of an inline command sequence found, but is not - * at the beginning of buffer. So, we flush all preceding bytes. - */ - return inline_cmds->bytes_to_flush; - } - else if (inline_cmds->cmd_found == INLINE_COMMAND_NONE) - { - /* partial command found */ - return 0; - } - else - { - /* complete inline command found and is at the start */ - if (run_inline_command (inline_cmds, hd)) - return -1; - - inline_cmds->cmd_found = INLINE_COMMAND_NONE; - skip_bytes = inline_cmds->new_buffer_ptr - buffer_ptr; - - if (skip_bytes >= bytes) - return 0; - else - { - buffer_ptr = inline_cmds->new_buffer_ptr; - bytes -= skip_bytes; - goto continue_inline_processing; - } - } + int skip_bytes, bytes; + bool inline_cmd_start_found; + + bytes = curr_bytes; + + continue_inline_processing: + /* parse_for_inline_commands_in_buffer hunts for start of an inline command + * sequence. The function maintains state information in inline_cmds. + */ + inline_cmd_start_found = + parse_for_inline_commands_in_buffer(buffer_ptr, bytes, + inline_cmds); + if (!inline_cmd_start_found) + return bytes; + + /* inline_cmd_start_found is set */ + + if (inline_cmds->bytes_to_flush) { + /* start of an inline command sequence found, but is not + * at the beginning of buffer. So, we flush all preceding bytes. + */ + return inline_cmds->bytes_to_flush; + } else if (inline_cmds->cmd_found == INLINE_COMMAND_NONE) { + /* partial command found */ + return 0; + } else { + /* complete inline command found and is at the start */ + if (run_inline_command(inline_cmds, hd)) + return -1; + + inline_cmds->cmd_found = INLINE_COMMAND_NONE; + skip_bytes = inline_cmds->new_buffer_ptr - buffer_ptr; + + if (skip_bytes >= bytes) + return 0; + else { + buffer_ptr = inline_cmds->new_buffer_ptr; + bytes -= skip_bytes; + goto continue_inline_processing; + } + } } -int -main (int argc, char **argv) +int main(int argc, char **argv) { - int ret; - int ii, inp; - char buffer[MAX_BUF + 1]; - int user_term = 0, retval = 0; - socket_st hd; - ssize_t bytes, keyboard_bytes; - char *keyboard_buffer_ptr; - inline_cmds_st inline_cmds; + int ret; + int ii, inp; + char buffer[MAX_BUF + 1]; + int user_term = 0, retval = 0; + socket_st hd; + ssize_t bytes, keyboard_bytes; + char *keyboard_buffer_ptr; + inline_cmds_st inline_cmds; #ifndef _WIN32 - struct sigaction new_action; + struct sigaction new_action; #endif - cmd_parser (argc, argv); + cmd_parser(argc, argv); + + gnutls_global_set_log_function(tls_log_func); + gnutls_global_set_log_level(OPT_VALUE_DEBUG); - gnutls_global_set_log_function (tls_log_func); - gnutls_global_set_log_level (OPT_VALUE_DEBUG); + if ((ret = gnutls_global_init()) < 0) { + fprintf(stderr, "global_init: %s\n", gnutls_strerror(ret)); + exit(1); + } - if ((ret = gnutls_global_init ()) < 0) - { - fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret)); - exit (1); - } + if (hostname == NULL) { + fprintf(stderr, "No hostname given\n"); + exit(1); + } - if (hostname == NULL) - { - fprintf (stderr, "No hostname given\n"); - exit (1); - } + sockets_init(); - sockets_init (); + init_global_tls_stuff(); - init_global_tls_stuff (); + socket_open(&hd, hostname, service, udp); - socket_open (&hd, hostname, service, udp); + hd.session = init_tls_session(hostname); + if (starttls) + goto after_handshake; - hd.session = init_tls_session (hostname); - if (starttls) - goto after_handshake; + ret = do_handshake(&hd); - ret = do_handshake (&hd); - - if (ret < 0) - { - fprintf (stderr, "*** Handshake has failed\n"); - gnutls_perror (ret); - gnutls_deinit (hd.session); - return 1; - } - else - printf ("- Handshake was completed\n"); - - if (resume != 0) - if (try_resume (&hd)) - return 1; + if (ret < 0) { + fprintf(stderr, "*** Handshake has failed\n"); + gnutls_perror(ret); + gnutls_deinit(hd.session); + return 1; + } else + printf("- Handshake was completed\n"); -after_handshake: + if (resume != 0) + if (try_resume(&hd)) + return 1; - /* Warning! Do not touch this text string, it is used by external - programs to search for when gnutls-cli has reached this point. */ - printf ("\n- Simple Client Mode:\n\n"); + after_handshake: - if (rehandshake) - if (try_rehandshake (&hd)) - return 1; + /* Warning! Do not touch this text string, it is used by external + programs to search for when gnutls-cli has reached this point. */ + printf("\n- Simple Client Mode:\n\n"); + + if (rehandshake) + if (try_rehandshake(&hd)) + return 1; #ifndef _WIN32 - new_action.sa_handler = starttls_alarm; - sigemptyset (&new_action.sa_mask); - new_action.sa_flags = 0; + new_action.sa_handler = starttls_alarm; + sigemptyset(&new_action.sa_mask); + new_action.sa_flags = 0; - sigaction (SIGALRM, &new_action, NULL); + sigaction(SIGALRM, &new_action, NULL); #endif - fflush (stdout); - fflush (stderr); + fflush(stdout); + fflush(stderr); - /* do not buffer */ + /* do not buffer */ #ifndef _WIN32 - setbuf (stdin, NULL); + setbuf(stdin, NULL); #endif - setbuf (stdout, NULL); - setbuf (stderr, NULL); - - if (inline_commands) - { - memset (&inline_cmds, 0, sizeof (inline_cmds_st)); - inline_cmds.lf_found = true; /* initially, at start of line */ - } - - for (;;) - { - if (starttls_alarmed && !hd.secure) - { - /* Warning! Do not touch this text string, it is used by - external programs to search for when gnutls-cli has - reached this point. */ - fprintf (stderr, "*** Starting TLS handshake\n"); - ret = do_handshake (&hd); - if (ret < 0) - { - fprintf (stderr, "*** Handshake has failed\n"); - user_term = 1; - retval = 1; - break; - } - } - - inp = check_net_or_keyboard_input(&hd); - - if (inp == IN_NET) - { - memset (buffer, 0, MAX_BUF + 1); - ret = socket_recv (&hd, buffer, MAX_BUF); - - if (ret == 0) - { - printf ("- Peer has closed the GnuTLS connection\n"); - break; - } - else if (handle_error (&hd, ret) < 0 && user_term == 0) - { - fprintf (stderr, - "*** Server has terminated the connection abnormally.\n"); - retval = 1; - break; - } - else if (ret > 0) - { - if (verbose != 0) - printf ("- Received[%d]: ", ret); - for (ii = 0; ii < ret; ii++) - { - fputc (buffer[ii], stdout); - } - fflush (stdout); - } - - if (user_term != 0) - break; - } - - if (inp == IN_KEYBOARD) - { - if ((bytes = read (fileno (stdin), buffer, MAX_BUF - 1)) <= 0) - { - if (hd.secure == 0) - { - /* Warning! Do not touch this text string, it is - used by external programs to search for when - gnutls-cli has reached this point. */ - fprintf (stderr, "*** Starting TLS handshake\n"); - ret = do_handshake (&hd); - clearerr (stdin); - if (ret < 0) - { - fprintf (stderr, "*** Handshake has failed\n"); - user_term = 1; - retval = 1; - break; - } - } - else - { - user_term = 1; - break; - } - continue; - } - - buffer[bytes] = 0; - if (crlf != 0) - { - char *b = strchr (buffer, '\n'); - if (b != NULL) - { - strcpy (b, "\r\n"); - bytes++; - } - } - - keyboard_bytes = bytes; - keyboard_buffer_ptr = buffer; - -inline_command_processing: - - if (inline_commands) - { - keyboard_bytes = do_inline_command_processing ( - keyboard_buffer_ptr, keyboard_bytes, - &hd, &inline_cmds); - if (keyboard_bytes == 0) - continue; - else if (keyboard_bytes < 0) - { /* error processing an inline command */ - retval = 1; - break; - } - else - { - /* current_ptr could point to either an inline_cmd_buffer - * or may point to start or an offset into buffer. - */ - keyboard_buffer_ptr = inline_cmds.current_ptr; - } - } - - if (ranges && gnutls_record_can_use_length_hiding(hd.session)) - { - gnutls_range_st range; - range.low = 0; - range.high = MAX_BUF; - ret = socket_send_range (&hd, keyboard_buffer_ptr, keyboard_bytes, &range); - } - else - { - ret = socket_send(&hd, keyboard_buffer_ptr, keyboard_bytes); - } - - if (ret > 0) - { - if (verbose != 0) - printf ("- Sent: %d bytes\n", ret); - } - else - handle_error (&hd, ret); - - if (inline_commands && - inline_cmds.new_buffer_ptr < (buffer + bytes)) - { - keyboard_buffer_ptr = inline_cmds.new_buffer_ptr; - keyboard_bytes = (buffer + bytes) - keyboard_buffer_ptr; - goto inline_command_processing; - } - } - } - - if (user_term != 0) - socket_bye (&hd); - else - gnutls_deinit (hd.session); + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + if (inline_commands) { + memset(&inline_cmds, 0, sizeof(inline_cmds_st)); + inline_cmds.lf_found = true; /* initially, at start of line */ + } + + for (;;) { + if (starttls_alarmed && !hd.secure) { + /* Warning! Do not touch this text string, it is used by + external programs to search for when gnutls-cli has + reached this point. */ + fprintf(stderr, "*** Starting TLS handshake\n"); + ret = do_handshake(&hd); + if (ret < 0) { + fprintf(stderr, + "*** Handshake has failed\n"); + user_term = 1; + retval = 1; + break; + } + } + + inp = check_net_or_keyboard_input(&hd); + + if (inp == IN_NET) { + memset(buffer, 0, MAX_BUF + 1); + ret = socket_recv(&hd, buffer, MAX_BUF); + + if (ret == 0) { + printf + ("- Peer has closed the GnuTLS connection\n"); + break; + } else if (handle_error(&hd, ret) < 0 + && user_term == 0) { + fprintf(stderr, + "*** Server has terminated the connection abnormally.\n"); + retval = 1; + break; + } else if (ret > 0) { + if (verbose != 0) + printf("- Received[%d]: ", ret); + for (ii = 0; ii < ret; ii++) { + fputc(buffer[ii], stdout); + } + fflush(stdout); + } + + if (user_term != 0) + break; + } + + if (inp == IN_KEYBOARD) { + if ((bytes = + read(fileno(stdin), buffer, + MAX_BUF - 1)) <= 0) { + if (hd.secure == 0) { + /* Warning! Do not touch this text string, it is + used by external programs to search for when + gnutls-cli has reached this point. */ + fprintf(stderr, + "*** Starting TLS handshake\n"); + ret = do_handshake(&hd); + clearerr(stdin); + if (ret < 0) { + fprintf(stderr, + "*** Handshake has failed\n"); + user_term = 1; + retval = 1; + break; + } + } else { + user_term = 1; + break; + } + continue; + } + + buffer[bytes] = 0; + if (crlf != 0) { + char *b = strchr(buffer, '\n'); + if (b != NULL) { + strcpy(b, "\r\n"); + bytes++; + } + } + + keyboard_bytes = bytes; + keyboard_buffer_ptr = buffer; + + inline_command_processing: + + if (inline_commands) { + keyboard_bytes = + do_inline_command_processing + (keyboard_buffer_ptr, keyboard_bytes, + &hd, &inline_cmds); + if (keyboard_bytes == 0) + continue; + else if (keyboard_bytes < 0) { /* error processing an inline command */ + retval = 1; + break; + } else { + /* current_ptr could point to either an inline_cmd_buffer + * or may point to start or an offset into buffer. + */ + keyboard_buffer_ptr = + inline_cmds.current_ptr; + } + } + + if (ranges + && gnutls_record_can_use_length_hiding(hd. + session)) + { + gnutls_range_st range; + range.low = 0; + range.high = MAX_BUF; + ret = + socket_send_range(&hd, + keyboard_buffer_ptr, + keyboard_bytes, + &range); + } else { + ret = + socket_send(&hd, keyboard_buffer_ptr, + keyboard_bytes); + } + + if (ret > 0) { + if (verbose != 0) + printf("- Sent: %d bytes\n", ret); + } else + handle_error(&hd, ret); + + if (inline_commands && + inline_cmds.new_buffer_ptr < (buffer + bytes)) + { + keyboard_buffer_ptr = + inline_cmds.new_buffer_ptr; + keyboard_bytes = + (buffer + bytes) - keyboard_buffer_ptr; + goto inline_command_processing; + } + } + } + + if (user_term != 0) + socket_bye(&hd); + else + gnutls_deinit(hd.session); #ifdef ENABLE_SRP - if (srp_cred) - gnutls_srp_free_client_credentials (srp_cred); + if (srp_cred) + gnutls_srp_free_client_credentials(srp_cred); #endif #ifdef ENABLE_PSK - if (psk_cred) - gnutls_psk_free_client_credentials (psk_cred); + if (psk_cred) + gnutls_psk_free_client_credentials(psk_cred); #endif - gnutls_certificate_free_credentials (xcred); + gnutls_certificate_free_credentials(xcred); #ifdef ENABLE_ANON - gnutls_anon_free_client_credentials (anon_cred); + gnutls_anon_free_client_credentials(anon_cred); #endif - gnutls_global_deinit (); + gnutls_global_deinit(); - return retval; + return retval; } -static void -cmd_parser (int argc, char **argv) +static void cmd_parser(int argc, char **argv) { -const char* rest = NULL; - - int optct = optionProcess( &gnutls_cliOptions, argc, argv); - argc -= optct; - argv += optct; - - if (rest == NULL && argc > 0) - rest = argv[0]; - - if (HAVE_OPT(BENCHMARK_CIPHERS)) - { - benchmark_cipher(1, OPT_VALUE_DEBUG); - exit(0); - } - - if (HAVE_OPT(BENCHMARK_SOFT_CIPHERS)) - { - benchmark_cipher(0, OPT_VALUE_DEBUG); - exit(0); - } - - if (HAVE_OPT(BENCHMARK_TLS_CIPHERS)) - { - benchmark_tls(OPT_VALUE_DEBUG, 1); - exit(0); - } - - if (HAVE_OPT(BENCHMARK_TLS_KX)) - { - benchmark_tls(OPT_VALUE_DEBUG, 0); - exit(0); - } - - if (HAVE_OPT(PRIORITY)) - { - priorities = OPT_ARG(PRIORITY); - } - verbose = HAVE_OPT( VERBOSE); - if (verbose) - print_cert = 1; - else - print_cert = HAVE_OPT( PRINT_CERT); - - if (HAVE_OPT(LIST)) - { - print_list(priorities, verbose); - exit(0); - } - - disable_sni = HAVE_OPT(DISABLE_SNI); - disable_extensions = HAVE_OPT( DISABLE_EXTENSIONS); - if (disable_extensions) - init_flags |= GNUTLS_NO_EXTENSIONS; - - inline_commands = HAVE_OPT(INLINE_COMMANDS); - if (HAVE_OPT(INLINE_COMMANDS_PREFIX)) - { - if (strlen(OPT_ARG(INLINE_COMMANDS_PREFIX)) > 1) - { - fprintf(stderr, "inline-commands-prefix value is a single US-ASCII character (octets 0 - 127)\n"); - exit(1); - } - inline_commands_prefix = (char *) OPT_ARG(INLINE_COMMANDS_PREFIX); - if (!isascii(inline_commands_prefix[0])) - { - fprintf(stderr, "inline-commands-prefix value is a single US-ASCII character (octets 0 - 127)\n"); - exit(1); - } - } - else - inline_commands_prefix = "^"; - - starttls = HAVE_OPT(STARTTLS); - resume = HAVE_OPT(RESUME); - rehandshake = HAVE_OPT(REHANDSHAKE); - insecure = HAVE_OPT(INSECURE); - ranges = HAVE_OPT(RANGES); - - udp = HAVE_OPT(UDP); - mtu = OPT_VALUE_MTU; - - if (HAVE_OPT(PORT)) - { - service = OPT_ARG(PORT); - } - else - { - service = "443"; - } - - record_max_size = OPT_VALUE_RECORDSIZE; - - fingerprint = HAVE_OPT(FINGERPRINT); - - if (HAVE_OPT(X509FMTDER)) - x509ctype = GNUTLS_X509_FMT_DER; - else - x509ctype = GNUTLS_X509_FMT_PEM; - - if (HAVE_OPT(SRPUSERNAME)) - srp_username = OPT_ARG(SRPUSERNAME); - - if (HAVE_OPT(SRPPASSWD)) - srp_passwd = OPT_ARG(SRPPASSWD); - - if (HAVE_OPT(X509CAFILE)) - x509_cafile = OPT_ARG(X509CAFILE); - - if (HAVE_OPT(X509CRLFILE)) - x509_crlfile = OPT_ARG(X509CRLFILE); - - if (HAVE_OPT(X509KEYFILE)) - x509_keyfile = OPT_ARG(X509KEYFILE); - - if (HAVE_OPT(X509CERTFILE)) - x509_certfile = OPT_ARG(X509CERTFILE); - - if (HAVE_OPT(PGPKEYFILE)) - pgp_keyfile = OPT_ARG(PGPKEYFILE); - - if (HAVE_OPT(PGPCERTFILE)) - pgp_certfile = OPT_ARG(PGPCERTFILE); - - if (HAVE_OPT(PSKUSERNAME)) - psk_username = OPT_ARG(PSKUSERNAME); - - if (HAVE_OPT(PSKKEY)) - { - psk_key.data = (unsigned char *) OPT_ARG(PSKKEY); - psk_key.size = strlen (OPT_ARG(PSKKEY)); - } - else - psk_key.size = 0; - - if (HAVE_OPT(PGPKEYRING)) - pgp_keyring = OPT_ARG(PGPKEYRING); - - crlf = HAVE_OPT(CRLF); - - if (rest != NULL) - hostname = rest; - - if (hostname == NULL) - { - fprintf(stderr, "No hostname specified\n"); - exit(1); - } + const char *rest = NULL; + + int optct = optionProcess(&gnutls_cliOptions, argc, argv); + argc -= optct; + argv += optct; + + if (rest == NULL && argc > 0) + rest = argv[0]; + + if (HAVE_OPT(BENCHMARK_CIPHERS)) { + benchmark_cipher(1, OPT_VALUE_DEBUG); + exit(0); + } + + if (HAVE_OPT(BENCHMARK_SOFT_CIPHERS)) { + benchmark_cipher(0, OPT_VALUE_DEBUG); + exit(0); + } + + if (HAVE_OPT(BENCHMARK_TLS_CIPHERS)) { + benchmark_tls(OPT_VALUE_DEBUG, 1); + exit(0); + } + + if (HAVE_OPT(BENCHMARK_TLS_KX)) { + benchmark_tls(OPT_VALUE_DEBUG, 0); + exit(0); + } + + if (HAVE_OPT(PRIORITY)) { + priorities = OPT_ARG(PRIORITY); + } + verbose = HAVE_OPT(VERBOSE); + if (verbose) + print_cert = 1; + else + print_cert = HAVE_OPT(PRINT_CERT); + + if (HAVE_OPT(LIST)) { + print_list(priorities, verbose); + exit(0); + } + + disable_sni = HAVE_OPT(DISABLE_SNI); + disable_extensions = HAVE_OPT(DISABLE_EXTENSIONS); + if (disable_extensions) + init_flags |= GNUTLS_NO_EXTENSIONS; + + inline_commands = HAVE_OPT(INLINE_COMMANDS); + if (HAVE_OPT(INLINE_COMMANDS_PREFIX)) { + if (strlen(OPT_ARG(INLINE_COMMANDS_PREFIX)) > 1) { + fprintf(stderr, + "inline-commands-prefix value is a single US-ASCII character (octets 0 - 127)\n"); + exit(1); + } + inline_commands_prefix = + (char *) OPT_ARG(INLINE_COMMANDS_PREFIX); + if (!isascii(inline_commands_prefix[0])) { + fprintf(stderr, + "inline-commands-prefix value is a single US-ASCII character (octets 0 - 127)\n"); + exit(1); + } + } else + inline_commands_prefix = "^"; + + starttls = HAVE_OPT(STARTTLS); + resume = HAVE_OPT(RESUME); + rehandshake = HAVE_OPT(REHANDSHAKE); + insecure = HAVE_OPT(INSECURE); + ranges = HAVE_OPT(RANGES); + + udp = HAVE_OPT(UDP); + mtu = OPT_VALUE_MTU; + + if (HAVE_OPT(PORT)) { + service = OPT_ARG(PORT); + } else { + service = "443"; + } + + record_max_size = OPT_VALUE_RECORDSIZE; + + fingerprint = HAVE_OPT(FINGERPRINT); + + if (HAVE_OPT(X509FMTDER)) + x509ctype = GNUTLS_X509_FMT_DER; + else + x509ctype = GNUTLS_X509_FMT_PEM; + + if (HAVE_OPT(SRPUSERNAME)) + srp_username = OPT_ARG(SRPUSERNAME); + + if (HAVE_OPT(SRPPASSWD)) + srp_passwd = OPT_ARG(SRPPASSWD); + + if (HAVE_OPT(X509CAFILE)) + x509_cafile = OPT_ARG(X509CAFILE); + + if (HAVE_OPT(X509CRLFILE)) + x509_crlfile = OPT_ARG(X509CRLFILE); + + if (HAVE_OPT(X509KEYFILE)) + x509_keyfile = OPT_ARG(X509KEYFILE); + + if (HAVE_OPT(X509CERTFILE)) + x509_certfile = OPT_ARG(X509CERTFILE); + + if (HAVE_OPT(PGPKEYFILE)) + pgp_keyfile = OPT_ARG(PGPKEYFILE); + + if (HAVE_OPT(PGPCERTFILE)) + pgp_certfile = OPT_ARG(PGPCERTFILE); + + if (HAVE_OPT(PSKUSERNAME)) + psk_username = OPT_ARG(PSKUSERNAME); + + if (HAVE_OPT(PSKKEY)) { + psk_key.data = (unsigned char *) OPT_ARG(PSKKEY); + psk_key.size = strlen(OPT_ARG(PSKKEY)); + } else + psk_key.size = 0; + + if (HAVE_OPT(PGPKEYRING)) + pgp_keyring = OPT_ARG(PGPKEYRING); + + crlf = HAVE_OPT(CRLF); + + if (rest != NULL) + hostname = rest; + + if (hostname == NULL) { + fprintf(stderr, "No hostname specified\n"); + exit(1); + } } -static void -check_rehandshake (socket_st * socket, int ret) +static void check_rehandshake(socket_st * socket, int ret) { - if (socket->secure && ret == GNUTLS_E_REHANDSHAKE) - { - /* There is a race condition here. If application - * data is sent after the rehandshake request, - * the server thinks we ignored his request. - * This is a bad design of this client. - */ - printf ("*** Received rehandshake request\n"); - /* gnutls_alert_send( session, GNUTLS_AL_WARNING, GNUTLS_A_NO_RENEGOTIATION); */ - - ret = do_handshake (socket); - - if (ret == 0) - { - printf ("*** Rehandshake was performed.\n"); - } - else - { - printf ("*** Rehandshake Failed.\n"); - } - } + if (socket->secure && ret == GNUTLS_E_REHANDSHAKE) { + /* There is a race condition here. If application + * data is sent after the rehandshake request, + * the server thinks we ignored his request. + * This is a bad design of this client. + */ + printf("*** Received rehandshake request\n"); + /* gnutls_alert_send( session, GNUTLS_AL_WARNING, GNUTLS_A_NO_RENEGOTIATION); */ + + ret = do_handshake(socket); + + if (ret == 0) { + printf("*** Rehandshake was performed.\n"); + } else { + printf("*** Rehandshake Failed.\n"); + } + } } -static int -do_handshake (socket_st * socket) +static int do_handshake(socket_st * socket) { - int ret; - - gnutls_transport_set_int (socket->session, socket->fd); - do - { - gnutls_handshake_set_timeout( socket->session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); - ret = gnutls_handshake (socket->session); - - if (ret < 0) - { - handle_error (socket, ret); - } - } - while (ret < 0 && gnutls_error_is_fatal (ret) == 0); - - if (ret == 0) - { - /* print some information */ - print_info (socket->session, verbose, 0); - socket->secure = 1; - } - else - { - gnutls_alert_send_appropriate (socket->session, ret); - shutdown (socket->fd, SHUT_RDWR); - } - return ret; + int ret; + + gnutls_transport_set_int(socket->session, socket->fd); + do { + gnutls_handshake_set_timeout(socket->session, + GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); + ret = gnutls_handshake(socket->session); + + if (ret < 0) { + handle_error(socket, ret); + } + } + while (ret < 0 && gnutls_error_is_fatal(ret) == 0); + + if (ret == 0) { + /* print some information */ + print_info(socket->session, verbose, 0); + socket->secure = 1; + } else { + gnutls_alert_send_appropriate(socket->session, ret); + shutdown(socket->fd, SHUT_RDWR); + } + return ret; } static int -srp_username_callback (gnutls_session_t session, - char **username, char **password) +srp_username_callback(gnutls_session_t session, + char **username, char **password) { - if (srp_username == NULL || srp_passwd == NULL) - { - return -1; - } + if (srp_username == NULL || srp_passwd == NULL) { + return -1; + } - *username = gnutls_strdup (srp_username); - *password = gnutls_strdup (srp_passwd); + *username = gnutls_strdup(srp_username); + *password = gnutls_strdup(srp_passwd); - return 0; + return 0; } static int -psk_callback (gnutls_session_t session, char **username, gnutls_datum_t * key) +psk_callback(gnutls_session_t session, char **username, + gnutls_datum_t * key) { - const char *hint = gnutls_psk_client_get_hint (session); - char *rawkey; - char *passwd; - int ret; - size_t res_size; - gnutls_datum_t tmp; - - printf ("- PSK client callback. "); - if (hint) - printf ("PSK hint '%s'\n", hint); - else - printf ("No PSK hint\n"); - - if (HAVE_OPT(PSKUSERNAME)) - *username = gnutls_strdup (OPT_ARG(PSKUSERNAME)); - else - { - char *tmp = NULL; - size_t n; - - printf ("Enter PSK identity: "); - fflush (stdout); - getline (&tmp, &n, stdin); - - if (tmp == NULL) - { - fprintf (stderr, "No username given, aborting...\n"); - return GNUTLS_E_INSUFFICIENT_CREDENTIALS; - } - - if (tmp[strlen (tmp) - 1] == '\n') - tmp[strlen (tmp) - 1] = '\0'; - if (tmp[strlen (tmp) - 1] == '\r') - tmp[strlen (tmp) - 1] = '\0'; - - *username = gnutls_strdup (tmp); - free (tmp); - } - if (!*username) - return GNUTLS_E_MEMORY_ERROR; - - passwd = getpass ("Enter key: "); - if (passwd == NULL) - { - fprintf (stderr, "No key given, aborting...\n"); - return GNUTLS_E_INSUFFICIENT_CREDENTIALS; - } - - tmp.data = (void*)passwd; - tmp.size = strlen (passwd); - - res_size = tmp.size / 2 + 1; - rawkey = gnutls_malloc (res_size); - if (rawkey == NULL) - return GNUTLS_E_MEMORY_ERROR; - - ret = gnutls_hex_decode (&tmp, rawkey, &res_size); - if (ret < 0) - { - fprintf (stderr, "Error deriving password: %s\n", - gnutls_strerror (ret)); - gnutls_free (*username); - return ret; - } - - key->data = (void*)rawkey; - key->size = res_size; - - if (HAVE_OPT(DEBUG)) - { - char hexkey[41]; - res_size = sizeof (hexkey); - gnutls_hex_encode (key, hexkey, &res_size); - fprintf (stderr, "PSK username: %s\n", *username); - fprintf (stderr, "PSK hint: %s\n", hint); - fprintf (stderr, "PSK key: %s\n", hexkey); - } - - return 0; + const char *hint = gnutls_psk_client_get_hint(session); + char *rawkey; + char *passwd; + int ret; + size_t res_size; + gnutls_datum_t tmp; + + printf("- PSK client callback. "); + if (hint) + printf("PSK hint '%s'\n", hint); + else + printf("No PSK hint\n"); + + if (HAVE_OPT(PSKUSERNAME)) + *username = gnutls_strdup(OPT_ARG(PSKUSERNAME)); + else { + char *tmp = NULL; + size_t n; + + printf("Enter PSK identity: "); + fflush(stdout); + getline(&tmp, &n, stdin); + + if (tmp == NULL) { + fprintf(stderr, + "No username given, aborting...\n"); + return GNUTLS_E_INSUFFICIENT_CREDENTIALS; + } + + if (tmp[strlen(tmp) - 1] == '\n') + tmp[strlen(tmp) - 1] = '\0'; + if (tmp[strlen(tmp) - 1] == '\r') + tmp[strlen(tmp) - 1] = '\0'; + + *username = gnutls_strdup(tmp); + free(tmp); + } + if (!*username) + return GNUTLS_E_MEMORY_ERROR; + + passwd = getpass("Enter key: "); + if (passwd == NULL) { + fprintf(stderr, "No key given, aborting...\n"); + return GNUTLS_E_INSUFFICIENT_CREDENTIALS; + } + + tmp.data = (void *) passwd; + tmp.size = strlen(passwd); + + res_size = tmp.size / 2 + 1; + rawkey = gnutls_malloc(res_size); + if (rawkey == NULL) + return GNUTLS_E_MEMORY_ERROR; + + ret = gnutls_hex_decode(&tmp, rawkey, &res_size); + if (ret < 0) { + fprintf(stderr, "Error deriving password: %s\n", + gnutls_strerror(ret)); + gnutls_free(*username); + return ret; + } + + key->data = (void *) rawkey; + key->size = res_size; + + if (HAVE_OPT(DEBUG)) { + char hexkey[41]; + res_size = sizeof(hexkey); + gnutls_hex_encode(key, hexkey, &res_size); + fprintf(stderr, "PSK username: %s\n", *username); + fprintf(stderr, "PSK hint: %s\n", hint); + fprintf(stderr, "PSK key: %s\n", hexkey); + } + + return 0; } -static void -init_global_tls_stuff (void) +static void init_global_tls_stuff(void) { - int ret; - - /* X509 stuff */ - if (gnutls_certificate_allocate_credentials (&xcred) < 0) - { - fprintf (stderr, "Certificate allocation memory error\n"); - exit (1); - } - gnutls_certificate_set_pin_function(xcred, pin_callback, NULL); - - if (x509_cafile != NULL) - { - ret = gnutls_certificate_set_x509_trust_file (xcred, - x509_cafile, x509ctype); - } - else - { - ret = gnutls_certificate_set_x509_system_trust (xcred); - } - if (ret < 0) - { - fprintf (stderr, "Error setting the x509 trust file\n"); - } - else - { - printf ("Processed %d CA certificate(s).\n", ret); - } - - if (x509_crlfile != NULL) - { - ret = gnutls_certificate_set_x509_crl_file (xcred, x509_crlfile, - x509ctype); - if (ret < 0) - { - fprintf (stderr, "Error setting the x509 CRL file\n"); - } - else - { - printf ("Processed %d CRL(s).\n", ret); - } - } - - load_keys (); + int ret; + + /* X509 stuff */ + if (gnutls_certificate_allocate_credentials(&xcred) < 0) { + fprintf(stderr, "Certificate allocation memory error\n"); + exit(1); + } + gnutls_certificate_set_pin_function(xcred, pin_callback, NULL); + + if (x509_cafile != NULL) { + ret = gnutls_certificate_set_x509_trust_file(xcred, + x509_cafile, + x509ctype); + } else { + ret = gnutls_certificate_set_x509_system_trust(xcred); + } + if (ret < 0) { + fprintf(stderr, "Error setting the x509 trust file\n"); + } else { + printf("Processed %d CA certificate(s).\n", ret); + } + + if (x509_crlfile != NULL) { + ret = + gnutls_certificate_set_x509_crl_file(xcred, + x509_crlfile, + x509ctype); + if (ret < 0) { + fprintf(stderr, + "Error setting the x509 CRL file\n"); + } else { + printf("Processed %d CRL(s).\n", ret); + } + } + + load_keys(); #ifdef ENABLE_OPENPGP - if (pgp_keyring != NULL) - { - ret = - gnutls_certificate_set_openpgp_keyring_file (xcred, pgp_keyring, - GNUTLS_OPENPGP_FMT_BASE64); - if (ret < 0) - { - fprintf (stderr, "Error setting the OpenPGP keyring file\n"); - } - } + if (pgp_keyring != NULL) { + ret = + gnutls_certificate_set_openpgp_keyring_file(xcred, + pgp_keyring, + GNUTLS_OPENPGP_FMT_BASE64); + if (ret < 0) { + fprintf(stderr, + "Error setting the OpenPGP keyring file\n"); + } + } #endif #ifdef ENABLE_SRP - if (srp_username && srp_passwd) - { - /* SRP stuff */ - if (gnutls_srp_allocate_client_credentials (&srp_cred) < 0) - { - fprintf (stderr, "SRP authentication error\n"); - } - - gnutls_srp_set_client_credentials_function (srp_cred, - srp_username_callback); - } + if (srp_username && srp_passwd) { + /* SRP stuff */ + if (gnutls_srp_allocate_client_credentials(&srp_cred) < 0) { + fprintf(stderr, "SRP authentication error\n"); + } + + gnutls_srp_set_client_credentials_function(srp_cred, + srp_username_callback); + } #endif #ifdef ENABLE_PSK - /* PSK stuff */ - if (gnutls_psk_allocate_client_credentials (&psk_cred) < 0) - { - fprintf (stderr, "PSK authentication error\n"); - } - - if (psk_username && psk_key.data) - { - ret = gnutls_psk_set_client_credentials (psk_cred, - psk_username, &psk_key, - GNUTLS_PSK_KEY_HEX); - if (ret < 0) - { - fprintf (stderr, "Error setting the PSK credentials: %s\n", - gnutls_strerror (ret)); - } - } - else - gnutls_psk_set_client_credentials_function (psk_cred, psk_callback); + /* PSK stuff */ + if (gnutls_psk_allocate_client_credentials(&psk_cred) < 0) { + fprintf(stderr, "PSK authentication error\n"); + } + + if (psk_username && psk_key.data) { + ret = gnutls_psk_set_client_credentials(psk_cred, + psk_username, + &psk_key, + GNUTLS_PSK_KEY_HEX); + if (ret < 0) { + fprintf(stderr, + "Error setting the PSK credentials: %s\n", + gnutls_strerror(ret)); + } + } else + gnutls_psk_set_client_credentials_function(psk_cred, + psk_callback); #endif #ifdef ENABLE_ANON - /* ANON stuff */ - if (gnutls_anon_allocate_client_credentials (&anon_cred) < 0) - { - fprintf (stderr, "Anonymous authentication error\n"); - } + /* ANON stuff */ + if (gnutls_anon_allocate_client_credentials(&anon_cred) < 0) { + fprintf(stderr, "Anonymous authentication error\n"); + } #endif } @@ -1755,69 +1701,63 @@ init_global_tls_stuff (void) * 1: certificate is ok * -1: dunno */ -static int -cert_verify_ocsp (gnutls_session_t session) +static int cert_verify_ocsp(gnutls_session_t session) { - gnutls_x509_crt_t crt, issuer; - const gnutls_datum_t *cert_list; - unsigned int cert_list_size = 0; - int deinit_issuer = 0; - gnutls_datum_t resp; - int ret; - - cert_list = gnutls_certificate_get_peers (session, &cert_list_size); - if (cert_list_size == 0) - { - fprintf (stderr, "No certificates found!\n"); - return -1; - } - - gnutls_x509_crt_init (&crt); - ret = - gnutls_x509_crt_import (crt, &cert_list[0], - GNUTLS_X509_FMT_DER); - if (ret < 0) - { - fprintf (stderr, "Decoding error: %s\n", - gnutls_strerror (ret)); - return -1; - } - - ret = gnutls_certificate_get_issuer(xcred, crt, &issuer, 0); - if (ret < 0 && cert_list_size > 1) - { - gnutls_x509_crt_init(&issuer); - ret = gnutls_x509_crt_import(issuer, &cert_list[1], GNUTLS_X509_FMT_DER); - if (ret < 0) - { - fprintf (stderr, "Decoding error: %s\n", - gnutls_strerror (ret)); - return -1; - } - deinit_issuer = 1; - } - else if (ret < 0) - { - fprintf(stderr, "Cannot find issuer\n"); - ret = -1; - goto cleanup; - } - - ret = send_ocsp_request(NULL, crt, issuer, &resp, 1); - if (ret < 0) - { - fprintf(stderr, "Cannot contact OCSP server\n"); - ret = -1; - goto cleanup; - } - - /* verify and check the response for revoked cert */ - ret = check_ocsp_response(crt, issuer, &resp); - -cleanup: - if (deinit_issuer) - gnutls_x509_crt_deinit (issuer); - gnutls_x509_crt_deinit (crt); - - return ret; + gnutls_x509_crt_t crt, issuer; + const gnutls_datum_t *cert_list; + unsigned int cert_list_size = 0; + int deinit_issuer = 0; + gnutls_datum_t resp; + int ret; + + cert_list = gnutls_certificate_get_peers(session, &cert_list_size); + if (cert_list_size == 0) { + fprintf(stderr, "No certificates found!\n"); + return -1; + } + + gnutls_x509_crt_init(&crt); + ret = + gnutls_x509_crt_import(crt, &cert_list[0], + GNUTLS_X509_FMT_DER); + if (ret < 0) { + fprintf(stderr, "Decoding error: %s\n", + gnutls_strerror(ret)); + return -1; + } + + ret = gnutls_certificate_get_issuer(xcred, crt, &issuer, 0); + if (ret < 0 && cert_list_size > 1) { + gnutls_x509_crt_init(&issuer); + ret = + gnutls_x509_crt_import(issuer, &cert_list[1], + GNUTLS_X509_FMT_DER); + if (ret < 0) { + fprintf(stderr, "Decoding error: %s\n", + gnutls_strerror(ret)); + return -1; + } + deinit_issuer = 1; + } else if (ret < 0) { + fprintf(stderr, "Cannot find issuer\n"); + ret = -1; + goto cleanup; + } + + ret = send_ocsp_request(NULL, crt, issuer, &resp, 1); + if (ret < 0) { + fprintf(stderr, "Cannot contact OCSP server\n"); + ret = -1; + goto cleanup; + } + + /* verify and check the response for revoked cert */ + ret = check_ocsp_response(crt, issuer, &resp); + + cleanup: + if (deinit_issuer) + gnutls_x509_crt_deinit(issuer); + gnutls_x509_crt_deinit(crt); + + return ret; } diff --git a/src/common.c b/src/common.c index e3e614864e..75728985d7 100644 --- a/src/common.c +++ b/src/common.c @@ -39,7 +39,7 @@ #include <common.h> #ifdef ENABLE_PKCS11 -# include <gnutls/pkcs11.h> +#include <gnutls/pkcs11.h> #endif #define SU(x) (x!=NULL?x:"Unknown") @@ -48,1054 +48,1017 @@ const char str_unknown[] = "(unknown)"; /* Hex encodes the given data. */ -const char * -raw_to_string (const unsigned char *raw, size_t raw_size) +const char *raw_to_string(const unsigned char *raw, size_t raw_size) { - static char buf[1024]; - size_t i; - if (raw_size == 0) - return "(empty)"; - - if (raw_size * 3 + 1 >= sizeof (buf)) - return "(too large)"; - - for (i = 0; i < raw_size; i++) - { - sprintf (&(buf[i * 3]), "%02X%s", raw[i], - (i == raw_size - 1) ? "" : ":"); - } - buf[sizeof (buf) - 1] = '\0'; - - return buf; + static char buf[1024]; + size_t i; + if (raw_size == 0) + return "(empty)"; + + if (raw_size * 3 + 1 >= sizeof(buf)) + return "(too large)"; + + for (i = 0; i < raw_size; i++) { + sprintf(&(buf[i * 3]), "%02X%s", raw[i], + (i == raw_size - 1) ? "" : ":"); + } + buf[sizeof(buf) - 1] = '\0'; + + return buf; } -static void -print_x509_info_compact (gnutls_session_t session) +static void print_x509_info_compact(gnutls_session_t session) { - gnutls_x509_crt_t crt; - const gnutls_datum_t *cert_list; - unsigned int cert_list_size = 0; - int ret; - gnutls_datum_t cinfo; - - cert_list = gnutls_certificate_get_peers (session, &cert_list_size); - if (cert_list_size == 0) - { - fprintf (stderr, "No certificates found!\n"); - return; - } - - gnutls_x509_crt_init (&crt); - ret = - gnutls_x509_crt_import (crt, &cert_list[0], - GNUTLS_X509_FMT_DER); - if (ret < 0) - { - fprintf (stderr, "Decoding error: %s\n", - gnutls_strerror (ret)); - return; - } - - ret = - gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_COMPACT, &cinfo); - if (ret == 0) - { - printf ("- X.509 cert: %s\n", cinfo.data); - gnutls_free (cinfo.data); - } - - gnutls_x509_crt_deinit (crt); + gnutls_x509_crt_t crt; + const gnutls_datum_t *cert_list; + unsigned int cert_list_size = 0; + int ret; + gnutls_datum_t cinfo; + + cert_list = gnutls_certificate_get_peers(session, &cert_list_size); + if (cert_list_size == 0) { + fprintf(stderr, "No certificates found!\n"); + return; + } + + gnutls_x509_crt_init(&crt); + ret = + gnutls_x509_crt_import(crt, &cert_list[0], + GNUTLS_X509_FMT_DER); + if (ret < 0) { + fprintf(stderr, "Decoding error: %s\n", + gnutls_strerror(ret)); + return; + } + + ret = gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_COMPACT, &cinfo); + if (ret == 0) { + printf("- X.509 cert: %s\n", cinfo.data); + gnutls_free(cinfo.data); + } + + gnutls_x509_crt_deinit(crt); } static void -print_x509_info (gnutls_session_t session, int flag, int print_cert) +print_x509_info(gnutls_session_t session, int flag, int print_cert) { - gnutls_x509_crt_t crt; - const gnutls_datum_t *cert_list; - unsigned int cert_list_size = 0, j; - int ret; - - cert_list = gnutls_certificate_get_peers (session, &cert_list_size); - if (cert_list_size == 0) - { - fprintf (stderr, "No certificates found!\n"); - return; - } - - printf ("- Certificate type: X.509\n"); - printf ("- Got a certificate list of %d certificates.\n", - cert_list_size); - - for (j = 0; j < cert_list_size; j++) - { - gnutls_datum_t cinfo; - - gnutls_x509_crt_init (&crt); - ret = - gnutls_x509_crt_import (crt, &cert_list[j], - GNUTLS_X509_FMT_DER); - if (ret < 0) - { - fprintf (stderr, "Decoding error: %s\n", - gnutls_strerror (ret)); - return; - } - - printf ("- Certificate[%d] info:\n - ", j); - if (flag == GNUTLS_CRT_PRINT_COMPACT && j > 0) flag = GNUTLS_CRT_PRINT_ONELINE; - - ret = - gnutls_x509_crt_print (crt, flag, &cinfo); - if (ret == 0) - { - printf ("%s\n", cinfo.data); - gnutls_free (cinfo.data); - } - - if (print_cert) - { - size_t size = 0; - char *p = NULL; - - ret = - gnutls_x509_crt_export (crt, GNUTLS_X509_FMT_PEM, p, - &size); - if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) - { - p = malloc (size+1); - if (!p) - { - fprintf (stderr, "gnutls_malloc\n"); - exit (1); - } - - ret = - gnutls_x509_crt_export (crt, GNUTLS_X509_FMT_PEM, - p, &size); - } - if (ret < 0) - { - fprintf (stderr, "Encoding error: %s\n", - gnutls_strerror (ret)); - return; - } - - p[size] = 0; - fputs ("\n", stdout); - fputs (p, stdout); - fputs ("\n", stdout); - - gnutls_free (p); - } - - gnutls_x509_crt_deinit (crt); - } + gnutls_x509_crt_t crt; + const gnutls_datum_t *cert_list; + unsigned int cert_list_size = 0, j; + int ret; + + cert_list = gnutls_certificate_get_peers(session, &cert_list_size); + if (cert_list_size == 0) { + fprintf(stderr, "No certificates found!\n"); + return; + } + + printf("- Certificate type: X.509\n"); + printf("- Got a certificate list of %d certificates.\n", + cert_list_size); + + for (j = 0; j < cert_list_size; j++) { + gnutls_datum_t cinfo; + + gnutls_x509_crt_init(&crt); + ret = + gnutls_x509_crt_import(crt, &cert_list[j], + GNUTLS_X509_FMT_DER); + if (ret < 0) { + fprintf(stderr, "Decoding error: %s\n", + gnutls_strerror(ret)); + return; + } + + printf("- Certificate[%d] info:\n - ", j); + if (flag == GNUTLS_CRT_PRINT_COMPACT && j > 0) + flag = GNUTLS_CRT_PRINT_ONELINE; + + ret = gnutls_x509_crt_print(crt, flag, &cinfo); + if (ret == 0) { + printf("%s\n", cinfo.data); + gnutls_free(cinfo.data); + } + + if (print_cert) { + size_t size = 0; + char *p = NULL; + + ret = + gnutls_x509_crt_export(crt, + GNUTLS_X509_FMT_PEM, p, + &size); + if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { + p = malloc(size + 1); + if (!p) { + fprintf(stderr, "gnutls_malloc\n"); + exit(1); + } + + ret = + gnutls_x509_crt_export(crt, + GNUTLS_X509_FMT_PEM, + p, &size); + } + if (ret < 0) { + fprintf(stderr, "Encoding error: %s\n", + gnutls_strerror(ret)); + return; + } + + p[size] = 0; + fputs("\n", stdout); + fputs(p, stdout); + fputs("\n", stdout); + + gnutls_free(p); + } + + gnutls_x509_crt_deinit(crt); + } } #ifdef ENABLE_OPENPGP -static void -print_openpgp_info_compact (gnutls_session_t session) +static void print_openpgp_info_compact(gnutls_session_t session) { - gnutls_openpgp_crt_t crt; - const gnutls_datum_t *cert_list; - unsigned int cert_list_size = 0; - int ret; - - cert_list = gnutls_certificate_get_peers (session, &cert_list_size); - - if (cert_list_size > 0) - { - gnutls_datum_t cinfo; - - gnutls_openpgp_crt_init (&crt); - ret = gnutls_openpgp_crt_import (crt, &cert_list[0], - GNUTLS_OPENPGP_FMT_RAW); - if (ret < 0) - { - fprintf (stderr, "Decoding error: %s\n", - gnutls_strerror (ret)); - return; - } - - ret = - gnutls_openpgp_crt_print (crt, GNUTLS_CRT_PRINT_COMPACT, &cinfo); - if (ret == 0) - { - printf ("- OpenPGP cert: %s\n", cinfo.data); - gnutls_free (cinfo.data); - } - - gnutls_openpgp_crt_deinit (crt); - } + gnutls_openpgp_crt_t crt; + const gnutls_datum_t *cert_list; + unsigned int cert_list_size = 0; + int ret; + + cert_list = gnutls_certificate_get_peers(session, &cert_list_size); + + if (cert_list_size > 0) { + gnutls_datum_t cinfo; + + gnutls_openpgp_crt_init(&crt); + ret = gnutls_openpgp_crt_import(crt, &cert_list[0], + GNUTLS_OPENPGP_FMT_RAW); + if (ret < 0) { + fprintf(stderr, "Decoding error: %s\n", + gnutls_strerror(ret)); + return; + } + + ret = + gnutls_openpgp_crt_print(crt, GNUTLS_CRT_PRINT_COMPACT, + &cinfo); + if (ret == 0) { + printf("- OpenPGP cert: %s\n", cinfo.data); + gnutls_free(cinfo.data); + } + + gnutls_openpgp_crt_deinit(crt); + } } static void -print_openpgp_info (gnutls_session_t session, int flag, int print_cert) +print_openpgp_info(gnutls_session_t session, int flag, int print_cert) { - gnutls_openpgp_crt_t crt; - const gnutls_datum_t *cert_list; - unsigned int cert_list_size = 0; - int ret; - - printf ("- Certificate type: OpenPGP\n"); - - cert_list = gnutls_certificate_get_peers (session, &cert_list_size); - - if (cert_list_size > 0) - { - gnutls_datum_t cinfo; - - gnutls_openpgp_crt_init (&crt); - ret = gnutls_openpgp_crt_import (crt, &cert_list[0], - GNUTLS_OPENPGP_FMT_RAW); - if (ret < 0) - { - fprintf (stderr, "Decoding error: %s\n", - gnutls_strerror (ret)); - return; - } - - ret = - gnutls_openpgp_crt_print (crt, flag, &cinfo); - if (ret == 0) - { - printf ("- %s\n", cinfo.data); - gnutls_free (cinfo.data); - } - - if (print_cert) - { - size_t size = 0; - char *p = NULL; - - ret = - gnutls_openpgp_crt_export (crt, - GNUTLS_OPENPGP_FMT_BASE64, - p, &size); - if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) - { - p = malloc (size); - if (!p) - { - fprintf (stderr, "gnutls_malloc\n"); - exit (1); - } - - ret = - gnutls_openpgp_crt_export (crt, - GNUTLS_OPENPGP_FMT_BASE64, - p, &size); - } - if (ret < 0) - { - fprintf (stderr, "Encoding error: %s\n", - gnutls_strerror (ret)); - return; - } - - fputs (p, stdout); - fputs ("\n", stdout); - - gnutls_free (p); - } - - gnutls_openpgp_crt_deinit (crt); - } + gnutls_openpgp_crt_t crt; + const gnutls_datum_t *cert_list; + unsigned int cert_list_size = 0; + int ret; + + printf("- Certificate type: OpenPGP\n"); + + cert_list = gnutls_certificate_get_peers(session, &cert_list_size); + + if (cert_list_size > 0) { + gnutls_datum_t cinfo; + + gnutls_openpgp_crt_init(&crt); + ret = gnutls_openpgp_crt_import(crt, &cert_list[0], + GNUTLS_OPENPGP_FMT_RAW); + if (ret < 0) { + fprintf(stderr, "Decoding error: %s\n", + gnutls_strerror(ret)); + return; + } + + ret = gnutls_openpgp_crt_print(crt, flag, &cinfo); + if (ret == 0) { + printf("- %s\n", cinfo.data); + gnutls_free(cinfo.data); + } + + if (print_cert) { + size_t size = 0; + char *p = NULL; + + ret = + gnutls_openpgp_crt_export(crt, + GNUTLS_OPENPGP_FMT_BASE64, + p, &size); + if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { + p = malloc(size); + if (!p) { + fprintf(stderr, "gnutls_malloc\n"); + exit(1); + } + + ret = + gnutls_openpgp_crt_export(crt, + GNUTLS_OPENPGP_FMT_BASE64, + p, &size); + } + if (ret < 0) { + fprintf(stderr, "Encoding error: %s\n", + gnutls_strerror(ret)); + return; + } + + fputs(p, stdout); + fputs("\n", stdout); + + gnutls_free(p); + } + + gnutls_openpgp_crt_deinit(crt); + } } #endif /* returns false (0) if not verified, or true (1) otherwise */ -int -cert_verify (gnutls_session_t session, const char* hostname) +int cert_verify(gnutls_session_t session, const char *hostname) { - int rc; - unsigned int status = 0; - gnutls_datum_t out; - int type; - - rc = gnutls_certificate_verify_peers3 (session, hostname, &status); - if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND) - { - printf ("- Peer did not send any certificate.\n"); - return 0; - } - - if (rc < 0) - { - printf ("- Could not verify certificate (err: %s)\n", - gnutls_strerror (rc)); - return 0; - } - - type = gnutls_certificate_type_get (session); - rc = gnutls_certificate_verification_status_print( status, type, &out, 0); - if (rc < 0) - { - printf ("- Could not print verification flags (err: %s)\n", - gnutls_strerror (rc)); - return 0; - } - - printf ("- Status: %s\n", out.data); - - gnutls_free(out.data); - - if (status) - return 0; - - return 1; + int rc; + unsigned int status = 0; + gnutls_datum_t out; + int type; + + rc = gnutls_certificate_verify_peers3(session, hostname, &status); + if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND) { + printf("- Peer did not send any certificate.\n"); + return 0; + } + + if (rc < 0) { + printf("- Could not verify certificate (err: %s)\n", + gnutls_strerror(rc)); + return 0; + } + + type = gnutls_certificate_type_get(session); + rc = gnutls_certificate_verification_status_print(status, type, + &out, 0); + if (rc < 0) { + printf("- Could not print verification flags (err: %s)\n", + gnutls_strerror(rc)); + return 0; + } + + printf("- Status: %s\n", out.data); + + gnutls_free(out.data); + + if (status) + return 0; + + return 1; } static void -print_dh_info (gnutls_session_t session, const char *str, int print) +print_dh_info(gnutls_session_t session, const char *str, int print) { - printf ("- %sDiffie-Hellman parameters\n", str); - printf (" - Using prime: %d bits\n", - gnutls_dh_get_prime_bits (session)); - printf (" - Secret key: %d bits\n", - gnutls_dh_get_secret_bits (session)); - printf (" - Peer's public key: %d bits\n", - gnutls_dh_get_peers_public_bits (session)); - - if (print) - { - int ret; - gnutls_datum_t raw_gen = { NULL, 0 }; - gnutls_datum_t raw_prime = { NULL, 0 }; - gnutls_dh_params_t dh_params = NULL; - unsigned char *params_data = NULL; - size_t params_data_size = 0; - - ret = gnutls_dh_get_group (session, &raw_gen, &raw_prime); - if (ret) - { - fprintf (stderr, "gnutls_dh_get_group %d\n", ret); - goto out; - } - - ret = gnutls_dh_params_init (&dh_params); - if (ret) - { - fprintf (stderr, "gnutls_dh_params_init %d\n", ret); - goto out; - } - - ret = - gnutls_dh_params_import_raw (dh_params, &raw_prime, - &raw_gen); - if (ret) - { - fprintf (stderr, "gnutls_dh_params_import_raw %d\n", ret); - goto out; - } - - ret = gnutls_dh_params_export_pkcs3 (dh_params, - GNUTLS_X509_FMT_PEM, - params_data, - ¶ms_data_size); - if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) - { - fprintf (stderr, "gnutls_dh_params_export_pkcs3 %d\n", - ret); - goto out; - } - - params_data = gnutls_malloc (params_data_size); - if (!params_data) - { - fprintf (stderr, "gnutls_malloc %d\n", ret); - goto out; - } - - ret = gnutls_dh_params_export_pkcs3 (dh_params, - GNUTLS_X509_FMT_PEM, - params_data, - ¶ms_data_size); - if (ret) - { - fprintf (stderr, "gnutls_dh_params_export_pkcs3-2 %d\n", - ret); - goto out; - } - - printf (" - PKCS#3 format:\n\n%.*s\n", (int) params_data_size, - params_data); - - out: - gnutls_free (params_data); - gnutls_free (raw_prime.data); - gnutls_free (raw_gen.data); - gnutls_dh_params_deinit (dh_params); - } + printf("- %sDiffie-Hellman parameters\n", str); + printf(" - Using prime: %d bits\n", + gnutls_dh_get_prime_bits(session)); + printf(" - Secret key: %d bits\n", + gnutls_dh_get_secret_bits(session)); + printf(" - Peer's public key: %d bits\n", + gnutls_dh_get_peers_public_bits(session)); + + if (print) { + int ret; + gnutls_datum_t raw_gen = { NULL, 0 }; + gnutls_datum_t raw_prime = { NULL, 0 }; + gnutls_dh_params_t dh_params = NULL; + unsigned char *params_data = NULL; + size_t params_data_size = 0; + + ret = gnutls_dh_get_group(session, &raw_gen, &raw_prime); + if (ret) { + fprintf(stderr, "gnutls_dh_get_group %d\n", ret); + goto out; + } + + ret = gnutls_dh_params_init(&dh_params); + if (ret) { + fprintf(stderr, "gnutls_dh_params_init %d\n", ret); + goto out; + } + + ret = + gnutls_dh_params_import_raw(dh_params, &raw_prime, + &raw_gen); + if (ret) { + fprintf(stderr, "gnutls_dh_params_import_raw %d\n", + ret); + goto out; + } + + ret = gnutls_dh_params_export_pkcs3(dh_params, + GNUTLS_X509_FMT_PEM, + params_data, + ¶ms_data_size); + if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) { + fprintf(stderr, + "gnutls_dh_params_export_pkcs3 %d\n", ret); + goto out; + } + + params_data = gnutls_malloc(params_data_size); + if (!params_data) { + fprintf(stderr, "gnutls_malloc %d\n", ret); + goto out; + } + + ret = gnutls_dh_params_export_pkcs3(dh_params, + GNUTLS_X509_FMT_PEM, + params_data, + ¶ms_data_size); + if (ret) { + fprintf(stderr, + "gnutls_dh_params_export_pkcs3-2 %d\n", + ret); + goto out; + } + + printf(" - PKCS#3 format:\n\n%.*s\n", + (int) params_data_size, params_data); + + out: + gnutls_free(params_data); + gnutls_free(raw_prime.data); + gnutls_free(raw_gen.data); + gnutls_dh_params_deinit(dh_params); + } } -static void -print_ecdh_info (gnutls_session_t session, const char *str) +static void print_ecdh_info(gnutls_session_t session, const char *str) { - int curve; + int curve; - printf ("- %sEC Diffie-Hellman parameters\n", str); + printf("- %sEC Diffie-Hellman parameters\n", str); - curve = gnutls_ecc_curve_get (session); + curve = gnutls_ecc_curve_get(session); - printf (" - Using curve: %s\n", gnutls_ecc_curve_get_name (curve)); - printf (" - Curve size: %d bits\n", - gnutls_ecc_curve_get_size (curve) * 8); + printf(" - Using curve: %s\n", gnutls_ecc_curve_get_name(curve)); + printf(" - Curve size: %d bits\n", + gnutls_ecc_curve_get_size(curve) * 8); } -int -print_info (gnutls_session_t session, int verbose, int print_cert) +int print_info(gnutls_session_t session, int verbose, int print_cert) { - const char *tmp; - gnutls_credentials_type_t cred; - gnutls_kx_algorithm_t kx; - unsigned char session_id[33]; - size_t session_id_size = sizeof (session_id); - gnutls_srtp_profile_t srtp_profile; - gnutls_datum_t p; - char *desc; - int rc; - - desc = gnutls_session_get_desc(session); - printf ("- Description: %s\n", desc); - gnutls_free(desc); - - /* print session ID */ - gnutls_session_get_id (session, session_id, &session_id_size); - printf ("- Session ID: %s\n", - raw_to_string (session_id, session_id_size)); - - /* print the key exchange's algorithm name - */ - kx = gnutls_kx_get (session); - - cred = gnutls_auth_get_type (session); - switch (cred) - { + const char *tmp; + gnutls_credentials_type_t cred; + gnutls_kx_algorithm_t kx; + unsigned char session_id[33]; + size_t session_id_size = sizeof(session_id); + gnutls_srtp_profile_t srtp_profile; + gnutls_datum_t p; + char *desc; + int rc; + + desc = gnutls_session_get_desc(session); + printf("- Description: %s\n", desc); + gnutls_free(desc); + + /* print session ID */ + gnutls_session_get_id(session, session_id, &session_id_size); + printf("- Session ID: %s\n", + raw_to_string(session_id, session_id_size)); + + /* print the key exchange's algorithm name + */ + kx = gnutls_kx_get(session); + + cred = gnutls_auth_get_type(session); + switch (cred) { #ifdef ENABLE_ANON - case GNUTLS_CRD_ANON: - if (kx == GNUTLS_KX_ANON_ECDH) - print_ecdh_info (session, "Anonymous "); - else - print_dh_info (session, "Anonymous ", verbose); - break; + case GNUTLS_CRD_ANON: + if (kx == GNUTLS_KX_ANON_ECDH) + print_ecdh_info(session, "Anonymous "); + else + print_dh_info(session, "Anonymous ", verbose); + break; #endif #ifdef ENABLE_SRP - case GNUTLS_CRD_SRP: - /* This should be only called in server - * side. - */ - if (gnutls_srp_server_get_username (session) != NULL) - printf ("- SRP authentication. Connected as '%s'\n", - gnutls_srp_server_get_username (session)); - break; + case GNUTLS_CRD_SRP: + /* This should be only called in server + * side. + */ + if (gnutls_srp_server_get_username(session) != NULL) + printf("- SRP authentication. Connected as '%s'\n", + gnutls_srp_server_get_username(session)); + break; #endif #ifdef ENABLE_PSK - case GNUTLS_CRD_PSK: - /* This returns NULL in server side. - */ - if (gnutls_psk_client_get_hint (session) != NULL) - printf ("- PSK authentication. PSK hint '%s'\n", - gnutls_psk_client_get_hint (session)); - /* This returns NULL in client side. - */ - if (gnutls_psk_server_get_username (session) != NULL) - printf ("- PSK authentication. Connected as '%s'\n", - gnutls_psk_server_get_username (session)); - if (kx == GNUTLS_KX_DHE_PSK) - print_dh_info (session, "Ephemeral ", verbose); - if (kx == GNUTLS_KX_ECDHE_PSK) - print_ecdh_info (session, "Ephemeral "); - break; + case GNUTLS_CRD_PSK: + /* This returns NULL in server side. + */ + if (gnutls_psk_client_get_hint(session) != NULL) + printf("- PSK authentication. PSK hint '%s'\n", + gnutls_psk_client_get_hint(session)); + /* This returns NULL in client side. + */ + if (gnutls_psk_server_get_username(session) != NULL) + printf("- PSK authentication. Connected as '%s'\n", + gnutls_psk_server_get_username(session)); + if (kx == GNUTLS_KX_DHE_PSK) + print_dh_info(session, "Ephemeral ", verbose); + if (kx == GNUTLS_KX_ECDHE_PSK) + print_ecdh_info(session, "Ephemeral "); + break; #endif - case GNUTLS_CRD_IA: - printf ("- TLS/IA authentication\n"); - break; - case GNUTLS_CRD_CERTIFICATE: - { - char dns[256]; - size_t dns_size = sizeof (dns); - unsigned int type; - - /* This fails in client side */ - if (gnutls_server_name_get - (session, dns, &dns_size, &type, 0) == 0) - { - printf ("- Given server name[%d]: %s\n", type, dns); - } - } - - if (print_cert) - print_cert_info (session, verbose, print_cert); - - if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) - print_dh_info (session, "Ephemeral ", verbose); - else if (kx == GNUTLS_KX_ECDHE_RSA - || kx == GNUTLS_KX_ECDHE_ECDSA) - print_ecdh_info (session, "Ephemeral "); - } - - tmp = - SU (gnutls_protocol_get_name - (gnutls_protocol_get_version (session))); - printf ("- Version: %s\n", tmp); - - tmp = SU (gnutls_kx_get_name (kx)); - printf ("- Key Exchange: %s\n", tmp); - - if (gnutls_sign_algorithm_get(session) != GNUTLS_SIGN_UNKNOWN) - { - tmp = SU (gnutls_sign_get_name (gnutls_sign_algorithm_get (session))); - printf ("- Server Signature: %s\n", tmp); - } - - if (gnutls_sign_algorithm_get_client(session) != GNUTLS_SIGN_UNKNOWN) - { - tmp = SU (gnutls_sign_get_name (gnutls_sign_algorithm_get_client (session))); - printf ("- Client Signature: %s\n", tmp); - } - - tmp = SU (gnutls_cipher_get_name (gnutls_cipher_get (session))); - printf ("- Cipher: %s\n", tmp); - - tmp = SU (gnutls_mac_get_name (gnutls_mac_get (session))); - printf ("- MAC: %s\n", tmp); - - tmp = - SU (gnutls_compression_get_name - (gnutls_compression_get (session))); - printf ("- Compression: %s\n", tmp); + case GNUTLS_CRD_IA: + printf("- TLS/IA authentication\n"); + break; + case GNUTLS_CRD_CERTIFICATE: + { + char dns[256]; + size_t dns_size = sizeof(dns); + unsigned int type; + + /* This fails in client side */ + if (gnutls_server_name_get + (session, dns, &dns_size, &type, 0) == 0) { + printf("- Given server name[%d]: %s\n", + type, dns); + } + } + + if (print_cert) + print_cert_info(session, verbose, print_cert); + + if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) + print_dh_info(session, "Ephemeral ", verbose); + else if (kx == GNUTLS_KX_ECDHE_RSA + || kx == GNUTLS_KX_ECDHE_ECDSA) + print_ecdh_info(session, "Ephemeral "); + } + + tmp = + SU(gnutls_protocol_get_name + (gnutls_protocol_get_version(session))); + printf("- Version: %s\n", tmp); + + tmp = SU(gnutls_kx_get_name(kx)); + printf("- Key Exchange: %s\n", tmp); + + if (gnutls_sign_algorithm_get(session) != GNUTLS_SIGN_UNKNOWN) { + tmp = + SU(gnutls_sign_get_name + (gnutls_sign_algorithm_get(session))); + printf("- Server Signature: %s\n", tmp); + } + + if (gnutls_sign_algorithm_get_client(session) != + GNUTLS_SIGN_UNKNOWN) { + tmp = + SU(gnutls_sign_get_name + (gnutls_sign_algorithm_get_client(session))); + printf("- Client Signature: %s\n", tmp); + } + + tmp = SU(gnutls_cipher_get_name(gnutls_cipher_get(session))); + printf("- Cipher: %s\n", tmp); + + tmp = SU(gnutls_mac_get_name(gnutls_mac_get(session))); + printf("- MAC: %s\n", tmp); + + tmp = + SU(gnutls_compression_get_name + (gnutls_compression_get(session))); + printf("- Compression: %s\n", tmp); #ifdef ENABLE_DTLS_SRTP - rc = gnutls_srtp_get_selected_profile (session, &srtp_profile); - if (rc == 0) - printf ("- SRTP profile: %s\n", gnutls_srtp_get_profile_name (srtp_profile)); + rc = gnutls_srtp_get_selected_profile(session, &srtp_profile); + if (rc == 0) + printf("- SRTP profile: %s\n", + gnutls_srtp_get_profile_name(srtp_profile)); #endif #ifdef ENABLE_ALPN - rc = gnutls_alpn_get_selected_protocol (session, &p); - if (rc == 0) - printf ("- Application protocol: %.*s\n", p.size, p.data); + rc = gnutls_alpn_get_selected_protocol(session, &p); + if (rc == 0) + printf("- Application protocol: %.*s\n", p.size, p.data); #endif - if (verbose) - { - gnutls_datum_t cb; - - rc = gnutls_session_channel_binding (session, - GNUTLS_CB_TLS_UNIQUE, &cb); - if (rc) - fprintf (stderr, "Channel binding error: %s\n", - gnutls_strerror (rc)); - else - { - size_t i; - - printf ("- Channel binding 'tls-unique': "); - for (i = 0; i < cb.size; i++) - printf ("%02x", cb.data[i]); - printf ("\n"); - } - } - - /* Warning: Do not print anything more here. The 'Compression:' - output MUST be the last non-verbose output. This is used by - Emacs starttls.el code. */ - - fflush (stdout); - - return 0; + if (verbose) { + gnutls_datum_t cb; + + rc = gnutls_session_channel_binding(session, + GNUTLS_CB_TLS_UNIQUE, + &cb); + if (rc) + fprintf(stderr, "Channel binding error: %s\n", + gnutls_strerror(rc)); + else { + size_t i; + + printf("- Channel binding 'tls-unique': "); + for (i = 0; i < cb.size; i++) + printf("%02x", cb.data[i]); + printf("\n"); + } + } + + /* Warning: Do not print anything more here. The 'Compression:' + output MUST be the last non-verbose output. This is used by + Emacs starttls.el code. */ + + fflush(stdout); + + return 0; } -void -print_cert_info (gnutls_session_t session, int verbose, int print_cert) +void print_cert_info(gnutls_session_t session, int verbose, int print_cert) { -int flag; + int flag; - if (verbose) flag = GNUTLS_CRT_PRINT_FULL; - else flag = GNUTLS_CRT_PRINT_COMPACT; + if (verbose) + flag = GNUTLS_CRT_PRINT_FULL; + else + flag = GNUTLS_CRT_PRINT_COMPACT; - if (gnutls_certificate_client_get_request_status (session) != 0) - printf ("- Server has requested a certificate.\n"); + if (gnutls_certificate_client_get_request_status(session) != 0) + printf("- Server has requested a certificate.\n"); - switch (gnutls_certificate_type_get (session)) - { - case GNUTLS_CRT_X509: - print_x509_info (session, flag, print_cert); - break; + switch (gnutls_certificate_type_get(session)) { + case GNUTLS_CRT_X509: + print_x509_info(session, flag, print_cert); + break; #ifdef ENABLE_OPENPGP - case GNUTLS_CRT_OPENPGP: - print_openpgp_info (session, flag, print_cert); - break; + case GNUTLS_CRT_OPENPGP: + print_openpgp_info(session, flag, print_cert); + break; #endif - default: - printf ("Unknown type\n"); - break; - } + default: + printf("Unknown type\n"); + break; + } } -void -print_cert_info_compact (gnutls_session_t session) +void print_cert_info_compact(gnutls_session_t session) { - if (gnutls_certificate_client_get_request_status (session) != 0) - printf ("- Server has requested a certificate.\n"); + if (gnutls_certificate_client_get_request_status(session) != 0) + printf("- Server has requested a certificate.\n"); - switch (gnutls_certificate_type_get (session)) - { - case GNUTLS_CRT_X509: - print_x509_info_compact (session); - break; + switch (gnutls_certificate_type_get(session)) { + case GNUTLS_CRT_X509: + print_x509_info_compact(session); + break; #ifdef ENABLE_OPENPGP - case GNUTLS_CRT_OPENPGP: - print_openpgp_info_compact (session); - break; + case GNUTLS_CRT_OPENPGP: + print_openpgp_info_compact(session); + break; #endif - default: - printf ("Unknown type\n"); - break; - } + default: + printf("Unknown type\n"); + break; + } } -void -print_list (const char *priorities, int verbose) +void print_list(const char *priorities, int verbose) { - size_t i; - int ret; - unsigned int idx; - const char *name; - const char *err; - unsigned char id[2]; - gnutls_kx_algorithm_t kx; - gnutls_cipher_algorithm_t cipher; - gnutls_mac_algorithm_t mac; - gnutls_protocol_t version; - gnutls_priority_t pcache; - const unsigned int *list; - - if (priorities != NULL) - { - printf ("Cipher suites for %s\n", priorities); - - ret = gnutls_priority_init (&pcache, priorities, &err); - if (ret < 0) - { - fprintf (stderr, "Syntax error at: %s\n", err); - exit (1); - } - - for (i = 0;; i++) - { - ret = - gnutls_priority_get_cipher_suite_index (pcache, i, - &idx); - if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) - break; - if (ret == GNUTLS_E_UNKNOWN_CIPHER_SUITE) - continue; - - name = - gnutls_cipher_suite_info (idx, id, NULL, NULL, NULL, - &version); - - if (name != NULL) - printf ("%-50s\t0x%02x, 0x%02x\t%s\n", - name, (unsigned char) id[0], - (unsigned char) id[1], - gnutls_protocol_get_name (version)); - } - - printf("\n"); - { - ret = gnutls_priority_certificate_type_list (pcache, &list); - - printf ("Certificate types: "); - if (ret == 0) printf("none\n"); - for (i = 0; i < (unsigned)ret; i++) - { - printf ("CTYPE-%s", - gnutls_certificate_type_get_name (list[i])); - if (i+1!=(unsigned)ret) - printf (", "); - else - printf ("\n"); - } - } - - { - ret = gnutls_priority_protocol_list (pcache, &list); - - printf ("Protocols: "); - if (ret == 0) printf("none\n"); - for (i = 0; i < (unsigned)ret; i++) - { - printf ("VERS-%s", gnutls_protocol_get_name (list[i])); - if (i+1!=(unsigned)ret) - printf (", "); - else - printf ("\n"); - } - } - - { - ret = gnutls_priority_compression_list (pcache, &list); - - printf ("Compression: "); - if (ret == 0) printf("none\n"); - for (i = 0; i < (unsigned)ret; i++) - { - printf ("COMP-%s", - gnutls_compression_get_name (list[i])); - if (i+1!=(unsigned)ret) - printf (", "); - else - printf ("\n"); - } - } - - { - ret = gnutls_priority_ecc_curve_list (pcache, &list); - - printf ("Elliptic curves: "); - if (ret == 0) printf("none\n"); - for (i = 0; i < (unsigned)ret; i++) - { - printf ("CURVE-%s", - gnutls_ecc_curve_get_name (list[i])); - if (i+1!=(unsigned)ret) - printf (", "); - else - printf ("\n"); - } - } - - { - ret = gnutls_priority_sign_list (pcache, &list); - - printf ("PK-signatures: "); - if (ret == 0) printf("none\n"); - for (i = 0; i < (unsigned)ret; i++) - { - printf ("SIGN-%s", - gnutls_sign_algorithm_get_name (list[i])); - if (i+1!=(unsigned)ret) - printf (", "); - else - printf ("\n"); - } - } - - return; - } - - printf ("Cipher suites:\n"); - for (i = 0; (name = gnutls_cipher_suite_info - (i, id, &kx, &cipher, &mac, &version)); i++) - { - printf ("%-50s\t0x%02x, 0x%02x\t%s\n", - name, - (unsigned char) id[0], (unsigned char) id[1], - gnutls_protocol_get_name (version)); - if (verbose) - printf ("\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n", - gnutls_kx_get_name (kx), - gnutls_cipher_get_name (cipher), - gnutls_mac_get_name (mac)); - } - - printf("\n"); - { - const gnutls_certificate_type_t *p = - gnutls_certificate_type_list (); - - printf ("Certificate types: "); - for (; *p; p++) - { - printf ("CTYPE-%s", gnutls_certificate_type_get_name (*p)); - if (*(p + 1)) - printf (", "); - else - printf ("\n"); - } - } - - { - const gnutls_protocol_t *p = gnutls_protocol_list (); - - printf ("Protocols: "); - for (; *p; p++) - { - printf ("VERS-%s", gnutls_protocol_get_name (*p)); - if (*(p + 1)) - printf (", "); - else - printf ("\n"); - } - } - - { - const gnutls_cipher_algorithm_t *p = gnutls_cipher_list (); - - printf ("Ciphers: "); - for (; *p; p++) - { - printf ("%s", gnutls_cipher_get_name (*p)); - if (*(p + 1)) - printf (", "); - else - printf ("\n"); - } - } - - { - const gnutls_mac_algorithm_t *p = gnutls_mac_list (); - - printf ("MACs: "); - for (; *p; p++) - { - printf ("%s", gnutls_mac_get_name (*p)); - if (*(p + 1)) - printf (", "); - else - printf ("\n"); - } - } - - { - const gnutls_digest_algorithm_t *p = gnutls_digest_list (); - - printf ("Digests: "); - for (; *p; p++) - { - printf ("%s", gnutls_digest_get_name (*p)); - if (*(p + 1)) - printf (", "); - else - printf ("\n"); - } - } - - { - const gnutls_kx_algorithm_t *p = gnutls_kx_list (); - - printf ("Key exchange algorithms: "); - for (; *p; p++) - { - printf ("%s", gnutls_kx_get_name (*p)); - if (*(p + 1)) - printf (", "); - else - printf ("\n"); - } - } - - { - const gnutls_compression_method_t *p = gnutls_compression_list (); - - printf ("Compression: "); - for (; *p; p++) - { - printf ("COMP-%s", gnutls_compression_get_name (*p)); - if (*(p + 1)) - printf (", "); - else - printf ("\n"); - } - } - - { - const gnutls_ecc_curve_t *p = gnutls_ecc_curve_list (); - - printf ("Elliptic curves: "); - for (; *p; p++) - { - printf ("CURVE-%s", gnutls_ecc_curve_get_name (*p)); - if (*(p + 1)) - printf (", "); - else - printf ("\n"); - } - } - - { - const gnutls_pk_algorithm_t *p = gnutls_pk_list (); - - printf ("Public Key Systems: "); - for (; *p; p++) - { - printf ("%s", gnutls_pk_algorithm_get_name (*p)); - if (*(p + 1)) - printf (", "); - else - printf ("\n"); - } - } - - { - const gnutls_sign_algorithm_t *p = gnutls_sign_list (); - - printf ("PK-signatures: "); - for (; *p; p++) - { - printf ("SIGN-%s", gnutls_sign_algorithm_get_name (*p)); - if (*(p + 1)) - printf (", "); - else - printf ("\n"); - } - } + size_t i; + int ret; + unsigned int idx; + const char *name; + const char *err; + unsigned char id[2]; + gnutls_kx_algorithm_t kx; + gnutls_cipher_algorithm_t cipher; + gnutls_mac_algorithm_t mac; + gnutls_protocol_t version; + gnutls_priority_t pcache; + const unsigned int *list; + + if (priorities != NULL) { + printf("Cipher suites for %s\n", priorities); + + ret = gnutls_priority_init(&pcache, priorities, &err); + if (ret < 0) { + fprintf(stderr, "Syntax error at: %s\n", err); + exit(1); + } + + for (i = 0;; i++) { + ret = + gnutls_priority_get_cipher_suite_index(pcache, + i, + &idx); + if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) + break; + if (ret == GNUTLS_E_UNKNOWN_CIPHER_SUITE) + continue; + + name = + gnutls_cipher_suite_info(idx, id, NULL, NULL, + NULL, &version); + + if (name != NULL) + printf("%-50s\t0x%02x, 0x%02x\t%s\n", + name, (unsigned char) id[0], + (unsigned char) id[1], + gnutls_protocol_get_name(version)); + } + + printf("\n"); + { + ret = + gnutls_priority_certificate_type_list(pcache, + &list); + + printf("Certificate types: "); + if (ret == 0) + printf("none\n"); + for (i = 0; i < (unsigned) ret; i++) { + printf("CTYPE-%s", + gnutls_certificate_type_get_name + (list[i])); + if (i + 1 != (unsigned) ret) + printf(", "); + else + printf("\n"); + } + } + + { + ret = gnutls_priority_protocol_list(pcache, &list); + + printf("Protocols: "); + if (ret == 0) + printf("none\n"); + for (i = 0; i < (unsigned) ret; i++) { + printf("VERS-%s", + gnutls_protocol_get_name(list[i])); + if (i + 1 != (unsigned) ret) + printf(", "); + else + printf("\n"); + } + } + + { + ret = + gnutls_priority_compression_list(pcache, + &list); + + printf("Compression: "); + if (ret == 0) + printf("none\n"); + for (i = 0; i < (unsigned) ret; i++) { + printf("COMP-%s", + gnutls_compression_get_name(list + [i])); + if (i + 1 != (unsigned) ret) + printf(", "); + else + printf("\n"); + } + } + + { + ret = + gnutls_priority_ecc_curve_list(pcache, &list); + + printf("Elliptic curves: "); + if (ret == 0) + printf("none\n"); + for (i = 0; i < (unsigned) ret; i++) { + printf("CURVE-%s", + gnutls_ecc_curve_get_name(list[i])); + if (i + 1 != (unsigned) ret) + printf(", "); + else + printf("\n"); + } + } + + { + ret = gnutls_priority_sign_list(pcache, &list); + + printf("PK-signatures: "); + if (ret == 0) + printf("none\n"); + for (i = 0; i < (unsigned) ret; i++) { + printf("SIGN-%s", + gnutls_sign_algorithm_get_name(list + [i])); + if (i + 1 != (unsigned) ret) + printf(", "); + else + printf("\n"); + } + } + + return; + } + + printf("Cipher suites:\n"); + for (i = 0; (name = gnutls_cipher_suite_info + (i, id, &kx, &cipher, &mac, &version)); i++) { + printf("%-50s\t0x%02x, 0x%02x\t%s\n", + name, + (unsigned char) id[0], (unsigned char) id[1], + gnutls_protocol_get_name(version)); + if (verbose) + printf + ("\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n", + gnutls_kx_get_name(kx), + gnutls_cipher_get_name(cipher), + gnutls_mac_get_name(mac)); + } + + printf("\n"); + { + const gnutls_certificate_type_t *p = + gnutls_certificate_type_list(); + + printf("Certificate types: "); + for (; *p; p++) { + printf("CTYPE-%s", + gnutls_certificate_type_get_name(*p)); + if (*(p + 1)) + printf(", "); + else + printf("\n"); + } + } + + { + const gnutls_protocol_t *p = gnutls_protocol_list(); + + printf("Protocols: "); + for (; *p; p++) { + printf("VERS-%s", gnutls_protocol_get_name(*p)); + if (*(p + 1)) + printf(", "); + else + printf("\n"); + } + } + + { + const gnutls_cipher_algorithm_t *p = gnutls_cipher_list(); + + printf("Ciphers: "); + for (; *p; p++) { + printf("%s", gnutls_cipher_get_name(*p)); + if (*(p + 1)) + printf(", "); + else + printf("\n"); + } + } + + { + const gnutls_mac_algorithm_t *p = gnutls_mac_list(); + + printf("MACs: "); + for (; *p; p++) { + printf("%s", gnutls_mac_get_name(*p)); + if (*(p + 1)) + printf(", "); + else + printf("\n"); + } + } + + { + const gnutls_digest_algorithm_t *p = gnutls_digest_list(); + + printf("Digests: "); + for (; *p; p++) { + printf("%s", gnutls_digest_get_name(*p)); + if (*(p + 1)) + printf(", "); + else + printf("\n"); + } + } + + { + const gnutls_kx_algorithm_t *p = gnutls_kx_list(); + + printf("Key exchange algorithms: "); + for (; *p; p++) { + printf("%s", gnutls_kx_get_name(*p)); + if (*(p + 1)) + printf(", "); + else + printf("\n"); + } + } + + { + const gnutls_compression_method_t *p = + gnutls_compression_list(); + + printf("Compression: "); + for (; *p; p++) { + printf("COMP-%s", gnutls_compression_get_name(*p)); + if (*(p + 1)) + printf(", "); + else + printf("\n"); + } + } + + { + const gnutls_ecc_curve_t *p = gnutls_ecc_curve_list(); + + printf("Elliptic curves: "); + for (; *p; p++) { + printf("CURVE-%s", gnutls_ecc_curve_get_name(*p)); + if (*(p + 1)) + printf(", "); + else + printf("\n"); + } + } + + { + const gnutls_pk_algorithm_t *p = gnutls_pk_list(); + + printf("Public Key Systems: "); + for (; *p; p++) { + printf("%s", gnutls_pk_algorithm_get_name(*p)); + if (*(p + 1)) + printf(", "); + else + printf("\n"); + } + } + + { + const gnutls_sign_algorithm_t *p = gnutls_sign_list(); + + printf("PK-signatures: "); + for (; *p; p++) { + printf("SIGN-%s", + gnutls_sign_algorithm_get_name(*p)); + if (*(p + 1)) + printf(", "); + else + printf("\n"); + } + } } -int check_command(gnutls_session_t session, const char* str) +int check_command(gnutls_session_t session, const char *str) { - size_t len = strnlen(str, 128); - int ret; - - fprintf (stderr, "*** Processing %zu bytes command: %s\n", len, str); - if (len > 2 && str[0] == str[1] && str[0] == '*') - { - if (strncmp(str, "**REHANDSHAKE**", sizeof ("**REHANDSHAKE**") - 1) == 0) - { - fprintf (stderr, "*** Sending rehandshake request\n"); - gnutls_rehandshake (session); - return 1; - } else if (strncmp(str, "**HEARTBEAT**", sizeof ("**HEARTBEAT**") - 1) == 0) { - ret = gnutls_heartbeat_ping (session, 300, 5, GNUTLS_HEARTBEAT_WAIT); - if (ret < 0) - { - if (ret == GNUTLS_E_INVALID_REQUEST) - { - fprintf(stderr, "No heartbeat in this session\n"); - } - else - { - fprintf(stderr, "ping: %s\n", gnutls_strerror(ret)); - exit(1); - } - } - return 2; - } - } - return 0; + size_t len = strnlen(str, 128); + int ret; + + fprintf(stderr, "*** Processing %zu bytes command: %s\n", len, + str); + if (len > 2 && str[0] == str[1] && str[0] == '*') { + if (strncmp + (str, "**REHANDSHAKE**", + sizeof("**REHANDSHAKE**") - 1) == 0) { + fprintf(stderr, + "*** Sending rehandshake request\n"); + gnutls_rehandshake(session); + return 1; + } else + if (strncmp + (str, "**HEARTBEAT**", + sizeof("**HEARTBEAT**") - 1) == 0) { + ret = + gnutls_heartbeat_ping(session, 300, 5, + GNUTLS_HEARTBEAT_WAIT); + if (ret < 0) { + if (ret == GNUTLS_E_INVALID_REQUEST) { + fprintf(stderr, + "No heartbeat in this session\n"); + } else { + fprintf(stderr, "ping: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } + return 2; + } + } + return 0; } #define MIN(x,y) ((x)<(y))?(x):(y) #define MAX_CACHE_TRIES 5 int -pin_callback (void *user, int attempt, const char *token_url, - const char *token_label, unsigned int flags, char *pin, - size_t pin_max) +pin_callback(void *user, int attempt, const char *token_url, + const char *token_label, unsigned int flags, char *pin, + size_t pin_max) { - const char *password; - const char * desc; - int cache = MAX_CACHE_TRIES; - unsigned len; + const char *password; + const char *desc; + int cache = MAX_CACHE_TRIES; + unsigned len; /* allow caching of PIN */ - static char *cached_url = NULL; - static char cached_pin[32] = ""; - - if (flags & GNUTLS_PIN_SO) - desc = "security officer"; - else - desc = "user"; - - if (flags & GNUTLS_PIN_FINAL_TRY) - { - cache = 0; - printf ("*** This is the final try before locking!\n"); - } - if (flags & GNUTLS_PIN_COUNT_LOW) - { - cache = 0; - printf ("*** Only few tries left before locking!\n"); - } - - if (flags & GNUTLS_PIN_WRONG) - { - cache = 0; - printf ("*** Wrong PIN has been provided!\n"); - } - - if (cache > 0 && cached_url != NULL) - { - if (token_url != NULL && strcmp (cached_url, token_url) == 0) - { - if (strlen(pin) >= sizeof(cached_pin)) - { - fprintf (stderr, "Too long PIN given\n"); - exit (1); - } - - fprintf(stderr, "Re-using cached PIN for token '%s'\n", token_label); - strcpy (pin, cached_pin); - cache--; - return 0; - } - } - - printf ("Token '%s' with URL '%s' ", token_label, token_url); - printf ("requires %s PIN\n", desc); - - password = getpass ("Enter PIN: "); - if (password == NULL || password[0] == 0) - { - fprintf (stderr, "No password given\n"); - exit (1); - } - - len = MIN (pin_max-1, strlen (password)); - memcpy (pin, password, len); - pin[len] = 0; - - /* cache */ - if (len < sizeof(cached_pin)) - { - memcpy (cached_pin, pin, len); - cached_pin[len] = 0; - } - else - cached_pin[0] = 0; - - free (cached_url); - if (token_url) - cached_url = strdup (token_url); - else - cached_url = NULL; - - cache = MAX_CACHE_TRIES; - - return 0; + static char *cached_url = NULL; + static char cached_pin[32] = ""; + + if (flags & GNUTLS_PIN_SO) + desc = "security officer"; + else + desc = "user"; + + if (flags & GNUTLS_PIN_FINAL_TRY) { + cache = 0; + printf("*** This is the final try before locking!\n"); + } + if (flags & GNUTLS_PIN_COUNT_LOW) { + cache = 0; + printf("*** Only few tries left before locking!\n"); + } + + if (flags & GNUTLS_PIN_WRONG) { + cache = 0; + printf("*** Wrong PIN has been provided!\n"); + } + + if (cache > 0 && cached_url != NULL) { + if (token_url != NULL + && strcmp(cached_url, token_url) == 0) { + if (strlen(pin) >= sizeof(cached_pin)) { + fprintf(stderr, "Too long PIN given\n"); + exit(1); + } + + fprintf(stderr, + "Re-using cached PIN for token '%s'\n", + token_label); + strcpy(pin, cached_pin); + cache--; + return 0; + } + } + + printf("Token '%s' with URL '%s' ", token_label, token_url); + printf("requires %s PIN\n", desc); + + password = getpass("Enter PIN: "); + if (password == NULL || password[0] == 0) { + fprintf(stderr, "No password given\n"); + exit(1); + } + + len = MIN(pin_max - 1, strlen(password)); + memcpy(pin, password, len); + pin[len] = 0; + + /* cache */ + if (len < sizeof(cached_pin)) { + memcpy(cached_pin, pin, len); + cached_pin[len] = 0; + } else + cached_pin[0] = 0; + + free(cached_url); + if (token_url) + cached_url = strdup(token_url); + else + cached_url = NULL; + + cache = MAX_CACHE_TRIES; + + return 0; } #ifdef ENABLE_PKCS11 static int -token_callback (void *user, const char *label, const unsigned retry) +token_callback(void *user, const char *label, const unsigned retry) { - char buf[32]; + char buf[32]; - if (retry > 0) - { - fprintf (stderr, "Could not find token %s\n", label); - return -1; - } - printf ("Please insert token '%s' in slot and press enter\n", label); - fgets (buf, sizeof (buf), stdin); + if (retry > 0) { + fprintf(stderr, "Could not find token %s\n", label); + return -1; + } + printf("Please insert token '%s' in slot and press enter\n", + label); + fgets(buf, sizeof(buf), stdin); - return 0; + return 0; } -void -pkcs11_common (void) +void pkcs11_common(void) { - gnutls_pkcs11_set_pin_function (pin_callback, NULL); - gnutls_pkcs11_set_token_function (token_callback, NULL); + gnutls_pkcs11_set_pin_function(pin_callback, NULL); + gnutls_pkcs11_set_token_function(token_callback, NULL); } diff --git a/src/common.h b/src/common.h index 2f705f1dd0..577dc5b873 100644 --- a/src/common.h +++ b/src/common.h @@ -27,7 +27,7 @@ #include <netdb.h> #include <unistd.h> #ifndef _WIN32 -# include <netinet/in.h> +#include <netinet/in.h> #endif #include <signal.h> @@ -39,7 +39,7 @@ #ifndef __attribute__ #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) -#define __attribute__(Spec) /* empty */ +#define __attribute__(Spec) /* empty */ #endif #endif @@ -49,20 +49,20 @@ extern const char str_unknown[]; -int print_info (gnutls_session_t state, int verbose, int print_cert); -void print_cert_info (gnutls_session_t, int flag, int print_cert); -void print_cert_info_compact (gnutls_session_t session); +int print_info(gnutls_session_t state, int verbose, int print_cert); +void print_cert_info(gnutls_session_t, int flag, int print_cert); +void print_cert_info_compact(gnutls_session_t session); -void print_list (const char* priorities, int verbose); -int cert_verify (gnutls_session_t session, const char* hostname); +void print_list(const char *priorities, int verbose); +int cert_verify(gnutls_session_t session, const char *hostname); -const char *raw_to_string (const unsigned char *raw, size_t raw_size); -void pkcs11_common (void); -int check_command(gnutls_session_t session, const char* str); +const char *raw_to_string(const unsigned char *raw, size_t raw_size); +void pkcs11_common(void); +int check_command(gnutls_session_t session, const char *str); int -pin_callback (void *user, int attempt, const char *token_url, - const char *token_label, unsigned int flags, char *pin, - size_t pin_max); +pin_callback(void *user, int attempt, const char *token_url, + const char *token_label, unsigned int flags, char *pin, + size_t pin_max); -void pkcs11_common (void); +void pkcs11_common(void); diff --git a/src/crywrap/crywrap.c b/src/crywrap/crywrap.c index b0b0799a22..f1b822cb6d 100644 --- a/src/crywrap/crywrap.c +++ b/src/crywrap/crywrap.c @@ -52,53 +52,52 @@ #include "crywrap.h" #include "primes.h" -static int system_log(const char* fmt, ...) +static int system_log(const char *fmt, ...) #ifdef __GNUC__ - __attribute__ ((format (printf, 1, 2))) + __attribute__ ((format(printf, 1, 2))) #endif -; + ; -static int system_log_error(const char* fmt, ...) +static int system_log_error(const char *fmt, ...) #ifdef __GNUC__ - __attribute__ ((format (printf, 1, 2))) + __attribute__ ((format(printf, 1, 2))) #endif -; + ; -static int debug_log(const char* fmt, ...) +static int debug_log(const char *fmt, ...) #ifdef __GNUC__ - __attribute__ ((format (printf, 1, 2))) + __attribute__ ((format(printf, 1, 2))) #endif -; + ; -typedef int (*cry_log_func)(const char *format, ...) +typedef int (*cry_log_func) (const char *format, ...) #ifdef __GNUC__ - __attribute__ ((format (printf, 1, 2))) + __attribute__ ((format(printf, 1, 2))) #endif -; + ; static cry_log_func cry_log = system_log; static cry_log_func cry_error = system_log_error; -static void -tls_audit_log_func (gnutls_session_t session, const char *str) +static void tls_audit_log_func(gnutls_session_t session, const char *str) { - char peer_name[NI_MAXHOST] = "Unknown"; - gnutls_transport_ptr_t r, s; - struct sockaddr_storage faddr; - socklen_t socklen = sizeof (struct sockaddr_storage); - - if (session != NULL) - { - gnutls_transport_get_ptr2(session, &r, &s); - - /* Log the connection */ - if (getpeername ((int)(long)r, (struct sockaddr *)&faddr, &socklen) != 0) - cry_error ("getpeername(): %s", strerror (errno)); - - cry_log ("Peer %s: %s", peer_name, str); - } - else - cry_log ("%s", str); + char peer_name[NI_MAXHOST] = "Unknown"; + gnutls_transport_ptr_t r, s; + struct sockaddr_storage faddr; + socklen_t socklen = sizeof(struct sockaddr_storage); + + if (session != NULL) { + gnutls_transport_get_ptr2(session, &r, &s); + + /* Log the connection */ + if (getpeername + ((int) (long) r, (struct sockaddr *) &faddr, + &socklen) != 0) + cry_error("getpeername(): %s", strerror(errno)); + + cry_log("Peer %s: %s", peer_name, str); + } else + cry_log("%s", str); } @@ -118,7 +117,8 @@ static const char *pidfile = _CRYWRAP_PIDFILE; /**< File to log our PID */ static gnutls_certificate_server_credentials cred; static gnutls_dh_params dh_params; /**< GNUTLS DH parameters. */ -static gnutls_datum dh_file = { (void*)_crywrap_prime_dh_1024, sizeof(_crywrap_prime_dh_1024) }; /**< Diffie Hellman parameters */ +static gnutls_datum dh_file = { (void *) _crywrap_prime_dh_1024, sizeof(_crywrap_prime_dh_1024) }; + /**< Diffie Hellman parameters */ /** Bugreport address. * Used by the argp suite. @@ -138,36 +138,41 @@ static char *pem_key = NULL; * Used by the argp suite. */ static const struct argp_option _crywrap_options[] = { - {NULL, 0, NULL, 0, "Mandatory options:", 1}, - {"destination", 'd', "IP/PORT", 0, "IP and port to connect to", 1}, - {"listen", 'l', "IP/PORT", 0, "IP and port to listen on", 1}, - {NULL, 0, NULL, 0, "TLS certificates:", 2}, - {"key", 'k', "FILE", 0, "Server key", 2}, - {"cert", 'c', "FILE", 0, "Server certificate", 2}, - {"ca", 'z', "FILE", 0, "CA certificate", 2}, - {"anon", 'a', NULL, 0, "Enable anonymous authentication (no certificates)", 2}, - {"verify", 'v', "LEVEL", OPTION_ARG_OPTIONAL, - "Verify clients certificate (1: verify if exists, 2: require)", 2}, - {NULL, 0, NULL, 0, "Other options:", 3}, - {"dhparams", 'r', "FILE", 0, "Diffie Hellman (PKCS #3) parameters file", 3}, - {"user", 'u', "UID", 0, "User ID to run as", 3}, - {"pidfile", 'P', "PATH", 0, "File to log the PID into", 3}, - {"priority", 'p', "STRING", 0, "GnuTLS ciphersuite priority string", 3}, - {"inetd", 'i', NULL, 0, "Enable inetd mode", 3}, - {"debug", 'D', NULL, 0, "Run the server into foreground", 3}, - {0, 0, 0, 0, NULL, 0} + {NULL, 0, NULL, 0, "Mandatory options:", 1}, + {"destination", 'd', "IP/PORT", 0, "IP and port to connect to", 1}, + {"listen", 'l', "IP/PORT", 0, "IP and port to listen on", 1}, + {NULL, 0, NULL, 0, "TLS certificates:", 2}, + {"key", 'k', "FILE", 0, "Server key", 2}, + {"cert", 'c', "FILE", 0, "Server certificate", 2}, + {"ca", 'z', "FILE", 0, "CA certificate", 2}, + {"anon", 'a', NULL, 0, + "Enable anonymous authentication (no certificates)", 2}, + {"verify", 'v', "LEVEL", OPTION_ARG_OPTIONAL, + "Verify clients certificate (1: verify if exists, 2: require)", + 2}, + {NULL, 0, NULL, 0, "Other options:", 3}, + {"dhparams", 'r', "FILE", 0, + "Diffie Hellman (PKCS #3) parameters file", 3}, + {"user", 'u', "UID", 0, "User ID to run as", 3}, + {"pidfile", 'P', "PATH", 0, "File to log the PID into", 3}, + {"priority", 'p', "STRING", 0, + "GnuTLS ciphersuite priority string", 3}, + {"inetd", 'i', NULL, 0, "Enable inetd mode", 3}, + {"debug", 'D', NULL, 0, "Run the server into foreground", 3}, + {0, 0, 0, 0, NULL, 0} }; -static error_t _crywrap_config_parse_opt (int key, char *arg, - struct argp_state *state); +static error_t _crywrap_config_parse_opt(int key, char *arg, + struct argp_state *state); /** The main argp structure for Crywrap. */ static const struct argp _crywrap_argp = - {_crywrap_options, _crywrap_config_parse_opt, 0, - __CRYWRAP__ " -- Security for the masses\v" - "The --destination option is mandatory, as is --listen if --inetd " - "was not used.", - NULL, NULL, NULL}; + { _crywrap_options, _crywrap_config_parse_opt, 0, + __CRYWRAP__ " -- Security for the masses\v" + "The --destination option is mandatory, as is --listen if --inetd " + "was not used.", + NULL, NULL, NULL +}; /** @} */ @@ -177,44 +182,41 @@ static const struct argp _crywrap_argp = /** SIGCHLD handler */ -static void -_crywrap_sigchld_handler (int sig) +static void _crywrap_sigchld_handler(int sig) { -pid_t child; -int status; + pid_t child; + int status; - while ((child = waitpid (-1, &status, WNOHANG)) > (pid_t) 0) - signal (sig, _crywrap_sigchld_handler); + while ((child = waitpid(-1, &status, WNOHANG)) > (pid_t) 0) + signal(sig, _crywrap_sigchld_handler); } /* Helper functions to load a certificate and key * files into memory. */ -static gnutls_datum_t -load_file (const char *file) +static gnutls_datum_t load_file(const char *file) { - gnutls_datum_t loaded_file = { NULL, 0 }; + gnutls_datum_t loaded_file = { NULL, 0 }; - gnutls_load_file(file, &loaded_file); + gnutls_load_file(file, &loaded_file); - return loaded_file; + return loaded_file; } /** Generic signal handler. * This one removes the #pidfile, if necessary. */ -static void -_crywrap_sighandler (int sig) +static void _crywrap_sighandler(int sig) { - if (getpid () == main_pid) - { - cry_log ("Exiting on signal %d", sig); - if (pidfile && *pidfile) - unlink (pidfile); - closelog (); - exit (0); - } + if (getpid() == main_pid) { + cry_log("Exiting on signal %d", sig); + if (pidfile && *pidfile) + unlink(pidfile); + closelog(); + exit(0); + } } + /** @} */ /** @defgroup parsing Option parsing @@ -228,22 +230,21 @@ _crywrap_sighandler (int sig) * * @returns The purt number, or -1 on error. */ -static int -_crywrap_port_get (const char *serv) +static int _crywrap_port_get(const char *serv) { - int port; - struct servent *se; + int port; + struct servent *se; - if (!serv) - return -1; + if (!serv) + return -1; - se = getservbyname (serv, "tcp"); - if (!se) - port = atoi (serv); - else - port = ntohs (se->s_port); + se = getservbyname(serv, "tcp"); + if (!se) + port = atoi(serv); + else + port = ntohs(se->s_port); - return port; + return port; } /** Address resolver. @@ -255,58 +256,54 @@ _crywrap_port_get (const char *serv) * @returns Zero on success, -1 on error. */ static int -_crywrap_addr_get (const char *hostname, struct sockaddr_storage **addr) +_crywrap_addr_get(const char *hostname, struct sockaddr_storage **addr) { - struct addrinfo *res; - struct addrinfo hints; - ssize_t len; - char *lz = NULL; - - if (idna_to_ascii_lz (hostname, &lz, 0) != IDNA_SUCCESS) - return -1; - - memset (&hints, 0, sizeof (hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_IP; - *addr = calloc (1, sizeof (struct sockaddr_storage)); - if (*addr == NULL) - { - free(lz); - return -1; - } - - if (getaddrinfo (lz, NULL, &hints, &res) != 0) - { - free (lz); - return -1; - } - - free (lz); - - switch (res->ai_addr->sa_family) - { - case AF_INET: - len = sizeof (struct sockaddr_in); - break; - case AF_INET6: - len = sizeof (struct sockaddr_in6); - break; - default: - freeaddrinfo (res); - return -1; - } - - if (len < (ssize_t)res->ai_addrlen) - { - freeaddrinfo (res); - return -1; - } - - memcpy (*addr, res->ai_addr, res->ai_addrlen); - freeaddrinfo (res); - - return 0; + struct addrinfo *res; + struct addrinfo hints; + ssize_t len; + char *lz = NULL; + + if (idna_to_ascii_lz(hostname, &lz, 0) != IDNA_SUCCESS) + return -1; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_IP; + *addr = calloc(1, sizeof(struct sockaddr_storage)); + if (*addr == NULL) { + free(lz); + return -1; + } + + if (getaddrinfo(lz, NULL, &hints, &res) != 0) { + free(lz); + return -1; + } + + free(lz); + + switch (res->ai_addr->sa_family) { + case AF_INET: + len = sizeof(struct sockaddr_in); + break; + case AF_INET6: + len = sizeof(struct sockaddr_in6); + break; + default: + freeaddrinfo(res); + return -1; + } + + if (len < (ssize_t) res->ai_addrlen) { + freeaddrinfo(res); + return -1; + } + + memcpy(*addr, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + + return 0; } /** Parse a HOST/IP pair. @@ -321,151 +318,166 @@ _crywrap_addr_get (const char *hostname, struct sockaddr_storage **addr) * @returns Zero on success, -1 on error. */ static int -_crywrap_parse_ip (const char *ip, in_port_t *port, - struct sockaddr_storage **addr, char **host) +_crywrap_parse_ip(const char *ip, in_port_t * port, + struct sockaddr_storage **addr, char **host) { - char *s_ip; - char *tmp; + char *s_ip; + char *tmp; - tmp = strchr (ip, '/'); + tmp = strchr(ip, '/'); - if (!tmp) - return -1; + if (!tmp) + return -1; - if (tmp == ip) - { - s_ip = strdup ("0.0.0.0"); - *port = (in_port_t)_crywrap_port_get (&ip[1]); - } - else - { - *port = (in_port_t)_crywrap_port_get (&tmp[1]); - s_ip = strndup (ip, tmp - ip); - } + if (tmp == ip) { + s_ip = strdup("0.0.0.0"); + *port = (in_port_t) _crywrap_port_get(&ip[1]); + } else { + *port = (in_port_t) _crywrap_port_get(&tmp[1]); + s_ip = strndup(ip, tmp - ip); + } - if (!*port) - return -1; + if (!*port) + return -1; - if (host) - *host = strdup (s_ip); + if (host) + *host = strdup(s_ip); - return _crywrap_addr_get (s_ip, addr); + return _crywrap_addr_get(s_ip, addr); } /** Argument parsing routine. * Used by the argp suite. */ static error_t -_crywrap_config_parse_opt (int key, char *arg, struct argp_state *state) +_crywrap_config_parse_opt(int key, char *arg, struct argp_state *state) { - crywrap_config_t *cfg = (crywrap_config_t *)state->input; - int ret; - - switch (key) - { - case 'D': - cfg->debug = 1; - cry_log = debug_log; - cry_error = debug_log; - break; - case 'd': - if (_crywrap_parse_ip (arg, &cfg->dest.port, &cfg->dest.addr, - &cfg->dest.host) < 0) - argp_error (state, "Could not resolve address: `%s'", arg); - break; - case 'l': - if (_crywrap_parse_ip (arg, &cfg->listen.port, - &cfg->listen.addr, NULL) < 0) - argp_error (state, "Could not resolve address: `%s'", arg); - break; - case 'u': - cfg->uid = atoi (arg); - break; - case 'P': - if (arg && *arg) - cfg->pidfile = strdup (arg); - else - cfg->pidfile = NULL; - break; - case 'r': - if (arg && *arg) - { - dh_file = load_file(arg); - if (dh_file.data == NULL) - argp_error (state, "error loading Diffie Hellman parameters file: %s.", arg); - } - break; - case 'p': - if (arg && *arg) - { - const char* pos; - ret = gnutls_priority_init(&cfg->priority, arg, &pos); - if (ret < 0) - argp_error (state, "error in priority string at: %s.", pos); - } - break; - case 'c': - if (arg && *arg) - pem_cert = strdup (arg); - break; - case 'k': - if (arg && *arg) - pem_key = strdup (arg); - break; - - break; - case 'i': - cfg->inetd = 1; - break; - case 'a': - { - const char* pos; - ret = gnutls_priority_init(&cfg->priority, "NORMAL:+ANON-ECDH:+ANON-DH", &pos); - if (ret < 0) - argp_error (state, "error in priority string at: %s.", pos); - } - cfg->verify = 0; - cfg->anon = 1; - break; - case 'v': - cfg->verify = (arg) ? atoi (arg) : 1; - break; - case 'z': - ret = gnutls_certificate_set_x509_trust_file (cred, arg, - GNUTLS_X509_FMT_PEM); - if (ret < 0) - argp_error (state, "error reading X.509 CA file: %s.", gnutls_strerror(ret)); - break; - - case ARGP_KEY_END: - if (!cfg->inetd) - { - if (!cfg->listen.addr || !cfg->dest.addr) - argp_error - (state, - "a listening and a destination address must be set!"); + crywrap_config_t *cfg = (crywrap_config_t *) state->input; + int ret; + + switch (key) { + case 'D': + cfg->debug = 1; + cry_log = debug_log; + cry_error = debug_log; + break; + case 'd': + if (_crywrap_parse_ip + (arg, &cfg->dest.port, &cfg->dest.addr, + &cfg->dest.host) < 0) + argp_error(state, + "Could not resolve address: `%s'", arg); + break; + case 'l': + if (_crywrap_parse_ip(arg, &cfg->listen.port, + &cfg->listen.addr, NULL) < 0) + argp_error(state, + "Could not resolve address: `%s'", arg); + break; + case 'u': + cfg->uid = atoi(arg); + break; + case 'P': + if (arg && *arg) + cfg->pidfile = strdup(arg); + else + cfg->pidfile = NULL; + break; + case 'r': + if (arg && *arg) { + dh_file = load_file(arg); + if (dh_file.data == NULL) + argp_error(state, + "error loading Diffie Hellman parameters file: %s.", + arg); + } + break; + case 'p': + if (arg && *arg) { + const char *pos; + ret = + gnutls_priority_init(&cfg->priority, arg, + &pos); + if (ret < 0) + argp_error(state, + "error in priority string at: %s.", + pos); + } + break; + case 'c': + if (arg && *arg) + pem_cert = strdup(arg); + break; + case 'k': + if (arg && *arg) + pem_key = strdup(arg); + break; + + break; + case 'i': + cfg->inetd = 1; + break; + case 'a': + { + const char *pos; + ret = + gnutls_priority_init(&cfg->priority, + "NORMAL:+ANON-ECDH:+ANON-DH", + &pos); + if (ret < 0) + argp_error(state, + "error in priority string at: %s.", + pos); + } + cfg->verify = 0; + cfg->anon = 1; + break; + case 'v': + cfg->verify = (arg) ? atoi(arg) : 1; + break; + case 'z': + ret = gnutls_certificate_set_x509_trust_file(cred, arg, + GNUTLS_X509_FMT_PEM); + if (ret < 0) + argp_error(state, + "error reading X.509 CA file: %s.", + gnutls_strerror(ret)); + break; + + case ARGP_KEY_END: + if (!cfg->inetd) { + if (!cfg->listen.addr || !cfg->dest.addr) + argp_error + (state, + "a listening and a destination address must be set!"); + } else if (!cfg->dest.addr) + argp_error(state, + "a destination address must be set!"); + if (cfg->anon) + break; + if (pem_cert == NULL || pem_key == NULL) + ret = + gnutls_certificate_set_x509_key_file(cred, + _CRYWRAP_PEMFILE, + _CRYWRAP_PEMFILE, + GNUTLS_X509_FMT_PEM); + else + ret = + gnutls_certificate_set_x509_key_file(cred, + pem_cert, + pem_key, + GNUTLS_X509_FMT_PEM); + + if (ret < 0) + argp_error(state, + "Error reading X.509 key or certificate file: %s", + gnutls_strerror(ret)); + break; + default: + return ARGP_ERR_UNKNOWN; } - else - if (!cfg->dest.addr) - argp_error (state, "a destination address must be set!"); - if (cfg->anon) - break; - if (pem_cert == NULL || pem_key == NULL) - ret = gnutls_certificate_set_x509_key_file (cred, _CRYWRAP_PEMFILE, - _CRYWRAP_PEMFILE, - GNUTLS_X509_FMT_PEM); - else - ret = gnutls_certificate_set_x509_key_file (cred, pem_cert, pem_key, - GNUTLS_X509_FMT_PEM); - - if (ret < 0) - argp_error (state, "Error reading X.509 key or certificate file: %s", gnutls_strerror(ret)); - break; - default: - return ARGP_ERR_UNKNOWN; - } - - return 0; + + return 0; } /** Configuration parsing. @@ -474,33 +486,33 @@ _crywrap_config_parse_opt (int key, char *arg, struct argp_state *state) * * @note Does not return if an error occurred. */ -static crywrap_config_t * -_crywrap_config_parse (int argc, char **argv) +static crywrap_config_t *_crywrap_config_parse(int argc, char **argv) { - crywrap_config_t *config = - (crywrap_config_t *)malloc (sizeof (crywrap_config_t)); + crywrap_config_t *config = + (crywrap_config_t *) malloc(sizeof(crywrap_config_t)); - if (config == NULL) - return NULL; + if (config == NULL) + return NULL; - config->listen.port = 0; - config->listen.addr = NULL; - config->dest.port = 0; - config->dest.addr = NULL; - config->priority = NULL; - config->uid = _CRYWRAP_UID; - config->pidfile = _CRYWRAP_PIDFILE; - config->inetd = 0; - config->anon = 0; - config->verify = 0; + config->listen.port = 0; + config->listen.addr = NULL; + config->dest.port = 0; + config->dest.addr = NULL; + config->priority = NULL; + config->uid = _CRYWRAP_UID; + config->pidfile = _CRYWRAP_PIDFILE; + config->inetd = 0; + config->anon = 0; + config->verify = 0; - argp_parse (&_crywrap_argp, argc, argv, 0, 0, config); + argp_parse(&_crywrap_argp, argc, argv, 0, 0, config); - if (config->priority == NULL) - gnutls_priority_init(&config->priority, "NORMAL", NULL); + if (config->priority == NULL) + gnutls_priority_init(&config->priority, "NORMAL", NULL); - return config; + return config; } + /** @} */ /** @defgroup tls Lower-level TLS routines. @@ -514,46 +526,50 @@ _crywrap_config_parse (int argc, char **argv) * @returns The newly created TLS session. */ static gnutls_session_t -_crywrap_tls_session_create (const crywrap_config_t *config) +_crywrap_tls_session_create(const crywrap_config_t * config) { - gnutls_session_t session; - int ret; - - gnutls_init (&session, GNUTLS_SERVER); - - if (config->anon) { - gnutls_credentials_set (session, GNUTLS_CRD_ANON, cred); - } else { - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, cred); - } - - ret = gnutls_priority_set(session, config->priority); - if (ret < 0) - { - cry_error ("Error setting priority %s: ", gnutls_strerror(ret)); - exit (4); - } - - if (config->verify==1) - gnutls_certificate_server_set_request (session, GNUTLS_CERT_REQUEST); - else if (config->verify==2) - gnutls_certificate_server_set_request (session, GNUTLS_CERT_REQUIRE); - - return session; + gnutls_session_t session; + int ret; + + gnutls_init(&session, GNUTLS_SERVER); + + if (config->anon) { + gnutls_credentials_set(session, GNUTLS_CRD_ANON, cred); + } else { + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, + cred); + } + + ret = gnutls_priority_set(session, config->priority); + if (ret < 0) { + cry_error("Error setting priority %s: ", + gnutls_strerror(ret)); + exit(4); + } + + if (config->verify == 1) + gnutls_certificate_server_set_request(session, + GNUTLS_CERT_REQUEST); + else if (config->verify == 2) + gnutls_certificate_server_set_request(session, + GNUTLS_CERT_REQUIRE); + + return session; } /** Generate initial DH and RSA params. * Loads the pre-generated DH primes. */ -static void -_crywrap_tls_init (void) +static void _crywrap_tls_init(void) { - gnutls_dh_params_init (&dh_params); - gnutls_dh_params_import_pkcs3 (dh_params, &dh_file, GNUTLS_X509_FMT_PEM); + gnutls_dh_params_init(&dh_params); + gnutls_dh_params_import_pkcs3(dh_params, &dh_file, + GNUTLS_X509_FMT_PEM); - gnutls_certificate_set_dh_params (cred, dh_params); + gnutls_certificate_set_dh_params(cred, dh_params); } + /** @} */ /** @defgroup networking Networking @@ -569,59 +585,59 @@ _crywrap_tls_init (void) * * @returns The bound filedescriptor, or -1 on error. */ -static int -_crywrap_bind (const struct addrinfo *ai, int listen_port) +static int _crywrap_bind(const struct addrinfo *ai, int listen_port) { - int ret; - const int one = 1; - int listenfd; - char sock_name[NI_MAXHOST]; - - listenfd = socket (ai->ai_family, SOCK_STREAM, IPPROTO_IP); - if (listenfd == -1) - { - cry_error ("socket: %s", strerror (errno)); - return -1; - } - - memset (sock_name, 0, sizeof (sock_name)); - getnameinfo ((struct sockaddr *)ai->ai_addr, ai->ai_addrlen, sock_name, - sizeof (sock_name), NULL, 0, NI_NUMERICHOST); - - switch (ai->ai_family) - { - case AF_INET6: - ((struct sockaddr_in6 *)(ai->ai_addr))->sin6_port = listen_port; - break; - case AF_INET: - ((struct sockaddr_in *)(ai->ai_addr))->sin_port = listen_port; - break; - } - - ret = setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, - &one, sizeof (one)); - if (ret != 0) - { - cry_error ("setsockopt: %s (%s)", strerror (errno), sock_name); - return -1; - } - - ret = bind (listenfd, ai->ai_addr, ai->ai_addrlen); - if (ret != 0) - { - cry_error ("bind to %s failed: %s", sock_name, strerror (errno)); - return -1; - } - - if (listen (listenfd, _CRYWRAP_MAXCONN) != 0) - { - cry_error ("listen on %s failed: %s", sock_name, strerror (errno)); - return -1; - } - - cry_log ("Socket bound to port %d on %s.", ntohs (listen_port), sock_name); - - return listenfd; + int ret; + const int one = 1; + int listenfd; + char sock_name[NI_MAXHOST]; + + listenfd = socket(ai->ai_family, SOCK_STREAM, IPPROTO_IP); + if (listenfd == -1) { + cry_error("socket: %s", strerror(errno)); + return -1; + } + + memset(sock_name, 0, sizeof(sock_name)); + getnameinfo((struct sockaddr *) ai->ai_addr, ai->ai_addrlen, + sock_name, sizeof(sock_name), NULL, 0, NI_NUMERICHOST); + + switch (ai->ai_family) { + case AF_INET6: + ((struct sockaddr_in6 *) (ai->ai_addr))->sin6_port = + listen_port; + break; + case AF_INET: + ((struct sockaddr_in *) (ai->ai_addr))->sin_port = + listen_port; + break; + } + + ret = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, + &one, sizeof(one)); + if (ret != 0) { + cry_error("setsockopt: %s (%s)", strerror(errno), + sock_name); + return -1; + } + + ret = bind(listenfd, ai->ai_addr, ai->ai_addrlen); + if (ret != 0) { + cry_error("bind to %s failed: %s", sock_name, + strerror(errno)); + return -1; + } + + if (listen(listenfd, _CRYWRAP_MAXCONN) != 0) { + cry_error("listen on %s failed: %s", sock_name, + strerror(errno)); + return -1; + } + + cry_log("Socket bound to port %d on %s.", ntohs(listen_port), + sock_name); + + return listenfd; } /** Set up a listening socket. @@ -632,39 +648,37 @@ _crywrap_bind (const struct addrinfo *ai, int listen_port) * * @returns The listening FD on success, -1 on error. */ -static int -_crywrap_listen (const crywrap_config_t *config) +static int _crywrap_listen(const crywrap_config_t * config) { - struct addrinfo *cur; - int ret; - - cur = calloc (1, sizeof (struct addrinfo)); - if (cur == NULL) - return -1; - - cur->ai_family = config->listen.addr->ss_family; - - switch (cur->ai_family) - { - case AF_INET6: - cur->ai_addrlen = sizeof (struct sockaddr_in6); - break; - case AF_INET: - cur->ai_addrlen = sizeof (struct sockaddr_in); - break; - } - - cur->ai_addr = malloc (cur->ai_addrlen); - if (cur->ai_addr == NULL) - return -1; - - memcpy (cur->ai_addr, config->listen.addr, cur->ai_addrlen); - - ret = _crywrap_bind (cur, htons (config->listen.port)); - free (cur->ai_addr); - free (cur); - - return ret; + struct addrinfo *cur; + int ret; + + cur = calloc(1, sizeof(struct addrinfo)); + if (cur == NULL) + return -1; + + cur->ai_family = config->listen.addr->ss_family; + + switch (cur->ai_family) { + case AF_INET6: + cur->ai_addrlen = sizeof(struct sockaddr_in6); + break; + case AF_INET: + cur->ai_addrlen = sizeof(struct sockaddr_in); + break; + } + + cur->ai_addr = malloc(cur->ai_addrlen); + if (cur->ai_addr == NULL) + return -1; + + memcpy(cur->ai_addr, config->listen.addr, cur->ai_addrlen); + + ret = _crywrap_bind(cur, htons(config->listen.port)); + free(cur->ai_addr); + free(cur); + + return ret; } /** Connect to a remote server. @@ -677,60 +691,56 @@ _crywrap_listen (const crywrap_config_t *config) * @returns the connected socket on success, otherwise it exits. */ static int -_crywrap_remote_connect (const struct sockaddr_storage *addr, int port) +_crywrap_remote_connect(const struct sockaddr_storage *addr, int port) { - struct addrinfo *cur; - int sock; - - cur = calloc (1, sizeof (struct addrinfo)); - if (cur == NULL) - return -1; - - cur->ai_family = addr->ss_family; - - switch (cur->ai_family) - { - case AF_INET6: - cur->ai_addrlen = sizeof (struct sockaddr_in6); - break; - case AF_INET: - cur->ai_addrlen = sizeof (struct sockaddr_in); - break; - } - - cur->ai_addr = malloc (cur->ai_addrlen); - if (cur->ai_addr == NULL) - return -1; - - memcpy (cur->ai_addr, addr, cur->ai_addrlen); - - switch (cur->ai_family) - { - case AF_INET6: - ((struct sockaddr_in6 *)(cur->ai_addr))->sin6_port = port; - break; - case AF_INET: - ((struct sockaddr_in *)(cur->ai_addr))->sin_port = port; - break; - } - - sock = socket (cur->ai_family, SOCK_STREAM, IPPROTO_IP); - if (sock < 0) - { - cry_error ("socket(): %s", strerror (errno)); - exit (1); - } - - if (connect (sock, cur->ai_addr, cur->ai_addrlen) < 0) - { - cry_error ("connect(): %s", strerror (errno)); - exit (1); - } - - free (cur->ai_addr); - free (cur); - - return sock; + struct addrinfo *cur; + int sock; + + cur = calloc(1, sizeof(struct addrinfo)); + if (cur == NULL) + return -1; + + cur->ai_family = addr->ss_family; + + switch (cur->ai_family) { + case AF_INET6: + cur->ai_addrlen = sizeof(struct sockaddr_in6); + break; + case AF_INET: + cur->ai_addrlen = sizeof(struct sockaddr_in); + break; + } + + cur->ai_addr = malloc(cur->ai_addrlen); + if (cur->ai_addr == NULL) + return -1; + + memcpy(cur->ai_addr, addr, cur->ai_addrlen); + + switch (cur->ai_family) { + case AF_INET6: + ((struct sockaddr_in6 *) (cur->ai_addr))->sin6_port = port; + break; + case AF_INET: + ((struct sockaddr_in *) (cur->ai_addr))->sin_port = port; + break; + } + + sock = socket(cur->ai_family, SOCK_STREAM, IPPROTO_IP); + if (sock < 0) { + cry_error("socket(): %s", strerror(errno)); + exit(1); + } + + if (connect(sock, cur->ai_addr, cur->ai_addrlen) < 0) { + cry_error("connect(): %s", strerror(errno)); + exit(1); + } + + free(cur->ai_addr); + free(cur); + + return sock; } /** @} */ @@ -743,40 +753,35 @@ _crywrap_remote_connect (const struct sockaddr_storage *addr, int port) * Drop privileges, if running as root. * Upon failure, it will make CryWrap exit. */ -static void -_crywrap_privs_drop (const crywrap_config_t *config) +static void _crywrap_privs_drop(const crywrap_config_t * config) { - struct passwd *pwd; - - if (getuid () != 0) - { - cry_log ("%s", "Not running as root, not dropping privileges."); - return; - } - - if ((pwd = getpwuid (config->uid)) == NULL) - { - cry_error ("getpwuid(): %s", strerror (errno)); - exit (1); - } - - if (initgroups (pwd->pw_name, pwd->pw_gid) == -1) - { - cry_error ("initgroups(): %s", strerror (errno)); - exit (1); - } - - if (setgid (pwd->pw_gid) == -1) - { - cry_error ("setgid(): %s", strerror (errno)); - exit (1); - } - - if (setuid (config->uid)) - { - cry_error ("setuid(): %s", strerror (errno)); - exit (1); - } + struct passwd *pwd; + + if (getuid() != 0) { + cry_log("%s", + "Not running as root, not dropping privileges."); + return; + } + + if ((pwd = getpwuid(config->uid)) == NULL) { + cry_error("getpwuid(): %s", strerror(errno)); + exit(1); + } + + if (initgroups(pwd->pw_name, pwd->pw_gid) == -1) { + cry_error("initgroups(): %s", strerror(errno)); + exit(1); + } + + if (setgid(pwd->pw_gid) == -1) { + cry_error("setgid(): %s", strerror(errno)); + exit(1); + } + + if (setuid(config->uid)) { + cry_error("setuid(): %s", strerror(errno)); + exit(1); + } } /** Set up the PID file. @@ -785,34 +790,32 @@ _crywrap_privs_drop (const crywrap_config_t *config) * * @note Exits upon error. */ -static void -_crywrap_setup_pidfile (const crywrap_config_t *config) +static void _crywrap_setup_pidfile(const crywrap_config_t * config) { - char mypid[128]; - int pidfilefd; - - if (!config->pidfile || !*(config->pidfile)) - return; - - if (!access (config->pidfile, F_OK)) - { - cry_error ("Pidfile (%s) already exists. Exiting.", config->pidfile); - exit (1); - } - if ((pidfilefd = open (config->pidfile, - O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) - { - cry_error ("Cannot create pidfile (%s): %s.\n", config->pidfile, - strerror (errno)); - exit (1); - } - fchown (pidfilefd, config->uid, (gid_t)-1); - - main_pid = getpid (); - snprintf (mypid, sizeof (mypid), "%d\n", main_pid); - write (pidfilefd, mypid, strlen (mypid)); - close (pidfilefd); - pidfile = config->pidfile; + char mypid[128]; + int pidfilefd; + + if (!config->pidfile || !*(config->pidfile)) + return; + + if (!access(config->pidfile, F_OK)) { + cry_error("Pidfile (%s) already exists. Exiting.", + config->pidfile); + exit(1); + } + if ((pidfilefd = open(config->pidfile, + O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) { + cry_error("Cannot create pidfile (%s): %s.\n", + config->pidfile, strerror(errno)); + exit(1); + } + fchown(pidfilefd, config->uid, (gid_t) - 1); + + main_pid = getpid(); + snprintf(mypid, sizeof(mypid), "%d\n", main_pid); + write(pidfilefd, mypid, strlen(mypid)); + close(pidfilefd); + pidfile = config->pidfile; } @@ -827,273 +830,258 @@ _crywrap_setup_pidfile (const crywrap_config_t *config) * @note Exits on error. */ static int -_crywrap_do_one (const crywrap_config_t *config, int insock, int outsock) +_crywrap_do_one(const crywrap_config_t * config, int insock, int outsock) { - int sock, ret, tls_pending; - gnutls_session_t session; - char buffer[_CRYWRAP_MAXBUF + 2]; - fd_set fdset; - unsigned int status = 0; - struct sockaddr_storage faddr; - socklen_t socklen = sizeof (struct sockaddr_storage); - char peer_name[NI_MAXHOST]; - - /* Log the connection */ - if (getpeername (insock, (struct sockaddr *)&faddr, &socklen) != 0) - cry_error ("getpeername(): %s", strerror (errno)); - else - { - getnameinfo ((struct sockaddr *)&faddr, - sizeof (struct sockaddr_storage), peer_name, - sizeof (peer_name), NULL, 0, NI_NUMERICHOST); - cry_log ("Accepted connection from %s on %d to %s/%d", - peer_name, insock, config->dest.host, - config->dest.port); - } - - /* Do the handshake with our peer */ - session = _crywrap_tls_session_create (config); - gnutls_transport_set_ptr2 (session, - (gnutls_transport_ptr_t)insock, - (gnutls_transport_ptr_t)outsock); - - do - { - ret = gnutls_handshake(session); - } - while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); - - if (ret < 0) - { - cry_error ("Handshake failed: %s", gnutls_strerror (ret)); - gnutls_alert_send_appropriate(session, ret); - goto error; - } - - /* Verify the client's certificate, if any. */ - if (config->verify) - { - ret = gnutls_certificate_verify_peers2 (session, &status); - if (ret < 0) - cry_log ("Error getting certificate from client: %s", - gnutls_strerror (ret)); - - if (ret == 0 && status != 0) - { - if (status & GNUTLS_CERT_INVALID) - cry_log ("%s", "Client certificate not trusted or invalid"); - } - - if (config->verify > 0 && status != 0) - { - ret = -1; - gnutls_alert_send( session, GNUTLS_AL_FATAL, GNUTLS_A_INSUFFICIENT_SECURITY); - goto error; - } - } - - /* Connect to the remote host */ - sock = _crywrap_remote_connect (config->dest.addr, - htons (config->dest.port)); - - for (;;) - { - FD_ZERO (&fdset); - FD_SET (insock, &fdset); - FD_SET (sock, &fdset); - - memset (buffer, 0, _CRYWRAP_MAXBUF + 1); - - tls_pending = 0; - - if (gnutls_record_check_pending(session) > 0) - tls_pending = 1; - else - { - select (sock + 1, &fdset, NULL, NULL, NULL); - if (FD_ISSET (insock, &fdset)) - tls_pending = 1; - } - /* TLS client */ - if (tls_pending != 0) - { - ret = gnutls_record_recv (session, buffer, _CRYWRAP_MAXBUF); - if (ret == 0) - { - cry_log ("%s", "Peer has closed the GNUTLS connection"); - break; - } - else if (ret < 0) - { - cry_log ("Received corrupted data: %s.", - gnutls_strerror (ret)); - break; - } - else - send (sock, buffer, ret, 0); + int sock, ret, tls_pending; + gnutls_session_t session; + char buffer[_CRYWRAP_MAXBUF + 2]; + fd_set fdset; + unsigned int status = 0; + struct sockaddr_storage faddr; + socklen_t socklen = sizeof(struct sockaddr_storage); + char peer_name[NI_MAXHOST]; + + /* Log the connection */ + if (getpeername(insock, (struct sockaddr *) &faddr, &socklen) != 0) + cry_error("getpeername(): %s", strerror(errno)); + else { + getnameinfo((struct sockaddr *) &faddr, + sizeof(struct sockaddr_storage), peer_name, + sizeof(peer_name), NULL, 0, NI_NUMERICHOST); + cry_log("Accepted connection from %s on %d to %s/%d", + peer_name, insock, config->dest.host, + config->dest.port); } - /* Remote server */ - if (FD_ISSET (sock, &fdset)) - { - ret = recv (sock, buffer, _CRYWRAP_MAXBUF, 0); - if (ret == 0) - { - cry_log ("%s", "Server has closed the connection"); - break; - } - else if (ret < 0) - { - cry_log ("Received corrupted data: %s.", strerror (errno)); - break; - } - else - { - int r, o = 0; - - do - { - r = gnutls_record_send (session, &buffer[o], ret - o); - o += r; - } while (r > 0 && ret > o); + /* Do the handshake with our peer */ + session = _crywrap_tls_session_create(config); + gnutls_transport_set_ptr2(session, + (gnutls_transport_ptr_t) insock, + (gnutls_transport_ptr_t) outsock); - if (r < 0) - cry_log ("Received corrupt data: %s", gnutls_strerror (r)); - } + do { + ret = gnutls_handshake(session); } - } + while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); -error: - gnutls_bye (session, GNUTLS_SHUT_WR); - gnutls_deinit (session); - close (insock); - close (outsock); + if (ret < 0) { + cry_error("Handshake failed: %s", gnutls_strerror(ret)); + gnutls_alert_send_appropriate(session, ret); + goto error; + } - return (ret == 0) ? 0 : 1; + /* Verify the client's certificate, if any. */ + if (config->verify) { + ret = gnutls_certificate_verify_peers2(session, &status); + if (ret < 0) + cry_log + ("Error getting certificate from client: %s", + gnutls_strerror(ret)); + + if (ret == 0 && status != 0) { + if (status & GNUTLS_CERT_INVALID) + cry_log("%s", + "Client certificate not trusted or invalid"); + } + + if (config->verify > 0 && status != 0) { + ret = -1; + gnutls_alert_send(session, GNUTLS_AL_FATAL, + GNUTLS_A_INSUFFICIENT_SECURITY); + goto error; + } + } + + /* Connect to the remote host */ + sock = _crywrap_remote_connect(config->dest.addr, + htons(config->dest.port)); + + for (;;) { + FD_ZERO(&fdset); + FD_SET(insock, &fdset); + FD_SET(sock, &fdset); + + memset(buffer, 0, _CRYWRAP_MAXBUF + 1); + + tls_pending = 0; + + if (gnutls_record_check_pending(session) > 0) + tls_pending = 1; + else { + select(sock + 1, &fdset, NULL, NULL, NULL); + if (FD_ISSET(insock, &fdset)) + tls_pending = 1; + } + /* TLS client */ + if (tls_pending != 0) { + ret = + gnutls_record_recv(session, buffer, + _CRYWRAP_MAXBUF); + if (ret == 0) { + cry_log("%s", + "Peer has closed the GNUTLS connection"); + break; + } else if (ret < 0) { + cry_log("Received corrupted data: %s.", + gnutls_strerror(ret)); + break; + } else + send(sock, buffer, ret, 0); + } + + /* Remote server */ + if (FD_ISSET(sock, &fdset)) { + ret = recv(sock, buffer, _CRYWRAP_MAXBUF, 0); + if (ret == 0) { + cry_log("%s", + "Server has closed the connection"); + break; + } else if (ret < 0) { + cry_log("Received corrupted data: %s.", + strerror(errno)); + break; + } else { + int r, o = 0; + + do { + r = gnutls_record_send(session, + &buffer[o], + ret - o); + o += r; + } while (r > 0 && ret > o); + + if (r < 0) + cry_log + ("Received corrupt data: %s", + gnutls_strerror(r)); + } + } + } + + error: + gnutls_bye(session, GNUTLS_SHUT_WR); + gnutls_deinit(session); + close(insock); + close(outsock); + + return (ret == 0) ? 0 : 1; } /** CryWrap entry point. * This is the main entry point - controls the whole program and so * on... */ -int -main (int argc, char **argv, char **envp) +int main(int argc, char **argv, char **envp) { - crywrap_config_t *config; - int server_socket; - - openlog (__CRYWRAP__, LOG_PID, LOG_DAEMON); - - gnutls_global_set_audit_log_function (tls_audit_log_func); - - if (gnutls_global_init () < 0) - { - cry_error ("%s", "Global TLS state initialisation failed."); - exit (1); - } - if (gnutls_certificate_allocate_credentials (&cred) < 0) - { - cry_error ("%s", "Couldn't allocate credentials."); - exit (1); - } - - stringprep_locale_charset (); - - config = _crywrap_config_parse (argc, argv); - - _crywrap_tls_init (); - - if (config->inetd) - { - _crywrap_privs_drop (config); - exit (_crywrap_do_one (config, 0, 1)); - } - - if (!config->debug) - if (daemon (0, 0)) - { - cry_error ("daemon: %s", strerror (errno)); - exit (1); - } - - cry_log ("%s", "Crywrap starting..."); - - server_socket = _crywrap_listen (config); - if (server_socket < 0) - exit (1); - - if (!config->debug) _crywrap_setup_pidfile (config); - _crywrap_privs_drop (config); - - signal (SIGTERM, _crywrap_sighandler); - signal (SIGQUIT, _crywrap_sighandler); - signal (SIGSEGV, _crywrap_sighandler); - signal (SIGPIPE, SIG_IGN); - signal (SIGHUP, SIG_IGN); - signal (SIGCHLD, _crywrap_sigchld_handler); - - cry_log ("%s", "Accepting connections"); - - - for (;;) - { - int csock; - int child; - - csock = accept (server_socket, NULL, NULL); - if (csock < 0) - continue; - - child = fork (); - switch (child) - { - case 0: - exit (_crywrap_do_one (config, csock, csock)); - break; - case -1: - cry_error ("%s", "Forking error."); - exit (1); - break; + crywrap_config_t *config; + int server_socket; + + openlog(__CRYWRAP__, LOG_PID, LOG_DAEMON); + + gnutls_global_set_audit_log_function(tls_audit_log_func); + + if (gnutls_global_init() < 0) { + cry_error("%s", "Global TLS state initialisation failed."); + exit(1); + } + if (gnutls_certificate_allocate_credentials(&cred) < 0) { + cry_error("%s", "Couldn't allocate credentials."); + exit(1); } - close(csock); - } - return 0; + stringprep_locale_charset(); + + config = _crywrap_config_parse(argc, argv); + + _crywrap_tls_init(); + + if (config->inetd) { + _crywrap_privs_drop(config); + exit(_crywrap_do_one(config, 0, 1)); + } + + if (!config->debug) + if (daemon(0, 0)) { + cry_error("daemon: %s", strerror(errno)); + exit(1); + } + + cry_log("%s", "Crywrap starting..."); + + server_socket = _crywrap_listen(config); + if (server_socket < 0) + exit(1); + + if (!config->debug) + _crywrap_setup_pidfile(config); + _crywrap_privs_drop(config); + + signal(SIGTERM, _crywrap_sighandler); + signal(SIGQUIT, _crywrap_sighandler); + signal(SIGSEGV, _crywrap_sighandler); + signal(SIGPIPE, SIG_IGN); + signal(SIGHUP, SIG_IGN); + signal(SIGCHLD, _crywrap_sigchld_handler); + + cry_log("%s", "Accepting connections"); + + + for (;;) { + int csock; + int child; + + csock = accept(server_socket, NULL, NULL); + if (csock < 0) + continue; + + child = fork(); + switch (child) { + case 0: + exit(_crywrap_do_one(config, csock, csock)); + break; + case -1: + cry_error("%s", "Forking error."); + exit(1); + break; + } + close(csock); + } + + return 0; } -static int system_log(const char* fmt, ...) +static int system_log(const char *fmt, ...) { - va_list args; + va_list args; - va_start (args, fmt); - vsyslog(LOG_NOTICE, fmt, args); - va_end (args); + va_start(args, fmt); + vsyslog(LOG_NOTICE, fmt, args); + va_end(args); - return 0; + return 0; } -static int system_log_error(const char* fmt, ...) +static int system_log_error(const char *fmt, ...) { - va_list args; + va_list args; - va_start (args, fmt); - vsyslog(LOG_ERR, fmt, args); - va_end (args); + va_start(args, fmt); + vsyslog(LOG_ERR, fmt, args); + va_end(args); - return 0; + return 0; } -static int debug_log(const char* fmt, ...) +static int debug_log(const char *fmt, ...) { - va_list args; + va_list args; - va_start (args, fmt); - vprintf(fmt, args); - puts(""); - va_end (args); + va_start(args, fmt); + vprintf(fmt, args); + puts(""); + va_end(args); - return 0; + return 0; } /** @} */ - diff --git a/src/crywrap/crywrap.h b/src/crywrap/crywrap.h index e246e27a44..a41990f4a0 100644 --- a/src/crywrap/crywrap.h +++ b/src/crywrap/crywrap.h @@ -57,35 +57,37 @@ * Most of the CryWrap configuration - those options that are settable * via the command-line are stored in a variable of this type. */ -typedef struct -{ +typedef struct { /** Properties of the listening socket. */ - struct - { - in_port_t port; - struct sockaddr_storage *addr; - } listen; + struct { + in_port_t port; + struct sockaddr_storage *addr; + } listen; /** Properties of the destination socket. */ - struct - { - in_port_t port; - char *host; - struct sockaddr_storage *addr; - } dest; + struct { + in_port_t port; + char *host; + struct sockaddr_storage *addr; + } dest; - gnutls_priority_t priority; /**< GnuTLS priority string. */ - const char *pidfile; /**< File to store our PID in. */ - uid_t uid; /**< User ID to run as. */ - int inetd; /**< InetD-mode toggle. */ - int anon; /**< Anon-DH toggle. */ - int verify; /**< Client certificate verify level. */ - int debug; + gnutls_priority_t priority; + /**< GnuTLS priority string. */ + const char *pidfile; + /**< File to store our PID in. */ + uid_t uid; + /**< User ID to run as. */ + int inetd; + /**< InetD-mode toggle. */ + int anon; + /**< Anon-DH toggle. */ + int verify; + /**< Client certificate verify level. */ + int debug; } crywrap_config_t; -/** @} *//* End of the Options group */ - -#endif /* !_CRYWRAP_H */ + /** @} *//* End of the Options group */ +#endif /* !_CRYWRAP_H */ diff --git a/src/crywrap/primes.h b/src/crywrap/primes.h index 50c331d39d..2ca1e1ad86 100644 --- a/src/crywrap/primes.h +++ b/src/crywrap/primes.h @@ -33,10 +33,9 @@ /** Initial DH primes, 1024 bits. */ static char _crywrap_prime_dh_1024[] = "-----BEGIN DH PARAMETERS-----\n" -"MIGHAoGBAO6vCrmts43WnDP4CvqPxehgcmGHdf88C56iMUycJWV21nTfdJbqgdM4\n" -"O0gT1pLG4ODV2OJQuYvkjklcHWCJ2tFdx9e0YVTWts6O9K1psV1JglWbKXvPGIXF\n" -"KfVmZg5X7GjtvDwFcmzAL9TL9Jduqpr9UTj+g3ZDW5/GHS/A6wbjAgEC\n" -"-----END DH PARAMETERS-----\n"; + "MIGHAoGBAO6vCrmts43WnDP4CvqPxehgcmGHdf88C56iMUycJWV21nTfdJbqgdM4\n" + "O0gT1pLG4ODV2OJQuYvkjklcHWCJ2tFdx9e0YVTWts6O9K1psV1JglWbKXvPGIXF\n" + "KfVmZg5X7GjtvDwFcmzAL9TL9Jduqpr9UTj+g3ZDW5/GHS/A6wbjAgEC\n" + "-----END DH PARAMETERS-----\n"; #endif - diff --git a/src/danetool.c b/src/danetool.c index 436de5413f..1f2c8e27e4 100644 --- a/src/danetool.c +++ b/src/danetool.c @@ -29,7 +29,7 @@ #include <gnutls/crypto.h> #ifdef HAVE_DANE -# include <gnutls/dane.h> +#include <gnutls/dane.h> #endif #include <stdio.h> @@ -50,12 +50,13 @@ #include "danetool-args.h" #include "certtool-common.h" -static void cmd_parser (int argc, char **argv); -static void dane_info(const char* host, const char* proto, unsigned int port, - unsigned int ca, unsigned int domain, common_info_st * cinfo); +static void cmd_parser(int argc, char **argv); +static void dane_info(const char *host, const char *proto, + unsigned int port, unsigned int ca, + unsigned int domain, common_info_st * cinfo); -static void dane_check(const char* host, const char* proto, unsigned int port, - common_info_st * cinfo); +static void dane_check(const char *host, const char *proto, + unsigned int port, common_info_st * cinfo); FILE *outfile; static gnutls_digest_algorithm_t default_dig; @@ -65,406 +66,420 @@ static gnutls_digest_algorithm_t default_dig; int batch; -static void -tls_log_func (int level, const char *str) +static void tls_log_func(int level, const char *str) { - fprintf (stderr, "|<%d>| %s", level, str); + fprintf(stderr, "|<%d>| %s", level, str); } -int -main (int argc, char **argv) +int main(int argc, char **argv) { - cmd_parser (argc, argv); + cmd_parser(argc, argv); - return 0; + return 0; } -static void -cmd_parser (int argc, char **argv) +static void cmd_parser(int argc, char **argv) { - int ret, privkey_op = 0; - common_info_st cinfo; - const char* proto = "tcp"; - unsigned int port = 443; - - optionProcess( &danetoolOptions, argc, argv); - - if (HAVE_OPT(OUTFILE)) - { - outfile = safe_open_rw (OPT_ARG(OUTFILE), privkey_op); - if (outfile == NULL) - { - fprintf (stderr, "%s", OPT_ARG(OUTFILE)); - exit(1); - } - } - else - outfile = stdout; - - default_dig = GNUTLS_DIG_UNKNOWN; - if (HAVE_OPT(HASH)) - { - if (strcasecmp (OPT_ARG(HASH), "md5") == 0) - { - fprintf (stderr, - "Warning: MD5 is broken, and should not be used any more for digital signatures.\n"); - default_dig = GNUTLS_DIG_MD5; - } - else if (strcasecmp (OPT_ARG(HASH), "sha1") == 0) - default_dig = GNUTLS_DIG_SHA1; - else if (strcasecmp (OPT_ARG(HASH), "sha256") == 0) - default_dig = GNUTLS_DIG_SHA256; - else if (strcasecmp (OPT_ARG(HASH), "sha224") == 0) - default_dig = GNUTLS_DIG_SHA224; - else if (strcasecmp (OPT_ARG(HASH), "sha384") == 0) - default_dig = GNUTLS_DIG_SHA384; - else if (strcasecmp (OPT_ARG(HASH), "sha512") == 0) - default_dig = GNUTLS_DIG_SHA512; - else if (strcasecmp (OPT_ARG(HASH), "rmd160") == 0) - default_dig = GNUTLS_DIG_RMD160; - else - { - fprintf (stderr, "invalid hash: %s", OPT_ARG(HASH)); - exit(1); - } - } - - gnutls_global_set_log_function (tls_log_func); - - if (HAVE_OPT(DEBUG)) - { - gnutls_global_set_log_level (OPT_VALUE_DEBUG); - printf ("Setting log level to %d\n", (int)OPT_VALUE_DEBUG); - } - - if ((ret = gnutls_global_init ()) < 0) - { - fprintf (stderr, "global_init: %s", gnutls_strerror (ret)); - exit(1); - } - + int ret, privkey_op = 0; + common_info_st cinfo; + const char *proto = "tcp"; + unsigned int port = 443; + + optionProcess(&danetoolOptions, argc, argv); + + if (HAVE_OPT(OUTFILE)) { + outfile = safe_open_rw(OPT_ARG(OUTFILE), privkey_op); + if (outfile == NULL) { + fprintf(stderr, "%s", OPT_ARG(OUTFILE)); + exit(1); + } + } else + outfile = stdout; + + default_dig = GNUTLS_DIG_UNKNOWN; + if (HAVE_OPT(HASH)) { + if (strcasecmp(OPT_ARG(HASH), "md5") == 0) { + fprintf(stderr, + "Warning: MD5 is broken, and should not be used any more for digital signatures.\n"); + default_dig = GNUTLS_DIG_MD5; + } else if (strcasecmp(OPT_ARG(HASH), "sha1") == 0) + default_dig = GNUTLS_DIG_SHA1; + else if (strcasecmp(OPT_ARG(HASH), "sha256") == 0) + default_dig = GNUTLS_DIG_SHA256; + else if (strcasecmp(OPT_ARG(HASH), "sha224") == 0) + default_dig = GNUTLS_DIG_SHA224; + else if (strcasecmp(OPT_ARG(HASH), "sha384") == 0) + default_dig = GNUTLS_DIG_SHA384; + else if (strcasecmp(OPT_ARG(HASH), "sha512") == 0) + default_dig = GNUTLS_DIG_SHA512; + else if (strcasecmp(OPT_ARG(HASH), "rmd160") == 0) + default_dig = GNUTLS_DIG_RMD160; + else { + fprintf(stderr, "invalid hash: %s", OPT_ARG(HASH)); + exit(1); + } + } + + gnutls_global_set_log_function(tls_log_func); + + if (HAVE_OPT(DEBUG)) { + gnutls_global_set_log_level(OPT_VALUE_DEBUG); + printf("Setting log level to %d\n", (int) OPT_VALUE_DEBUG); + } + + if ((ret = gnutls_global_init()) < 0) { + fprintf(stderr, "global_init: %s", gnutls_strerror(ret)); + exit(1); + } #ifdef ENABLE_PKCS11 - pkcs11_common(); + pkcs11_common(); #endif - memset (&cinfo, 0, sizeof (cinfo)); - - if (HAVE_OPT(INDER) || HAVE_OPT(INRAW)) - cinfo.incert_format = GNUTLS_X509_FMT_DER; - else - cinfo.incert_format = GNUTLS_X509_FMT_PEM; - - if (HAVE_OPT(VERBOSE)) - cinfo.verbose = 1; - - if (HAVE_OPT(LOAD_PUBKEY)) - cinfo.pubkey = OPT_ARG(LOAD_PUBKEY); - - if (HAVE_OPT(LOAD_CERTIFICATE)) - cinfo.cert = OPT_ARG(LOAD_CERTIFICATE); - - if (HAVE_OPT(PORT)) - port = OPT_VALUE_PORT; - if (HAVE_OPT(PROTO)) - proto = OPT_ARG(PROTO); - - if (HAVE_OPT(TLSA_RR)) - dane_info (OPT_ARG(HOST), proto, port, - HAVE_OPT(CA), ENABLED_OPT(DOMAIN), &cinfo); - else if (HAVE_OPT(CHECK)) - dane_check (OPT_ARG(CHECK), proto, port, - &cinfo); - else - USAGE(1); - - fclose (outfile); + memset(&cinfo, 0, sizeof(cinfo)); + + if (HAVE_OPT(INDER) || HAVE_OPT(INRAW)) + cinfo.incert_format = GNUTLS_X509_FMT_DER; + else + cinfo.incert_format = GNUTLS_X509_FMT_PEM; + + if (HAVE_OPT(VERBOSE)) + cinfo.verbose = 1; + + if (HAVE_OPT(LOAD_PUBKEY)) + cinfo.pubkey = OPT_ARG(LOAD_PUBKEY); + + if (HAVE_OPT(LOAD_CERTIFICATE)) + cinfo.cert = OPT_ARG(LOAD_CERTIFICATE); + + if (HAVE_OPT(PORT)) + port = OPT_VALUE_PORT; + if (HAVE_OPT(PROTO)) + proto = OPT_ARG(PROTO); + + if (HAVE_OPT(TLSA_RR)) + dane_info(OPT_ARG(HOST), proto, port, + HAVE_OPT(CA), ENABLED_OPT(DOMAIN), &cinfo); + else if (HAVE_OPT(CHECK)) + dane_check(OPT_ARG(CHECK), proto, port, &cinfo); + else + USAGE(1); + + fclose(outfile); #ifdef ENABLE_PKCS11 - gnutls_pkcs11_deinit (); + gnutls_pkcs11_deinit(); #endif - gnutls_global_deinit (); + gnutls_global_deinit(); } -static void dane_check(const char* host, const char* proto, unsigned int port, - common_info_st * cinfo) +static void dane_check(const char *host, const char *proto, + unsigned int port, common_info_st * cinfo) { #ifdef HAVE_DANE -dane_state_t s; -dane_query_t q; -int ret, retcode = 0; -unsigned entries; -unsigned int flags = DANE_F_IGNORE_LOCAL_RESOLVER, i; -unsigned int usage, type, match; -gnutls_datum_t data, file; -size_t size; -unsigned vflags = DANE_VFLAG_FAIL_IF_NOT_CHECKED; - - if (ENABLED_OPT(LOCAL_DNS)) - flags = 0; - - if (HAVE_OPT(INSECURE)) - flags |= DANE_F_INSECURE; - - if (HAVE_OPT(CHECK_EE)) - vflags |= DANE_VFLAG_ONLY_CHECK_EE_USAGE; - - if (HAVE_OPT(CHECK_CA)) - vflags |= DANE_VFLAG_ONLY_CHECK_CA_USAGE; - - printf("Querying %s (%s:%d)...\n", host, proto, port); - ret = dane_state_init(&s, flags); - if (ret < 0) - { - fprintf (stderr, "dane_state_init: %s\n", dane_strerror (ret)); - exit(1); - } - - if (HAVE_OPT(DLV)) - { - ret = dane_state_set_dlv_file(s, OPT_ARG(DLV)); - if (ret < 0) - { - fprintf (stderr, "dane_state_set_dlv_file: %s\n", dane_strerror (ret)); - exit(1); - } - } - - ret = dane_query_tlsa(s, &q, host, proto, port); - if (ret < 0) - { - fprintf (stderr, "dane_query_tlsa: %s\n", dane_strerror (ret)); - exit(1); - } - - entries = dane_query_entries(q); - for (i=0;i<entries;i++) - { - ret = dane_query_data(q, i, &usage, &type, &match, &data); - if (ret < 0) - { - fprintf (stderr, "dane_query_data: %s\n", dane_strerror (ret)); - exit(1); - } - - - size = buffer_size; - ret = gnutls_hex_encode(&data, (void*)buffer, &size); - if (ret < 0) - { - fprintf (stderr, "gnutls_hex_encode: %s\n", dane_strerror (ret)); - exit(1); - } - - if (entries > 1) printf("\nEntry %d:\n", i+1); - - fprintf(outfile, "_%u._%s.%s. IN TLSA ( %.2x %.2x %.2x %s )\n", port, proto, host, usage, type, match, buffer); - printf("Certificate usage: %s (%.2x)\n", dane_cert_usage_name(usage), usage); - printf("Certificate type: %s (%.2x)\n", dane_cert_type_name(type), type); - printf("Contents: %s (%.2x)\n", dane_match_type_name(match), match); - printf("Data: %s\n", buffer); - - /* Verify the DANE data */ - if (cinfo->cert) - { - gnutls_x509_crt_t *clist; - unsigned int clist_size, status; - - ret = gnutls_load_file(cinfo->cert, &file); - if (ret < 0) - { - fprintf (stderr, "gnutls_load_file: %s\n", gnutls_strerror (ret)); - exit(1); - } - - ret = gnutls_x509_crt_list_import2( &clist, &clist_size, &file, cinfo->incert_format, 0); - if (ret < 0) - { - fprintf (stderr, "gnutls_x509_crt_list_import2: %s\n", gnutls_strerror (ret)); - exit(1); - } - - if (clist_size > 0) - { - gnutls_datum_t certs[clist_size]; - gnutls_datum_t out; - unsigned int i; - - for (i=0;i<clist_size;i++) - { - ret = gnutls_x509_crt_export2( clist[i], GNUTLS_X509_FMT_DER, &certs[i]); - if (ret < 0) - { - fprintf (stderr, "gnutls_x509_crt_export2: %s\n", gnutls_strerror (ret)); - exit(1); - } - } - - ret = dane_verify_crt( s, certs, clist_size, GNUTLS_CRT_X509, - host, proto, port, 0, vflags, &status); - if (ret < 0) - { - fprintf (stderr, "dane_verify_crt: %s\n", dane_strerror (ret)); - exit(1); - } - - ret = dane_verification_status_print(status, &out, 0); - if (ret < 0) - { - fprintf( stderr, "dane_verification_status_print: %s\n", dane_strerror (ret)); - exit(1); - } - - printf("\nVerification: %s\n", out.data); - gnutls_free(out.data); - - if (status != 0) retcode = 1; - - for (i=0;i<clist_size;i++) - { - gnutls_free(certs[i].data); - gnutls_x509_crt_deinit(clist[i]); - } - gnutls_free(clist); - } - } - else - { - fprintf(stderr, "\nCertificate was not verified. Use --load-certificate.\n"); - } - } - - - dane_query_deinit(q); - dane_state_deinit(s); - - exit(retcode); + dane_state_t s; + dane_query_t q; + int ret, retcode = 0; + unsigned entries; + unsigned int flags = DANE_F_IGNORE_LOCAL_RESOLVER, i; + unsigned int usage, type, match; + gnutls_datum_t data, file; + size_t size; + unsigned vflags = DANE_VFLAG_FAIL_IF_NOT_CHECKED; + + if (ENABLED_OPT(LOCAL_DNS)) + flags = 0; + + if (HAVE_OPT(INSECURE)) + flags |= DANE_F_INSECURE; + + if (HAVE_OPT(CHECK_EE)) + vflags |= DANE_VFLAG_ONLY_CHECK_EE_USAGE; + + if (HAVE_OPT(CHECK_CA)) + vflags |= DANE_VFLAG_ONLY_CHECK_CA_USAGE; + + printf("Querying %s (%s:%d)...\n", host, proto, port); + ret = dane_state_init(&s, flags); + if (ret < 0) { + fprintf(stderr, "dane_state_init: %s\n", + dane_strerror(ret)); + exit(1); + } + + if (HAVE_OPT(DLV)) { + ret = dane_state_set_dlv_file(s, OPT_ARG(DLV)); + if (ret < 0) { + fprintf(stderr, "dane_state_set_dlv_file: %s\n", + dane_strerror(ret)); + exit(1); + } + } + + ret = dane_query_tlsa(s, &q, host, proto, port); + if (ret < 0) { + fprintf(stderr, "dane_query_tlsa: %s\n", + dane_strerror(ret)); + exit(1); + } + + entries = dane_query_entries(q); + for (i = 0; i < entries; i++) { + ret = dane_query_data(q, i, &usage, &type, &match, &data); + if (ret < 0) { + fprintf(stderr, "dane_query_data: %s\n", + dane_strerror(ret)); + exit(1); + } + + + size = buffer_size; + ret = gnutls_hex_encode(&data, (void *) buffer, &size); + if (ret < 0) { + fprintf(stderr, "gnutls_hex_encode: %s\n", + dane_strerror(ret)); + exit(1); + } + + if (entries > 1) + printf("\nEntry %d:\n", i + 1); + + fprintf(outfile, + "_%u._%s.%s. IN TLSA ( %.2x %.2x %.2x %s )\n", + port, proto, host, usage, type, match, buffer); + printf("Certificate usage: %s (%.2x)\n", + dane_cert_usage_name(usage), usage); + printf("Certificate type: %s (%.2x)\n", + dane_cert_type_name(type), type); + printf("Contents: %s (%.2x)\n", + dane_match_type_name(match), match); + printf("Data: %s\n", buffer); + + /* Verify the DANE data */ + if (cinfo->cert) { + gnutls_x509_crt_t *clist; + unsigned int clist_size, status; + + ret = gnutls_load_file(cinfo->cert, &file); + if (ret < 0) { + fprintf(stderr, "gnutls_load_file: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + ret = + gnutls_x509_crt_list_import2(&clist, + &clist_size, + &file, + cinfo-> + incert_format, 0); + if (ret < 0) { + fprintf(stderr, + "gnutls_x509_crt_list_import2: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + if (clist_size > 0) { + gnutls_datum_t certs[clist_size]; + gnutls_datum_t out; + unsigned int i; + + for (i = 0; i < clist_size; i++) { + ret = + gnutls_x509_crt_export2(clist + [i], + GNUTLS_X509_FMT_DER, + &certs + [i]); + if (ret < 0) { + fprintf(stderr, + "gnutls_x509_crt_export2: %s\n", + gnutls_strerror + (ret)); + exit(1); + } + } + + ret = + dane_verify_crt(s, certs, clist_size, + GNUTLS_CRT_X509, host, + proto, port, 0, vflags, + &status); + if (ret < 0) { + fprintf(stderr, + "dane_verify_crt: %s\n", + dane_strerror(ret)); + exit(1); + } + + ret = + dane_verification_status_print(status, + &out, + 0); + if (ret < 0) { + fprintf(stderr, + "dane_verification_status_print: %s\n", + dane_strerror(ret)); + exit(1); + } + + printf("\nVerification: %s\n", out.data); + gnutls_free(out.data); + + if (status != 0) + retcode = 1; + + for (i = 0; i < clist_size; i++) { + gnutls_free(certs[i].data); + gnutls_x509_crt_deinit(clist[i]); + } + gnutls_free(clist); + } + } else { + fprintf(stderr, + "\nCertificate was not verified. Use --load-certificate.\n"); + } + } + + + dane_query_deinit(q); + dane_state_deinit(s); + + exit(retcode); #else - fprintf(stderr, "This functionality was disabled (GnuTLS was not compiled with support for DANE).\n"); - return; + fprintf(stderr, + "This functionality was disabled (GnuTLS was not compiled with support for DANE).\n"); + return; #endif } -static void dane_info(const char* host, const char* proto, unsigned int port, - unsigned int ca, unsigned int domain, common_info_st * cinfo) +static void dane_info(const char *host, const char *proto, + unsigned int port, unsigned int ca, + unsigned int domain, common_info_st * cinfo) { - gnutls_pubkey_t pubkey; - gnutls_x509_crt_t crt; - unsigned char digest[64]; - gnutls_datum_t t; - int ret; - unsigned int usage, selector, type; - size_t size; - - if (proto == NULL) - proto = "tcp"; - if (port == 0) - port = 443; - - crt = load_cert (0, cinfo); - if (crt != NULL && HAVE_OPT(X509)) - { - selector = 0; /* X.509 */ - - size = buffer_size; - ret = gnutls_x509_crt_export (crt, GNUTLS_X509_FMT_DER, buffer, &size); - if (ret < 0) - { - fprintf( stderr, "export error: %s\n", gnutls_strerror (ret)); - exit(1); - } - - gnutls_x509_crt_deinit (crt); - } - else /* use public key only */ - { - selector = 1; - - ret = gnutls_pubkey_init (&pubkey); - if (ret < 0) - { - fprintf (stderr, "pubkey_init: %s\n", gnutls_strerror (ret)); - exit(1); - } - - if (crt != NULL) - { - - ret = gnutls_pubkey_import_x509 (pubkey, crt, 0); - if (ret < 0) - { - fprintf (stderr, "pubkey_import_x509: %s\n", - gnutls_strerror (ret)); - exit(1); - } - - size = buffer_size; - ret = gnutls_pubkey_export (pubkey, GNUTLS_X509_FMT_DER, buffer, &size); - if (ret < 0) - { - fprintf( stderr, "pubkey_export: %s\n", - gnutls_strerror (ret)); - exit(1); - } - - gnutls_x509_crt_deinit(crt); - } - else - { - pubkey = load_pubkey (1, cinfo); - - size = buffer_size; - ret = gnutls_pubkey_export (pubkey, GNUTLS_X509_FMT_DER, buffer, &size); - if (ret < 0) - { - fprintf (stderr, "export error: %s\n", gnutls_strerror (ret)); - exit(1); - } - } - - gnutls_pubkey_deinit (pubkey); - } - - if (default_dig != GNUTLS_DIG_SHA256 && default_dig != GNUTLS_DIG_SHA512) - { - if (default_dig != GNUTLS_DIG_UNKNOWN) fprintf(stderr, "Unsupported digest. Assuming SHA256.\n"); - default_dig = GNUTLS_DIG_SHA256; - } - - ret = gnutls_hash_fast(default_dig, buffer, size, digest); - if (ret < 0) - { - fprintf( stderr, "hash error: %s\n", gnutls_strerror (ret)); - exit(1); - } - - if (default_dig == GNUTLS_DIG_SHA256) - type = 1; - else type = 2; - - /* DANE certificate classification crap */ - if (domain==0) - { - if (ca) usage = 0; - else usage = 1; - } - else - { - if (ca) usage = 2; - else usage = 3; - } - - t.data = digest; - t.size = gnutls_hash_get_len(default_dig); - - size = buffer_size; - ret = gnutls_hex_encode(&t, (void*)buffer, &size); - if (ret < 0) - { - fprintf (stderr, "hex encode error: %s\n", gnutls_strerror (ret)); - exit(1); - } - - fprintf(outfile, "_%u._%s.%s. IN TLSA ( %.2x %.2x %.2x %s )\n", port, proto, host, usage, selector, type, buffer); + gnutls_pubkey_t pubkey; + gnutls_x509_crt_t crt; + unsigned char digest[64]; + gnutls_datum_t t; + int ret; + unsigned int usage, selector, type; + size_t size; + + if (proto == NULL) + proto = "tcp"; + if (port == 0) + port = 443; + + crt = load_cert(0, cinfo); + if (crt != NULL && HAVE_OPT(X509)) { + selector = 0; /* X.509 */ + + size = buffer_size; + ret = + gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_DER, + buffer, &size); + if (ret < 0) { + fprintf(stderr, "export error: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + gnutls_x509_crt_deinit(crt); + } else { /* use public key only */ + + selector = 1; + + ret = gnutls_pubkey_init(&pubkey); + if (ret < 0) { + fprintf(stderr, "pubkey_init: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + if (crt != NULL) { + + ret = gnutls_pubkey_import_x509(pubkey, crt, 0); + if (ret < 0) { + fprintf(stderr, "pubkey_import_x509: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + size = buffer_size; + ret = + gnutls_pubkey_export(pubkey, + GNUTLS_X509_FMT_DER, + buffer, &size); + if (ret < 0) { + fprintf(stderr, "pubkey_export: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + gnutls_x509_crt_deinit(crt); + } else { + pubkey = load_pubkey(1, cinfo); + + size = buffer_size; + ret = + gnutls_pubkey_export(pubkey, + GNUTLS_X509_FMT_DER, + buffer, &size); + if (ret < 0) { + fprintf(stderr, "export error: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } + + gnutls_pubkey_deinit(pubkey); + } + + if (default_dig != GNUTLS_DIG_SHA256 + && default_dig != GNUTLS_DIG_SHA512) { + if (default_dig != GNUTLS_DIG_UNKNOWN) + fprintf(stderr, + "Unsupported digest. Assuming SHA256.\n"); + default_dig = GNUTLS_DIG_SHA256; + } + + ret = gnutls_hash_fast(default_dig, buffer, size, digest); + if (ret < 0) { + fprintf(stderr, "hash error: %s\n", gnutls_strerror(ret)); + exit(1); + } + + if (default_dig == GNUTLS_DIG_SHA256) + type = 1; + else + type = 2; + + /* DANE certificate classification crap */ + if (domain == 0) { + if (ca) + usage = 0; + else + usage = 1; + } else { + if (ca) + usage = 2; + else + usage = 3; + } + + t.data = digest; + t.size = gnutls_hash_get_len(default_dig); + + size = buffer_size; + ret = gnutls_hex_encode(&t, (void *) buffer, &size); + if (ret < 0) { + fprintf(stderr, "hex encode error: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "_%u._%s.%s. IN TLSA ( %.2x %.2x %.2x %s )\n", + port, proto, host, usage, selector, type, buffer); } diff --git a/src/inline_cmds.h b/src/inline_cmds.h index 49bc5dd120..5cff93362a 100755 --- a/src/inline_cmds.h +++ b/src/inline_cmds.h @@ -38,37 +38,33 @@ * For ex: if --inline-commands-prefix=@, the inline commands will be * @resume@, @renegotiate@, etc... */ -typedef enum INLINE_COMMAND -{ INLINE_COMMAND_NONE, - INLINE_COMMAND_RESUME, - INLINE_COMMAND_RENEGOTIATE +typedef enum INLINE_COMMAND { INLINE_COMMAND_NONE, + INLINE_COMMAND_RESUME, + INLINE_COMMAND_RENEGOTIATE } inline_command_t; #define NUM_INLINE_COMMANDS 2 #define MAX_INLINE_COMMAND_BYTES 20 -typedef struct inline_cmds -{ - char *current_ptr; /* points to the start of the current buffer being processed */ - char *new_buffer_ptr; /* points to start or offset within the caller's buffer, - * and refers to bytes yet to be processed. */ - inline_command_t cmd_found; - int lf_found; - int bytes_to_flush; - ssize_t bytes_copied; - char inline_cmd_buffer[MAX_INLINE_COMMAND_BYTES]; +typedef struct inline_cmds { + char *current_ptr; /* points to the start of the current buffer being processed */ + char *new_buffer_ptr; /* points to start or offset within the caller's buffer, + * and refers to bytes yet to be processed. */ + inline_command_t cmd_found; + int lf_found; + int bytes_to_flush; + ssize_t bytes_copied; + char inline_cmd_buffer[MAX_INLINE_COMMAND_BYTES]; } inline_cmds_st; -struct inline_command_definitions -{ - int command; - char string[MAX_INLINE_COMMAND_BYTES]; +struct inline_command_definitions { + int command; + char string[MAX_INLINE_COMMAND_BYTES]; }; /* All inline commands will contain a trailing LF */ -struct inline_command_definitions inline_commands_def[] = -{ - {INLINE_COMMAND_RESUME, "^resume^\n"}, - {INLINE_COMMAND_RENEGOTIATE, "^renegotiate^\n"}, +struct inline_command_definitions inline_commands_def[] = { + {INLINE_COMMAND_RESUME, "^resume^\n"}, + {INLINE_COMMAND_RENEGOTIATE, "^renegotiate^\n"}, }; diff --git a/src/list.h b/src/list.h index 17a7aa1ce1..0cccd25857 100644 --- a/src/list.h +++ b/src/list.h @@ -132,17 +132,15 @@ int main (int argc, char **argv) the consecutive list-item, or the pre-consecutive list-item. this obviates the need for a hash table for 99% of cercumstances the time */ -struct list -{ - long length; - long item_size; - struct list_item - { - struct list_item *next; - struct list_item *prev; - char data[1]; - } *head, *tail, *search; - void (*free_func) (struct list_item *); +struct list { + long length; + long item_size; + struct list_item { + struct list_item *next; + struct list_item *prev; + char data[1]; + } *head, *tail, *search; + void (*free_func) (struct list_item *); }; /* declare a list of type `x', also called `x' having members `typelist' */ @@ -446,4 +444,4 @@ struct list free (__t); \ } \ -#endif /* _LIST_H */ +#endif /* _LIST_H */ diff --git a/src/ocsptool-common.c b/src/ocsptool-common.c index 4bc3f59341..42ca2fee96 100644 --- a/src/ocsptool-common.c +++ b/src/ocsptool-common.c @@ -46,271 +46,259 @@ static char buffer[MAX_BUF + 1]; /* returns the host part of a URL */ -static const char* host_from_url(const char* url, unsigned int* port) +static const char *host_from_url(const char *url, unsigned int *port) { -static char hostname[512]; -char * p; - - *port = 0; - - if ((p=strstr(url, "http://")) != NULL) - { - snprintf(hostname, sizeof(hostname), "%s", p+7); - p = strchr(hostname, '/'); - if (p != NULL) *p = 0; - - p = strchr(hostname, ':'); - if (p != NULL) { - *p = 0; - *port = atoi(p+1); - } - - return hostname; - } - else - { - return url; - } + static char hostname[512]; + char *p; + + *port = 0; + + if ((p = strstr(url, "http://")) != NULL) { + snprintf(hostname, sizeof(hostname), "%s", p + 7); + p = strchr(hostname, '/'); + if (p != NULL) + *p = 0; + + p = strchr(hostname, ':'); + if (p != NULL) { + *p = 0; + *port = atoi(p + 1); + } + + return hostname; + } else { + return url; + } } void -_generate_request (gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer, - gnutls_datum_t * rdata, int nonce) +_generate_request(gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer, + gnutls_datum_t * rdata, int nonce) { - gnutls_ocsp_req_t req; - int ret; - - ret = gnutls_ocsp_req_init (&req); - if (ret < 0) - { - fprintf( stderr, "ocsp_req_init: %s", gnutls_strerror (ret)); - exit(1); - } - - ret = gnutls_ocsp_req_add_cert (req, GNUTLS_DIG_SHA1, - issuer, cert); - if (ret < 0) - { - fprintf( stderr, "ocsp_req_add_cert: %s", gnutls_strerror (ret)); - exit(1); - } - - if (nonce) - { - unsigned char noncebuf[23]; - gnutls_datum_t nonce = { noncebuf, sizeof (noncebuf) }; - - ret = gnutls_rnd (GNUTLS_RND_RANDOM, nonce.data, nonce.size); - if (ret < 0) - { - fprintf( stderr, "gnutls_rnd: %s", gnutls_strerror (ret)); - exit(1); - } - - ret = gnutls_ocsp_req_set_nonce (req, 0, &nonce); - if (ret < 0) - { - fprintf( stderr, "ocsp_req_set_nonce: %s", - gnutls_strerror (ret)); - exit(1); - } - } - - ret = gnutls_ocsp_req_export (req, rdata); - if (ret != 0) - { - fprintf( stderr, "ocsp_req_export: %s", gnutls_strerror (ret)); - exit(1); - } - - gnutls_ocsp_req_deinit (req); - return; + gnutls_ocsp_req_t req; + int ret; + + ret = gnutls_ocsp_req_init(&req); + if (ret < 0) { + fprintf(stderr, "ocsp_req_init: %s", gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_ocsp_req_add_cert(req, GNUTLS_DIG_SHA1, issuer, cert); + if (ret < 0) { + fprintf(stderr, "ocsp_req_add_cert: %s", + gnutls_strerror(ret)); + exit(1); + } + + if (nonce) { + unsigned char noncebuf[23]; + gnutls_datum_t nonce = { noncebuf, sizeof(noncebuf) }; + + ret = + gnutls_rnd(GNUTLS_RND_RANDOM, nonce.data, nonce.size); + if (ret < 0) { + fprintf(stderr, "gnutls_rnd: %s", + gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_ocsp_req_set_nonce(req, 0, &nonce); + if (ret < 0) { + fprintf(stderr, "ocsp_req_set_nonce: %s", + gnutls_strerror(ret)); + exit(1); + } + } + + ret = gnutls_ocsp_req_export(req, rdata); + if (ret != 0) { + fprintf(stderr, "ocsp_req_export: %s", + gnutls_strerror(ret)); + exit(1); + } + + gnutls_ocsp_req_deinit(req); + return; } -static size_t get_data(void *buffer, size_t size, size_t nmemb, void *userp) +static size_t get_data(void *buffer, size_t size, size_t nmemb, + void *userp) { -gnutls_datum_t *ud = userp; - - size *= nmemb; - - ud->data = realloc(ud->data, size+ud->size); - if (ud->data == NULL) - { - fprintf(stderr, "Not enough memory for the request\n"); - exit(1); - } - - memcpy(&ud->data[ud->size], buffer, size); - ud->size += size; - - return size; + gnutls_datum_t *ud = userp; + + size *= nmemb; + + ud->data = realloc(ud->data, size + ud->size); + if (ud->data == NULL) { + fprintf(stderr, "Not enough memory for the request\n"); + exit(1); + } + + memcpy(&ud->data[ud->size], buffer, size); + ud->size += size; + + return size; } /* Returns 0 on ok, and -1 on error */ -int send_ocsp_request(const char* server, - gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer, - gnutls_datum_t * resp_data, int nonce) +int send_ocsp_request(const char *server, + gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer, + gnutls_datum_t * resp_data, int nonce) { -gnutls_datum_t ud; -int ret; -gnutls_datum_t req; -char* url = (void*)server; -char headers[1024]; -char service[16]; -unsigned char * p; -const char *hostname; -unsigned int headers_size = 0, port; -socket_st hd; - - sockets_init (); - - if (url == NULL) - { - /* try to read URL from issuer certificate */ - gnutls_datum_t data; - - ret = gnutls_x509_crt_get_authority_info_access(cert, 0, - GNUTLS_IA_OCSP_URI, &data, NULL); - - if (ret < 0) - ret = gnutls_x509_crt_get_authority_info_access(issuer, 0, - GNUTLS_IA_OCSP_URI, &data, NULL); - if (ret < 0) - { - fprintf(stderr, "Cannot find URL from issuer: %s\n", gnutls_strerror(ret)); - return -1; - } - - url = malloc(data.size+1); - memcpy(url, data.data, data.size); - url[data.size] = 0; - - gnutls_free(data.data); - } - - hostname = host_from_url(url, &port); - if (port != 0) - snprintf(service, sizeof(service), "%u", port); - else strcpy(service, "80"); - - fprintf(stderr, "Connecting to OCSP server: %s...\n", hostname); - - memset(&ud, 0, sizeof(ud)); - - _generate_request(cert, issuer, &req, nonce); - - snprintf(headers, sizeof(headers), HEADER_PATTERN, hostname, (unsigned int)req.size); - headers_size = strlen(headers); - - socket_open(&hd, hostname, service, 0); - - socket_send(&hd, headers, headers_size); - socket_send(&hd, req.data, req.size); - - do { - ret = socket_recv(&hd, buffer, sizeof(buffer)); - if (ret > 0) get_data(buffer, ret, 1, &ud); - } while(ret > 0); - - if (ret < 0 || ud.size == 0) - { - perror("recv"); - return -1; - } - - socket_bye(&hd); - - p = memmem(ud.data, ud.size, "\r\n\r\n", 4); - if (p == NULL) - { - fprintf(stderr, "Cannot interpret HTTP response\n"); - return -1; - } - - p += 4; - resp_data->size = ud.size - (p - ud.data); - resp_data->data = malloc(resp_data->size); - if (resp_data->data == NULL) - return -1; - - memcpy(resp_data->data, p, resp_data->size); - - free(ud.data); - - return 0; + gnutls_datum_t ud; + int ret; + gnutls_datum_t req; + char *url = (void *) server; + char headers[1024]; + char service[16]; + unsigned char *p; + const char *hostname; + unsigned int headers_size = 0, port; + socket_st hd; + + sockets_init(); + + if (url == NULL) { + /* try to read URL from issuer certificate */ + gnutls_datum_t data; + + ret = gnutls_x509_crt_get_authority_info_access(cert, 0, + GNUTLS_IA_OCSP_URI, + &data, + NULL); + + if (ret < 0) + ret = + gnutls_x509_crt_get_authority_info_access + (issuer, 0, GNUTLS_IA_OCSP_URI, &data, NULL); + if (ret < 0) { + fprintf(stderr, + "Cannot find URL from issuer: %s\n", + gnutls_strerror(ret)); + return -1; + } + + url = malloc(data.size + 1); + memcpy(url, data.data, data.size); + url[data.size] = 0; + + gnutls_free(data.data); + } + + hostname = host_from_url(url, &port); + if (port != 0) + snprintf(service, sizeof(service), "%u", port); + else + strcpy(service, "80"); + + fprintf(stderr, "Connecting to OCSP server: %s...\n", hostname); + + memset(&ud, 0, sizeof(ud)); + + _generate_request(cert, issuer, &req, nonce); + + snprintf(headers, sizeof(headers), HEADER_PATTERN, hostname, + (unsigned int) req.size); + headers_size = strlen(headers); + + socket_open(&hd, hostname, service, 0); + + socket_send(&hd, headers, headers_size); + socket_send(&hd, req.data, req.size); + + do { + ret = socket_recv(&hd, buffer, sizeof(buffer)); + if (ret > 0) + get_data(buffer, ret, 1, &ud); + } while (ret > 0); + + if (ret < 0 || ud.size == 0) { + perror("recv"); + return -1; + } + + socket_bye(&hd); + + p = memmem(ud.data, ud.size, "\r\n\r\n", 4); + if (p == NULL) { + fprintf(stderr, "Cannot interpret HTTP response\n"); + return -1; + } + + p += 4; + resp_data->size = ud.size - (p - ud.data); + resp_data->data = malloc(resp_data->size); + if (resp_data->data == NULL) + return -1; + + memcpy(resp_data->data, p, resp_data->size); + + free(ud.data); + + return 0; } -void -print_ocsp_verify_res (unsigned int output) +void print_ocsp_verify_res(unsigned int output) { - int comma = 0; - - if (output) - { - printf ("Failure"); - comma = 1; - } - else - { - printf ("Success"); - comma = 1; - } - - if (output & GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND) - { - if (comma) - printf (", "); - printf ("Signer cert not found"); - comma = 1; - } - - if (output & GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR) - { - if (comma) - printf (", "); - printf ("Signer cert keyusage error"); - comma = 1; - } - - if (output & GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER) - { - if (comma) - printf (", "); - printf ("Signer cert is not trusted"); - comma = 1; - } - - if (output & GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM) - { - if (comma) - printf (", "); - printf ("Insecure algorithm"); - comma = 1; - } - - if (output & GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE) - { - if (comma) - printf (", "); - printf ("Signature failure"); - comma = 1; - } - - if (output & GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED) - { - if (comma) - printf (", "); - printf ("Signer cert not yet activated"); - comma = 1; - } - - if (output & GNUTLS_OCSP_VERIFY_CERT_EXPIRED) - { - if (comma) - printf (", "); - printf ("Signer cert expired"); - comma = 1; - } + int comma = 0; + + if (output) { + printf("Failure"); + comma = 1; + } else { + printf("Success"); + comma = 1; + } + + if (output & GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND) { + if (comma) + printf(", "); + printf("Signer cert not found"); + comma = 1; + } + + if (output & GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR) { + if (comma) + printf(", "); + printf("Signer cert keyusage error"); + comma = 1; + } + + if (output & GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER) { + if (comma) + printf(", "); + printf("Signer cert is not trusted"); + comma = 1; + } + + if (output & GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM) { + if (comma) + printf(", "); + printf("Insecure algorithm"); + comma = 1; + } + + if (output & GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE) { + if (comma) + printf(", "); + printf("Signature failure"); + comma = 1; + } + + if (output & GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED) { + if (comma) + printf(", "); + printf("Signer cert not yet activated"); + comma = 1; + } + + if (output & GNUTLS_OCSP_VERIFY_CERT_EXPIRED) { + if (comma) + printf(", "); + printf("Signer cert expired"); + comma = 1; + } } /* three days */ @@ -322,101 +310,96 @@ print_ocsp_verify_res (unsigned int output) * -1: dunno */ int -check_ocsp_response (gnutls_x509_crt_t cert, - gnutls_x509_crt_t issuer, - gnutls_datum_t *data) +check_ocsp_response(gnutls_x509_crt_t cert, + gnutls_x509_crt_t issuer, gnutls_datum_t * data) { - gnutls_ocsp_resp_t resp; - int ret; - unsigned int status, cert_status; - time_t rtime, vtime, ntime, now; - - now = time(0); - - ret = gnutls_ocsp_resp_init (&resp); - if (ret < 0) - { - fprintf(stderr, "ocsp_resp_init: %s", gnutls_strerror (ret)); - exit(1); - } - - ret = gnutls_ocsp_resp_import (resp, data); - if (ret < 0) - { - fprintf(stderr, "importing response: %s", gnutls_strerror (ret)); - exit(1); - } - - ret = gnutls_ocsp_resp_check_crt(resp, 0, cert); - if (ret < 0) - { - printf ("*** Got OCSP response on an unrelated certificate (ignoring)\n"); - ret = -1; - goto cleanup; - } - - ret = gnutls_ocsp_resp_verify_direct( resp, issuer, &status, 0); - if (ret < 0) - { - fprintf(stderr, "gnutls_ocsp_resp_verify_direct: %s", - gnutls_strerror (ret)); - exit(1); - } - - if (status != 0) - { - printf ("*** Verifying OCSP Response: "); - print_ocsp_verify_res (status); - printf (".\n"); - } - - /* do not print revocation data if response was not verified */ - if (status != 0) - { - ret = -1; - goto cleanup; - } - - ret = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL, NULL, - &cert_status, &vtime, &ntime, &rtime, NULL); - if (ret < 0) - { - fprintf(stderr, "reading response: %s", gnutls_strerror (ret)); - exit(1); - } - - if (cert_status == GNUTLS_OCSP_CERT_REVOKED) - { - printf("*** Certificate was revoked at %s", ctime(&rtime)); - ret = 0; - goto cleanup; - } - - if (ntime == -1) - { - if (now - vtime > OCSP_VALIDITY_SECS) - { - printf("*** The OCSP response is old (was issued at: %s) ignoring", ctime(&vtime)); - ret = -1; - goto cleanup; - } - } - else - { - /* there is a newer OCSP answer, don't trust this one */ - if (ntime < now) - { - printf("*** The OCSP response was issued at: %s, but there is a newer issue at %s", ctime(&vtime), ctime(&ntime)); - ret = -1; - goto cleanup; - } - } - - printf("- OCSP server flags certificate not revoked as of %s", ctime(&vtime)); - ret = 1; -cleanup: - gnutls_ocsp_resp_deinit (resp); - - return ret; + gnutls_ocsp_resp_t resp; + int ret; + unsigned int status, cert_status; + time_t rtime, vtime, ntime, now; + + now = time(0); + + ret = gnutls_ocsp_resp_init(&resp); + if (ret < 0) { + fprintf(stderr, "ocsp_resp_init: %s", + gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_ocsp_resp_import(resp, data); + if (ret < 0) { + fprintf(stderr, "importing response: %s", + gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_ocsp_resp_check_crt(resp, 0, cert); + if (ret < 0) { + printf + ("*** Got OCSP response on an unrelated certificate (ignoring)\n"); + ret = -1; + goto cleanup; + } + + ret = gnutls_ocsp_resp_verify_direct(resp, issuer, &status, 0); + if (ret < 0) { + fprintf(stderr, "gnutls_ocsp_resp_verify_direct: %s", + gnutls_strerror(ret)); + exit(1); + } + + if (status != 0) { + printf("*** Verifying OCSP Response: "); + print_ocsp_verify_res(status); + printf(".\n"); + } + + /* do not print revocation data if response was not verified */ + if (status != 0) { + ret = -1; + goto cleanup; + } + + ret = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL, NULL, + &cert_status, &vtime, &ntime, + &rtime, NULL); + if (ret < 0) { + fprintf(stderr, "reading response: %s", + gnutls_strerror(ret)); + exit(1); + } + + if (cert_status == GNUTLS_OCSP_CERT_REVOKED) { + printf("*** Certificate was revoked at %s", ctime(&rtime)); + ret = 0; + goto cleanup; + } + + if (ntime == -1) { + if (now - vtime > OCSP_VALIDITY_SECS) { + printf + ("*** The OCSP response is old (was issued at: %s) ignoring", + ctime(&vtime)); + ret = -1; + goto cleanup; + } + } else { + /* there is a newer OCSP answer, don't trust this one */ + if (ntime < now) { + printf + ("*** The OCSP response was issued at: %s, but there is a newer issue at %s", + ctime(&vtime), ctime(&ntime)); + ret = -1; + goto cleanup; + } + } + + printf("- OCSP server flags certificate not revoked as of %s", + ctime(&vtime)); + ret = 1; + cleanup: + gnutls_ocsp_resp_deinit(resp); + + return ret; } - diff --git a/src/ocsptool-common.h b/src/ocsptool-common.h index 1158b61f40..67d255eae3 100644 --- a/src/ocsptool-common.h +++ b/src/ocsptool-common.h @@ -23,26 +23,25 @@ #include <gnutls/ocsp.h> -enum - { - ACTION_NONE, - ACTION_REQ_INFO, - ACTION_RESP_INFO, - ACTION_VERIFY_RESP, - ACTION_GEN_REQ - }; +enum { + ACTION_NONE, + ACTION_REQ_INFO, + ACTION_RESP_INFO, + ACTION_VERIFY_RESP, + ACTION_GEN_REQ +}; -extern void ocsptool_version (void); +extern void ocsptool_version(void); void -_generate_request (gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer, - gnutls_datum_t * rdata, int nonce); -int send_ocsp_request(const char* server, - gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer, - gnutls_datum_t * resp_data, int nonce); -void -print_ocsp_verify_res (unsigned int output); +_generate_request(gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer, + gnutls_datum_t * rdata, int nonce); +int send_ocsp_request(const char *server, + gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer, + gnutls_datum_t * resp_data, int nonce); +void print_ocsp_verify_res(unsigned int output); int -check_ocsp_response (gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer, gnutls_datum_t *data); +check_ocsp_response(gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer, + gnutls_datum_t * data); #endif diff --git a/src/ocsptool.c b/src/ocsptool.c index cd92c1d23c..a8dcfc34e5 100644 --- a/src/ocsptool.c +++ b/src/ocsptool.c @@ -42,491 +42,474 @@ FILE *infile; static unsigned int encoding; unsigned int verbose = 0; -static void -tls_log_func (int level, const char *str) +static void tls_log_func(int level, const char *str) { - fprintf (stderr, "|<%d>| %s", level, str); + fprintf(stderr, "|<%d>| %s", level, str); } -static void -request_info (void) +static void request_info(void) { - gnutls_ocsp_req_t req; - int ret; - gnutls_datum_t dat; - size_t size; - - ret = gnutls_ocsp_req_init (&req); - if (ret < 0) - { - fprintf (stderr, "ocsp_req_init: %s", gnutls_strerror (ret)); - exit(1); - } - - if (HAVE_OPT(LOAD_REQUEST)) - dat.data = (void*)read_binary_file (OPT_ARG(LOAD_REQUEST), &size); - else - dat.data = (void*)fread_file (infile, &size); - if (dat.data == NULL) - { - fprintf (stderr, "reading request"); - exit(1); - } - dat.size = size; - - ret = gnutls_ocsp_req_import (req, &dat); - free (dat.data); - if (ret < 0) - { - fprintf (stderr, "importing request: %s", gnutls_strerror (ret)); - exit(1); - } - - ret = gnutls_ocsp_req_print (req, GNUTLS_OCSP_PRINT_FULL, &dat); - if (ret != 0) - { - fprintf (stderr, "ocsp_req_print: %s", gnutls_strerror (ret)); - exit(1); - } - - printf ("%.*s", dat.size, dat.data); - gnutls_free (dat.data); - - gnutls_ocsp_req_deinit (req); + gnutls_ocsp_req_t req; + int ret; + gnutls_datum_t dat; + size_t size; + + ret = gnutls_ocsp_req_init(&req); + if (ret < 0) { + fprintf(stderr, "ocsp_req_init: %s", gnutls_strerror(ret)); + exit(1); + } + + if (HAVE_OPT(LOAD_REQUEST)) + dat.data = + (void *) read_binary_file(OPT_ARG(LOAD_REQUEST), + &size); + else + dat.data = (void *) fread_file(infile, &size); + if (dat.data == NULL) { + fprintf(stderr, "reading request"); + exit(1); + } + dat.size = size; + + ret = gnutls_ocsp_req_import(req, &dat); + free(dat.data); + if (ret < 0) { + fprintf(stderr, "importing request: %s", + gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_ocsp_req_print(req, GNUTLS_OCSP_PRINT_FULL, &dat); + if (ret != 0) { + fprintf(stderr, "ocsp_req_print: %s", + gnutls_strerror(ret)); + exit(1); + } + + printf("%.*s", dat.size, dat.data); + gnutls_free(dat.data); + + gnutls_ocsp_req_deinit(req); } -static void -_response_info (const gnutls_datum_t* data) +static void _response_info(const gnutls_datum_t * data) { - gnutls_ocsp_resp_t resp; - int ret; - gnutls_datum buf; - - ret = gnutls_ocsp_resp_init (&resp); - if (ret < 0) - { - fprintf (stderr, "ocsp_resp_init: %s", gnutls_strerror (ret)); - exit(1); - } - - ret = gnutls_ocsp_resp_import (resp, data); - if (ret < 0) - { - fprintf (stderr, "importing response: %s", gnutls_strerror (ret)); - exit(1); - } - - if (ENABLED_OPT(VERBOSE)) - ret = gnutls_ocsp_resp_print (resp, GNUTLS_OCSP_PRINT_FULL, &buf); - else - ret = gnutls_ocsp_resp_print (resp, GNUTLS_OCSP_PRINT_COMPACT, &buf); - if (ret != 0) - { - fprintf (stderr, "ocsp_resp_print: %s", gnutls_strerror (ret)); - exit(1); - } - - printf ("%.*s", buf.size, buf.data); - gnutls_free (buf.data); - - gnutls_ocsp_resp_deinit (resp); + gnutls_ocsp_resp_t resp; + int ret; + gnutls_datum buf; + + ret = gnutls_ocsp_resp_init(&resp); + if (ret < 0) { + fprintf(stderr, "ocsp_resp_init: %s", + gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_ocsp_resp_import(resp, data); + if (ret < 0) { + fprintf(stderr, "importing response: %s", + gnutls_strerror(ret)); + exit(1); + } + + if (ENABLED_OPT(VERBOSE)) + ret = + gnutls_ocsp_resp_print(resp, GNUTLS_OCSP_PRINT_FULL, + &buf); + else + ret = + gnutls_ocsp_resp_print(resp, GNUTLS_OCSP_PRINT_COMPACT, + &buf); + if (ret != 0) { + fprintf(stderr, "ocsp_resp_print: %s", + gnutls_strerror(ret)); + exit(1); + } + + printf("%.*s", buf.size, buf.data); + gnutls_free(buf.data); + + gnutls_ocsp_resp_deinit(resp); } -static void -response_info (void) +static void response_info(void) { - gnutls_datum_t dat; - size_t size; - - if (HAVE_OPT(LOAD_RESPONSE)) - dat.data = (void*)read_binary_file (OPT_ARG(LOAD_RESPONSE), &size); - else - dat.data = (void*)fread_file (infile, &size); - if (dat.data == NULL) - { - fprintf (stderr, "reading response"); - exit(1); - } - dat.size = size; - - _response_info(&dat); - gnutls_free (dat.data); + gnutls_datum_t dat; + size_t size; + + if (HAVE_OPT(LOAD_RESPONSE)) + dat.data = + (void *) read_binary_file(OPT_ARG(LOAD_RESPONSE), + &size); + else + dat.data = (void *) fread_file(infile, &size); + if (dat.data == NULL) { + fprintf(stderr, "reading response"); + exit(1); + } + dat.size = size; + + _response_info(&dat); + gnutls_free(dat.data); } -static gnutls_x509_crt_t -load_issuer (void) +static gnutls_x509_crt_t load_issuer(void) { - gnutls_x509_crt_t crt; - int ret; - gnutls_datum_t dat; - size_t size; - - if (!HAVE_OPT(LOAD_ISSUER)) - { - fprintf( stderr, "missing --load-issuer"); - exit(1); - } - - ret = gnutls_x509_crt_init (&crt); - if (ret < 0) - { - fprintf (stderr, "crt_init: %s", gnutls_strerror (ret)); - exit(1); - } - - dat.data = (void*)read_binary_file (OPT_ARG(LOAD_ISSUER), &size); - dat.size = size; - - if (!dat.data) - { - fprintf (stderr, "reading --load-issuer: %s", OPT_ARG(LOAD_ISSUER)); - exit(1); - } - - ret = gnutls_x509_crt_import (crt, &dat, encoding); - free (dat.data); - if (ret < 0) - { - fprintf (stderr, "importing --load-issuer: %s: %s", - OPT_ARG(LOAD_ISSUER), gnutls_strerror (ret)); - exit(1); - } - - return crt; + gnutls_x509_crt_t crt; + int ret; + gnutls_datum_t dat; + size_t size; + + if (!HAVE_OPT(LOAD_ISSUER)) { + fprintf(stderr, "missing --load-issuer"); + exit(1); + } + + ret = gnutls_x509_crt_init(&crt); + if (ret < 0) { + fprintf(stderr, "crt_init: %s", gnutls_strerror(ret)); + exit(1); + } + + dat.data = (void *) read_binary_file(OPT_ARG(LOAD_ISSUER), &size); + dat.size = size; + + if (!dat.data) { + fprintf(stderr, "reading --load-issuer: %s", + OPT_ARG(LOAD_ISSUER)); + exit(1); + } + + ret = gnutls_x509_crt_import(crt, &dat, encoding); + free(dat.data); + if (ret < 0) { + fprintf(stderr, "importing --load-issuer: %s: %s", + OPT_ARG(LOAD_ISSUER), gnutls_strerror(ret)); + exit(1); + } + + return crt; } -static gnutls_x509_crt_t -load_cert (void) +static gnutls_x509_crt_t load_cert(void) { - gnutls_x509_crt_t crt; - int ret; - gnutls_datum_t dat; - size_t size; - - if (!HAVE_OPT(LOAD_CERT)) - { - fprintf (stderr, "missing --load-cert"); - exit(1); - } - - ret = gnutls_x509_crt_init (&crt); - if (ret < 0) - { - fprintf (stderr, "crt_init: %s", gnutls_strerror (ret)); - exit(1); - } - - dat.data = (void*)read_binary_file (OPT_ARG(LOAD_CERT), &size); - dat.size = size; - - if (!dat.data) - { - fprintf (stderr, "reading --load-cert: %s", OPT_ARG(LOAD_CERT)); - exit(1); - } - - ret = gnutls_x509_crt_import (crt, &dat, encoding); - free (dat.data); - if (ret < 0) - { - fprintf (stderr, "importing --load-cert: %s: %s", - OPT_ARG(LOAD_CERT), gnutls_strerror (ret)); - exit(1); - } - - return crt; + gnutls_x509_crt_t crt; + int ret; + gnutls_datum_t dat; + size_t size; + + if (!HAVE_OPT(LOAD_CERT)) { + fprintf(stderr, "missing --load-cert"); + exit(1); + } + + ret = gnutls_x509_crt_init(&crt); + if (ret < 0) { + fprintf(stderr, "crt_init: %s", gnutls_strerror(ret)); + exit(1); + } + + dat.data = (void *) read_binary_file(OPT_ARG(LOAD_CERT), &size); + dat.size = size; + + if (!dat.data) { + fprintf(stderr, "reading --load-cert: %s", + OPT_ARG(LOAD_CERT)); + exit(1); + } + + ret = gnutls_x509_crt_import(crt, &dat, encoding); + free(dat.data); + if (ret < 0) { + fprintf(stderr, "importing --load-cert: %s: %s", + OPT_ARG(LOAD_CERT), gnutls_strerror(ret)); + exit(1); + } + + return crt; } -static void -generate_request (void) +static void generate_request(void) { - gnutls_datum_t dat; - - _generate_request(load_cert(), load_issuer(), &dat, ENABLED_OPT(NONCE)); + gnutls_datum_t dat; - fwrite (dat.data, 1, dat.size, outfile); + _generate_request(load_cert(), load_issuer(), &dat, + ENABLED_OPT(NONCE)); - gnutls_free (dat.data); + fwrite(dat.data, 1, dat.size, outfile); + + gnutls_free(dat.data); } -static int -_verify_response (gnutls_datum_t *data) +static int _verify_response(gnutls_datum_t * data) { - gnutls_ocsp_resp_t resp; - int ret; - size_t size; - gnutls_x509_crt_t *x509_ca_list = NULL; - unsigned int x509_ncas = 0; - gnutls_x509_trust_list_t list; - gnutls_x509_crt_t signer; - unsigned verify; - gnutls_datum_t dat; - - ret = gnutls_ocsp_resp_init (&resp); - if (ret < 0) - { - fprintf (stderr, "ocsp_resp_init: %s", gnutls_strerror (ret)); - exit(1); - } - - ret = gnutls_ocsp_resp_import (resp, data); - if (ret < 0) - { - fprintf (stderr, "importing response: %s", gnutls_strerror (ret)); - exit(1); - } - - if (HAVE_OPT(LOAD_TRUST)) - { - dat.data = (void*)read_binary_file (OPT_ARG(LOAD_TRUST), &size); - if (dat.data == NULL) - { - fprintf (stderr, "reading --load-trust: %s", OPT_ARG(LOAD_TRUST)); - exit(1); - } - dat.size = size; - - ret = gnutls_x509_trust_list_init (&list, 0); - if (ret < 0) - { - fprintf (stderr, "gnutls_x509_trust_list_init: %s", - gnutls_strerror (ret)); - exit(1); + gnutls_ocsp_resp_t resp; + int ret; + size_t size; + gnutls_x509_crt_t *x509_ca_list = NULL; + unsigned int x509_ncas = 0; + gnutls_x509_trust_list_t list; + gnutls_x509_crt_t signer; + unsigned verify; + gnutls_datum_t dat; + + ret = gnutls_ocsp_resp_init(&resp); + if (ret < 0) { + fprintf(stderr, "ocsp_resp_init: %s", + gnutls_strerror(ret)); + exit(1); } - ret = gnutls_x509_crt_list_import2 (&x509_ca_list, &x509_ncas, &dat, - GNUTLS_X509_FMT_PEM, 0); - if (ret < 0 || x509_ncas < 1) - { - fprintf (stderr, "error parsing CAs: %s", - gnutls_strerror (ret)); - exit(1); + ret = gnutls_ocsp_resp_import(resp, data); + if (ret < 0) { + fprintf(stderr, "importing response: %s", + gnutls_strerror(ret)); + exit(1); } - if (HAVE_OPT(VERBOSE)) - { - unsigned int i; - printf ("Trust anchors:\n"); - for (i = 0; i < x509_ncas; i++) - { - gnutls_datum_t out; - - ret = gnutls_x509_crt_print (x509_ca_list[i], - GNUTLS_CRT_PRINT_ONELINE, &out); - if (ret < 0) - { - fprintf (stderr, "gnutls_x509_crt_print: %s", - gnutls_strerror (ret)); - exit(1); + if (HAVE_OPT(LOAD_TRUST)) { + dat.data = + (void *) read_binary_file(OPT_ARG(LOAD_TRUST), &size); + if (dat.data == NULL) { + fprintf(stderr, "reading --load-trust: %s", + OPT_ARG(LOAD_TRUST)); + exit(1); } + dat.size = size; - printf ("%d: %.*s\n", i, out.size, out.data); - gnutls_free (out.data); - } - printf("\n"); - } + ret = gnutls_x509_trust_list_init(&list, 0); + if (ret < 0) { + fprintf(stderr, "gnutls_x509_trust_list_init: %s", + gnutls_strerror(ret)); + exit(1); + } - ret = gnutls_x509_trust_list_add_cas (list, x509_ca_list, x509_ncas, 0); - if (ret < 0) - { - fprintf (stderr, "gnutls_x509_trust_add_cas: %s", - gnutls_strerror (ret)); - exit(1); - } + ret = + gnutls_x509_crt_list_import2(&x509_ca_list, &x509_ncas, + &dat, GNUTLS_X509_FMT_PEM, + 0); + if (ret < 0 || x509_ncas < 1) { + fprintf(stderr, "error parsing CAs: %s", + gnutls_strerror(ret)); + exit(1); + } - if (HAVE_OPT(VERBOSE)) - fprintf (stdout, "Loaded %d trust anchors\n", x509_ncas); + if (HAVE_OPT(VERBOSE)) { + unsigned int i; + printf("Trust anchors:\n"); + for (i = 0; i < x509_ncas; i++) { + gnutls_datum_t out; + + ret = + gnutls_x509_crt_print(x509_ca_list[i], + GNUTLS_CRT_PRINT_ONELINE, + &out); + if (ret < 0) { + fprintf(stderr, + "gnutls_x509_crt_print: %s", + gnutls_strerror(ret)); + exit(1); + } + + printf("%d: %.*s\n", i, out.size, + out.data); + gnutls_free(out.data); + } + printf("\n"); + } - ret = gnutls_ocsp_resp_verify (resp, list, &verify, 0); - if (ret < 0) - { - fprintf (stderr, "gnutls_ocsp_resp_verify: %s", - gnutls_strerror (ret)); - exit(1); - } - } - else if (HAVE_OPT(LOAD_SIGNER)) - { - ret = gnutls_x509_crt_init (&signer); - if (ret < 0) - { - fprintf (stderr, "crt_init: %s", gnutls_strerror (ret)); - exit(1); + ret = + gnutls_x509_trust_list_add_cas(list, x509_ca_list, + x509_ncas, 0); + if (ret < 0) { + fprintf(stderr, "gnutls_x509_trust_add_cas: %s", + gnutls_strerror(ret)); + exit(1); + } + + if (HAVE_OPT(VERBOSE)) + fprintf(stdout, "Loaded %d trust anchors\n", + x509_ncas); + + ret = gnutls_ocsp_resp_verify(resp, list, &verify, 0); + if (ret < 0) { + fprintf(stderr, "gnutls_ocsp_resp_verify: %s", + gnutls_strerror(ret)); + exit(1); + } + } else if (HAVE_OPT(LOAD_SIGNER)) { + ret = gnutls_x509_crt_init(&signer); + if (ret < 0) { + fprintf(stderr, "crt_init: %s", + gnutls_strerror(ret)); + exit(1); + } + + dat.data = + (void *) read_binary_file(OPT_ARG(LOAD_SIGNER), &size); + if (dat.data == NULL) { + fprintf(stderr, "reading --load-signer: %s", + OPT_ARG(LOAD_SIGNER)); + exit(1); + } + dat.size = size; + + ret = gnutls_x509_crt_import(signer, &dat, encoding); + free(dat.data); + if (ret < 0) { + fprintf(stderr, "importing --load-signer: %s: %s", + OPT_ARG(LOAD_SIGNER), + gnutls_strerror(ret)); + exit(1); + } + + if (HAVE_OPT(VERBOSE)) { + gnutls_datum_t out; + + ret = + gnutls_x509_crt_print(signer, + GNUTLS_CRT_PRINT_ONELINE, + &out); + if (ret < 0) { + fprintf(stderr, + "gnutls_x509_crt_print: %s", + gnutls_strerror(ret)); + exit(1); + } + + printf("Signer: %.*s\n", out.size, out.data); + gnutls_free(out.data); + printf("\n"); + } + + ret = + gnutls_ocsp_resp_verify_direct(resp, signer, &verify, + 0); + if (ret < 0) { + fprintf(stderr, + "gnutls_ocsp_resp_verify_direct: %s", + gnutls_strerror(ret)); + exit(1); + } + } else { + fprintf(stderr, "missing --load-trust or --load-signer"); + exit(1); } - dat.data = (void*)read_binary_file (OPT_ARG(LOAD_SIGNER), &size); - if (dat.data == NULL) - { - fprintf (stderr, "reading --load-signer: %s", OPT_ARG(LOAD_SIGNER)); - exit(1); + printf("Verifying OCSP Response: "); + print_ocsp_verify_res(verify); + printf(".\n"); + + gnutls_ocsp_resp_deinit(resp); + + return verify; +} + +static void verify_response(void) +{ + gnutls_datum_t dat; + size_t size; + + if (HAVE_OPT(LOAD_RESPONSE)) + dat.data = + (void *) read_binary_file(OPT_ARG(LOAD_RESPONSE), + &size); + else + dat.data = (void *) fread_file(infile, &size); + if (dat.data == NULL) { + fprintf(stderr, "reading response"); + exit(1); } - dat.size = size; - - ret = gnutls_x509_crt_import (signer, &dat, encoding); - free (dat.data); - if (ret < 0) - { - fprintf (stderr, "importing --load-signer: %s: %s", - OPT_ARG(LOAD_SIGNER), gnutls_strerror (ret)); - exit(1); + dat.size = size; + + _verify_response(&dat); +} + +static void ask_server(const char *url) +{ + gnutls_datum_t resp_data; + int ret, v; + gnutls_x509_crt_t cert, issuer; + + cert = load_cert(); + issuer = load_issuer(); + + ret = + send_ocsp_request(url, cert, issuer, &resp_data, + ENABLED_OPT(NONCE)); + if (ret < 0) { + fprintf(stderr, "Cannot send OCSP request\n"); + exit(1); } - if (HAVE_OPT(VERBOSE)) - { - gnutls_datum_t out; - - ret = gnutls_x509_crt_print (signer, GNUTLS_CRT_PRINT_ONELINE, &out); - if (ret < 0) - { - fprintf (stderr, "gnutls_x509_crt_print: %s", - gnutls_strerror (ret)); - exit(1); - } - - printf ("Signer: %.*s\n", out.size, out.data); - gnutls_free (out.data); - printf("\n"); + _response_info(&resp_data); + + if (HAVE_OPT(LOAD_SIGNER) || HAVE_OPT(LOAD_TRUST)) { + fprintf(outfile, "\n"); + v = _verify_response(&resp_data); + } else { + fprintf(stderr, + "\nResponse could not be verified (use --load-signer).\n"); + v = 0; } - ret = gnutls_ocsp_resp_verify_direct (resp, signer, &verify, 0); - if (ret < 0) - { - fprintf (stderr, "gnutls_ocsp_resp_verify_direct: %s", - gnutls_strerror (ret)); - exit(1); + if (HAVE_OPT(OUTFILE) && v == 0) { + fwrite(resp_data.data, 1, resp_data.size, outfile); } - } - else - { - fprintf (stderr, "missing --load-trust or --load-signer"); - exit(1); - } - - printf ("Verifying OCSP Response: "); - print_ocsp_verify_res (verify); - printf (".\n"); - - gnutls_ocsp_resp_deinit (resp); - - return verify; } -static void -verify_response (void) +int main(int argc, char **argv) { - gnutls_datum_t dat; - size_t size; - - if (HAVE_OPT(LOAD_RESPONSE)) - dat.data = (void*)read_binary_file (OPT_ARG(LOAD_RESPONSE), &size); - else - dat.data = (void*)fread_file (infile, &size); - if (dat.data == NULL) - { - fprintf (stderr, "reading response"); - exit(1); - } - dat.size = size; - - _verify_response(&dat); -} + int ret; -static void ask_server(const char* url) -{ -gnutls_datum_t resp_data; -int ret, v; -gnutls_x509_crt_t cert, issuer; - - cert = load_cert(); - issuer = load_issuer(); - - ret = send_ocsp_request(url, cert, issuer, &resp_data, ENABLED_OPT(NONCE)); - if (ret < 0) - { - fprintf(stderr, "Cannot send OCSP request\n"); - exit(1); - } - - _response_info (&resp_data); - - if (HAVE_OPT(LOAD_SIGNER) || HAVE_OPT(LOAD_TRUST)) - { - fprintf(outfile, "\n"); - v = _verify_response(&resp_data); - } - else - { - fprintf(stderr, "\nResponse could not be verified (use --load-signer).\n"); - v = 0; - } - - if (HAVE_OPT(OUTFILE) && v == 0) - { - fwrite(resp_data.data, 1, resp_data.size, outfile); - } -} - -int -main (int argc, char **argv) -{ - int ret; - - if ((ret = gnutls_global_init ()) < 0) - { - fprintf( stderr, "global_init: %s", gnutls_strerror (ret)); - exit(1); - } - - optionProcess( &ocsptoolOptions, argc, argv); - - gnutls_global_set_log_function (tls_log_func); - gnutls_global_set_log_level (OPT_VALUE_DEBUG); - - if (HAVE_OPT(OUTFILE)) - { - outfile = fopen (OPT_ARG(OUTFILE), "wb"); - if (outfile == NULL) - { - fprintf( stderr, "%s", OPT_ARG(OUTFILE)); - exit(1); - } - } - else - outfile = stdout; - - if (HAVE_OPT(INFILE)) - { - infile = fopen (OPT_ARG(INFILE), "rb"); - if (infile == NULL) - { - fprintf( stderr, "%s", OPT_ARG(INFILE)); - exit(1); - } - } - else - infile = stdin; - - if (ENABLED_OPT(INDER)) - encoding = GNUTLS_X509_FMT_DER; - else - encoding = GNUTLS_X509_FMT_PEM; - - if (HAVE_OPT(REQUEST_INFO)) - request_info (); - else if (HAVE_OPT(RESPONSE_INFO)) - response_info (); - else if (HAVE_OPT(GENERATE_REQUEST)) - generate_request (); - else if (HAVE_OPT(VERIFY_RESPONSE)) - verify_response (); - else if (HAVE_OPT(ASK)) - ask_server(OPT_ARG(ASK)); - else - { - USAGE(1); - } - - return 0; -} + if ((ret = gnutls_global_init()) < 0) { + fprintf(stderr, "global_init: %s", gnutls_strerror(ret)); + exit(1); + } + + optionProcess(&ocsptoolOptions, argc, argv); + gnutls_global_set_log_function(tls_log_func); + gnutls_global_set_log_level(OPT_VALUE_DEBUG); + + if (HAVE_OPT(OUTFILE)) { + outfile = fopen(OPT_ARG(OUTFILE), "wb"); + if (outfile == NULL) { + fprintf(stderr, "%s", OPT_ARG(OUTFILE)); + exit(1); + } + } else + outfile = stdout; + + if (HAVE_OPT(INFILE)) { + infile = fopen(OPT_ARG(INFILE), "rb"); + if (infile == NULL) { + fprintf(stderr, "%s", OPT_ARG(INFILE)); + exit(1); + } + } else + infile = stdin; + + if (ENABLED_OPT(INDER)) + encoding = GNUTLS_X509_FMT_DER; + else + encoding = GNUTLS_X509_FMT_PEM; + + if (HAVE_OPT(REQUEST_INFO)) + request_info(); + else if (HAVE_OPT(RESPONSE_INFO)) + response_info(); + else if (HAVE_OPT(GENERATE_REQUEST)) + generate_request(); + else if (HAVE_OPT(VERIFY_RESPONSE)) + verify_response(); + else if (HAVE_OPT(ASK)) + ask_server(OPT_ARG(ASK)); + else { + USAGE(1); + } + + return 0; +} diff --git a/src/p11tool.c b/src/p11tool.c index 10988829d2..93c4200434 100644 --- a/src/p11tool.c +++ b/src/p11tool.c @@ -47,234 +47,210 @@ #include "p11tool.h" #include "certtool-common.h" -static void cmd_parser (int argc, char **argv); +static void cmd_parser(int argc, char **argv); static FILE *outfile; int batch = 0; -static void -tls_log_func (int level, const char *str) +static void tls_log_func(int level, const char *str) { - fprintf (stderr, "|<%d>| %s", level, str); + fprintf(stderr, "|<%d>| %s", level, str); } -int -main (int argc, char **argv) +int main(int argc, char **argv) { - cmd_parser (argc, argv); + cmd_parser(argc, argv); - return 0; + return 0; } -static void -cmd_parser (int argc, char **argv) +static void cmd_parser(int argc, char **argv) { - int ret, debug = 0; - common_info_st cinfo; - unsigned int pkcs11_type = -1, key_type = GNUTLS_PK_UNKNOWN; - const char* url = NULL; - unsigned int detailed_url = 0, optct; - unsigned int login = 0, bits = 0; - const char* label = NULL, *sec_param = NULL; - - optct = optionProcess( &p11toolOptions, argc, argv); - argc += optct; - argv += optct; - - if (url == NULL && argc > 0) - url = argv[0]; - else - url = "pkcs11:"; - - if (HAVE_OPT(DEBUG)) - debug = OPT_VALUE_DEBUG; - - gnutls_global_set_log_function (tls_log_func); - gnutls_global_set_log_level (debug); - if (debug > 1) - printf ("Setting log level to %d\n", debug); - - if ((ret = gnutls_global_init ()) < 0) - { - fprintf (stderr, "global_init: %s", gnutls_strerror (ret)); - exit(1); - } - - if (HAVE_OPT(PROVIDER)) - { - ret = gnutls_pkcs11_init (GNUTLS_PKCS11_FLAG_MANUAL, NULL); - if (ret < 0) - fprintf (stderr, "pkcs11_init: %s", gnutls_strerror (ret)); - else - { - ret = gnutls_pkcs11_add_provider (OPT_ARG(PROVIDER), NULL); - if (ret < 0) - { - fprintf (stderr, "pkcs11_add_provider: %s", - gnutls_strerror (ret)); - exit(1); - } - } - } - else - { - ret = gnutls_pkcs11_init (GNUTLS_PKCS11_FLAG_AUTO, NULL); - if (ret < 0) - fprintf (stderr, "pkcs11_init: %s", gnutls_strerror (ret)); - } - - if (HAVE_OPT(OUTFILE)) - { - outfile = safe_open_rw (OPT_ARG(OUTFILE), 0); - if (outfile == NULL) - { - fprintf (stderr, "%s", OPT_ARG(OUTFILE)); - exit(1); - } - } - else - outfile = stdout; - - memset (&cinfo, 0, sizeof (cinfo)); - - if (HAVE_OPT(SECRET_KEY)) - cinfo.secret_key = OPT_ARG(SECRET_KEY); - - if (HAVE_OPT(LOAD_PRIVKEY)) - cinfo.privkey = OPT_ARG(LOAD_PRIVKEY); - - if (HAVE_OPT(PKCS8)) - cinfo.pkcs8 = 1; - - if (ENABLED_OPT(INDER) || ENABLED_OPT(INRAW)) - cinfo.incert_format = GNUTLS_X509_FMT_DER; - else - cinfo.incert_format = GNUTLS_X509_FMT_PEM; - - if (HAVE_OPT(LOAD_CERTIFICATE)) - cinfo.cert = OPT_ARG(LOAD_CERTIFICATE); - - if (HAVE_OPT(LOAD_PUBKEY)) - cinfo.pubkey = OPT_ARG(LOAD_PUBKEY); - - if (ENABLED_OPT(DETAILED_URL)) - detailed_url = 1; - - if (ENABLED_OPT(LOGIN)) - login = 1; - - if (HAVE_OPT(LABEL)) - { - label = OPT_ARG(LABEL); - } - - if (HAVE_OPT(BITS)) - { - bits = OPT_VALUE_BITS; - } - - if (HAVE_OPT(SEC_PARAM)) - { - sec_param = OPT_ARG(SEC_PARAM); - } - - if (debug > 0) - { - if (HAVE_OPT(PRIVATE)) fprintf(stderr, "Private: %s\n", ENABLED_OPT(PRIVATE)?"yes":"no"); - fprintf(stderr, "Trusted: %s\n", ENABLED_OPT(TRUSTED)?"yes":"no"); - fprintf(stderr, "Login: %s\n", ENABLED_OPT(LOGIN)?"yes":"no"); - fprintf(stderr, "Detailed URLs: %s\n", ENABLED_OPT(DETAILED_URL)?"yes":"no"); - fprintf(stderr, "\n"); - } - - /* handle actions - */ - if (HAVE_OPT(LIST_TOKENS)) - pkcs11_token_list (outfile, detailed_url, &cinfo); - else if (HAVE_OPT(LIST_MECHANISMS)) - pkcs11_mechanism_list (outfile, url, login, - &cinfo); - else if (HAVE_OPT(GENERATE_RANDOM)) - pkcs11_get_random (outfile, url, OPT_VALUE_GENERATE_RANDOM, &cinfo); - else if (HAVE_OPT(LIST_ALL)) - { - pkcs11_type = PKCS11_TYPE_ALL; - pkcs11_list (outfile, url, pkcs11_type, - login, detailed_url, &cinfo); - } - else if (HAVE_OPT(LIST_ALL_CERTS)) - { - pkcs11_type = PKCS11_TYPE_CRT_ALL; - pkcs11_list (outfile, url, pkcs11_type, - login, detailed_url, &cinfo); - } - else if (HAVE_OPT(LIST_CERTS)) - { - pkcs11_type = PKCS11_TYPE_PK; - pkcs11_list (outfile, url, pkcs11_type, - login, detailed_url, &cinfo); - } - else if (HAVE_OPT(LIST_ALL_PRIVKEYS)) - { - pkcs11_type = PKCS11_TYPE_PRIVKEY; - pkcs11_list (outfile, url, pkcs11_type, - login, detailed_url, &cinfo); - } - else if (HAVE_OPT(LIST_ALL_TRUSTED)) - { - pkcs11_type = PKCS11_TYPE_TRUSTED; - pkcs11_list (outfile, url, pkcs11_type, - login, detailed_url, &cinfo); - } - else if (HAVE_OPT(EXPORT)) - { - pkcs11_export (outfile, url, login, &cinfo); - } - else if (HAVE_OPT(WRITE)) - { - int priv; - - if (HAVE_OPT(PRIVATE)) - priv = ENABLED_OPT(PRIVATE); - else priv = -1; - pkcs11_write (outfile, url, label, - ENABLED_OPT(TRUSTED), priv, login, &cinfo); - } - else if (HAVE_OPT(INITIALIZE)) - pkcs11_init (outfile, url, label, &cinfo); - else if (HAVE_OPT(DELETE)) - pkcs11_delete (outfile, url, 0, login, &cinfo); - else if (HAVE_OPT(GENERATE_ECC)) - { - key_type = GNUTLS_PK_EC; - pkcs11_generate (outfile, url, key_type, get_bits(key_type, bits, sec_param, 0), - label, ENABLED_OPT(PRIVATE), detailed_url, login, - &cinfo); - } - else if (HAVE_OPT(GENERATE_RSA)) - { - key_type = GNUTLS_PK_RSA; - pkcs11_generate (outfile, url, key_type, get_bits(key_type, bits, sec_param, 0), - label, ENABLED_OPT(PRIVATE), detailed_url, login, - &cinfo); - } - else if (HAVE_OPT(GENERATE_DSA)) - { - key_type = GNUTLS_PK_DSA; - pkcs11_generate (outfile, url, key_type, get_bits(key_type, bits, sec_param, 0), - label, ENABLED_OPT(PRIVATE), detailed_url, login, - &cinfo); - } - else - { - USAGE(1); - } - - fclose (outfile); + int ret, debug = 0; + common_info_st cinfo; + unsigned int pkcs11_type = -1, key_type = GNUTLS_PK_UNKNOWN; + const char *url = NULL; + unsigned int detailed_url = 0, optct; + unsigned int login = 0, bits = 0; + const char *label = NULL, *sec_param = NULL; + + optct = optionProcess(&p11toolOptions, argc, argv); + argc += optct; + argv += optct; + + if (url == NULL && argc > 0) + url = argv[0]; + else + url = "pkcs11:"; + + if (HAVE_OPT(DEBUG)) + debug = OPT_VALUE_DEBUG; + + gnutls_global_set_log_function(tls_log_func); + gnutls_global_set_log_level(debug); + if (debug > 1) + printf("Setting log level to %d\n", debug); + + if ((ret = gnutls_global_init()) < 0) { + fprintf(stderr, "global_init: %s", gnutls_strerror(ret)); + exit(1); + } + + if (HAVE_OPT(PROVIDER)) { + ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL); + if (ret < 0) + fprintf(stderr, "pkcs11_init: %s", + gnutls_strerror(ret)); + else { + ret = + gnutls_pkcs11_add_provider(OPT_ARG(PROVIDER), + NULL); + if (ret < 0) { + fprintf(stderr, "pkcs11_add_provider: %s", + gnutls_strerror(ret)); + exit(1); + } + } + } else { + ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_AUTO, NULL); + if (ret < 0) + fprintf(stderr, "pkcs11_init: %s", + gnutls_strerror(ret)); + } + + if (HAVE_OPT(OUTFILE)) { + outfile = safe_open_rw(OPT_ARG(OUTFILE), 0); + if (outfile == NULL) { + fprintf(stderr, "%s", OPT_ARG(OUTFILE)); + exit(1); + } + } else + outfile = stdout; + + memset(&cinfo, 0, sizeof(cinfo)); + + if (HAVE_OPT(SECRET_KEY)) + cinfo.secret_key = OPT_ARG(SECRET_KEY); + + if (HAVE_OPT(LOAD_PRIVKEY)) + cinfo.privkey = OPT_ARG(LOAD_PRIVKEY); + + if (HAVE_OPT(PKCS8)) + cinfo.pkcs8 = 1; + + if (ENABLED_OPT(INDER) || ENABLED_OPT(INRAW)) + cinfo.incert_format = GNUTLS_X509_FMT_DER; + else + cinfo.incert_format = GNUTLS_X509_FMT_PEM; + + if (HAVE_OPT(LOAD_CERTIFICATE)) + cinfo.cert = OPT_ARG(LOAD_CERTIFICATE); + + if (HAVE_OPT(LOAD_PUBKEY)) + cinfo.pubkey = OPT_ARG(LOAD_PUBKEY); + + if (ENABLED_OPT(DETAILED_URL)) + detailed_url = 1; + + if (ENABLED_OPT(LOGIN)) + login = 1; + + if (HAVE_OPT(LABEL)) { + label = OPT_ARG(LABEL); + } + + if (HAVE_OPT(BITS)) { + bits = OPT_VALUE_BITS; + } + + if (HAVE_OPT(SEC_PARAM)) { + sec_param = OPT_ARG(SEC_PARAM); + } + + if (debug > 0) { + if (HAVE_OPT(PRIVATE)) + fprintf(stderr, "Private: %s\n", + ENABLED_OPT(PRIVATE) ? "yes" : "no"); + fprintf(stderr, "Trusted: %s\n", + ENABLED_OPT(TRUSTED) ? "yes" : "no"); + fprintf(stderr, "Login: %s\n", + ENABLED_OPT(LOGIN) ? "yes" : "no"); + fprintf(stderr, "Detailed URLs: %s\n", + ENABLED_OPT(DETAILED_URL) ? "yes" : "no"); + fprintf(stderr, "\n"); + } + + /* handle actions + */ + if (HAVE_OPT(LIST_TOKENS)) + pkcs11_token_list(outfile, detailed_url, &cinfo); + else if (HAVE_OPT(LIST_MECHANISMS)) + pkcs11_mechanism_list(outfile, url, login, &cinfo); + else if (HAVE_OPT(GENERATE_RANDOM)) + pkcs11_get_random(outfile, url, OPT_VALUE_GENERATE_RANDOM, + &cinfo); + else if (HAVE_OPT(LIST_ALL)) { + pkcs11_type = PKCS11_TYPE_ALL; + pkcs11_list(outfile, url, pkcs11_type, + login, detailed_url, &cinfo); + } else if (HAVE_OPT(LIST_ALL_CERTS)) { + pkcs11_type = PKCS11_TYPE_CRT_ALL; + pkcs11_list(outfile, url, pkcs11_type, + login, detailed_url, &cinfo); + } else if (HAVE_OPT(LIST_CERTS)) { + pkcs11_type = PKCS11_TYPE_PK; + pkcs11_list(outfile, url, pkcs11_type, + login, detailed_url, &cinfo); + } else if (HAVE_OPT(LIST_ALL_PRIVKEYS)) { + pkcs11_type = PKCS11_TYPE_PRIVKEY; + pkcs11_list(outfile, url, pkcs11_type, + login, detailed_url, &cinfo); + } else if (HAVE_OPT(LIST_ALL_TRUSTED)) { + pkcs11_type = PKCS11_TYPE_TRUSTED; + pkcs11_list(outfile, url, pkcs11_type, + login, detailed_url, &cinfo); + } else if (HAVE_OPT(EXPORT)) { + pkcs11_export(outfile, url, login, &cinfo); + } else if (HAVE_OPT(WRITE)) { + int priv; + + if (HAVE_OPT(PRIVATE)) + priv = ENABLED_OPT(PRIVATE); + else + priv = -1; + pkcs11_write(outfile, url, label, + ENABLED_OPT(TRUSTED), priv, login, &cinfo); + } else if (HAVE_OPT(INITIALIZE)) + pkcs11_init(outfile, url, label, &cinfo); + else if (HAVE_OPT(DELETE)) + pkcs11_delete(outfile, url, 0, login, &cinfo); + else if (HAVE_OPT(GENERATE_ECC)) { + key_type = GNUTLS_PK_EC; + pkcs11_generate(outfile, url, key_type, + get_bits(key_type, bits, sec_param, 0), + label, ENABLED_OPT(PRIVATE), detailed_url, + login, &cinfo); + } else if (HAVE_OPT(GENERATE_RSA)) { + key_type = GNUTLS_PK_RSA; + pkcs11_generate(outfile, url, key_type, + get_bits(key_type, bits, sec_param, 0), + label, ENABLED_OPT(PRIVATE), detailed_url, + login, &cinfo); + } else if (HAVE_OPT(GENERATE_DSA)) { + key_type = GNUTLS_PK_DSA; + pkcs11_generate(outfile, url, key_type, + get_bits(key_type, bits, sec_param, 0), + label, ENABLED_OPT(PRIVATE), detailed_url, + login, &cinfo); + } else { + USAGE(1); + } + + fclose(outfile); #ifdef ENABLE_PKCS11 - gnutls_pkcs11_deinit (); + gnutls_pkcs11_deinit(); #endif - gnutls_global_deinit (); + gnutls_global_deinit(); } diff --git a/src/p11tool.h b/src/p11tool.h index f7ea73bfdb..7adb7108fd 100644 --- a/src/p11tool.h +++ b/src/p11tool.h @@ -25,28 +25,28 @@ #include "certtool-common.h" -void pkcs11_list (FILE * outfile, const char *url, int type, - unsigned int login, unsigned int detailed, - common_info_st *); -void pkcs11_mechanism_list (FILE * outfile, const char *url, - unsigned int login, common_info_st *); -void pkcs11_get_random (FILE * outfile, const char *url, - unsigned bytes, common_info_st *); -void pkcs11_export (FILE * outfile, const char *pkcs11_url, - unsigned int login, common_info_st *); -void pkcs11_token_list (FILE * outfile, unsigned int detailed, - common_info_st *); -void pkcs11_write (FILE * outfile, const char *pkcs11_url, const char *label, - int trusted, int private, unsigned int login, common_info_st *); -void pkcs11_delete (FILE * outfile, const char *pkcs11_url, int batch, - unsigned int login, common_info_st *); -void pkcs11_init (FILE * outfile, const char *pkcs11_url, const char *label, - common_info_st *); -void -pkcs11_generate (FILE * outfile, const char *url, gnutls_pk_algorithm_t type, - unsigned int bits, - const char *label, int private, int detailed, - unsigned int login, common_info_st * info); +void pkcs11_list(FILE * outfile, const char *url, int type, + unsigned int login, unsigned int detailed, + common_info_st *); +void pkcs11_mechanism_list(FILE * outfile, const char *url, + unsigned int login, common_info_st *); +void pkcs11_get_random(FILE * outfile, const char *url, + unsigned bytes, common_info_st *); +void pkcs11_export(FILE * outfile, const char *pkcs11_url, + unsigned int login, common_info_st *); +void pkcs11_token_list(FILE * outfile, unsigned int detailed, + common_info_st *); +void pkcs11_write(FILE * outfile, const char *pkcs11_url, + const char *label, int trusted, int private, + unsigned int login, common_info_st *); +void pkcs11_delete(FILE * outfile, const char *pkcs11_url, int batch, + unsigned int login, common_info_st *); +void pkcs11_init(FILE * outfile, const char *pkcs11_url, const char *label, + common_info_st *); +void pkcs11_generate(FILE * outfile, const char *url, + gnutls_pk_algorithm_t type, unsigned int bits, + const char *label, int private, int detailed, + unsigned int login, common_info_st * info); #define PKCS11_TYPE_CRT_ALL 1 #define PKCS11_TYPE_TRUSTED 2 diff --git a/src/pkcs11.c b/src/pkcs11.c index c5dc1979c0..68a4ca5689 100644 --- a/src/pkcs11.c +++ b/src/pkcs11.c @@ -35,811 +35,792 @@ #include <common.h> void -pkcs11_delete (FILE * outfile, const char *url, int batch, unsigned int login, - common_info_st * info) +pkcs11_delete(FILE * outfile, const char *url, int batch, + unsigned int login, common_info_st * info) { - int ret; - unsigned int obj_flags = 0; - - if (login) - obj_flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN; - - if (!batch) - { - pkcs11_list (outfile, url, PKCS11_TYPE_ALL, login, - GNUTLS_PKCS11_URL_LIB, info); - ret = - read_yesno ("Are you sure you want to delete those objects? (y/N): ", 0); - if (ret == 0) - { - exit (1); - } - } - - ret = gnutls_pkcs11_delete_url (url, obj_flags); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - fprintf (outfile, "\n%d objects deleted\n", ret); - - return; + int ret; + unsigned int obj_flags = 0; + + if (login) + obj_flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN; + + if (!batch) { + pkcs11_list(outfile, url, PKCS11_TYPE_ALL, login, + GNUTLS_PKCS11_URL_LIB, info); + ret = + read_yesno + ("Are you sure you want to delete those objects? (y/N): ", + 0); + if (ret == 0) { + exit(1); + } + } + + ret = gnutls_pkcs11_delete_url(url, obj_flags); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, + gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "\n%d objects deleted\n", ret); + + return; } /* lists certificates from a token */ void -pkcs11_list (FILE * outfile, const char *url, int type, unsigned int login, - unsigned int detailed, common_info_st * info) +pkcs11_list(FILE * outfile, const char *url, int type, unsigned int login, + unsigned int detailed, common_info_st * info) { - gnutls_pkcs11_obj_t *crt_list; - unsigned int crt_list_size = 0, i; - int ret, otype; - char *output; - int attrs; - unsigned int obj_flags = 0; - - if (login) - obj_flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN; - - pkcs11_common (); - - if (url == NULL) - url = "pkcs11:"; - - if (type == PKCS11_TYPE_TRUSTED) - { - attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED; - } - else if (type == PKCS11_TYPE_PK) - { - attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY; - } - else if (type == PKCS11_TYPE_CRT_ALL) - { - attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL; - } - else if (type == PKCS11_TYPE_PRIVKEY) - { - attrs = GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY; - } - else - { - attrs = GNUTLS_PKCS11_OBJ_ATTR_ALL; - } - - /* give some initial value to avoid asking for the pkcs11 pin twice. - */ - ret = gnutls_pkcs11_obj_list_import_url2 (&crt_list, &crt_list_size, url, - attrs, obj_flags); - if (ret < 0) - { - fprintf (stderr, "Error in crt_list_import (1): %s\n", - gnutls_strerror (ret)); - exit (1); - } - - if (crt_list_size == 0) - { - fprintf (stderr, "No matching objects found\n"); - exit (0); - } - - for (i = 0; i < crt_list_size; i++) - { - char buf[128]; - size_t size; - - ret = gnutls_pkcs11_obj_export_url (crt_list[i], detailed, &output); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - fprintf (outfile, "Object %d:\n\tURL: %s\n", i, output); - - otype = gnutls_pkcs11_obj_get_type(crt_list[i]); - fprintf (outfile, "\tType: %s\n", - gnutls_pkcs11_type_get_name (otype)); - - size = sizeof (buf); - ret = - gnutls_pkcs11_obj_get_info (crt_list[i], GNUTLS_PKCS11_OBJ_LABEL, buf, - &size); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - fprintf (outfile, "\tLabel: %s\n", buf); - - size = sizeof (buf); - ret = - gnutls_pkcs11_obj_get_info (crt_list[i], GNUTLS_PKCS11_OBJ_ID_HEX, - buf, &size); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - fprintf (outfile, "\tID: %s\n\n", buf); - } - - return; + gnutls_pkcs11_obj_t *crt_list; + unsigned int crt_list_size = 0, i; + int ret, otype; + char *output; + int attrs; + unsigned int obj_flags = 0; + + if (login) + obj_flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN; + + pkcs11_common(); + + if (url == NULL) + url = "pkcs11:"; + + if (type == PKCS11_TYPE_TRUSTED) { + attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED; + } else if (type == PKCS11_TYPE_PK) { + attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY; + } else if (type == PKCS11_TYPE_CRT_ALL) { + attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL; + } else if (type == PKCS11_TYPE_PRIVKEY) { + attrs = GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY; + } else { + attrs = GNUTLS_PKCS11_OBJ_ATTR_ALL; + } + + /* give some initial value to avoid asking for the pkcs11 pin twice. + */ + ret = + gnutls_pkcs11_obj_list_import_url2(&crt_list, &crt_list_size, + url, attrs, obj_flags); + if (ret < 0) { + fprintf(stderr, "Error in crt_list_import (1): %s\n", + gnutls_strerror(ret)); + exit(1); + } + + if (crt_list_size == 0) { + fprintf(stderr, "No matching objects found\n"); + exit(0); + } + + for (i = 0; i < crt_list_size; i++) { + char buf[128]; + size_t size; + + ret = + gnutls_pkcs11_obj_export_url(crt_list[i], detailed, + &output); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, + __LINE__, gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "Object %d:\n\tURL: %s\n", i, output); + + otype = gnutls_pkcs11_obj_get_type(crt_list[i]); + fprintf(outfile, "\tType: %s\n", + gnutls_pkcs11_type_get_name(otype)); + + size = sizeof(buf); + ret = + gnutls_pkcs11_obj_get_info(crt_list[i], + GNUTLS_PKCS11_OBJ_LABEL, + buf, &size); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, + __LINE__, gnutls_strerror(ret)); + exit(1); + } + fprintf(outfile, "\tLabel: %s\n", buf); + + size = sizeof(buf); + ret = + gnutls_pkcs11_obj_get_info(crt_list[i], + GNUTLS_PKCS11_OBJ_ID_HEX, + buf, &size); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, + __LINE__, gnutls_strerror(ret)); + exit(1); + } + fprintf(outfile, "\tID: %s\n\n", buf); + } + + return; } void -pkcs11_export (FILE * outfile, const char *url, unsigned int login, - common_info_st * info) +pkcs11_export(FILE * outfile, const char *url, unsigned int login, + common_info_st * info) { - gnutls_pkcs11_obj_t crt; - gnutls_x509_crt_t xcrt; - gnutls_pubkey_t pubkey; - int ret; - size_t size; - unsigned int obj_flags = 0; - - if (login) - obj_flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN; - - pkcs11_common (); - - if (url == NULL) - url = "pkcs11:"; - - ret = gnutls_pkcs11_obj_init (&crt); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - ret = gnutls_pkcs11_obj_import_url (crt, url, obj_flags); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - switch (gnutls_pkcs11_obj_get_type (crt)) - { - case GNUTLS_PKCS11_OBJ_X509_CRT: - ret = gnutls_x509_crt_init (&xcrt); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - ret = gnutls_x509_crt_import_pkcs11 (xcrt, crt); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - size = buffer_size; - ret = gnutls_x509_crt_export (xcrt, GNUTLS_X509_FMT_PEM, buffer, &size); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - fwrite (buffer, 1, size, outfile); - - gnutls_x509_crt_deinit (xcrt); - break; - case GNUTLS_PKCS11_OBJ_PUBKEY: - ret = gnutls_pubkey_init (&pubkey); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - ret = gnutls_pubkey_import_pkcs11 (pubkey, crt, 0); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - size = buffer_size; - ret = gnutls_pubkey_export (pubkey, GNUTLS_X509_FMT_PEM, buffer, &size); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - fwrite (buffer, 1, size, outfile); - - gnutls_pubkey_deinit (pubkey); - break; - default: - { - gnutls_datum_t data, enc; - - size = buffer_size; - ret = gnutls_pkcs11_obj_export (crt, buffer, &size); - if (ret < 0) - { - break; - } - - data.data = buffer; - data.size = size; - - ret = gnutls_pem_base64_encode_alloc ("DATA", &data, &enc); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - fwrite (enc.data, 1, enc.size, outfile); - - gnutls_free (enc.data); - break; - } - } - fputs ("\n\n", outfile); - - - gnutls_pkcs11_obj_deinit (crt); - - return; + gnutls_pkcs11_obj_t crt; + gnutls_x509_crt_t xcrt; + gnutls_pubkey_t pubkey; + int ret; + size_t size; + unsigned int obj_flags = 0; + + if (login) + obj_flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN; + + pkcs11_common(); + + if (url == NULL) + url = "pkcs11:"; + + ret = gnutls_pkcs11_obj_init(&crt); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, + gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_pkcs11_obj_import_url(crt, url, obj_flags); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, + gnutls_strerror(ret)); + exit(1); + } + + switch (gnutls_pkcs11_obj_get_type(crt)) { + case GNUTLS_PKCS11_OBJ_X509_CRT: + ret = gnutls_x509_crt_init(&xcrt); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, + __LINE__, gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_x509_crt_import_pkcs11(xcrt, crt); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, + __LINE__, gnutls_strerror(ret)); + exit(1); + } + + size = buffer_size; + ret = + gnutls_x509_crt_export(xcrt, GNUTLS_X509_FMT_PEM, + buffer, &size); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, + __LINE__, gnutls_strerror(ret)); + exit(1); + } + fwrite(buffer, 1, size, outfile); + + gnutls_x509_crt_deinit(xcrt); + break; + case GNUTLS_PKCS11_OBJ_PUBKEY: + ret = gnutls_pubkey_init(&pubkey); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, + __LINE__, gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_pubkey_import_pkcs11(pubkey, crt, 0); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, + __LINE__, gnutls_strerror(ret)); + exit(1); + } + + size = buffer_size; + ret = + gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_PEM, + buffer, &size); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, + __LINE__, gnutls_strerror(ret)); + exit(1); + } + fwrite(buffer, 1, size, outfile); + + gnutls_pubkey_deinit(pubkey); + break; + default: + { + gnutls_datum_t data, enc; + + size = buffer_size; + ret = gnutls_pkcs11_obj_export(crt, buffer, &size); + if (ret < 0) { + break; + } + + data.data = buffer; + data.size = size; + + ret = + gnutls_pem_base64_encode_alloc("DATA", &data, + &enc); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", + __func__, __LINE__, + gnutls_strerror(ret)); + exit(1); + } + + fwrite(enc.data, 1, enc.size, outfile); + + gnutls_free(enc.data); + break; + } + } + fputs("\n\n", outfile); + + + gnutls_pkcs11_obj_deinit(crt); + + return; } void -pkcs11_token_list (FILE * outfile, unsigned int detailed, - common_info_st * info) +pkcs11_token_list(FILE * outfile, unsigned int detailed, + common_info_st * info) { - int ret; - int i; - char *url; - char buf[128]; - size_t size; - - pkcs11_common (); - - for (i = 0;; i++) - { - ret = gnutls_pkcs11_token_get_url (i, detailed, &url); - if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) - break; - - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - fprintf (outfile, "Token %d:\n\tURL: %s\n", i, url); - - size = sizeof (buf); - ret = - gnutls_pkcs11_token_get_info (url, GNUTLS_PKCS11_TOKEN_LABEL, buf, - &size); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - fprintf (outfile, "\tLabel: %s\n", buf); - - size = sizeof (buf); - ret = - gnutls_pkcs11_token_get_info (url, GNUTLS_PKCS11_TOKEN_MANUFACTURER, - buf, &size); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - fprintf (outfile, "\tManufacturer: %s\n", buf); - - size = sizeof (buf); - ret = - gnutls_pkcs11_token_get_info (url, GNUTLS_PKCS11_TOKEN_MODEL, buf, - &size); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - fprintf (outfile, "\tModel: %s\n", buf); - - size = sizeof (buf); - ret = - gnutls_pkcs11_token_get_info (url, GNUTLS_PKCS11_TOKEN_SERIAL, buf, - &size); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - fprintf (outfile, "\tSerial: %s\n", buf); - fprintf (outfile, "\n\n"); - - gnutls_free (url); - - } - - return; + int ret; + int i; + char *url; + char buf[128]; + size_t size; + + pkcs11_common(); + + for (i = 0;; i++) { + ret = gnutls_pkcs11_token_get_url(i, detailed, &url); + if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) + break; + + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, + __LINE__, gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "Token %d:\n\tURL: %s\n", i, url); + + size = sizeof(buf); + ret = + gnutls_pkcs11_token_get_info(url, + GNUTLS_PKCS11_TOKEN_LABEL, + buf, &size); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, + __LINE__, gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "\tLabel: %s\n", buf); + + size = sizeof(buf); + ret = + gnutls_pkcs11_token_get_info(url, + GNUTLS_PKCS11_TOKEN_MANUFACTURER, + buf, &size); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, + __LINE__, gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "\tManufacturer: %s\n", buf); + + size = sizeof(buf); + ret = + gnutls_pkcs11_token_get_info(url, + GNUTLS_PKCS11_TOKEN_MODEL, + buf, &size); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, + __LINE__, gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "\tModel: %s\n", buf); + + size = sizeof(buf); + ret = + gnutls_pkcs11_token_get_info(url, + GNUTLS_PKCS11_TOKEN_SERIAL, + buf, &size); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, + __LINE__, gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "\tSerial: %s\n", buf); + fprintf(outfile, "\n\n"); + + gnutls_free(url); + + } + + return; } void -pkcs11_write (FILE * outfile, const char *url, const char *label, - int trusted, int private, - unsigned int login, common_info_st * info) +pkcs11_write(FILE * outfile, const char *url, const char *label, + int trusted, int private, + unsigned int login, common_info_st * info) { - gnutls_x509_crt_t xcrt; - gnutls_x509_privkey_t xkey; - int ret; - unsigned int flags = 0; - unsigned int key_usage = 0; - gnutls_datum_t *secret_key; - - if (login) - flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN; - - pkcs11_common (); - - if (url == NULL) - url = "pkcs11:"; - - secret_key = load_secret_key (0, info); - if (secret_key != NULL) - { - ret = - gnutls_pkcs11_copy_secret_key (url, secret_key, label, key_usage, - flags | - GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - } - - if (private == 1) - flags |= GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE; - else if (private == 0) - flags |= GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_PRIVATE; - - xcrt = load_cert (0, info); - if (xcrt != NULL) - { - if (trusted) - flags |= GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED|GNUTLS_PKCS11_OBJ_FLAG_LOGIN_SO; - - ret = gnutls_pkcs11_copy_x509_crt (url, xcrt, label, flags); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - gnutls_x509_crt_get_key_usage (xcrt, &key_usage, NULL); - } - - xkey = load_x509_private_key (0, info); - if (xkey != NULL) - { - ret = - gnutls_pkcs11_copy_x509_privkey (url, xkey, label, key_usage, - flags | - GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - } - - if (xkey == NULL && xcrt == NULL && secret_key == NULL) - { - fprintf (stderr, - "You must use --load-privkey, --load-certificate or --secret-key to load the file to be copied\n"); - exit (1); - } - - return; + gnutls_x509_crt_t xcrt; + gnutls_x509_privkey_t xkey; + int ret; + unsigned int flags = 0; + unsigned int key_usage = 0; + gnutls_datum_t *secret_key; + + if (login) + flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN; + + pkcs11_common(); + + if (url == NULL) + url = "pkcs11:"; + + secret_key = load_secret_key(0, info); + if (secret_key != NULL) { + ret = + gnutls_pkcs11_copy_secret_key(url, secret_key, label, + key_usage, + flags | + GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, + __LINE__, gnutls_strerror(ret)); + exit(1); + } + } + + if (private == 1) + flags |= GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE; + else if (private == 0) + flags |= GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_PRIVATE; + + xcrt = load_cert(0, info); + if (xcrt != NULL) { + if (trusted) + flags |= + GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED | + GNUTLS_PKCS11_OBJ_FLAG_LOGIN_SO; + + ret = gnutls_pkcs11_copy_x509_crt(url, xcrt, label, flags); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, + __LINE__, gnutls_strerror(ret)); + exit(1); + } + + gnutls_x509_crt_get_key_usage(xcrt, &key_usage, NULL); + } + + xkey = load_x509_private_key(0, info); + if (xkey != NULL) { + ret = + gnutls_pkcs11_copy_x509_privkey(url, xkey, label, + key_usage, + flags | + GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, + __LINE__, gnutls_strerror(ret)); + exit(1); + } + } + + if (xkey == NULL && xcrt == NULL && secret_key == NULL) { + fprintf(stderr, + "You must use --load-privkey, --load-certificate or --secret-key to load the file to be copied\n"); + exit(1); + } + + return; } void -pkcs11_generate (FILE * outfile, const char *url, gnutls_pk_algorithm_t pk, - unsigned int bits, - const char *label, int private, int detailed, - unsigned int login, common_info_st * info) +pkcs11_generate(FILE * outfile, const char *url, gnutls_pk_algorithm_t pk, + unsigned int bits, + const char *label, int private, int detailed, + unsigned int login, common_info_st * info) { - int ret; - unsigned int flags = 0; - gnutls_datum_t pubkey; - - if (login) - flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN; - - pkcs11_common (); - - if (url == NULL) - url = "pkcs11:"; - - if (private == 1) - flags |= GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE; - else if (private == 0) - flags |= GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_PRIVATE; - - ret = gnutls_pkcs11_privkey_generate2(url, pk, bits, label, GNUTLS_X509_FMT_PEM, - &pubkey, flags); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - if (login == 0) - fprintf(stderr, "Note that --login was not specified and it may be required for generation.\n"); - else if (bits != 1024) - fprintf (stderr, "Note that several smart cards do not support arbitrary size keys.\nTry --bits 1024 or 2048.\n"); - exit(1); - } - - fwrite (pubkey.data, 1, pubkey.size, outfile); - gnutls_free(pubkey.data); - - return; + int ret; + unsigned int flags = 0; + gnutls_datum_t pubkey; + + if (login) + flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN; + + pkcs11_common(); + + if (url == NULL) + url = "pkcs11:"; + + if (private == 1) + flags |= GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE; + else if (private == 0) + flags |= GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_PRIVATE; + + ret = + gnutls_pkcs11_privkey_generate2(url, pk, bits, label, + GNUTLS_X509_FMT_PEM, &pubkey, + flags); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, + gnutls_strerror(ret)); + if (login == 0) + fprintf(stderr, + "Note that --login was not specified and it may be required for generation.\n"); + else if (bits != 1024) + fprintf(stderr, + "Note that several smart cards do not support arbitrary size keys.\nTry --bits 1024 or 2048.\n"); + exit(1); + } + + fwrite(pubkey.data, 1, pubkey.size, outfile); + gnutls_free(pubkey.data); + + return; } void -pkcs11_init (FILE * outfile, const char *url, const char *label, - common_info_st * info) +pkcs11_init(FILE * outfile, const char *url, const char *label, + common_info_st * info) { - int ret; - char *pin; - char so_pin[32]; - - pkcs11_common (); - - if (url == NULL) - { - fprintf (stderr, "No token URL given to initialize!\n"); - exit (1); - } - - pin = getpass ("Enter Security Officer's PIN: "); - if (pin == NULL) - exit (1); - - if (strlen(pin) >= sizeof(so_pin)) - exit (1); - - strcpy (so_pin, pin); - - pin = getpass ("Enter new User's PIN: "); - if (pin == NULL) - exit (1); - - ret = gnutls_pkcs11_token_init (url, so_pin, label); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - ret = gnutls_pkcs11_token_set_pin (url, NULL, pin, GNUTLS_PIN_USER); - if (ret < 0) - { - fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, - gnutls_strerror (ret)); - exit (1); - } - - return; + int ret; + char *pin; + char so_pin[32]; + + pkcs11_common(); + + if (url == NULL) { + fprintf(stderr, "No token URL given to initialize!\n"); + exit(1); + } + + pin = getpass("Enter Security Officer's PIN: "); + if (pin == NULL) + exit(1); + + if (strlen(pin) >= sizeof(so_pin)) + exit(1); + + strcpy(so_pin, pin); + + pin = getpass("Enter new User's PIN: "); + if (pin == NULL) + exit(1); + + ret = gnutls_pkcs11_token_init(url, so_pin, label); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, + gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_pkcs11_token_set_pin(url, NULL, pin, GNUTLS_PIN_USER); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, + gnutls_strerror(ret)); + exit(1); + } + + return; } const char *mech_list[] = { - [0] = "CKM_RSA_PKCS_KEY_PAIR_GEN", - [1] = "CKM_RSA_PKCS", - [2] = "CKM_RSA_9796", - [3] = "CKM_RSA_X_509", - [4] = "CKM_MD2_RSA_PKCS", - [5] = "CKM_MD5_RSA_PKCS", - [6] = "CKM_SHA1_RSA_PKCS", - [7] = "CKM_RIPEMD128_RSA_PKCS", - [8] = "CKM_RIPEMD160_RSA_PKCS", - [9] = "CKM_RSA_PKCS_OAEP", - [0xa] = "CKM_RSA_X9_31_KEY_PAIR_GEN", - [0xb] = "CKM_RSA_X9_31", - [0xc] = "CKM_SHA1_RSA_X9_31", - [0xd] = "CKM_RSA_PKCS_PSS", - [0xe] = "CKM_SHA1_RSA_PKCS_PSS", - [0x10] = "CKM_DSA_KEY_PAIR_GEN", - [0x11] = "CKM_DSA", - [0x12] = "CKM_DSA_SHA1", - [0x20] = "CKM_DH_PKCS_KEY_PAIR_GEN", - [0x21] = "CKM_DH_PKCS_DERIVE", - [0x30] = "CKM_X9_42_DH_KEY_PAIR_GEN", - [0x31] = "CKM_X9_42_DH_DERIVE", - [0x32] = "CKM_X9_42_DH_HYBRID_DERIVE", - [0x33] = "CKM_X9_42_MQV_DERIVE", - [0x40] = "CKM_SHA256_RSA_PKCS", - [0x41] = "CKM_SHA384_RSA_PKCS", - [0x42] = "CKM_SHA512_RSA_PKCS", - [0x43] = "CKM_SHA256_RSA_PKCS_PSS", - [0x44] = "CKM_SHA384_RSA_PKCS_PSS", - [0x45] = "CKM_SHA512_RSA_PKCS_PSS", - [0x100] = "CKM_RC2_KEY_GEN", - [0x101] = "CKM_RC2_ECB", - [0x102] = "CKM_RC2_CBC", - [0x103] = "CKM_RC2_MAC", - [0x104] = "CKM_RC2_MAC_GENERAL", - [0x105] = "CKM_RC2_CBC_PAD", - [0x110] = "CKM_RC4_KEY_GEN", - [0x111] = "CKM_RC4", - [0x120] = "CKM_DES_KEY_GEN", - [0x121] = "CKM_DES_ECB", - [0x122] = "CKM_DES_CBC", - [0x123] = "CKM_DES_MAC", - [0x124] = "CKM_DES_MAC_GENERAL", - [0x125] = "CKM_DES_CBC_PAD", - [0x130] = "CKM_DES2_KEY_GEN", - [0x131] = "CKM_DES3_KEY_GEN", - [0x132] = "CKM_DES3_ECB", - [0x133] = "CKM_DES3_CBC", - [0x134] = "CKM_DES3_MAC", - [0x135] = "CKM_DES3_MAC_GENERAL", - [0x136] = "CKM_DES3_CBC_PAD", - [0x140] = "CKM_CDMF_KEY_GEN", - [0x141] = "CKM_CDMF_ECB", - [0x142] = "CKM_CDMF_CBC", - [0x143] = "CKM_CDMF_MAC", - [0x144] = "CKM_CDMF_MAC_GENERAL", - [0x145] = "CKM_CDMF_CBC_PAD", - [0x200] = "CKM_MD2", - [0x201] = "CKM_MD2_HMAC", - [0x202] = "CKM_MD2_HMAC_GENERAL", - [0x210] = "CKM_MD5", - [0x211] = "CKM_MD5_HMAC", - [0x212] = "CKM_MD5_HMAC_GENERAL", - [0x220] = "CKM_SHA_1", - [0x221] = "CKM_SHA_1_HMAC", - [0x222] = "CKM_SHA_1_HMAC_GENERAL", - [0x230] = "CKM_RIPEMD128", - [0x231] = "CKM_RIPEMD128_HMAC", - [0x232] = "CKM_RIPEMD128_HMAC_GENERAL", - [0x240] = "CKM_RIPEMD160", - [0x241] = "CKM_RIPEMD160_HMAC", - [0x242] = "CKM_RIPEMD160_HMAC_GENERAL", - [0x250] = "CKM_SHA256", - [0x251] = "CKM_SHA256_HMAC", - [0x252] = "CKM_SHA256_HMAC_GENERAL", - [0x260] = "CKM_SHA384", - [0x261] = "CKM_SHA384_HMAC", - [0x262] = "CKM_SHA384_HMAC_GENERAL", - [0x270] = "CKM_SHA512", - [0x271] = "CKM_SHA512_HMAC", - [0x272] = "CKM_SHA512_HMAC_GENERAL", - [0x300] = "CKM_CAST_KEY_GEN", - [0x301] = "CKM_CAST_ECB", - [0x302] = "CKM_CAST_CBC", - [0x303] = "CKM_CAST_MAC", - [0x304] = "CKM_CAST_MAC_GENERAL", - [0x305] = "CKM_CAST_CBC_PAD", - [0x310] = "CKM_CAST3_KEY_GEN", - [0x311] = "CKM_CAST3_ECB", - [0x312] = "CKM_CAST3_CBC", - [0x313] = "CKM_CAST3_MAC", - [0x314] = "CKM_CAST3_MAC_GENERAL", - [0x315] = "CKM_CAST3_CBC_PAD", - [0x320] = "CKM_CAST128_KEY_GEN", - [0x321] = "CKM_CAST128_ECB", - [0x322] = "CKM_CAST128_CBC", - [0x323] = "CKM_CAST128_MAC", - [0x324] = "CKM_CAST128_MAC_GENERAL", - [0x325] = "CKM_CAST128_CBC_PAD", - [0x330] = "CKM_RC5_KEY_GEN", - [0x331] = "CKM_RC5_ECB", - [0x332] = "CKM_RC5_CBC", - [0x333] = "CKM_RC5_MAC", - [0x334] = "CKM_RC5_MAC_GENERAL", - [0x335] = "CKM_RC5_CBC_PAD", - [0x340] = "CKM_IDEA_KEY_GEN", - [0x341] = "CKM_IDEA_ECB", - [0x342] = "CKM_IDEA_CBC", - [0x343] = "CKM_IDEA_MAC", - [0x344] = "CKM_IDEA_MAC_GENERAL", - [0x345] = "CKM_IDEA_CBC_PAD", - [0x350] = "CKM_GENERIC_SECRET_KEY_GEN", - [0x360] = "CKM_CONCATENATE_BASE_AND_KEY", - [0x362] = "CKM_CONCATENATE_BASE_AND_DATA", - [0x363] = "CKM_CONCATENATE_DATA_AND_BASE", - [0x364] = "CKM_XOR_BASE_AND_DATA", - [0x365] = "CKM_EXTRACT_KEY_FROM_KEY", - [0x370] = "CKM_SSL3_PRE_MASTER_KEY_GEN", - [0x371] = "CKM_SSL3_MASTER_KEY_DERIVE", - [0x372] = "CKM_SSL3_KEY_AND_MAC_DERIVE", - [0x373] = "CKM_SSL3_MASTER_KEY_DERIVE_DH", - [0x374] = "CKM_TLS_PRE_MASTER_KEY_GEN", - [0x375] = "CKM_TLS_MASTER_KEY_DERIVE", - [0x376] = "CKM_TLS_KEY_AND_MAC_DERIVE", - [0x377] = "CKM_TLS_MASTER_KEY_DERIVE_DH", - [0x380] = "CKM_SSL3_MD5_MAC", - [0x381] = "CKM_SSL3_SHA1_MAC", - [0x390] = "CKM_MD5_KEY_DERIVATION", - [0x391] = "CKM_MD2_KEY_DERIVATION", - [0x392] = "CKM_SHA1_KEY_DERIVATION", - [0x3a0] = "CKM_PBE_MD2_DES_CBC", - [0x3a1] = "CKM_PBE_MD5_DES_CBC", - [0x3a2] = "CKM_PBE_MD5_CAST_CBC", - [0x3a3] = "CKM_PBE_MD5_CAST3_CBC", - [0x3a4] = "CKM_PBE_MD5_CAST128_CBC", - [0x3a5] = "CKM_PBE_SHA1_CAST128_CBC", - [0x3a6] = "CKM_PBE_SHA1_RC4_128", - [0x3a7] = "CKM_PBE_SHA1_RC4_40", - [0x3a8] = "CKM_PBE_SHA1_DES3_EDE_CBC", - [0x3a9] = "CKM_PBE_SHA1_DES2_EDE_CBC", - [0x3aa] = "CKM_PBE_SHA1_RC2_128_CBC", - [0x3ab] = "CKM_PBE_SHA1_RC2_40_CBC", - [0x3b0] = "CKM_PKCS5_PBKD2", - [0x3c0] = "CKM_PBA_SHA1_WITH_SHA1_HMAC", - [0x400] = "CKM_KEY_WRAP_LYNKS", - [0x401] = "CKM_KEY_WRAP_SET_OAEP", - [0x1000] = "CKM_SKIPJACK_KEY_GEN", - [0x1001] = "CKM_SKIPJACK_ECB64", - [0x1002] = "CKM_SKIPJACK_CBC64", - [0x1003] = "CKM_SKIPJACK_OFB64", - [0x1004] = "CKM_SKIPJACK_CFB64", - [0x1005] = "CKM_SKIPJACK_CFB32", - [0x1006] = "CKM_SKIPJACK_CFB16", - [0x1007] = "CKM_SKIPJACK_CFB8", - [0x1008] = "CKM_SKIPJACK_WRAP", - [0x1009] = "CKM_SKIPJACK_PRIVATE_WRAP", - [0x100a] = "CKM_SKIPJACK_RELAYX", - [0x1010] = "CKM_KEA_KEY_PAIR_GEN", - [0x1011] = "CKM_KEA_KEY_DERIVE", - [0x1020] = "CKM_FORTEZZA_TIMESTAMP", - [0x1030] = "CKM_BATON_KEY_GEN", - [0x1031] = "CKM_BATON_ECB128", - [0x1032] = "CKM_BATON_ECB96", - [0x1033] = "CKM_BATON_CBC128", - [0x1034] = "CKM_BATON_COUNTER", - [0x1035] = "CKM_BATON_SHUFFLE", - [0x1036] = "CKM_BATON_WRAP", - [0x1040] = "CKM_ECDSA_KEY_PAIR_GEN", - [0x1041] = "CKM_ECDSA", - [0x1042] = "CKM_ECDSA_SHA1", - [0x1050] = "CKM_ECDH1_DERIVE", - [0x1051] = "CKM_ECDH1_COFACTOR_DERIVE", - [0x1052] = "CKM_ECMQV_DERIVE", - [0x1060] = "CKM_JUNIPER_KEY_GEN", - [0x1061] = "CKM_JUNIPER_ECB128", - [0x1062] = "CKM_JUNIPER_CBC128", - [0x1063] = "CKM_JUNIPER_COUNTER", - [0x1064] = "CKM_JUNIPER_SHUFFLE", - [0x1065] = "CKM_JUNIPER_WRAP", - [0x1070] = "CKM_FASTHASH", - [0x1080] = "CKM_AES_KEY_GEN", - [0x1081] = "CKM_AES_ECB", - [0x1082] = "CKM_AES_CBC", - [0x1083] = "CKM_AES_MAC", - [0x1084] = "CKM_AES_MAC_GENERAL", - [0x1085] = "CKM_AES_CBC_PAD", - [0x2000] = "CKM_DSA_PARAMETER_GEN", - [0x2001] = "CKM_DH_PKCS_PARAMETER_GEN", - [0x2002] = "CKM_X9_42_DH_PARAMETER_GEN", - [0x1200] = "CKM_GOSTR3410_KEY_PAIR_GEN", - [0x1201] = "CKM_GOSTR3410", - [0x1202] = "CKM_GOSTR3410_WITH_GOSTR3411", - [0x1203] = "CKM_GOSTR3410_KEY_WRAP", - [0x1204] = "CKM_GOSTR3410_DERIVE", - [0x1210] = "CKM_GOSTR3411", - [0x1211] = "CKM_GOSTR3411_HMAC", - [0x255] = "CKM_SHA224", - [0x256] = "CKM_SHA224_HMAC", - [0x257] = "CKM_SHA224_HMAC_GENERAL", - [0x46] = "CKM_SHA224_RSA_PKCS", - [0x47] = "CKM_SHA224_RSA_PKCS_PSS", - [0x396] = "CKM_SHA224_KEY_DERIVATION", - [0x550] = "CKM_CAMELLIA_KEY_GEN", - [0x551] = "CKM_CAMELLIA_ECB", - [0x552] = "CKM_CAMELLIA_CBC", - [0x553] = "CKM_CAMELLIA_MAC", - [0x554] = "CKM_CAMELLIA_MAC_GENERAL", - [0x555] = "CKM_CAMELLIA_CBC_PAD", - [0x556] = "CKM_CAMELLIA_ECB_ENCRYPT_DATA", - [0x557] = "CKM_CAMELLIA_CBC_ENCRYPT_DATA" + [0] = "CKM_RSA_PKCS_KEY_PAIR_GEN", + [1] = "CKM_RSA_PKCS", + [2] = "CKM_RSA_9796", + [3] = "CKM_RSA_X_509", + [4] = "CKM_MD2_RSA_PKCS", + [5] = "CKM_MD5_RSA_PKCS", + [6] = "CKM_SHA1_RSA_PKCS", + [7] = "CKM_RIPEMD128_RSA_PKCS", + [8] = "CKM_RIPEMD160_RSA_PKCS", + [9] = "CKM_RSA_PKCS_OAEP", + [0xa] = "CKM_RSA_X9_31_KEY_PAIR_GEN", + [0xb] = "CKM_RSA_X9_31", + [0xc] = "CKM_SHA1_RSA_X9_31", + [0xd] = "CKM_RSA_PKCS_PSS", + [0xe] = "CKM_SHA1_RSA_PKCS_PSS", + [0x10] = "CKM_DSA_KEY_PAIR_GEN", + [0x11] = "CKM_DSA", + [0x12] = "CKM_DSA_SHA1", + [0x20] = "CKM_DH_PKCS_KEY_PAIR_GEN", + [0x21] = "CKM_DH_PKCS_DERIVE", + [0x30] = "CKM_X9_42_DH_KEY_PAIR_GEN", + [0x31] = "CKM_X9_42_DH_DERIVE", + [0x32] = "CKM_X9_42_DH_HYBRID_DERIVE", + [0x33] = "CKM_X9_42_MQV_DERIVE", + [0x40] = "CKM_SHA256_RSA_PKCS", + [0x41] = "CKM_SHA384_RSA_PKCS", + [0x42] = "CKM_SHA512_RSA_PKCS", + [0x43] = "CKM_SHA256_RSA_PKCS_PSS", + [0x44] = "CKM_SHA384_RSA_PKCS_PSS", + [0x45] = "CKM_SHA512_RSA_PKCS_PSS", + [0x100] = "CKM_RC2_KEY_GEN", + [0x101] = "CKM_RC2_ECB", + [0x102] = "CKM_RC2_CBC", + [0x103] = "CKM_RC2_MAC", + [0x104] = "CKM_RC2_MAC_GENERAL", + [0x105] = "CKM_RC2_CBC_PAD", + [0x110] = "CKM_RC4_KEY_GEN", + [0x111] = "CKM_RC4", + [0x120] = "CKM_DES_KEY_GEN", + [0x121] = "CKM_DES_ECB", + [0x122] = "CKM_DES_CBC", + [0x123] = "CKM_DES_MAC", + [0x124] = "CKM_DES_MAC_GENERAL", + [0x125] = "CKM_DES_CBC_PAD", + [0x130] = "CKM_DES2_KEY_GEN", + [0x131] = "CKM_DES3_KEY_GEN", + [0x132] = "CKM_DES3_ECB", + [0x133] = "CKM_DES3_CBC", + [0x134] = "CKM_DES3_MAC", + [0x135] = "CKM_DES3_MAC_GENERAL", + [0x136] = "CKM_DES3_CBC_PAD", + [0x140] = "CKM_CDMF_KEY_GEN", + [0x141] = "CKM_CDMF_ECB", + [0x142] = "CKM_CDMF_CBC", + [0x143] = "CKM_CDMF_MAC", + [0x144] = "CKM_CDMF_MAC_GENERAL", + [0x145] = "CKM_CDMF_CBC_PAD", + [0x200] = "CKM_MD2", + [0x201] = "CKM_MD2_HMAC", + [0x202] = "CKM_MD2_HMAC_GENERAL", + [0x210] = "CKM_MD5", + [0x211] = "CKM_MD5_HMAC", + [0x212] = "CKM_MD5_HMAC_GENERAL", + [0x220] = "CKM_SHA_1", + [0x221] = "CKM_SHA_1_HMAC", + [0x222] = "CKM_SHA_1_HMAC_GENERAL", + [0x230] = "CKM_RIPEMD128", + [0x231] = "CKM_RIPEMD128_HMAC", + [0x232] = "CKM_RIPEMD128_HMAC_GENERAL", + [0x240] = "CKM_RIPEMD160", + [0x241] = "CKM_RIPEMD160_HMAC", + [0x242] = "CKM_RIPEMD160_HMAC_GENERAL", + [0x250] = "CKM_SHA256", + [0x251] = "CKM_SHA256_HMAC", + [0x252] = "CKM_SHA256_HMAC_GENERAL", + [0x260] = "CKM_SHA384", + [0x261] = "CKM_SHA384_HMAC", + [0x262] = "CKM_SHA384_HMAC_GENERAL", + [0x270] = "CKM_SHA512", + [0x271] = "CKM_SHA512_HMAC", + [0x272] = "CKM_SHA512_HMAC_GENERAL", + [0x300] = "CKM_CAST_KEY_GEN", + [0x301] = "CKM_CAST_ECB", + [0x302] = "CKM_CAST_CBC", + [0x303] = "CKM_CAST_MAC", + [0x304] = "CKM_CAST_MAC_GENERAL", + [0x305] = "CKM_CAST_CBC_PAD", + [0x310] = "CKM_CAST3_KEY_GEN", + [0x311] = "CKM_CAST3_ECB", + [0x312] = "CKM_CAST3_CBC", + [0x313] = "CKM_CAST3_MAC", + [0x314] = "CKM_CAST3_MAC_GENERAL", + [0x315] = "CKM_CAST3_CBC_PAD", + [0x320] = "CKM_CAST128_KEY_GEN", + [0x321] = "CKM_CAST128_ECB", + [0x322] = "CKM_CAST128_CBC", + [0x323] = "CKM_CAST128_MAC", + [0x324] = "CKM_CAST128_MAC_GENERAL", + [0x325] = "CKM_CAST128_CBC_PAD", + [0x330] = "CKM_RC5_KEY_GEN", + [0x331] = "CKM_RC5_ECB", + [0x332] = "CKM_RC5_CBC", + [0x333] = "CKM_RC5_MAC", + [0x334] = "CKM_RC5_MAC_GENERAL", + [0x335] = "CKM_RC5_CBC_PAD", + [0x340] = "CKM_IDEA_KEY_GEN", + [0x341] = "CKM_IDEA_ECB", + [0x342] = "CKM_IDEA_CBC", + [0x343] = "CKM_IDEA_MAC", + [0x344] = "CKM_IDEA_MAC_GENERAL", + [0x345] = "CKM_IDEA_CBC_PAD", + [0x350] = "CKM_GENERIC_SECRET_KEY_GEN", + [0x360] = "CKM_CONCATENATE_BASE_AND_KEY", + [0x362] = "CKM_CONCATENATE_BASE_AND_DATA", + [0x363] = "CKM_CONCATENATE_DATA_AND_BASE", + [0x364] = "CKM_XOR_BASE_AND_DATA", + [0x365] = "CKM_EXTRACT_KEY_FROM_KEY", + [0x370] = "CKM_SSL3_PRE_MASTER_KEY_GEN", + [0x371] = "CKM_SSL3_MASTER_KEY_DERIVE", + [0x372] = "CKM_SSL3_KEY_AND_MAC_DERIVE", + [0x373] = "CKM_SSL3_MASTER_KEY_DERIVE_DH", + [0x374] = "CKM_TLS_PRE_MASTER_KEY_GEN", + [0x375] = "CKM_TLS_MASTER_KEY_DERIVE", + [0x376] = "CKM_TLS_KEY_AND_MAC_DERIVE", + [0x377] = "CKM_TLS_MASTER_KEY_DERIVE_DH", + [0x380] = "CKM_SSL3_MD5_MAC", + [0x381] = "CKM_SSL3_SHA1_MAC", + [0x390] = "CKM_MD5_KEY_DERIVATION", + [0x391] = "CKM_MD2_KEY_DERIVATION", + [0x392] = "CKM_SHA1_KEY_DERIVATION", + [0x3a0] = "CKM_PBE_MD2_DES_CBC", + [0x3a1] = "CKM_PBE_MD5_DES_CBC", + [0x3a2] = "CKM_PBE_MD5_CAST_CBC", + [0x3a3] = "CKM_PBE_MD5_CAST3_CBC", + [0x3a4] = "CKM_PBE_MD5_CAST128_CBC", + [0x3a5] = "CKM_PBE_SHA1_CAST128_CBC", + [0x3a6] = "CKM_PBE_SHA1_RC4_128", + [0x3a7] = "CKM_PBE_SHA1_RC4_40", + [0x3a8] = "CKM_PBE_SHA1_DES3_EDE_CBC", + [0x3a9] = "CKM_PBE_SHA1_DES2_EDE_CBC", + [0x3aa] = "CKM_PBE_SHA1_RC2_128_CBC", + [0x3ab] = "CKM_PBE_SHA1_RC2_40_CBC", + [0x3b0] = "CKM_PKCS5_PBKD2", + [0x3c0] = "CKM_PBA_SHA1_WITH_SHA1_HMAC", + [0x400] = "CKM_KEY_WRAP_LYNKS", + [0x401] = "CKM_KEY_WRAP_SET_OAEP", + [0x1000] = "CKM_SKIPJACK_KEY_GEN", + [0x1001] = "CKM_SKIPJACK_ECB64", + [0x1002] = "CKM_SKIPJACK_CBC64", + [0x1003] = "CKM_SKIPJACK_OFB64", + [0x1004] = "CKM_SKIPJACK_CFB64", + [0x1005] = "CKM_SKIPJACK_CFB32", + [0x1006] = "CKM_SKIPJACK_CFB16", + [0x1007] = "CKM_SKIPJACK_CFB8", + [0x1008] = "CKM_SKIPJACK_WRAP", + [0x1009] = "CKM_SKIPJACK_PRIVATE_WRAP", + [0x100a] = "CKM_SKIPJACK_RELAYX", + [0x1010] = "CKM_KEA_KEY_PAIR_GEN", + [0x1011] = "CKM_KEA_KEY_DERIVE", + [0x1020] = "CKM_FORTEZZA_TIMESTAMP", + [0x1030] = "CKM_BATON_KEY_GEN", + [0x1031] = "CKM_BATON_ECB128", + [0x1032] = "CKM_BATON_ECB96", + [0x1033] = "CKM_BATON_CBC128", + [0x1034] = "CKM_BATON_COUNTER", + [0x1035] = "CKM_BATON_SHUFFLE", + [0x1036] = "CKM_BATON_WRAP", + [0x1040] = "CKM_ECDSA_KEY_PAIR_GEN", + [0x1041] = "CKM_ECDSA", + [0x1042] = "CKM_ECDSA_SHA1", + [0x1050] = "CKM_ECDH1_DERIVE", + [0x1051] = "CKM_ECDH1_COFACTOR_DERIVE", + [0x1052] = "CKM_ECMQV_DERIVE", + [0x1060] = "CKM_JUNIPER_KEY_GEN", + [0x1061] = "CKM_JUNIPER_ECB128", + [0x1062] = "CKM_JUNIPER_CBC128", + [0x1063] = "CKM_JUNIPER_COUNTER", + [0x1064] = "CKM_JUNIPER_SHUFFLE", + [0x1065] = "CKM_JUNIPER_WRAP", + [0x1070] = "CKM_FASTHASH", + [0x1080] = "CKM_AES_KEY_GEN", + [0x1081] = "CKM_AES_ECB", + [0x1082] = "CKM_AES_CBC", + [0x1083] = "CKM_AES_MAC", + [0x1084] = "CKM_AES_MAC_GENERAL", + [0x1085] = "CKM_AES_CBC_PAD", + [0x2000] = "CKM_DSA_PARAMETER_GEN", + [0x2001] = "CKM_DH_PKCS_PARAMETER_GEN", + [0x2002] = "CKM_X9_42_DH_PARAMETER_GEN", + [0x1200] = "CKM_GOSTR3410_KEY_PAIR_GEN", + [0x1201] = "CKM_GOSTR3410", + [0x1202] = "CKM_GOSTR3410_WITH_GOSTR3411", + [0x1203] = "CKM_GOSTR3410_KEY_WRAP", + [0x1204] = "CKM_GOSTR3410_DERIVE", + [0x1210] = "CKM_GOSTR3411", + [0x1211] = "CKM_GOSTR3411_HMAC", + [0x255] = "CKM_SHA224", + [0x256] = "CKM_SHA224_HMAC", + [0x257] = "CKM_SHA224_HMAC_GENERAL", + [0x46] = "CKM_SHA224_RSA_PKCS", + [0x47] = "CKM_SHA224_RSA_PKCS_PSS", + [0x396] = "CKM_SHA224_KEY_DERIVATION", + [0x550] = "CKM_CAMELLIA_KEY_GEN", + [0x551] = "CKM_CAMELLIA_ECB", + [0x552] = "CKM_CAMELLIA_CBC", + [0x553] = "CKM_CAMELLIA_MAC", + [0x554] = "CKM_CAMELLIA_MAC_GENERAL", + [0x555] = "CKM_CAMELLIA_CBC_PAD", + [0x556] = "CKM_CAMELLIA_ECB_ENCRYPT_DATA", + [0x557] = "CKM_CAMELLIA_CBC_ENCRYPT_DATA" }; void -pkcs11_mechanism_list (FILE * outfile, const char *url, unsigned int login, - common_info_st * info) +pkcs11_mechanism_list(FILE * outfile, const char *url, unsigned int login, + common_info_st * info) { - int ret; - int idx; - unsigned long mechanism; - const char *str; - - pkcs11_common (); - - if (url == NULL) - url = "pkcs11:"; - - idx = 0; - do - { - ret = gnutls_pkcs11_token_get_mechanism (url, idx++, &mechanism); - if (ret >= 0) - { - str = NULL; - if (mechanism <= sizeof (mech_list) / sizeof (mech_list[0])) - str = mech_list[mechanism]; - if (str == NULL) - str = "UNKNOWN"; - - fprintf (outfile, "[0x%.4lx] %s\n", mechanism, str); - } - } - while (ret >= 0); - - - return; + int ret; + int idx; + unsigned long mechanism; + const char *str; + + pkcs11_common(); + + if (url == NULL) + url = "pkcs11:"; + + idx = 0; + do { + ret = + gnutls_pkcs11_token_get_mechanism(url, idx++, + &mechanism); + if (ret >= 0) { + str = NULL; + if (mechanism <= + sizeof(mech_list) / sizeof(mech_list[0])) + str = mech_list[mechanism]; + if (str == NULL) + str = "UNKNOWN"; + + fprintf(outfile, "[0x%.4lx] %s\n", mechanism, str); + } + } + while (ret >= 0); + + + return; } void -pkcs11_get_random (FILE * outfile, const char *url, unsigned bytes, common_info_st * info) +pkcs11_get_random(FILE * outfile, const char *url, unsigned bytes, + common_info_st * info) { - int ret; - uint8_t* output; + int ret; + uint8_t *output; - pkcs11_common (); + pkcs11_common(); - if (url == NULL) - url = "pkcs11:"; + if (url == NULL) + url = "pkcs11:"; - output = malloc(bytes); - if (output == NULL) - { - fprintf(stderr, "Memory error\n"); - exit(1); - } + output = malloc(bytes); + if (output == NULL) { + fprintf(stderr, "Memory error\n"); + exit(1); + } - ret = gnutls_pkcs11_token_get_random (url, output, bytes); - if (ret < 0) - { - fprintf(stderr, "gnutls_pkcs11_token_get_random: %s\n", gnutls_strerror(ret)); - exit(1); - } + ret = gnutls_pkcs11_token_get_random(url, output, bytes); + if (ret < 0) { + fprintf(stderr, "gnutls_pkcs11_token_get_random: %s\n", + gnutls_strerror(ret)); + exit(1); + } - fwrite(output, 1, bytes, outfile); + fwrite(output, 1, bytes, outfile); - return; + return; } @@ -26,11 +26,10 @@ #include <stdio.h> -int -main (int argc, char **argv) +int main(int argc, char **argv) { - printf ("\nPSK not supported. This program is a dummy.\n\n"); - return 1; + printf("\nPSK not supported. This program is a dummy.\n\n"); + return 1; }; #else @@ -41,7 +40,7 @@ main (int argc, char **argv) #include <gnutls/gnutls.h> #include <psk-args.h> -#include <gnutls/crypto.h> /* for random */ +#include <gnutls/crypto.h> /* for random */ #include <sys/types.h> #include <sys/stat.h> @@ -57,226 +56,206 @@ main (int argc, char **argv) #include <minmax.h> #include "getpass.h" -static int write_key (const char *username, const char *key, int key_size, - const char *passwd_file); +static int write_key(const char *username, const char *key, int key_size, + const char *passwd_file); #define KPASSWD "/etc/passwd.psk" #define MAX_KEY_SIZE 64 -int -main (int argc, char **argv) +int main(int argc, char **argv) { - int ret; + int ret; #ifndef _WIN32 - struct passwd *pwd; + struct passwd *pwd; #endif - unsigned char key[MAX_KEY_SIZE]; - char hex_key[MAX_KEY_SIZE * 2 + 1]; - int optct, key_size; - gnutls_datum_t dkey; - const char* passwd, *username; - size_t hex_key_size = sizeof (hex_key); - - if ((ret = gnutls_global_init ()) < 0) - { - fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret)); - exit (1); - } - - umask (066); - - optct = optionProcess( &psktoolOptions, argc, argv); - argc -= optct; - argv += optct; - - if (!HAVE_OPT(PASSWD)) - passwd = (char *) KPASSWD; - else - passwd = OPT_ARG(PASSWD); - - if (!HAVE_OPT(USERNAME)) - { + unsigned char key[MAX_KEY_SIZE]; + char hex_key[MAX_KEY_SIZE * 2 + 1]; + int optct, key_size; + gnutls_datum_t dkey; + const char *passwd, *username; + size_t hex_key_size = sizeof(hex_key); + + if ((ret = gnutls_global_init()) < 0) { + fprintf(stderr, "global_init: %s\n", gnutls_strerror(ret)); + exit(1); + } + + umask(066); + + optct = optionProcess(&psktoolOptions, argc, argv); + argc -= optct; + argv += optct; + + if (!HAVE_OPT(PASSWD)) + passwd = (char *) KPASSWD; + else + passwd = OPT_ARG(PASSWD); + + if (!HAVE_OPT(USERNAME)) { #ifndef _WIN32 - pwd = getpwuid (getuid ()); + pwd = getpwuid(getuid()); - if (pwd == NULL) - { - fprintf (stderr, "No such user\n"); - return -1; - } + if (pwd == NULL) { + fprintf(stderr, "No such user\n"); + return -1; + } - username = pwd->pw_name; + username = pwd->pw_name; #else - fprintf (stderr, "Please specify a user\n"); - return -1; + fprintf(stderr, "Please specify a user\n"); + return -1; #endif - } - else - username = OPT_ARG(USERNAME); - - if (HAVE_OPT(KEYSIZE) && OPT_VALUE_KEYSIZE > MAX_KEY_SIZE) - { - fprintf (stderr, "Key size is too long\n"); - exit (1); - } - - if (!HAVE_OPT(KEYSIZE) || OPT_VALUE_KEYSIZE < 1) - key_size = 16; - else - key_size = OPT_VALUE_KEYSIZE; - - printf ("Generating a random key for user '%s'\n", username); - - ret = gnutls_rnd (GNUTLS_RND_RANDOM, (char *) key, key_size); - if (ret < 0) - { - fprintf (stderr, "Not enough randomness\n"); - exit (1); - } - - dkey.data = key; - dkey.size = key_size; - - ret = gnutls_hex_encode (&dkey, hex_key, &hex_key_size); - if (ret < 0) - { - fprintf (stderr, "HEX encoding error\n"); - exit (1); - } - - ret = write_key (username, hex_key, hex_key_size, passwd); - if (ret == 0) - printf ("Key stored to %s\n", passwd); - - return ret; + } else + username = OPT_ARG(USERNAME); + + if (HAVE_OPT(KEYSIZE) && OPT_VALUE_KEYSIZE > MAX_KEY_SIZE) { + fprintf(stderr, "Key size is too long\n"); + exit(1); + } + + if (!HAVE_OPT(KEYSIZE) || OPT_VALUE_KEYSIZE < 1) + key_size = 16; + else + key_size = OPT_VALUE_KEYSIZE; + + printf("Generating a random key for user '%s'\n", username); + + ret = gnutls_rnd(GNUTLS_RND_RANDOM, (char *) key, key_size); + if (ret < 0) { + fprintf(stderr, "Not enough randomness\n"); + exit(1); + } + + dkey.data = key; + dkey.size = key_size; + + ret = gnutls_hex_encode(&dkey, hex_key, &hex_key_size); + if (ret < 0) { + fprintf(stderr, "HEX encoding error\n"); + exit(1); + } + + ret = write_key(username, hex_key, hex_key_size, passwd); + if (ret == 0) + printf("Key stored to %s\n", passwd); + + return ret; } -static int -filecopy (const char *src, const char *dst) +static int filecopy(const char *src, const char *dst) { - FILE *fd, *fd2; - char line[5 * 1024]; - char *p; - - fd = fopen (dst, "w"); - if (fd == NULL) - { - fprintf (stderr, "Cannot open '%s' for write\n", dst); - return -1; - } - - fd2 = fopen (src, "r"); - if (fd2 == NULL) - { - /* empty file */ - fclose (fd); - return 0; - } - - line[sizeof (line) - 1] = 0; - do - { - p = fgets (line, sizeof (line) - 1, fd2); - if (p == NULL) - break; - - fputs (line, fd); - } - while (1); - - fclose (fd); - fclose (fd2); - - return 0; + FILE *fd, *fd2; + char line[5 * 1024]; + char *p; + + fd = fopen(dst, "w"); + if (fd == NULL) { + fprintf(stderr, "Cannot open '%s' for write\n", dst); + return -1; + } + + fd2 = fopen(src, "r"); + if (fd2 == NULL) { + /* empty file */ + fclose(fd); + return 0; + } + + line[sizeof(line) - 1] = 0; + do { + p = fgets(line, sizeof(line) - 1, fd2); + if (p == NULL) + break; + + fputs(line, fd); + } + while (1); + + fclose(fd); + fclose(fd2); + + return 0; } static int -write_key (const char *username, const char *key, int key_size, - const char *passwd_file) +write_key(const char *username, const char *key, int key_size, + const char *passwd_file) { - FILE *fd; - char line[5 * 1024]; - char *p, *pp; - char tmpname[1024]; - - - /* delete previous entry */ - struct stat st; - FILE *fd2; - int put; - - if (strlen (passwd_file) + 5 > sizeof (tmpname)) - { - fprintf (stderr, "file '%s' is tooooo long\n", passwd_file); - return -1; - } - - snprintf (tmpname, sizeof(tmpname), "%s.tmp", passwd_file); - - if (stat (tmpname, &st) != -1) - { - fprintf (stderr, "file '%s' is locked\n", tmpname); - return -1; - } - - if (filecopy (passwd_file, tmpname) != 0) - { - fprintf (stderr, "Cannot copy '%s' to '%s'\n", passwd_file, tmpname); - return -1; - } - - fd = fopen (passwd_file, "w"); - if (fd == NULL) - { - fprintf (stderr, "Cannot open '%s' for write\n", passwd_file); - remove (tmpname); - return -1; - } - - fd2 = fopen (tmpname, "r"); - if (fd2 == NULL) - { - fprintf (stderr, "Cannot open '%s' for read\n", tmpname); - remove (tmpname); - return -1; - } - - put = 0; - do - { - p = fgets (line, sizeof (line) - 1, fd2); - if (p == NULL) - break; - - pp = strchr (line, ':'); - if (pp == NULL) - continue; - - if (strncmp (p, username, - MAX (strlen (username), (unsigned int) (pp - p))) == 0) - { - put = 1; - fprintf (fd, "%s:%s\n", username, key); - } - else - { - fputs (line, fd); - } - } - while (1); - - if (put == 0) - { - fprintf (fd, "%s:%s\n", username, key); - } - - fclose (fd); - fclose (fd2); - - remove (tmpname); - - - return 0; + FILE *fd; + char line[5 * 1024]; + char *p, *pp; + char tmpname[1024]; + + + /* delete previous entry */ + struct stat st; + FILE *fd2; + int put; + + if (strlen(passwd_file) + 5 > sizeof(tmpname)) { + fprintf(stderr, "file '%s' is tooooo long\n", passwd_file); + return -1; + } + + snprintf(tmpname, sizeof(tmpname), "%s.tmp", passwd_file); + + if (stat(tmpname, &st) != -1) { + fprintf(stderr, "file '%s' is locked\n", tmpname); + return -1; + } + + if (filecopy(passwd_file, tmpname) != 0) { + fprintf(stderr, "Cannot copy '%s' to '%s'\n", passwd_file, + tmpname); + return -1; + } + + fd = fopen(passwd_file, "w"); + if (fd == NULL) { + fprintf(stderr, "Cannot open '%s' for write\n", + passwd_file); + remove(tmpname); + return -1; + } + + fd2 = fopen(tmpname, "r"); + if (fd2 == NULL) { + fprintf(stderr, "Cannot open '%s' for read\n", tmpname); + remove(tmpname); + return -1; + } + + put = 0; + do { + p = fgets(line, sizeof(line) - 1, fd2); + if (p == NULL) + break; + + pp = strchr(line, ':'); + if (pp == NULL) + continue; + + if (strncmp(p, username, + MAX(strlen(username), + (unsigned int) (pp - p))) == 0) { + put = 1; + fprintf(fd, "%s:%s\n", username, key); + } else { + fputs(line, fd); + } + } + while (1); + + if (put == 0) { + fprintf(fd, "%s:%s\n", username, key); + } + + fclose(fd); + fclose(fd2); + + remove(tmpname); + + + return 0; } -#endif /* ENABLE_PSK */ - +#endif /* ENABLE_PSK */ diff --git a/src/serv.c b/src/serv.c index d420cb8bec..61abf4e411 100644 --- a/src/serv.c +++ b/src/serv.c @@ -79,11 +79,11 @@ const char *x509_ecccertfile = NULL; const char *x509_cafile = NULL; const char *dh_params_file = NULL; const char *x509_crlfile = NULL; -const char * priorities = NULL; -const char * status_response_ocsp = NULL; +const char *priorities = NULL; +const char *status_response_ocsp = NULL; gnutls_datum_t session_ticket_key; -static void tcp_server (const char *name, int port); +static void tcp_server(const char *name, int port); /* end of globals */ @@ -115,47 +115,47 @@ gnutls_certificate_credentials_t cert_cred = NULL; const int ssl_session_cache = 128; -static void wrap_db_init (void); -static void wrap_db_deinit (void); -static int wrap_db_store (void *dbf, gnutls_datum_t key, gnutls_datum_t data); -static gnutls_datum_t wrap_db_fetch (void *dbf, gnutls_datum_t key); -static int wrap_db_delete (void *dbf, gnutls_datum_t key); +static void wrap_db_init(void); +static void wrap_db_deinit(void); +static int wrap_db_store(void *dbf, gnutls_datum_t key, + gnutls_datum_t data); +static gnutls_datum_t wrap_db_fetch(void *dbf, gnutls_datum_t key); +static int wrap_db_delete(void *dbf, gnutls_datum_t key); -static void cmd_parser (int argc, char **argv); +static void cmd_parser(int argc, char **argv); #define HTTP_STATE_REQUEST 1 #define HTTP_STATE_RESPONSE 2 #define HTTP_STATE_CLOSING 3 -LIST_TYPE_DECLARE (listener_item, char *http_request; - char *http_response; int request_length; - int response_length; int response_written; - int http_state; int listen_socket; - int fd; gnutls_session_t tls_session; int handshake_ok;); +LIST_TYPE_DECLARE(listener_item, char *http_request; char *http_response; + int request_length; int response_length; + int response_written; int http_state; + int listen_socket; int fd; + gnutls_session_t tls_session; + int handshake_ok; + ); -static const char * -safe_strerror (int value) +static const char *safe_strerror(int value) { - const char *ret = gnutls_strerror (value); - if (ret == NULL) - ret = str_unknown; - return ret; + const char *ret = gnutls_strerror(value); + if (ret == NULL) + ret = str_unknown; + return ret; } -static void -listener_free (listener_item * j) +static void listener_free(listener_item * j) { - free (j->http_request); - free (j->http_response); - if (j->fd >= 0) - { - gnutls_bye (j->tls_session, GNUTLS_SHUT_WR); - shutdown (j->fd, 2); - close (j->fd); - gnutls_deinit (j->tls_session); - } + free(j->http_request); + free(j->http_response); + if (j->fd >= 0) { + gnutls_bye(j->tls_session, GNUTLS_SHUT_WR); + shutdown(j->fd, 2); + close(j->fd); + gnutls_deinit(j->tls_session); + } } @@ -166,1538 +166,1550 @@ listener_free (listener_item * j) gnutls_dh_params_t dh_params = NULL; gnutls_rsa_params_t rsa_params = NULL; -static int -generate_dh_primes (void) +static int generate_dh_primes(void) { - int prime_bits = - gnutls_sec_param_to_pk_bits (GNUTLS_PK_DH, GNUTLS_SEC_PARAM_NORMAL); - - if (gnutls_dh_params_init (&dh_params) < 0) - { - fprintf (stderr, "Error in dh parameter initialization\n"); - exit (1); - } - - /* Generate Diffie-Hellman parameters - for use with DHE - * kx algorithms. These should be discarded and regenerated - * once a week or once a month. Depends on the - * security requirements. - */ - printf - ("Generating Diffie-Hellman parameters [%d]. Please wait...\n", - prime_bits); - fflush (stdout); - - if (gnutls_dh_params_generate2 (dh_params, prime_bits) < 0) - { - fprintf (stderr, "Error in prime generation\n"); - exit (1); - } - - return 0; + int prime_bits = + gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, + GNUTLS_SEC_PARAM_NORMAL); + + if (gnutls_dh_params_init(&dh_params) < 0) { + fprintf(stderr, "Error in dh parameter initialization\n"); + exit(1); + } + + /* Generate Diffie-Hellman parameters - for use with DHE + * kx algorithms. These should be discarded and regenerated + * once a week or once a month. Depends on the + * security requirements. + */ + printf + ("Generating Diffie-Hellman parameters [%d]. Please wait...\n", + prime_bits); + fflush(stdout); + + if (gnutls_dh_params_generate2(dh_params, prime_bits) < 0) { + fprintf(stderr, "Error in prime generation\n"); + exit(1); + } + + return 0; } -static void -read_dh_params (void) +static void read_dh_params(void) { - char tmpdata[2048]; - int size; - gnutls_datum_t params; - FILE *fd; - - if (gnutls_dh_params_init (&dh_params) < 0) - { - fprintf (stderr, "Error in dh parameter initialization\n"); - exit (1); - } - - /* read the params file - */ - fd = fopen (dh_params_file, "r"); - if (fd == NULL) - { - fprintf (stderr, "Could not open %s\n", dh_params_file); - exit (1); - } - - size = fread (tmpdata, 1, sizeof (tmpdata) - 1, fd); - tmpdata[size] = 0; - fclose (fd); - - params.data = (unsigned char *) tmpdata; - params.size = size; - - size = - gnutls_dh_params_import_pkcs3 (dh_params, ¶ms, GNUTLS_X509_FMT_PEM); - - if (size < 0) - { - fprintf (stderr, "Error parsing dh params: %s\n", safe_strerror (size)); - exit (1); - } - - printf ("Read Diffie-Hellman parameters.\n"); - fflush (stdout); + char tmpdata[2048]; + int size; + gnutls_datum_t params; + FILE *fd; + + if (gnutls_dh_params_init(&dh_params) < 0) { + fprintf(stderr, "Error in dh parameter initialization\n"); + exit(1); + } + + /* read the params file + */ + fd = fopen(dh_params_file, "r"); + if (fd == NULL) { + fprintf(stderr, "Could not open %s\n", dh_params_file); + exit(1); + } + + size = fread(tmpdata, 1, sizeof(tmpdata) - 1, fd); + tmpdata[size] = 0; + fclose(fd); + + params.data = (unsigned char *) tmpdata; + params.size = size; + + size = + gnutls_dh_params_import_pkcs3(dh_params, ¶ms, + GNUTLS_X509_FMT_PEM); + + if (size < 0) { + fprintf(stderr, "Error parsing dh params: %s\n", + safe_strerror(size)); + exit(1); + } + + printf("Read Diffie-Hellman parameters.\n"); + fflush(stdout); } static char pkcs3[] = - "-----BEGIN DH PARAMETERS-----\n" - "MIGGAoGAtkxw2jlsVCsrfLqxrN+IrF/3W8vVFvDzYbLmxi2GQv9s/PQGWP1d9i22\n" - "P2DprfcJknWt7KhCI1SaYseOQIIIAYP78CfyIpGScW/vS8khrw0rlQiyeCvQgF3O\n" - "GeGOEywcw+oQT4SmFOD7H0smJe2CNyjYpexBXQ/A0mbTF9QKm1cCAQU=\n" - "-----END DH PARAMETERS-----\n"; + "-----BEGIN DH PARAMETERS-----\n" + "MIGGAoGAtkxw2jlsVCsrfLqxrN+IrF/3W8vVFvDzYbLmxi2GQv9s/PQGWP1d9i22\n" + "P2DprfcJknWt7KhCI1SaYseOQIIIAYP78CfyIpGScW/vS8khrw0rlQiyeCvQgF3O\n" + "GeGOEywcw+oQT4SmFOD7H0smJe2CNyjYpexBXQ/A0mbTF9QKm1cCAQU=\n" + "-----END DH PARAMETERS-----\n"; -static int -static_dh_params (void) +static int static_dh_params(void) { - gnutls_datum_t params = { (void *) pkcs3, sizeof (pkcs3) }; - int ret; + gnutls_datum_t params = { (void *) pkcs3, sizeof(pkcs3) }; + int ret; - if (gnutls_dh_params_init (&dh_params) < 0) - { - fprintf (stderr, "Error in dh parameter initialization\n"); - exit (1); - } + if (gnutls_dh_params_init(&dh_params) < 0) { + fprintf(stderr, "Error in dh parameter initialization\n"); + exit(1); + } - ret = gnutls_dh_params_import_pkcs3 (dh_params, ¶ms, - GNUTLS_X509_FMT_PEM); + ret = gnutls_dh_params_import_pkcs3(dh_params, ¶ms, + GNUTLS_X509_FMT_PEM); - if (ret < 0) - { - fprintf (stderr, "Error parsing dh params: %s\n", safe_strerror (ret)); - exit (1); - } + if (ret < 0) { + fprintf(stderr, "Error parsing dh params: %s\n", + safe_strerror(ret)); + exit(1); + } - printf ("Set static Diffie-Hellman parameters, consider --dhparams.\n"); + printf + ("Set static Diffie-Hellman parameters, consider --dhparams.\n"); - return 0; + return 0; } static int -get_params (gnutls_session_t session, gnutls_params_type_t type, - gnutls_params_st * st) +get_params(gnutls_session_t session, gnutls_params_type_t type, + gnutls_params_st * st) { - if (type == GNUTLS_PARAMS_RSA_EXPORT) - { - if (rsa_params == NULL) - return -1; - st->params.rsa_export = rsa_params; - } - else if (type == GNUTLS_PARAMS_DH) - { - if (dh_params == NULL) - return -1; - st->params.dh = dh_params; - } - else - return -1; - - st->type = type; - st->deinit = 0; - - return 0; + if (type == GNUTLS_PARAMS_RSA_EXPORT) { + if (rsa_params == NULL) + return -1; + st->params.rsa_export = rsa_params; + } else if (type == GNUTLS_PARAMS_DH) { + if (dh_params == NULL) + return -1; + st->params.dh = dh_params; + } else + return -1; + + st->type = type; + st->deinit = 0; + + return 0; } #ifdef ENABLE_RSA_EXPORT -static int -generate_rsa_params (void) +static int generate_rsa_params(void) { - if (gnutls_rsa_params_init (&rsa_params) < 0) - { - fprintf (stderr, "Error in rsa parameter initialization\n"); - exit (1); - } - - /* Generate RSA parameters - for use with RSA-export - * cipher suites. These should be discarded and regenerated - * once a day, once every 500 transactions etc. Depends on the - * security requirements. - */ - printf ("Generating temporary RSA parameters. Please wait...\n"); - fflush (stdout); - - if (gnutls_rsa_params_generate2 (rsa_params, 512) < 0) - { - fprintf (stderr, "Error in rsa parameter generation\n"); - exit (1); - } - - return 0; + if (gnutls_rsa_params_init(&rsa_params) < 0) { + fprintf(stderr, "Error in rsa parameter initialization\n"); + exit(1); + } + + /* Generate RSA parameters - for use with RSA-export + * cipher suites. These should be discarded and regenerated + * once a day, once every 500 transactions etc. Depends on the + * security requirements. + */ + printf("Generating temporary RSA parameters. Please wait...\n"); + fflush(stdout); + + if (gnutls_rsa_params_generate2(rsa_params, 512) < 0) { + fprintf(stderr, "Error in rsa parameter generation\n"); + exit(1); + } + + return 0; } #else -static int -generate_rsa_params (void) +static int generate_rsa_params(void) { - return 0; + return 0; } #endif -LIST_DECLARE_INIT (listener_list, listener_item, listener_free); +LIST_DECLARE_INIT(listener_list, listener_item, listener_free); -gnutls_session_t initialize_session (int dtls) +gnutls_session_t initialize_session(int dtls) { - gnutls_session_t session; - int ret; - const char *err; - - if (priorities == NULL) - priorities = "NORMAL"; - - if (dtls) - gnutls_init (&session, GNUTLS_SERVER | GNUTLS_DATAGRAM); - else - gnutls_init (&session, GNUTLS_SERVER); - - /* allow the use of private ciphersuites. - */ - gnutls_handshake_set_private_extensions (session, 1); - - if (nodb == 0) - { - gnutls_db_set_retrieve_function (session, wrap_db_fetch); - gnutls_db_set_remove_function (session, wrap_db_delete); - gnutls_db_set_store_function (session, wrap_db_store); - gnutls_db_set_ptr (session, NULL); - } - - if (noticket == 0) - gnutls_session_ticket_enable_server (session, &session_ticket_key); - - if (gnutls_priority_set_direct (session, priorities, &err) < 0) - { - fprintf (stderr, "Syntax error at: %s\n", err); - exit (1); - } - - gnutls_credentials_set (session, GNUTLS_CRD_ANON, dh_cred); - - if (srp_cred != NULL) - gnutls_credentials_set (session, GNUTLS_CRD_SRP, srp_cred); - - if (psk_cred != NULL) - gnutls_credentials_set (session, GNUTLS_CRD_PSK, psk_cred); - - if (cert_cred != NULL) - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, cert_cred); - - if (disable_client_cert) - gnutls_certificate_server_set_request (session, GNUTLS_CERT_IGNORE); - else - { - if (require_cert) - gnutls_certificate_server_set_request (session, GNUTLS_CERT_REQUIRE); - else - gnutls_certificate_server_set_request (session, GNUTLS_CERT_REQUEST); - } - - if (HAVE_OPT (HEARTBEAT)) - gnutls_heartbeat_enable(session, GNUTLS_HB_PEER_ALLOWED_TO_SEND); + gnutls_session_t session; + int ret; + const char *err; + + if (priorities == NULL) + priorities = "NORMAL"; + + if (dtls) + gnutls_init(&session, GNUTLS_SERVER | GNUTLS_DATAGRAM); + else + gnutls_init(&session, GNUTLS_SERVER); + + /* allow the use of private ciphersuites. + */ + gnutls_handshake_set_private_extensions(session, 1); + + if (nodb == 0) { + gnutls_db_set_retrieve_function(session, wrap_db_fetch); + gnutls_db_set_remove_function(session, wrap_db_delete); + gnutls_db_set_store_function(session, wrap_db_store); + gnutls_db_set_ptr(session, NULL); + } + + if (noticket == 0) + gnutls_session_ticket_enable_server(session, + &session_ticket_key); + + if (gnutls_priority_set_direct(session, priorities, &err) < 0) { + fprintf(stderr, "Syntax error at: %s\n", err); + exit(1); + } + + gnutls_credentials_set(session, GNUTLS_CRD_ANON, dh_cred); + + if (srp_cred != NULL) + gnutls_credentials_set(session, GNUTLS_CRD_SRP, srp_cred); + + if (psk_cred != NULL) + gnutls_credentials_set(session, GNUTLS_CRD_PSK, psk_cred); + + if (cert_cred != NULL) + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, + cert_cred); + + if (disable_client_cert) + gnutls_certificate_server_set_request(session, + GNUTLS_CERT_IGNORE); + else { + if (require_cert) + gnutls_certificate_server_set_request(session, + GNUTLS_CERT_REQUIRE); + else + gnutls_certificate_server_set_request(session, + GNUTLS_CERT_REQUEST); + } + + if (HAVE_OPT(HEARTBEAT)) + gnutls_heartbeat_enable(session, + GNUTLS_HB_PEER_ALLOWED_TO_SEND); #ifdef ENABLE_DTLS_SRTP - if (HAVE_OPT (SRTP_PROFILES)) - { - ret = gnutls_srtp_set_profile_direct (session, OPT_ARG(SRTP_PROFILES), &err); - if (ret == GNUTLS_E_INVALID_REQUEST) fprintf (stderr, "Syntax error at: %s\n", err); - else - fprintf(stderr, "Error in profiles: %s\n", gnutls_strerror(ret)); - exit (1); - } + if (HAVE_OPT(SRTP_PROFILES)) { + ret = + gnutls_srtp_set_profile_direct(session, + OPT_ARG(SRTP_PROFILES), + &err); + if (ret == GNUTLS_E_INVALID_REQUEST) + fprintf(stderr, "Syntax error at: %s\n", err); + else + fprintf(stderr, "Error in profiles: %s\n", + gnutls_strerror(ret)); + exit(1); + } #endif - return session; + return session; } #include <gnutls/x509.h> static const char DEFAULT_DATA[] = - "This is the default message reported by the GnuTLS implementation. " - "For more information please visit " - "<a href=\"http://www.gnutls.org/\">http://www.gnutls.org/</a>."; + "This is the default message reported by the GnuTLS implementation. " + "For more information please visit " + "<a href=\"http://www.gnutls.org/\">http://www.gnutls.org/</a>."; /* Creates html with the current session information. */ #define tmp_buffer &http_buffer[strlen(http_buffer)] #define tmp_buffer_size len-strlen(http_buffer) -static char * -peer_print_info (gnutls_session_t session, int *ret_length, - const char *header) +static char *peer_print_info(gnutls_session_t session, int *ret_length, + const char *header) { - const char *tmp; - unsigned char sesid[32]; - size_t i, sesid_size; - char *http_buffer; - gnutls_kx_algorithm_t kx_alg; - size_t len = 20 * 1024 + strlen (header); - char *crtinfo = NULL; - size_t ncrtinfo = 0; - - if (verbose == 0) - { - http_buffer = malloc (len); - if (http_buffer == NULL) - return NULL; - - strcpy (http_buffer, HTTP_BEGIN); - strcpy (&http_buffer[sizeof (HTTP_BEGIN) - 1], DEFAULT_DATA); - strcpy (&http_buffer[sizeof (HTTP_BEGIN) + sizeof (DEFAULT_DATA) - 2], - HTTP_END); - *ret_length = - sizeof (DEFAULT_DATA) + sizeof (HTTP_BEGIN) + sizeof (HTTP_END) - 3; - return http_buffer; - } - - if (gnutls_certificate_type_get (session) == GNUTLS_CRT_X509) - { - const gnutls_datum_t *cert_list; - unsigned int cert_list_size = 0; - - cert_list = gnutls_certificate_get_peers (session, &cert_list_size); - - for (i = 0; i < cert_list_size; i++) - { - gnutls_x509_crt_t cert; - gnutls_datum_t info; - - if (gnutls_x509_crt_init (&cert) == 0 && - gnutls_x509_crt_import (cert, &cert_list[i], - GNUTLS_X509_FMT_DER) == 0 && - gnutls_x509_crt_print (cert, GNUTLS_CRT_PRINT_FULL, &info) == 0) - { - const char *post = "</PRE><P><PRE>"; - - crtinfo = realloc (crtinfo, ncrtinfo + info.size + - strlen (post) + 1); - if (crtinfo == NULL) - return NULL; - memcpy (crtinfo + ncrtinfo, info.data, info.size); - ncrtinfo += info.size; - memcpy (crtinfo + ncrtinfo, post, strlen (post)); - ncrtinfo += strlen (post); - crtinfo[ncrtinfo] = '\0'; - gnutls_free (info.data); - } - } - } - - http_buffer = malloc (len); - if (http_buffer == NULL) - { - free (crtinfo); - return NULL; - } - - strcpy (http_buffer, HTTP_BEGIN); - - /* print session_id */ - sesid_size = sizeof(sesid); - gnutls_session_get_id (session, sesid, &sesid_size); - snprintf (tmp_buffer, tmp_buffer_size, "\n<p>Session ID: <i>"); - for (i = 0; i < sesid_size; i++) - snprintf (tmp_buffer, tmp_buffer_size, "%.2X", sesid[i]); - snprintf (tmp_buffer, tmp_buffer_size, "</i></p>\n"); - snprintf (tmp_buffer, tmp_buffer_size, - "<h5>If your browser supports session resuming, then you should see the " - "same session ID, when you press the <b>reload</b> button.</h5>\n"); - - /* Here unlike print_info() we use the kx algorithm to distinguish - * the functions to call. - */ - { - char dns[256]; - size_t dns_size = sizeof (dns); - unsigned int type; - - if (gnutls_server_name_get (session, dns, &dns_size, &type, 0) == 0) - { - snprintf (tmp_buffer, tmp_buffer_size, "\n<p>Server Name: %s</p>\n", - dns); - } - - } - - kx_alg = gnutls_kx_get (session); - - /* print srp specific data */ + const char *tmp; + unsigned char sesid[32]; + size_t i, sesid_size; + char *http_buffer; + gnutls_kx_algorithm_t kx_alg; + size_t len = 20 * 1024 + strlen(header); + char *crtinfo = NULL; + size_t ncrtinfo = 0; + + if (verbose == 0) { + http_buffer = malloc(len); + if (http_buffer == NULL) + return NULL; + + strcpy(http_buffer, HTTP_BEGIN); + strcpy(&http_buffer[sizeof(HTTP_BEGIN) - 1], DEFAULT_DATA); + strcpy(&http_buffer + [sizeof(HTTP_BEGIN) + sizeof(DEFAULT_DATA) - 2], + HTTP_END); + *ret_length = + sizeof(DEFAULT_DATA) + sizeof(HTTP_BEGIN) + + sizeof(HTTP_END) - 3; + return http_buffer; + } + + if (gnutls_certificate_type_get(session) == GNUTLS_CRT_X509) { + const gnutls_datum_t *cert_list; + unsigned int cert_list_size = 0; + + cert_list = + gnutls_certificate_get_peers(session, &cert_list_size); + + for (i = 0; i < cert_list_size; i++) { + gnutls_x509_crt_t cert; + gnutls_datum_t info; + + if (gnutls_x509_crt_init(&cert) == 0 && + gnutls_x509_crt_import(cert, &cert_list[i], + GNUTLS_X509_FMT_DER) == + 0 + && gnutls_x509_crt_print(cert, + GNUTLS_CRT_PRINT_FULL, + &info) == 0) { + const char *post = "</PRE><P><PRE>"; + + crtinfo = + realloc(crtinfo, + ncrtinfo + info.size + + strlen(post) + 1); + if (crtinfo == NULL) + return NULL; + memcpy(crtinfo + ncrtinfo, info.data, + info.size); + ncrtinfo += info.size; + memcpy(crtinfo + ncrtinfo, post, + strlen(post)); + ncrtinfo += strlen(post); + crtinfo[ncrtinfo] = '\0'; + gnutls_free(info.data); + } + } + } + + http_buffer = malloc(len); + if (http_buffer == NULL) { + free(crtinfo); + return NULL; + } + + strcpy(http_buffer, HTTP_BEGIN); + + /* print session_id */ + sesid_size = sizeof(sesid); + gnutls_session_get_id(session, sesid, &sesid_size); + snprintf(tmp_buffer, tmp_buffer_size, "\n<p>Session ID: <i>"); + for (i = 0; i < sesid_size; i++) + snprintf(tmp_buffer, tmp_buffer_size, "%.2X", sesid[i]); + snprintf(tmp_buffer, tmp_buffer_size, "</i></p>\n"); + snprintf(tmp_buffer, tmp_buffer_size, + "<h5>If your browser supports session resuming, then you should see the " + "same session ID, when you press the <b>reload</b> button.</h5>\n"); + + /* Here unlike print_info() we use the kx algorithm to distinguish + * the functions to call. + */ + { + char dns[256]; + size_t dns_size = sizeof(dns); + unsigned int type; + + if (gnutls_server_name_get + (session, dns, &dns_size, &type, 0) == 0) { + snprintf(tmp_buffer, tmp_buffer_size, + "\n<p>Server Name: %s</p>\n", dns); + } + + } + + kx_alg = gnutls_kx_get(session); + + /* print srp specific data */ #ifdef ENABLE_SRP - if (kx_alg == GNUTLS_KX_SRP) - { - snprintf (tmp_buffer, tmp_buffer_size, - "<p>Connected as user '%s'.</p>\n", - gnutls_srp_server_get_username (session)); - } + if (kx_alg == GNUTLS_KX_SRP) { + snprintf(tmp_buffer, tmp_buffer_size, + "<p>Connected as user '%s'.</p>\n", + gnutls_srp_server_get_username(session)); + } #endif #ifdef ENABLE_PSK - if (kx_alg == GNUTLS_KX_PSK) - { - snprintf (tmp_buffer, tmp_buffer_size, - "<p>Connected as user '%s'.</p>\n", - gnutls_psk_server_get_username (session)); - } + if (kx_alg == GNUTLS_KX_PSK) { + snprintf(tmp_buffer, tmp_buffer_size, + "<p>Connected as user '%s'.</p>\n", + gnutls_psk_server_get_username(session)); + } #endif #ifdef ENABLE_ANON - if (kx_alg == GNUTLS_KX_ANON_DH) - { - snprintf (tmp_buffer, tmp_buffer_size, - "<p> Connect using anonymous DH (prime of %d bits)</p>\n", - gnutls_dh_get_prime_bits (session)); - } + if (kx_alg == GNUTLS_KX_ANON_DH) { + snprintf(tmp_buffer, tmp_buffer_size, + "<p> Connect using anonymous DH (prime of %d bits)</p>\n", + gnutls_dh_get_prime_bits(session)); + } #endif - if (kx_alg == GNUTLS_KX_DHE_RSA || kx_alg == GNUTLS_KX_DHE_DSS) - { - snprintf (tmp_buffer, tmp_buffer_size, - "Ephemeral DH using prime of <b>%d</b> bits.<br>\n", - gnutls_dh_get_prime_bits (session)); - } - - /* print session information */ - strcat (http_buffer, "<P>\n"); - - tmp = gnutls_protocol_get_name (gnutls_protocol_get_version (session)); - if (tmp == NULL) - tmp = str_unknown; - snprintf (tmp_buffer, tmp_buffer_size, - "<TABLE border=1><TR><TD>Protocol version:</TD><TD>%s</TD></TR>\n", - tmp); - - if (gnutls_auth_get_type (session) == GNUTLS_CRD_CERTIFICATE) - { - tmp = - gnutls_certificate_type_get_name (gnutls_certificate_type_get - (session)); - if (tmp == NULL) - tmp = str_unknown; - snprintf (tmp_buffer, tmp_buffer_size, - "<TR><TD>Certificate Type:</TD><TD>%s</TD></TR>\n", tmp); - } - - tmp = gnutls_kx_get_name (kx_alg); - if (tmp == NULL) - tmp = str_unknown; - snprintf (tmp_buffer, tmp_buffer_size, - "<TR><TD>Key Exchange:</TD><TD>%s</TD></TR>\n", tmp); - - tmp = gnutls_compression_get_name (gnutls_compression_get (session)); - if (tmp == NULL) - tmp = str_unknown; - snprintf (tmp_buffer, tmp_buffer_size, - "<TR><TD>Compression</TD><TD>%s</TD></TR>\n", tmp); - - tmp = gnutls_cipher_get_name (gnutls_cipher_get (session)); - if (tmp == NULL) - tmp = str_unknown; - snprintf (tmp_buffer, tmp_buffer_size, - "<TR><TD>Cipher</TD><TD>%s</TD></TR>\n", tmp); - - tmp = gnutls_mac_get_name (gnutls_mac_get (session)); - if (tmp == NULL) - tmp = str_unknown; - snprintf (tmp_buffer, tmp_buffer_size, "<TR><TD>MAC</TD><TD>%s</TD></TR>\n", - tmp); - - tmp = gnutls_cipher_suite_get_name (kx_alg, - gnutls_cipher_get (session), - gnutls_mac_get (session)); - if (tmp == NULL) - tmp = str_unknown; - snprintf (tmp_buffer, tmp_buffer_size, - "<TR><TD>Ciphersuite</TD><TD>%s</TD></TR></p></TABLE>\n", tmp); - - if (crtinfo) - { - snprintf (tmp_buffer, tmp_buffer_size, "<hr><PRE>%s\n</PRE>\n", - crtinfo); - free (crtinfo); - } - - snprintf (tmp_buffer, tmp_buffer_size, - "<hr><P>Your HTTP header was:<PRE>%s</PRE></P>\n" HTTP_END, - header); - - *ret_length = strlen (http_buffer); - - return http_buffer; + if (kx_alg == GNUTLS_KX_DHE_RSA || kx_alg == GNUTLS_KX_DHE_DSS) { + snprintf(tmp_buffer, tmp_buffer_size, + "Ephemeral DH using prime of <b>%d</b> bits.<br>\n", + gnutls_dh_get_prime_bits(session)); + } + + /* print session information */ + strcat(http_buffer, "<P>\n"); + + tmp = + gnutls_protocol_get_name(gnutls_protocol_get_version(session)); + if (tmp == NULL) + tmp = str_unknown; + snprintf(tmp_buffer, tmp_buffer_size, + "<TABLE border=1><TR><TD>Protocol version:</TD><TD>%s</TD></TR>\n", + tmp); + + if (gnutls_auth_get_type(session) == GNUTLS_CRD_CERTIFICATE) { + tmp = + gnutls_certificate_type_get_name + (gnutls_certificate_type_get(session)); + if (tmp == NULL) + tmp = str_unknown; + snprintf(tmp_buffer, tmp_buffer_size, + "<TR><TD>Certificate Type:</TD><TD>%s</TD></TR>\n", + tmp); + } + + tmp = gnutls_kx_get_name(kx_alg); + if (tmp == NULL) + tmp = str_unknown; + snprintf(tmp_buffer, tmp_buffer_size, + "<TR><TD>Key Exchange:</TD><TD>%s</TD></TR>\n", tmp); + + tmp = gnutls_compression_get_name(gnutls_compression_get(session)); + if (tmp == NULL) + tmp = str_unknown; + snprintf(tmp_buffer, tmp_buffer_size, + "<TR><TD>Compression</TD><TD>%s</TD></TR>\n", tmp); + + tmp = gnutls_cipher_get_name(gnutls_cipher_get(session)); + if (tmp == NULL) + tmp = str_unknown; + snprintf(tmp_buffer, tmp_buffer_size, + "<TR><TD>Cipher</TD><TD>%s</TD></TR>\n", tmp); + + tmp = gnutls_mac_get_name(gnutls_mac_get(session)); + if (tmp == NULL) + tmp = str_unknown; + snprintf(tmp_buffer, tmp_buffer_size, + "<TR><TD>MAC</TD><TD>%s</TD></TR>\n", tmp); + + tmp = gnutls_cipher_suite_get_name(kx_alg, + gnutls_cipher_get(session), + gnutls_mac_get(session)); + if (tmp == NULL) + tmp = str_unknown; + snprintf(tmp_buffer, tmp_buffer_size, + "<TR><TD>Ciphersuite</TD><TD>%s</TD></TR></p></TABLE>\n", + tmp); + + if (crtinfo) { + snprintf(tmp_buffer, tmp_buffer_size, + "<hr><PRE>%s\n</PRE>\n", crtinfo); + free(crtinfo); + } + + snprintf(tmp_buffer, tmp_buffer_size, + "<hr><P>Your HTTP header was:<PRE>%s</PRE></P>\n" + HTTP_END, header); + + *ret_length = strlen(http_buffer); + + return http_buffer; } -const char * -human_addr (const struct sockaddr *sa, socklen_t salen, - char *buf, size_t buflen) +const char *human_addr(const struct sockaddr *sa, socklen_t salen, + char *buf, size_t buflen) { - const char *save_buf = buf; - size_t l; + const char *save_buf = buf; + size_t l; - if (!buf || !buflen) - return NULL; + if (!buf || !buflen) + return NULL; - *buf = '\0'; + *buf = '\0'; - switch (sa->sa_family) - { + switch (sa->sa_family) { #if HAVE_IPV6 - case AF_INET6: - snprintf (buf, buflen, "IPv6 "); - break; + case AF_INET6: + snprintf(buf, buflen, "IPv6 "); + break; #endif - case AF_INET: - snprintf (buf, buflen, "IPv4 "); - break; - } + case AF_INET: + snprintf(buf, buflen, "IPv4 "); + break; + } - l = strlen (buf); - buf += l; - buflen -= l; + l = strlen(buf); + buf += l; + buflen -= l; - if (getnameinfo (sa, salen, buf, buflen, NULL, 0, NI_NUMERICHOST) != 0) - return NULL; + if (getnameinfo(sa, salen, buf, buflen, NULL, 0, NI_NUMERICHOST) != + 0) + return NULL; - l = strlen (buf); - buf += l; - buflen -= l; + l = strlen(buf); + buf += l; + buflen -= l; - strncat (buf, " port ", buflen); + strncat(buf, " port ", buflen); - l = strlen (buf); - buf += l; - buflen -= l; + l = strlen(buf); + buf += l; + buflen -= l; - if (getnameinfo (sa, salen, NULL, 0, buf, buflen, NI_NUMERICSERV) != 0) - return NULL; + if (getnameinfo(sa, salen, NULL, 0, buf, buflen, NI_NUMERICSERV) != + 0) + return NULL; - return save_buf; + return save_buf; } -int -wait_for_connection (void) +int wait_for_connection(void) { - listener_item *j; - fd_set rd, wr; - int n, sock = -1; - - FD_ZERO (&rd); - FD_ZERO (&wr); - n = 0; - - lloopstart (listener_list, j) - { - if (j->listen_socket) - { - FD_SET (j->fd, &rd); - n = MAX (n, j->fd); - } - } - lloopend (listener_list, j); - - /* waiting part */ - n = select (n + 1, &rd, &wr, NULL, NULL); - if (n == -1 && errno == EINTR) - return -1; - if (n < 0) - { - perror ("select()"); - exit (1); - } - - /* find which one is ready */ - lloopstart (listener_list, j) - { - /* a new connection has arrived */ - if (FD_ISSET (j->fd, &rd) && j->listen_socket) - { - sock = j->fd; - break; - } - } - lloopend (listener_list, j); - return sock; + listener_item *j; + fd_set rd, wr; + int n, sock = -1; + + FD_ZERO(&rd); + FD_ZERO(&wr); + n = 0; + + lloopstart(listener_list, j) { + if (j->listen_socket) { + FD_SET(j->fd, &rd); + n = MAX(n, j->fd); + } + } + lloopend(listener_list, j); + + /* waiting part */ + n = select(n + 1, &rd, &wr, NULL, NULL); + if (n == -1 && errno == EINTR) + return -1; + if (n < 0) { + perror("select()"); + exit(1); + } + + /* find which one is ready */ + lloopstart(listener_list, j) { + /* a new connection has arrived */ + if (FD_ISSET(j->fd, &rd) && j->listen_socket) { + sock = j->fd; + break; + } + } + lloopend(listener_list, j); + return sock; } -int -listen_socket (const char *name, int listen_port, int socktype) +int listen_socket(const char *name, int listen_port, int socktype) { - struct addrinfo hints, *res, *ptr; - char portname[6]; - int s; - int yes; - listener_item *j = NULL; - - snprintf (portname, sizeof (portname), "%d", listen_port); - memset (&hints, 0, sizeof (hints)); - hints.ai_socktype = socktype; - hints.ai_flags = AI_PASSIVE + struct addrinfo hints, *res, *ptr; + char portname[6]; + int s; + int yes; + listener_item *j = NULL; + + snprintf(portname, sizeof(portname), "%d", listen_port); + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = socktype; + hints.ai_flags = AI_PASSIVE #ifdef AI_ADDRCONFIG - | AI_ADDRCONFIG + | AI_ADDRCONFIG #endif - ; + ; - if ((s = getaddrinfo (NULL, portname, &hints, &res)) != 0) - { - fprintf (stderr, "getaddrinfo() failed: %s\n", gai_strerror (s)); - return -1; - } + if ((s = getaddrinfo(NULL, portname, &hints, &res)) != 0) { + fprintf(stderr, "getaddrinfo() failed: %s\n", + gai_strerror(s)); + return -1; + } - for (ptr = res; ptr != NULL; ptr = ptr->ai_next) - { + for (ptr = res; ptr != NULL; ptr = ptr->ai_next) { #ifndef HAVE_IPV6 - if (ptr->ai_family != AF_INET) - continue; + if (ptr->ai_family != AF_INET) + continue; #endif - /* Print what we are doing. */ - { - char topbuf[512]; - - fprintf (stderr, "%s listening on %s...", - name, human_addr (ptr->ai_addr, ptr->ai_addrlen, - topbuf, sizeof (topbuf))); - } - - if ((s = socket (ptr->ai_family, ptr->ai_socktype, - ptr->ai_protocol)) < 0) - { - perror ("socket() failed"); - continue; - } - + /* Print what we are doing. */ + { + char topbuf[512]; + + fprintf(stderr, "%s listening on %s...", + name, human_addr(ptr->ai_addr, + ptr->ai_addrlen, topbuf, + sizeof(topbuf))); + } + + if ((s = socket(ptr->ai_family, ptr->ai_socktype, + ptr->ai_protocol)) < 0) { + perror("socket() failed"); + continue; + } #if defined(HAVE_IPV6) && !defined(_WIN32) - if (ptr->ai_family == AF_INET6) - { - yes = 1; - /* avoid listen on ipv6 addresses failing - * because already listening on ipv4 addresses: */ - setsockopt (s, IPPROTO_IPV6, IPV6_V6ONLY, - (const void *) &yes, sizeof (yes)); - } + if (ptr->ai_family == AF_INET6) { + yes = 1; + /* avoid listen on ipv6 addresses failing + * because already listening on ipv4 addresses: */ + setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, + (const void *) &yes, sizeof(yes)); + } #endif - if (socktype == SOCK_STREAM) - { - yes = 1; - if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, - (const void *) &yes, sizeof (yes)) < 0) - { - perror ("setsockopt() failed"); - close (s); - continue; - } - } - else - { + if (socktype == SOCK_STREAM) { + yes = 1; + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, + (const void *) &yes, + sizeof(yes)) < 0) { + perror("setsockopt() failed"); + close(s); + continue; + } + } else { #if defined(IP_DONTFRAG) - yes = 1; - if (setsockopt (s, IPPROTO_IP, IP_DONTFRAG, - (const void *) &yes, sizeof (yes)) < 0) - perror ("setsockopt(IP_DF) failed"); + yes = 1; + if (setsockopt(s, IPPROTO_IP, IP_DONTFRAG, + (const void *) &yes, + sizeof(yes)) < 0) + perror("setsockopt(IP_DF) failed"); #elif defined(IP_MTU_DISCOVER) - yes = IP_PMTUDISC_DO; - if (setsockopt (s, IPPROTO_IP, IP_MTU_DISCOVER, - (const void *) &yes, sizeof (yes)) < 0) - perror ("setsockopt(IP_DF) failed"); + yes = IP_PMTUDISC_DO; + if (setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, + (const void *) &yes, + sizeof(yes)) < 0) + perror("setsockopt(IP_DF) failed"); #endif - } - - if (bind (s, ptr->ai_addr, ptr->ai_addrlen) < 0) - { - perror ("bind() failed"); - close (s); - continue; - } - - if (socktype == SOCK_STREAM) - { - if (listen (s, 10) < 0) - { - perror ("listen() failed"); - exit (1); - } - } - - /* new list entry for the connection */ - lappend (listener_list); - j = listener_list.tail; - j->listen_socket = 1; - j->fd = s; - - /* Complete earlier message. */ - fprintf (stderr, "done\n"); - } - - fflush (stderr); - - freeaddrinfo (res); - - return s; + } + + if (bind(s, ptr->ai_addr, ptr->ai_addrlen) < 0) { + perror("bind() failed"); + close(s); + continue; + } + + if (socktype == SOCK_STREAM) { + if (listen(s, 10) < 0) { + perror("listen() failed"); + exit(1); + } + } + + /* new list entry for the connection */ + lappend(listener_list); + j = listener_list.tail; + j->listen_socket = 1; + j->fd = s; + + /* Complete earlier message. */ + fprintf(stderr, "done\n"); + } + + fflush(stderr); + + freeaddrinfo(res); + + return s; } /* strips \r\n from the end of the string */ -static void -strip (char *data) +static void strip(char *data) { - int i; - int len = strlen (data); - - for (i = 0; i < len; i++) - { - if (data[i] == '\r' && data[i + 1] == '\n' && data[i + 1] == 0) - { - data[i] = '\n'; - data[i + 1] = 0; - break; - } - } + int i; + int len = strlen(data); + + for (i = 0; i < len; i++) { + if (data[i] == '\r' && data[i + 1] == '\n' + && data[i + 1] == 0) { + data[i] = '\n'; + data[i + 1] = 0; + break; + } + } } static void -get_response (gnutls_session_t session, char *request, - char **response, int *response_length) +get_response(gnutls_session_t session, char *request, + char **response, int *response_length) { - char *p, *h; + char *p, *h; - if (http != 0) - { - if (strncmp (request, "GET ", 4)) - goto unimplemented; + if (http != 0) { + if (strncmp(request, "GET ", 4)) + goto unimplemented; - if (!(h = strchr (request, '\n'))) - goto unimplemented; + if (!(h = strchr(request, '\n'))) + goto unimplemented; - *h++ = '\0'; - while (*h == '\r' || *h == '\n') - h++; + *h++ = '\0'; + while (*h == '\r' || *h == '\n') + h++; - if (!(p = strchr (request + 4, ' '))) - goto unimplemented; - *p = '\0'; - } + if (!(p = strchr(request + 4, ' '))) + goto unimplemented; + *p = '\0'; + } /* *response = peer_print_info(session, request+4, h, response_length); */ - if (http != 0) - { - *response = peer_print_info (session, response_length, h); - } - else - { - strip (request); - fprintf (stderr, "received: %s\n", request); - if (check_command (session, request)) - { - *response = NULL; - *response_length = 0; - return; - } - *response = strdup (request); - *response_length = ((*response) ? strlen (*response) : 0); - } - - return; - -unimplemented: - *response = strdup (HTTP_UNIMPLEMENTED); - *response_length = ((*response) ? strlen (*response) : 0); + if (http != 0) { + *response = peer_print_info(session, response_length, h); + } else { + strip(request); + fprintf(stderr, "received: %s\n", request); + if (check_command(session, request)) { + *response = NULL; + *response_length = 0; + return; + } + *response = strdup(request); + *response_length = ((*response) ? strlen(*response) : 0); + } + + return; + + unimplemented: + *response = strdup(HTTP_UNIMPLEMENTED); + *response_length = ((*response) ? strlen(*response) : 0); } -static void terminate (int sig) __attribute__ ((noreturn)); +static void terminate(int sig) __attribute__ ((noreturn)); -static void -terminate (int sig) +static void terminate(int sig) { - fprintf (stderr, "Exiting via signal %d\n", sig); - exit (1); + fprintf(stderr, "Exiting via signal %d\n", sig); + exit(1); } -static void -check_alert (gnutls_session_t session, int ret) +static void check_alert(gnutls_session_t session, int ret) { - if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED - || ret == GNUTLS_E_FATAL_ALERT_RECEIVED) - { - int last_alert = gnutls_alert_get (session); - if (last_alert == GNUTLS_A_NO_RENEGOTIATION && - ret == GNUTLS_E_WARNING_ALERT_RECEIVED) - printf - ("* Received NO_RENEGOTIATION alert. Client does not support renegotiation.\n"); - else - printf ("* Received alert '%d': %s.\n", last_alert, - gnutls_alert_get_name (last_alert)); - } + if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED + || ret == GNUTLS_E_FATAL_ALERT_RECEIVED) { + int last_alert = gnutls_alert_get(session); + if (last_alert == GNUTLS_A_NO_RENEGOTIATION && + ret == GNUTLS_E_WARNING_ALERT_RECEIVED) + printf + ("* Received NO_RENEGOTIATION alert. Client does not support renegotiation.\n"); + else + printf("* Received alert '%d': %s.\n", last_alert, + gnutls_alert_get_name(last_alert)); + } } -static void -tls_log_func (int level, const char *str) +static void tls_log_func(int level, const char *str) { - fprintf (stderr, "|<%d>| %s", level, str); + fprintf(stderr, "|<%d>| %s", level, str); } -static void -tls_audit_log_func (gnutls_session_t session, const char *str) +static void tls_audit_log_func(gnutls_session_t session, const char *str) { - fprintf (stderr, "|<%p>| %s", session, str); + fprintf(stderr, "|<%p>| %s", session, str); } -int -main (int argc, char **argv) +int main(int argc, char **argv) { - int ret, mtu, port; - char name[256]; - int cert_set = 0; + int ret, mtu, port; + char name[256]; + int cert_set = 0; - cmd_parser (argc, argv); + cmd_parser(argc, argv); #ifndef _WIN32 - signal (SIGHUP, SIG_IGN); - signal (SIGTERM, terminate); - if (signal (SIGINT, terminate) == SIG_IGN) - signal (SIGINT, SIG_IGN); /* e.g. background process */ + signal(SIGHUP, SIG_IGN); + signal(SIGTERM, terminate); + if (signal(SIGINT, terminate) == SIG_IGN) + signal(SIGINT, SIG_IGN); /* e.g. background process */ #endif - sockets_init (); - - if (nodb == 0) - wrap_db_init (); + sockets_init(); - if (HAVE_OPT (UDP)) - strcpy (name, "UDP "); - else - name[0] = 0; + if (nodb == 0) + wrap_db_init(); - if (http == 1) - { - strcat (name, "HTTP Server"); - } - else - { - strcat (name, "Echo Server"); - } + if (HAVE_OPT(UDP)) + strcpy(name, "UDP "); + else + name[0] = 0; - gnutls_global_set_log_function (tls_log_func); - gnutls_global_set_audit_log_function (tls_audit_log_func); - gnutls_global_set_log_level (debug); + if (http == 1) { + strcat(name, "HTTP Server"); + } else { + strcat(name, "Echo Server"); + } - if ((ret = gnutls_global_init ()) < 0) - { - fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret)); - exit (1); - } + gnutls_global_set_log_function(tls_log_func); + gnutls_global_set_audit_log_function(tls_audit_log_func); + gnutls_global_set_log_level(debug); + if ((ret = gnutls_global_init()) < 0) { + fprintf(stderr, "global_init: %s\n", gnutls_strerror(ret)); + exit(1); + } #ifdef ENABLE_PKCS11 - pkcs11_common (); + pkcs11_common(); #endif - /* Note that servers must generate parameters for - * Diffie-Hellman. See gnutls_dh_params_generate(), and - * gnutls_dh_params_set(). - */ - if (generate != 0) - { - generate_rsa_params (); - generate_dh_primes (); - } - else if (dh_params_file) - { - read_dh_params (); - } - else - { - static_dh_params (); - } - - if (gnutls_certificate_allocate_credentials (&cert_cred) < 0) - { - fprintf (stderr, "memory error\n"); - exit (1); - } - - if (x509_cafile != NULL) - { - if ((ret = gnutls_certificate_set_x509_trust_file - (cert_cred, x509_cafile, x509ctype)) < 0) - { - fprintf (stderr, "Error reading '%s'\n", x509_cafile); - GERR (ret); - exit (1); - } - else - { - printf ("Processed %d CA certificate(s).\n", ret); - } - } - if (x509_crlfile != NULL) - { - if ((ret = gnutls_certificate_set_x509_crl_file - (cert_cred, x509_crlfile, x509ctype)) < 0) - { - fprintf (stderr, "Error reading '%s'\n", x509_crlfile); - GERR (ret); - exit (1); - } - else - { - printf ("Processed %d CRL(s).\n", ret); - } - } + /* Note that servers must generate parameters for + * Diffie-Hellman. See gnutls_dh_params_generate(), and + * gnutls_dh_params_set(). + */ + if (generate != 0) { + generate_rsa_params(); + generate_dh_primes(); + } else if (dh_params_file) { + read_dh_params(); + } else { + static_dh_params(); + } + + if (gnutls_certificate_allocate_credentials(&cert_cred) < 0) { + fprintf(stderr, "memory error\n"); + exit(1); + } + if (x509_cafile != NULL) { + if ((ret = gnutls_certificate_set_x509_trust_file + (cert_cred, x509_cafile, x509ctype)) < 0) { + fprintf(stderr, "Error reading '%s'\n", + x509_cafile); + GERR(ret); + exit(1); + } else { + printf("Processed %d CA certificate(s).\n", ret); + } + } + if (x509_crlfile != NULL) { + if ((ret = gnutls_certificate_set_x509_crl_file + (cert_cred, x509_crlfile, x509ctype)) < 0) { + fprintf(stderr, "Error reading '%s'\n", + x509_crlfile); + GERR(ret); + exit(1); + } else { + printf("Processed %d CRL(s).\n", ret); + } + } #ifdef ENABLE_OPENPGP - if (pgp_keyring != NULL) - { - ret = - gnutls_certificate_set_openpgp_keyring_file (cert_cred, pgp_keyring, - GNUTLS_OPENPGP_FMT_BASE64); - if (ret < 0) - { - fprintf (stderr, "Error setting the OpenPGP keyring file\n"); - GERR (ret); - } - } - - if (pgp_certfile != NULL && pgp_keyfile != NULL) - { - if (HAVE_OPT (PGPSUBKEY)) - ret = gnutls_certificate_set_openpgp_key_file2 - (cert_cred, pgp_certfile, pgp_keyfile, OPT_ARG (PGPSUBKEY), - GNUTLS_OPENPGP_FMT_BASE64); - else - ret = gnutls_certificate_set_openpgp_key_file - (cert_cred, pgp_certfile, pgp_keyfile, GNUTLS_OPENPGP_FMT_BASE64); - - if (ret < 0) - { - fprintf (stderr, - "Error[%d] while reading the OpenPGP key pair ('%s', '%s')\n", - ret, pgp_certfile, pgp_keyfile); - GERR (ret); - } - else - cert_set = 1; - } + if (pgp_keyring != NULL) { + ret = + gnutls_certificate_set_openpgp_keyring_file(cert_cred, + pgp_keyring, + GNUTLS_OPENPGP_FMT_BASE64); + if (ret < 0) { + fprintf(stderr, + "Error setting the OpenPGP keyring file\n"); + GERR(ret); + } + } + + if (pgp_certfile != NULL && pgp_keyfile != NULL) { + if (HAVE_OPT(PGPSUBKEY)) + ret = gnutls_certificate_set_openpgp_key_file2 + (cert_cred, pgp_certfile, pgp_keyfile, + OPT_ARG(PGPSUBKEY), + GNUTLS_OPENPGP_FMT_BASE64); + else + ret = gnutls_certificate_set_openpgp_key_file + (cert_cred, pgp_certfile, pgp_keyfile, + GNUTLS_OPENPGP_FMT_BASE64); + + if (ret < 0) { + fprintf(stderr, + "Error[%d] while reading the OpenPGP key pair ('%s', '%s')\n", + ret, pgp_certfile, pgp_keyfile); + GERR(ret); + } else + cert_set = 1; + } #endif - if (x509_certfile != NULL && x509_keyfile != NULL) - { - ret = gnutls_certificate_set_x509_key_file - (cert_cred, x509_certfile, x509_keyfile, x509ctype); - if (ret < 0) - { - fprintf (stderr, - "Error reading '%s' or '%s'\n", x509_certfile, x509_keyfile); - GERR (ret); - exit (1); - } - else - cert_set = 1; - } - - if (x509_dsacertfile != NULL && x509_dsakeyfile != NULL) - { - ret = gnutls_certificate_set_x509_key_file - (cert_cred, x509_dsacertfile, x509_dsakeyfile, x509ctype); - if (ret < 0) - { - fprintf (stderr, - "Error reading '%s' or '%s'\n", x509_dsacertfile, x509_dsakeyfile); - GERR (ret); - exit (1); - } - else - cert_set = 1; - } - - if (x509_ecccertfile != NULL && x509_ecckeyfile != NULL) - { - ret = gnutls_certificate_set_x509_key_file - (cert_cred, x509_ecccertfile, x509_ecckeyfile, x509ctype); - if (ret < 0) - { - fprintf (stderr, - "Error reading '%s' or '%s'\n", x509_ecccertfile, x509_ecckeyfile); - GERR (ret); - exit (1); - } - else - cert_set = 1; - } - - if (cert_set == 0) - { - fprintf(stderr, "Warning: no private key and certificate pairs were set.\n"); - } - - /* OCSP status-request TLS extension */ - if (status_response_ocsp) - { - if (gnutls_certificate_set_ocsp_status_request_file (cert_cred, status_response_ocsp, 0) < 0) - { - fprintf (stderr, "Cannot set OCSP status request file: %s\n", gnutls_strerror(ret)); - exit (1); + if (x509_certfile != NULL && x509_keyfile != NULL) { + ret = gnutls_certificate_set_x509_key_file + (cert_cred, x509_certfile, x509_keyfile, x509ctype); + if (ret < 0) { + fprintf(stderr, + "Error reading '%s' or '%s'\n", + x509_certfile, x509_keyfile); + GERR(ret); + exit(1); + } else + cert_set = 1; + } + + if (x509_dsacertfile != NULL && x509_dsakeyfile != NULL) { + ret = gnutls_certificate_set_x509_key_file + (cert_cred, x509_dsacertfile, x509_dsakeyfile, + x509ctype); + if (ret < 0) { + fprintf(stderr, + "Error reading '%s' or '%s'\n", + x509_dsacertfile, x509_dsakeyfile); + GERR(ret); + exit(1); + } else + cert_set = 1; } - } - gnutls_certificate_set_params_function (cert_cred, get_params); + if (x509_ecccertfile != NULL && x509_ecckeyfile != NULL) { + ret = gnutls_certificate_set_x509_key_file + (cert_cred, x509_ecccertfile, x509_ecckeyfile, + x509ctype); + if (ret < 0) { + fprintf(stderr, + "Error reading '%s' or '%s'\n", + x509_ecccertfile, x509_ecckeyfile); + GERR(ret); + exit(1); + } else + cert_set = 1; + } + + if (cert_set == 0) { + fprintf(stderr, + "Warning: no private key and certificate pairs were set.\n"); + } + + /* OCSP status-request TLS extension */ + if (status_response_ocsp) { + if (gnutls_certificate_set_ocsp_status_request_file + (cert_cred, status_response_ocsp, 0) < 0) { + fprintf(stderr, + "Cannot set OCSP status request file: %s\n", + gnutls_strerror(ret)); + exit(1); + } + } + + gnutls_certificate_set_params_function(cert_cred, get_params); /* gnutls_certificate_set_dh_params(cert_cred, dh_params); * gnutls_certificate_set_rsa_export_params(cert_cred, rsa_params); */ - /* this is a password file (created with the included srpcrypt utility) - * Read README.crypt prior to using SRP. - */ + /* this is a password file (created with the included srpcrypt utility) + * Read README.crypt prior to using SRP. + */ #ifdef ENABLE_SRP - if (srp_passwd != NULL) - { - gnutls_srp_allocate_server_credentials (&srp_cred); - - if ((ret = - gnutls_srp_set_server_credentials_file (srp_cred, srp_passwd, - srp_passwd_conf)) < 0) - { - /* only exit is this function is not disabled - */ - fprintf (stderr, "Error while setting SRP parameters\n"); - GERR (ret); - } - } + if (srp_passwd != NULL) { + gnutls_srp_allocate_server_credentials(&srp_cred); + + if ((ret = + gnutls_srp_set_server_credentials_file(srp_cred, + srp_passwd, + srp_passwd_conf)) + < 0) { + /* only exit is this function is not disabled + */ + fprintf(stderr, + "Error while setting SRP parameters\n"); + GERR(ret); + } + } #endif - /* this is a password file - */ + /* this is a password file + */ #ifdef ENABLE_PSK - if (psk_passwd != NULL) - { - gnutls_psk_allocate_server_credentials (&psk_cred); - - if ((ret = - gnutls_psk_set_server_credentials_file (psk_cred, psk_passwd)) < 0) - { - /* only exit is this function is not disabled - */ - fprintf (stderr, "Error while setting PSK parameters\n"); - GERR (ret); - } - - if (HAVE_OPT (PSKHINT)) - { - ret = gnutls_psk_set_server_credentials_hint (psk_cred, - OPT_ARG (PSKHINT)); - if (ret) - { - fprintf (stderr, "Error setting PSK identity hint.\n"); - GERR (ret); - } - } - - gnutls_psk_set_server_params_function (psk_cred, get_params); - } + if (psk_passwd != NULL) { + gnutls_psk_allocate_server_credentials(&psk_cred); + + if ((ret = + gnutls_psk_set_server_credentials_file(psk_cred, + psk_passwd)) < + 0) { + /* only exit is this function is not disabled + */ + fprintf(stderr, + "Error while setting PSK parameters\n"); + GERR(ret); + } + + if (HAVE_OPT(PSKHINT)) { + ret = + gnutls_psk_set_server_credentials_hint + (psk_cred, OPT_ARG(PSKHINT)); + if (ret) { + fprintf(stderr, + "Error setting PSK identity hint.\n"); + GERR(ret); + } + } + + gnutls_psk_set_server_params_function(psk_cred, + get_params); + } #endif #ifdef ENABLE_ANON - gnutls_anon_allocate_server_credentials (&dh_cred); - gnutls_anon_set_server_params_function (dh_cred, get_params); + gnutls_anon_allocate_server_credentials(&dh_cred); + gnutls_anon_set_server_params_function(dh_cred, get_params); /* gnutls_anon_set_server_dh_params(dh_cred, dh_params); */ #endif - if (noticket == 0) - gnutls_session_ticket_key_generate (&session_ticket_key); - - if (HAVE_OPT (MTU)) - mtu = OPT_VALUE_MTU; - else - mtu = 1300; - - if (HAVE_OPT (PORT)) - port = OPT_VALUE_PORT; - else - port = 5556; - - if (HAVE_OPT (UDP)) - udp_server (name, port, mtu); - else - tcp_server (name, port); - - return 0; + if (noticket == 0) + gnutls_session_ticket_key_generate(&session_ticket_key); + + if (HAVE_OPT(MTU)) + mtu = OPT_VALUE_MTU; + else + mtu = 1300; + + if (HAVE_OPT(PORT)) + port = OPT_VALUE_PORT; + else + port = 5556; + + if (HAVE_OPT(UDP)) + udp_server(name, port, mtu); + else + tcp_server(name, port); + + return 0; } -static void -tcp_server (const char *name, int port) +static void tcp_server(const char *name, int port) { - int n, s; - char topbuf[512]; - int accept_fd; - struct sockaddr_storage client_address; - socklen_t calen; - - s = listen_socket (name, port, SOCK_STREAM); - if (s < 0) - exit (1); - - for (;;) - { - listener_item *j; - fd_set rd, wr; + int n, s; + char topbuf[512]; + int accept_fd; + struct sockaddr_storage client_address; + socklen_t calen; + + s = listen_socket(name, port, SOCK_STREAM); + if (s < 0) + exit(1); + + for (;;) { + listener_item *j; + fd_set rd, wr; #ifndef _WIN32 - int val; + int val; #endif - FD_ZERO (&rd); - FD_ZERO (&wr); - n = 0; + FD_ZERO(&rd); + FD_ZERO(&wr); + n = 0; /* flag which connections we are reading or writing to within the fd sets */ - lloopstart (listener_list, j) - { + lloopstart(listener_list, j) { #ifndef _WIN32 - val = fcntl (j->fd, F_GETFL, 0); - if ((val == -1) || (fcntl (j->fd, F_SETFL, val | O_NONBLOCK) < 0)) - { - perror ("fcntl()"); - exit (1); - } + val = fcntl(j->fd, F_GETFL, 0); + if ((val == -1) + || (fcntl(j->fd, F_SETFL, val | O_NONBLOCK) < + 0)) { + perror("fcntl()"); + exit(1); + } #endif - if (j->listen_socket) - { - FD_SET (j->fd, &rd); - n = MAX (n, j->fd); - } - if (j->http_state == HTTP_STATE_REQUEST) - { - FD_SET (j->fd, &rd); - n = MAX (n, j->fd); - } - if (j->http_state == HTTP_STATE_RESPONSE) - { - FD_SET (j->fd, &wr); - n = MAX (n, j->fd); - } - } - lloopend (listener_list, j); + if (j->listen_socket) { + FD_SET(j->fd, &rd); + n = MAX(n, j->fd); + } + if (j->http_state == HTTP_STATE_REQUEST) { + FD_SET(j->fd, &rd); + n = MAX(n, j->fd); + } + if (j->http_state == HTTP_STATE_RESPONSE) { + FD_SET(j->fd, &wr); + n = MAX(n, j->fd); + } + } + lloopend(listener_list, j); /* core operation */ - n = select (n + 1, &rd, &wr, NULL, NULL); - if (n == -1 && errno == EINTR) - continue; - if (n < 0) - { - perror ("select()"); - exit (1); - } + n = select(n + 1, &rd, &wr, NULL, NULL); + if (n == -1 && errno == EINTR) + continue; + if (n < 0) { + perror("select()"); + exit(1); + } /* read or write to each connection as indicated by select()'s return argument */ - lloopstart (listener_list, j) - { - - /* a new connection has arrived */ - if (FD_ISSET (j->fd, &rd) && j->listen_socket) - { - gnutls_session_t tls_session; - - tls_session = initialize_session (0); - - calen = sizeof (client_address); - memset (&client_address, 0, calen); - accept_fd = accept (j->fd, (struct sockaddr *) &client_address, - &calen); - - if (accept_fd < 0) - { - perror ("accept()"); - } - else - { - time_t tt; - char *ctt; - - /* new list entry for the connection */ - lappend (listener_list); - j = listener_list.tail; - j->http_request = (char *) strdup (""); - j->http_state = HTTP_STATE_REQUEST; - j->fd = accept_fd; - - j->tls_session = tls_session; - gnutls_transport_set_int (tls_session, accept_fd); - j->handshake_ok = 0; - - if (verbose != 0) - { - tt = time (0); - ctt = ctime (&tt); - ctt[strlen (ctt) - 1] = 0; - - printf ("\n* Accepted connection from %s on %s\n", - human_addr ((struct sockaddr *) - &client_address, calen, topbuf, - sizeof (topbuf)), ctt); - } - } - } - - if (FD_ISSET (j->fd, &rd) && !j->listen_socket) - { + lloopstart(listener_list, j) { + + /* a new connection has arrived */ + if (FD_ISSET(j->fd, &rd) && j->listen_socket) { + gnutls_session_t tls_session; + + tls_session = initialize_session(0); + + calen = sizeof(client_address); + memset(&client_address, 0, calen); + accept_fd = + accept(j->fd, + (struct sockaddr *) + &client_address, &calen); + + if (accept_fd < 0) { + perror("accept()"); + } else { + time_t tt; + char *ctt; + + /* new list entry for the connection */ + lappend(listener_list); + j = listener_list.tail; + j->http_request = + (char *) strdup(""); + j->http_state = HTTP_STATE_REQUEST; + j->fd = accept_fd; + + j->tls_session = tls_session; + gnutls_transport_set_int + (tls_session, accept_fd); + j->handshake_ok = 0; + + if (verbose != 0) { + tt = time(0); + ctt = ctime(&tt); + ctt[strlen(ctt) - 1] = 0; + + printf + ("\n* Accepted connection from %s on %s\n", + human_addr((struct + sockaddr + *) + &client_address, + calen, + topbuf, + sizeof + (topbuf)), + ctt); + } + } + } + + if (FD_ISSET(j->fd, &rd) && !j->listen_socket) { /* read partial GET request */ - char buf[1024]; - int r, ret; - - if (j->handshake_ok == 0) - { - r = gnutls_handshake (j->tls_session); - if (r < 0 && gnutls_error_is_fatal (r) == 0) - { - check_alert (j->tls_session, r); - /* nothing */ - } - else if (r < 0 && gnutls_error_is_fatal (r) == 1) - { - check_alert (j->tls_session, r); - fprintf (stderr, "Error in handshake\n"); - GERR (r); - - do - { - ret = - gnutls_alert_send_appropriate (j->tls_session, r); - } - while (ret == GNUTLS_E_AGAIN - || ret == GNUTLS_E_INTERRUPTED); - j->http_state = HTTP_STATE_CLOSING; - } - else if (r == 0) - { - if (gnutls_session_is_resumed (j->tls_session) != 0 - && verbose != 0) - printf ("*** This is a resumed session\n"); - - if (verbose != 0) - { - printf ("\n* Successful handshake from %s\n", - human_addr ((struct sockaddr *) - &client_address, calen, topbuf, - sizeof (topbuf))); - print_info (j->tls_session, verbose, verbose); - if (gnutls_auth_get_type (j->tls_session) == - GNUTLS_CRD_CERTIFICATE) - cert_verify (j->tls_session, NULL); - } - j->handshake_ok = 1; - } - } - - if (j->handshake_ok == 1) - { - r = gnutls_record_recv (j->tls_session, buf, - MIN (1024, SMALL_READ_TEST)); - if (r == GNUTLS_E_HEARTBEAT_PING_RECEIVED) - { - gnutls_heartbeat_pong(j->tls_session, 0); - } - if (r == GNUTLS_E_INTERRUPTED || r == GNUTLS_E_AGAIN) - { - /* do nothing */ - } - else if (r <= 0) - { - if (r == GNUTLS_E_REHANDSHAKE) - { - fprintf (stderr, "*** Received hello message\n"); - do - { - r = gnutls_handshake (j->tls_session); - } - while (r == GNUTLS_E_INTERRUPTED - || r == GNUTLS_E_AGAIN); - - if (r < 0) - { - do - { - ret = gnutls_alert_send_appropriate - (j->tls_session, r); - } - while (ret == GNUTLS_E_AGAIN - || ret == GNUTLS_E_INTERRUPTED); - - GERR (r); - j->http_state = HTTP_STATE_CLOSING; - } - } - else - { - if (r < 0) - { - if (r != GNUTLS_E_UNEXPECTED_PACKET_LENGTH) - { - j->http_state = HTTP_STATE_CLOSING; - check_alert (j->tls_session, r); - fprintf (stderr, - "Error while receiving data\n"); - GERR (r); - } - } - } - } - else - { - j->http_request = - realloc (j->http_request, j->request_length + r + 1); - if (j->http_request != NULL) - { - memcpy (j->http_request + j->request_length, buf, r); - j->request_length += r; - j->http_request[j->request_length] = '\0'; - } - else - j->http_state = HTTP_STATE_CLOSING; - - } + char buf[1024]; + int r, ret; + + if (j->handshake_ok == 0) { + r = gnutls_handshake(j-> + tls_session); + if (r < 0 + && gnutls_error_is_fatal(r) == + 0) { + check_alert(j->tls_session, + r); + /* nothing */ + } else if (r < 0 + && + gnutls_error_is_fatal(r) + == 1) { + check_alert(j->tls_session, + r); + fprintf(stderr, + "Error in handshake\n"); + GERR(r); + + do { + ret = + gnutls_alert_send_appropriate + (j-> + tls_session, + r); + } + while (ret == + GNUTLS_E_AGAIN + || ret == + GNUTLS_E_INTERRUPTED); + j->http_state = + HTTP_STATE_CLOSING; + } else if (r == 0) { + if (gnutls_session_is_resumed(j->tls_session) != 0 && verbose != 0) + printf + ("*** This is a resumed session\n"); + + if (verbose != 0) { + printf + ("\n* Successful handshake from %s\n", + human_addr((struct sockaddr *) + &client_address, + calen, + topbuf, + sizeof + (topbuf))); + print_info(j-> + tls_session, + verbose, + verbose); + if (gnutls_auth_get_type(j->tls_session) == GNUTLS_CRD_CERTIFICATE) + cert_verify + (j-> + tls_session, + NULL); + } + j->handshake_ok = 1; + } + } + + if (j->handshake_ok == 1) { + r = gnutls_record_recv(j-> + tls_session, + buf, + MIN(1024, + SMALL_READ_TEST)); + if (r == + GNUTLS_E_HEARTBEAT_PING_RECEIVED) + { + gnutls_heartbeat_pong(j-> + tls_session, + 0); + } + if (r == GNUTLS_E_INTERRUPTED + || r == GNUTLS_E_AGAIN) { + /* do nothing */ + } else if (r <= 0) { + if (r == + GNUTLS_E_REHANDSHAKE) { + fprintf(stderr, + "*** Received hello message\n"); + do { + r = gnutls_handshake(j->tls_session); + } + while (r == + GNUTLS_E_INTERRUPTED + || r == + GNUTLS_E_AGAIN); + + if (r < 0) { + do { + ret = gnutls_alert_send_appropriate(j->tls_session, r); + } + while (ret + == + GNUTLS_E_AGAIN + || + ret + == + GNUTLS_E_INTERRUPTED); + + GERR(r); + j->http_state = HTTP_STATE_CLOSING; + } + } else { + if (r < 0) { + if (r != + GNUTLS_E_UNEXPECTED_PACKET_LENGTH) + { + j->http_state = HTTP_STATE_CLOSING; + check_alert + (j-> + tls_session, + r); + fprintf + (stderr, + "Error while receiving data\n"); + GERR(r); + } + } + } + } else { + j->http_request = + realloc(j-> + http_request, + j-> + request_length + + r + 1); + if (j->http_request != + NULL) { + memcpy(j-> + http_request + + + j-> + request_length, + buf, r); + j->request_length + += r; + j->http_request[j-> + request_length] + = '\0'; + } else + j->http_state = + HTTP_STATE_CLOSING; + + } /* check if we have a full HTTP header */ - j->http_response = NULL; - if (j->http_request != NULL) - { - if ((http == 0 && strchr (j->http_request, '\n')) - || strstr (j->http_request, "\r\n\r\n") - || strstr (j->http_request, "\n\n")) - { - get_response (j->tls_session, j->http_request, - &j->http_response, &j->response_length); - j->http_state = HTTP_STATE_RESPONSE; - j->response_written = 0; - } - } - } - } - if (FD_ISSET (j->fd, &wr)) - { + j->http_response = NULL; + if (j->http_request != NULL) { + if ((http == 0 + && strchr(j-> + http_request, + '\n')) + || strstr(j-> + http_request, + "\r\n\r\n") + || strstr(j-> + http_request, + "\n\n")) { + get_response(j-> + tls_session, + j-> + http_request, + &j-> + http_response, + &j-> + response_length); + j->http_state = + HTTP_STATE_RESPONSE; + j->response_written + = 0; + } + } + } + } + if (FD_ISSET(j->fd, &wr)) { /* write partial response request */ - int r; - - if (j->handshake_ok == 0) - { - r = gnutls_handshake (j->tls_session); - if (r < 0 && gnutls_error_is_fatal (r) == 0) - { - check_alert (j->tls_session, r); - /* nothing */ - } - else if (r < 0 && gnutls_error_is_fatal (r) == 1) - { - int ret; - - j->http_state = HTTP_STATE_CLOSING; - check_alert (j->tls_session, r); - fprintf (stderr, "Error in handshake\n"); - GERR (r); - - do - { - ret = - gnutls_alert_send_appropriate (j->tls_session, r); - } - while (ret == GNUTLS_E_AGAIN); - } - else if (r == 0) - { - if (gnutls_session_is_resumed (j->tls_session) != 0 - && verbose != 0) - printf ("*** This is a resumed session\n"); - if (verbose != 0) - { - printf ("- connection from %s\n", - human_addr ((struct sockaddr *) - &client_address, calen, topbuf, - sizeof (topbuf))); - - print_info (j->tls_session, verbose, verbose); - if (gnutls_auth_get_type (j->tls_session) == - GNUTLS_CRD_CERTIFICATE) - cert_verify (j->tls_session, NULL); - } - j->handshake_ok = 1; - } - } - - if (j->handshake_ok == 1 && j->http_response != NULL) - { - /* FIXME if j->http_response == NULL? */ - r = gnutls_record_send (j->tls_session, - j->http_response + - j->response_written, - MIN (j->response_length - - j->response_written, - SMALL_READ_TEST)); - if (r == GNUTLS_E_INTERRUPTED || r == GNUTLS_E_AGAIN) - { - /* do nothing */ - } - else if (r <= 0) - { - if (http != 0) - j->http_state = HTTP_STATE_CLOSING; - else - { - j->http_state = HTTP_STATE_REQUEST; - free (j->http_response); - j->response_length = 0; - j->request_length = 0; - j->http_request[0] = 0; - } - - if (r < 0) - { - fprintf (stderr, "Error while sending data\n"); - GERR (r); - } - check_alert (j->tls_session, r); - } - else - { - j->response_written += r; + int r; + + if (j->handshake_ok == 0) { + r = gnutls_handshake(j-> + tls_session); + if (r < 0 + && gnutls_error_is_fatal(r) == + 0) { + check_alert(j->tls_session, + r); + /* nothing */ + } else if (r < 0 + && + gnutls_error_is_fatal(r) + == 1) { + int ret; + + j->http_state = + HTTP_STATE_CLOSING; + check_alert(j->tls_session, + r); + fprintf(stderr, + "Error in handshake\n"); + GERR(r); + + do { + ret = + gnutls_alert_send_appropriate + (j-> + tls_session, + r); + } + while (ret == + GNUTLS_E_AGAIN); + } else if (r == 0) { + if (gnutls_session_is_resumed(j->tls_session) != 0 && verbose != 0) + printf + ("*** This is a resumed session\n"); + if (verbose != 0) { + printf + ("- connection from %s\n", + human_addr((struct sockaddr *) + &client_address, + calen, + topbuf, + sizeof + (topbuf))); + + print_info(j-> + tls_session, + verbose, + verbose); + if (gnutls_auth_get_type(j->tls_session) == GNUTLS_CRD_CERTIFICATE) + cert_verify + (j-> + tls_session, + NULL); + } + j->handshake_ok = 1; + } + } + + if (j->handshake_ok == 1 + && j->http_response != NULL) { + /* FIXME if j->http_response == NULL? */ + r = gnutls_record_send(j-> + tls_session, + j-> + http_response + + + j-> + response_written, + MIN(j-> + response_length + - + j-> + response_written, + SMALL_READ_TEST)); + if (r == GNUTLS_E_INTERRUPTED + || r == GNUTLS_E_AGAIN) { + /* do nothing */ + } else if (r <= 0) { + if (http != 0) + j->http_state = + HTTP_STATE_CLOSING; + else { + j->http_state = + HTTP_STATE_REQUEST; + free(j-> + http_response); + j->response_length + = 0; + j->request_length = + 0; + j->http_request[0] + = 0; + } + + if (r < 0) { + fprintf(stderr, + "Error while sending data\n"); + GERR(r); + } + check_alert(j->tls_session, + r); + } else { + j->response_written += r; /* check if we have written a complete response */ - if (j->response_written == j->response_length) - { - if (http != 0) - j->http_state = HTTP_STATE_CLOSING; - else - { - j->http_state = HTTP_STATE_REQUEST; - free (j->http_response); - j->response_length = 0; - j->request_length = 0; - j->http_request[0] = 0; - } - } - } - } - else - { - j->request_length = 0; - j->http_request[0] = 0; - j->http_state = HTTP_STATE_REQUEST; - } - } - } - lloopend (listener_list, j); + if (j->response_written == + j->response_length) { + if (http != 0) + j->http_state = HTTP_STATE_CLOSING; + else { + j->http_state = HTTP_STATE_REQUEST; + free(j-> + http_response); + j->response_length = 0; + j->request_length = 0; + j->http_request[0] = 0; + } + } + } + } else { + j->request_length = 0; + j->http_request[0] = 0; + j->http_state = HTTP_STATE_REQUEST; + } + } + } + lloopend(listener_list, j); /* loop through all connections, closing those that are in error */ - lloopstart (listener_list, j) - { - if (j->http_state == HTTP_STATE_CLOSING) - { - ldeleteinc (listener_list, j); - } - } - lloopend (listener_list, j); - } + lloopstart(listener_list, j) { + if (j->http_state == HTTP_STATE_CLOSING) { + ldeleteinc(listener_list, j); + } + } + lloopend(listener_list, j); + } - gnutls_certificate_free_credentials (cert_cred); + gnutls_certificate_free_credentials(cert_cred); #ifdef ENABLE_SRP - if (srp_cred) - gnutls_srp_free_server_credentials (srp_cred); + if (srp_cred) + gnutls_srp_free_server_credentials(srp_cred); #endif #ifdef ENABLE_PSK - if (psk_cred) - gnutls_psk_free_server_credentials (psk_cred); + if (psk_cred) + gnutls_psk_free_server_credentials(psk_cred); #endif #ifdef ENABLE_ANON - gnutls_anon_free_server_credentials (dh_cred); + gnutls_anon_free_server_credentials(dh_cred); #endif - if (noticket == 0) - gnutls_free (session_ticket_key.data); + if (noticket == 0) + gnutls_free(session_ticket_key.data); - if (nodb == 0) - wrap_db_deinit (); - gnutls_global_deinit (); + if (nodb == 0) + wrap_db_deinit(); + gnutls_global_deinit(); } -static void -cmd_parser (int argc, char **argv) +static void cmd_parser(int argc, char **argv) { - optionProcess (&gnutls_servOptions, argc, argv); + optionProcess(&gnutls_servOptions, argc, argv); - disable_client_cert = HAVE_OPT (DISABLE_CLIENT_CERT); - require_cert = HAVE_OPT (REQUIRE_CLIENT_CERT); - if (HAVE_OPT (DEBUG)) - debug = OPT_VALUE_DEBUG; + disable_client_cert = HAVE_OPT(DISABLE_CLIENT_CERT); + require_cert = HAVE_OPT(REQUIRE_CLIENT_CERT); + if (HAVE_OPT(DEBUG)) + debug = OPT_VALUE_DEBUG; - if (HAVE_OPT (QUIET)) - verbose = 0; + if (HAVE_OPT(QUIET)) + verbose = 0; - if (HAVE_OPT (PRIORITY)) - priorities = OPT_ARG (PRIORITY); + if (HAVE_OPT(PRIORITY)) + priorities = OPT_ARG(PRIORITY); - if (HAVE_OPT (LIST)) - { - print_list (priorities, verbose); - exit (0); - } + if (HAVE_OPT(LIST)) { + print_list(priorities, verbose); + exit(0); + } - nodb = HAVE_OPT (NODB); - noticket = HAVE_OPT (NOTICKET); + nodb = HAVE_OPT(NODB); + noticket = HAVE_OPT(NOTICKET); - if (HAVE_OPT (ECHO)) - http = 0; - else - http = 1; + if (HAVE_OPT(ECHO)) + http = 0; + else + http = 1; - if (HAVE_OPT (X509FMTDER)) - x509ctype = GNUTLS_X509_FMT_DER; - else - x509ctype = GNUTLS_X509_FMT_PEM; + if (HAVE_OPT(X509FMTDER)) + x509ctype = GNUTLS_X509_FMT_DER; + else + x509ctype = GNUTLS_X509_FMT_PEM; - generate = HAVE_OPT (GENERATE); + generate = HAVE_OPT(GENERATE); - if (HAVE_OPT (DHPARAMS)) - dh_params_file = OPT_ARG (DHPARAMS); + if (HAVE_OPT(DHPARAMS)) + dh_params_file = OPT_ARG(DHPARAMS); - if (HAVE_OPT (X509KEYFILE)) - x509_keyfile = OPT_ARG (X509KEYFILE); - if (HAVE_OPT (X509CERTFILE)) - x509_certfile = OPT_ARG (X509CERTFILE); + if (HAVE_OPT(X509KEYFILE)) + x509_keyfile = OPT_ARG(X509KEYFILE); + if (HAVE_OPT(X509CERTFILE)) + x509_certfile = OPT_ARG(X509CERTFILE); - if (HAVE_OPT (X509DSAKEYFILE)) - x509_dsakeyfile = OPT_ARG (X509DSAKEYFILE); - if (HAVE_OPT (X509DSACERTFILE)) - x509_dsacertfile = OPT_ARG (X509DSACERTFILE); + if (HAVE_OPT(X509DSAKEYFILE)) + x509_dsakeyfile = OPT_ARG(X509DSAKEYFILE); + if (HAVE_OPT(X509DSACERTFILE)) + x509_dsacertfile = OPT_ARG(X509DSACERTFILE); - if (HAVE_OPT (X509ECCKEYFILE)) - x509_ecckeyfile = OPT_ARG (X509ECCKEYFILE); - if (HAVE_OPT (X509ECCCERTFILE)) - x509_ecccertfile = OPT_ARG (X509ECCCERTFILE); + if (HAVE_OPT(X509ECCKEYFILE)) + x509_ecckeyfile = OPT_ARG(X509ECCKEYFILE); + if (HAVE_OPT(X509ECCCERTFILE)) + x509_ecccertfile = OPT_ARG(X509ECCCERTFILE); - if (HAVE_OPT (X509CAFILE)) - x509_cafile = OPT_ARG (X509CAFILE); - if (HAVE_OPT (X509CRLFILE)) - x509_crlfile = OPT_ARG (X509CRLFILE); + if (HAVE_OPT(X509CAFILE)) + x509_cafile = OPT_ARG(X509CAFILE); + if (HAVE_OPT(X509CRLFILE)) + x509_crlfile = OPT_ARG(X509CRLFILE); - if (HAVE_OPT (PGPKEYFILE)) - pgp_keyfile = OPT_ARG (PGPKEYFILE); - if (HAVE_OPT (PGPCERTFILE)) - pgp_certfile = OPT_ARG (PGPCERTFILE); + if (HAVE_OPT(PGPKEYFILE)) + pgp_keyfile = OPT_ARG(PGPKEYFILE); + if (HAVE_OPT(PGPCERTFILE)) + pgp_certfile = OPT_ARG(PGPCERTFILE); - if (HAVE_OPT (PGPKEYRING)) - pgp_keyring = OPT_ARG (PGPKEYRING); + if (HAVE_OPT(PGPKEYRING)) + pgp_keyring = OPT_ARG(PGPKEYRING); - if (HAVE_OPT (SRPPASSWD)) - srp_passwd = OPT_ARG (SRPPASSWD); - if (HAVE_OPT (SRPPASSWDCONF)) - srp_passwd_conf = OPT_ARG (SRPPASSWDCONF); + if (HAVE_OPT(SRPPASSWD)) + srp_passwd = OPT_ARG(SRPPASSWD); + if (HAVE_OPT(SRPPASSWDCONF)) + srp_passwd_conf = OPT_ARG(SRPPASSWDCONF); - if (HAVE_OPT (PSKPASSWD)) - psk_passwd = OPT_ARG (PSKPASSWD); + if (HAVE_OPT(PSKPASSWD)) + psk_passwd = OPT_ARG(PSKPASSWD); - if (HAVE_OPT(OCSP_RESPONSE)) - status_response_ocsp = OPT_ARG(OCSP_RESPONSE); + if (HAVE_OPT(OCSP_RESPONSE)) + status_response_ocsp = OPT_ARG(OCSP_RESPONSE); } @@ -1706,102 +1718,96 @@ cmd_parser (int argc, char **argv) #define SESSION_ID_SIZE 32 #define SESSION_DATA_SIZE 1024 -typedef struct -{ - char session_id[SESSION_ID_SIZE]; - unsigned int session_id_size; +typedef struct { + char session_id[SESSION_ID_SIZE]; + unsigned int session_id_size; - char session_data[SESSION_DATA_SIZE]; - unsigned int session_data_size; + char session_data[SESSION_DATA_SIZE]; + unsigned int session_data_size; } CACHE; static CACHE *cache_db; int cache_db_ptr = 0; -static void -wrap_db_init (void) +static void wrap_db_init(void) { - /* allocate cache_db */ - cache_db = calloc (1, ssl_session_cache * sizeof (CACHE)); + /* allocate cache_db */ + cache_db = calloc(1, ssl_session_cache * sizeof(CACHE)); } -static void -wrap_db_deinit (void) +static void wrap_db_deinit(void) { } static int -wrap_db_store (void *dbf, gnutls_datum_t key, gnutls_datum_t data) +wrap_db_store(void *dbf, gnutls_datum_t key, gnutls_datum_t data) { - if (cache_db == NULL) - return -1; + if (cache_db == NULL) + return -1; - if (key.size > SESSION_ID_SIZE) - return -1; - if (data.size > SESSION_DATA_SIZE) - return -1; + if (key.size > SESSION_ID_SIZE) + return -1; + if (data.size > SESSION_DATA_SIZE) + return -1; - memcpy (cache_db[cache_db_ptr].session_id, key.data, key.size); - cache_db[cache_db_ptr].session_id_size = key.size; + memcpy(cache_db[cache_db_ptr].session_id, key.data, key.size); + cache_db[cache_db_ptr].session_id_size = key.size; - memcpy (cache_db[cache_db_ptr].session_data, data.data, data.size); - cache_db[cache_db_ptr].session_data_size = data.size; + memcpy(cache_db[cache_db_ptr].session_data, data.data, data.size); + cache_db[cache_db_ptr].session_data_size = data.size; - cache_db_ptr++; - cache_db_ptr %= ssl_session_cache; + cache_db_ptr++; + cache_db_ptr %= ssl_session_cache; - return 0; + return 0; } -static gnutls_datum_t -wrap_db_fetch (void *dbf, gnutls_datum_t key) +static gnutls_datum_t wrap_db_fetch(void *dbf, gnutls_datum_t key) { - gnutls_datum_t res = { NULL, 0 }; - int i; + gnutls_datum_t res = { NULL, 0 }; + int i; - if (cache_db == NULL) - return res; + if (cache_db == NULL) + return res; - for (i = 0; i < ssl_session_cache; i++) - { - if (key.size == cache_db[i].session_id_size && - memcmp (key.data, cache_db[i].session_id, key.size) == 0) - { - res.size = cache_db[i].session_data_size; + for (i = 0; i < ssl_session_cache; i++) { + if (key.size == cache_db[i].session_id_size && + memcmp(key.data, cache_db[i].session_id, + key.size) == 0) { + res.size = cache_db[i].session_data_size; - res.data = gnutls_malloc (res.size); - if (res.data == NULL) - return res; + res.data = gnutls_malloc(res.size); + if (res.data == NULL) + return res; - memcpy (res.data, cache_db[i].session_data, res.size); + memcpy(res.data, cache_db[i].session_data, + res.size); - return res; - } - } - return res; + return res; + } + } + return res; } -static int -wrap_db_delete (void *dbf, gnutls_datum_t key) +static int wrap_db_delete(void *dbf, gnutls_datum_t key) { - int i; + int i; - if (cache_db == NULL) - return -1; + if (cache_db == NULL) + return -1; - for (i = 0; i < ssl_session_cache; i++) - { - if (key.size == (unsigned int) cache_db[i].session_id_size && - memcmp (key.data, cache_db[i].session_id, key.size) == 0) - { + for (i = 0; i < ssl_session_cache; i++) { + if (key.size == (unsigned int) cache_db[i].session_id_size + && memcmp(key.data, cache_db[i].session_id, + key.size) == 0) { - cache_db[i].session_id_size = 0; - cache_db[i].session_data_size = 0; + cache_db[i].session_id_size = 0; + cache_db[i].session_data_size = 0; - return 0; - } - } + return 0; + } + } - return -1; + return -1; } diff --git a/src/socket.c b/src/socket.c index c8606a0958..79c5eaeb51 100644 --- a/src/socket.c +++ b/src/socket.c @@ -20,9 +20,9 @@ #include <config.h> #if HAVE_SYS_SOCKET_H -# include <sys/socket.h> +#include <sys/socket.h> #elif HAVE_WS2TCPIP_H -# include <ws2tcpip.h> +#include <ws2tcpip.h> #endif #include <netdb.h> #include <string.h> @@ -33,7 +33,7 @@ #include <stdlib.h> #include <unistd.h> #ifndef _WIN32 -# include <signal.h> +#include <signal.h> #endif #include <socket.h> #include "sockets.h" @@ -45,192 +45,197 @@ extern unsigned int verbose; */ ssize_t -socket_recv (const socket_st * socket, void *buffer, int buffer_size) +socket_recv(const socket_st * socket, void *buffer, int buffer_size) { - int ret; - - if (socket->secure) - { - do - { - ret = gnutls_record_recv (socket->session, buffer, buffer_size); - if (ret == GNUTLS_E_HEARTBEAT_PING_RECEIVED) - gnutls_heartbeat_pong(socket->session, 0); - } - while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_HEARTBEAT_PING_RECEIVED); - - } - else - do - { - ret = recv (socket->fd, buffer, buffer_size, 0); - } - while (ret == -1 && errno == EINTR); - - return ret; + int ret; + + if (socket->secure) { + do { + ret = + gnutls_record_recv(socket->session, buffer, + buffer_size); + if (ret == GNUTLS_E_HEARTBEAT_PING_RECEIVED) + gnutls_heartbeat_pong(socket->session, 0); + } + while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN + || ret == GNUTLS_E_HEARTBEAT_PING_RECEIVED); + + } else + do { + ret = recv(socket->fd, buffer, buffer_size, 0); + } + while (ret == -1 && errno == EINTR); + + return ret; } ssize_t -socket_send (const socket_st * socket, const void *buffer, int buffer_size) +socket_send(const socket_st * socket, const void *buffer, int buffer_size) { - return socket_send_range(socket, buffer, buffer_size, NULL); + return socket_send_range(socket, buffer, buffer_size, NULL); } ssize_t -socket_send_range (const socket_st * socket, const void *buffer, int buffer_size, gnutls_range_st *range) +socket_send_range(const socket_st * socket, const void *buffer, + int buffer_size, gnutls_range_st * range) { - int ret; - - if (socket->secure) - do - { - if (range == NULL) - ret = gnutls_record_send (socket->session, buffer, buffer_size); - else - ret = gnutls_record_send_range(socket->session, buffer, buffer_size, range); - } - while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); - else - do - { - ret = send (socket->fd, buffer, buffer_size, 0); - } - while (ret == -1 && errno == EINTR); - - if (ret > 0 && ret != buffer_size && verbose) - fprintf (stderr, - "*** Only sent %d bytes instead of %d.\n", ret, buffer_size); - - return ret; + int ret; + + if (socket->secure) + do { + if (range == NULL) + ret = + gnutls_record_send(socket->session, + buffer, + buffer_size); + else + ret = + gnutls_record_send_range(socket-> + session, + buffer, + buffer_size, + range); + } + while (ret == GNUTLS_E_AGAIN + || ret == GNUTLS_E_INTERRUPTED); + else + do { + ret = send(socket->fd, buffer, buffer_size, 0); + } + while (ret == -1 && errno == EINTR); + + if (ret > 0 && ret != buffer_size && verbose) + fprintf(stderr, + "*** Only sent %d bytes instead of %d.\n", ret, + buffer_size); + + return ret; } -void -socket_bye (socket_st * socket) +void socket_bye(socket_st * socket) { - int ret; - if (socket->secure) - { - do - ret = gnutls_bye (socket->session, GNUTLS_SHUT_WR); - while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN); - if (ret < 0) - fprintf (stderr, "*** gnutls_bye() error: %s\n", - gnutls_strerror (ret)); - gnutls_deinit (socket->session); - socket->session = NULL; - } - - freeaddrinfo (socket->addr_info); - socket->addr_info = socket->ptr = NULL; - - free (socket->ip); - free (socket->hostname); - free (socket->service); - - shutdown (socket->fd, SHUT_RDWR); /* no more receptions */ - close (socket->fd); - - socket->fd = -1; - socket->secure = 0; + int ret; + if (socket->secure) { + do + ret = gnutls_bye(socket->session, GNUTLS_SHUT_WR); + while (ret == GNUTLS_E_INTERRUPTED + || ret == GNUTLS_E_AGAIN); + if (ret < 0) + fprintf(stderr, "*** gnutls_bye() error: %s\n", + gnutls_strerror(ret)); + gnutls_deinit(socket->session); + socket->session = NULL; + } + + freeaddrinfo(socket->addr_info); + socket->addr_info = socket->ptr = NULL; + + free(socket->ip); + free(socket->hostname); + free(socket->service); + + shutdown(socket->fd, SHUT_RDWR); /* no more receptions */ + close(socket->fd); + + socket->fd = -1; + socket->secure = 0; } void -socket_open (socket_st * hd, const char *hostname, const char *service, int udp) +socket_open(socket_st * hd, const char *hostname, const char *service, + int udp) { - struct addrinfo hints, *res, *ptr; - int sd, err; - char buffer[MAX_BUF + 1]; - char portname[16] = { 0 }; - - printf ("Resolving '%s'...\n", hostname); - /* get server name */ - memset (&hints, 0, sizeof (hints)); - hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM; - if ((err = getaddrinfo (hostname, service, &hints, &res))) - { - fprintf (stderr, "Cannot resolve %s:%s: %s\n", hostname, service, - gai_strerror (err)); - exit (1); - } - - sd = -1; - for (ptr = res; ptr != NULL; ptr = ptr->ai_next) - { - sd = socket (ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); - if (sd == -1) - continue; - - if ((err = getnameinfo (ptr->ai_addr, ptr->ai_addrlen, buffer, MAX_BUF, - portname, sizeof (portname), - NI_NUMERICHOST | NI_NUMERICSERV)) != 0) - { - fprintf (stderr, "getnameinfo(): %s\n", gai_strerror (err)); - continue; - } - - if (hints.ai_socktype == SOCK_DGRAM) - { + struct addrinfo hints, *res, *ptr; + int sd, err; + char buffer[MAX_BUF + 1]; + char portname[16] = { 0 }; + + printf("Resolving '%s'...\n", hostname); + /* get server name */ + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM; + if ((err = getaddrinfo(hostname, service, &hints, &res))) { + fprintf(stderr, "Cannot resolve %s:%s: %s\n", hostname, + service, gai_strerror(err)); + exit(1); + } + + sd = -1; + for (ptr = res; ptr != NULL; ptr = ptr->ai_next) { + sd = socket(ptr->ai_family, ptr->ai_socktype, + ptr->ai_protocol); + if (sd == -1) + continue; + + if ((err = + getnameinfo(ptr->ai_addr, ptr->ai_addrlen, buffer, + MAX_BUF, portname, sizeof(portname), + NI_NUMERICHOST | NI_NUMERICSERV)) != 0) { + fprintf(stderr, "getnameinfo(): %s\n", + gai_strerror(err)); + continue; + } + + if (hints.ai_socktype == SOCK_DGRAM) { #if defined(IP_DONTFRAG) - int yes = 1; - if (setsockopt (sd, IPPROTO_IP, IP_DONTFRAG, - (const void *) &yes, sizeof (yes)) < 0) - perror ("setsockopt(IP_DF) failed"); + int yes = 1; + if (setsockopt(sd, IPPROTO_IP, IP_DONTFRAG, + (const void *) &yes, + sizeof(yes)) < 0) + perror("setsockopt(IP_DF) failed"); #elif defined(IP_MTU_DISCOVER) - int yes = IP_PMTUDISC_DO; - if (setsockopt(sd, IPPROTO_IP, IP_MTU_DISCOVER, - (const void*) &yes, sizeof (yes)) < 0) - perror ("setsockopt(IP_DF) failed"); + int yes = IP_PMTUDISC_DO; + if (setsockopt(sd, IPPROTO_IP, IP_MTU_DISCOVER, + (const void *) &yes, + sizeof(yes)) < 0) + perror("setsockopt(IP_DF) failed"); #endif - } - - - printf ("Connecting to '%s:%s'...\n", buffer, portname); - - err = connect (sd, ptr->ai_addr, ptr->ai_addrlen); - if (err < 0) - { - fprintf (stderr, "Cannot connect to %s:%s: %s\n", buffer, - portname, strerror (errno)); - continue; - } - break; - } - - if (err != 0) - exit(1); - - if (sd == -1) - { - fprintf (stderr, "Could not find a supported socket\n"); - exit (1); - } - - hd->secure = 0; - hd->fd = sd; - hd->hostname = strdup (hostname); - hd->ip = strdup (buffer); - hd->service = strdup (portname); - hd->ptr = ptr; - hd->addr_info = res; - - return; + } + + + printf("Connecting to '%s:%s'...\n", buffer, portname); + + err = connect(sd, ptr->ai_addr, ptr->ai_addrlen); + if (err < 0) { + fprintf(stderr, "Cannot connect to %s:%s: %s\n", + buffer, portname, strerror(errno)); + continue; + } + break; + } + + if (err != 0) + exit(1); + + if (sd == -1) { + fprintf(stderr, "Could not find a supported socket\n"); + exit(1); + } + + hd->secure = 0; + hd->fd = sd; + hd->hostname = strdup(hostname); + hd->ip = strdup(buffer); + hd->service = strdup(portname); + hd->ptr = ptr; + hd->addr_info = res; + + return; } -void -sockets_init (void) +void sockets_init(void) { #ifdef _WIN32 - WORD wVersionRequested; - WSADATA wsaData; - - wVersionRequested = MAKEWORD (1, 1); - if (WSAStartup (wVersionRequested, &wsaData) != 0) - { - perror ("WSA_STARTUP_ERROR"); - } + WORD wVersionRequested; + WSADATA wsaData; + + wVersionRequested = MAKEWORD(1, 1); + if (WSAStartup(wVersionRequested, &wsaData) != 0) { + perror("WSA_STARTUP_ERROR"); + } #else - signal (SIGPIPE, SIG_IGN); + signal(SIGPIPE, SIG_IGN); #endif } diff --git a/src/socket.h b/src/socket.h index c503aff705..00ec616378 100644 --- a/src/socket.h +++ b/src/socket.h @@ -1,23 +1,24 @@ #include <gnutls/gnutls.h> -typedef struct -{ - int fd; - gnutls_session_t session; - int secure; - char *hostname; - char *ip; - char *service; - struct addrinfo *ptr; - struct addrinfo *addr_info; +typedef struct { + int fd; + gnutls_session_t session; + int secure; + char *hostname; + char *ip; + char *service; + struct addrinfo *ptr; + struct addrinfo *addr_info; } socket_st; -ssize_t socket_recv (const socket_st * socket, void *buffer, int buffer_size); -ssize_t socket_send (const socket_st * socket, const void *buffer, - int buffer_size); +ssize_t socket_recv(const socket_st * socket, void *buffer, + int buffer_size); +ssize_t socket_send(const socket_st * socket, const void *buffer, + int buffer_size); ssize_t socket_send_range(const socket_st * socket, const void *buffer, - int buffer_size, gnutls_range_st *range); -void socket_open (socket_st * hd, const char *hostname, const char *service, int udp); -void socket_bye (socket_st * socket); + int buffer_size, gnutls_range_st * range); +void socket_open(socket_st * hd, const char *hostname, const char *service, + int udp); +void socket_bye(socket_st * socket); -void sockets_init (void); +void sockets_init(void); diff --git a/src/srptool.c b/src/srptool.c index 5fcd17eaab..5d60cde0f7 100644 --- a/src/srptool.c +++ b/src/srptool.c @@ -24,7 +24,7 @@ #include <string.h> #include <stdlib.h> #include <gnutls/gnutls.h> -#include <gnutls/crypto.h> /* for random */ +#include <gnutls/crypto.h> /* for random */ #include <sys/types.h> #include <sys/stat.h> @@ -46,112 +46,94 @@ * are in the library, which is not good. */ -int crypt_int (const char *username, const char *passwd, int salt, - const char *tpasswd_conf, const char *tpasswd, int uindex); -static int read_conf_values (gnutls_datum_t * g, gnutls_datum_t * n, - char *str); -static int _verify_passwd_int (const char *username, const char *passwd, - char *verifier, const char *salt, - const gnutls_datum_t * g, - const gnutls_datum_t * n); - -static void -print_num (const char *msg, const gnutls_datum_t * num) +int crypt_int(const char *username, const char *passwd, int salt, + const char *tpasswd_conf, const char *tpasswd, int uindex); +static int read_conf_values(gnutls_datum_t * g, gnutls_datum_t * n, + char *str); +static int _verify_passwd_int(const char *username, const char *passwd, + char *verifier, const char *salt, + const gnutls_datum_t * g, + const gnutls_datum_t * n); + +static void print_num(const char *msg, const gnutls_datum_t * num) { - unsigned int i; + unsigned int i; - printf ("%s:\t", msg); + printf("%s:\t", msg); - for (i = 0; i < num->size; i++) - { - if (i != 0 && i % 12 == 0) - printf ("\n\t"); - else if (i != 0 && i != num->size) - printf (":"); - printf ("%.2x", num->data[i]); - } - printf ("\n\n"); + for (i = 0; i < num->size; i++) { + if (i != 0 && i % 12 == 0) + printf("\n\t"); + else if (i != 0 && i != num->size) + printf(":"); + printf("%.2x", num->data[i]); + } + printf("\n\n"); } -static int -generate_create_conf (const char *tpasswd_conf) +static int generate_create_conf(const char *tpasswd_conf) { - FILE *fd; - char line[5 * 1024]; - int index = 1; - gnutls_datum_t g, n; - gnutls_datum_t str_g, str_n; - - fd = fopen (tpasswd_conf, "w"); - if (fd == NULL) - { - fprintf (stderr, "Cannot open file '%s'\n", tpasswd_conf); - return -1; - } - - for (index = 1; index <= 5; index++) - { - - if (index == 1) - { - n = gnutls_srp_1024_group_prime; - g = gnutls_srp_1024_group_generator; - } - else if (index == 2) - { - n = gnutls_srp_1536_group_prime; - g = gnutls_srp_1536_group_generator; - } - else if (index == 3) - { - n = gnutls_srp_2048_group_prime; - g = gnutls_srp_2048_group_generator; - } - else if (index == 4) - { - n = gnutls_srp_3072_group_prime; - g = gnutls_srp_3072_group_generator; - } - else if (index == 5) - { - n = gnutls_srp_4096_group_prime; - g = gnutls_srp_4096_group_generator; - } - else - { - fprintf(stderr, "Unknown index: %d\n", index); - return -1; - } - - printf ("\nGroup %d, of %d bits:\n", index, n.size * 8); - print_num ("Generator", &g); - print_num ("Prime", &n); - - if (gnutls_srp_base64_encode_alloc (&n, &str_n) < 0) - { - fprintf (stderr, "Could not encode\n"); - return -1; - } - - if (gnutls_srp_base64_encode_alloc (&g, &str_g) < 0) - { - fprintf (stderr, "Could not encode\n"); - return -1; - } - - sprintf (line, "%d:%s:%s\n", index, str_n.data, str_g.data); - - gnutls_free (str_n.data); - gnutls_free (str_g.data); - - fwrite (line, 1, strlen (line), fd); - - } - - fclose (fd); - - return 0; + FILE *fd; + char line[5 * 1024]; + int index = 1; + gnutls_datum_t g, n; + gnutls_datum_t str_g, str_n; + + fd = fopen(tpasswd_conf, "w"); + if (fd == NULL) { + fprintf(stderr, "Cannot open file '%s'\n", tpasswd_conf); + return -1; + } + + for (index = 1; index <= 5; index++) { + + if (index == 1) { + n = gnutls_srp_1024_group_prime; + g = gnutls_srp_1024_group_generator; + } else if (index == 2) { + n = gnutls_srp_1536_group_prime; + g = gnutls_srp_1536_group_generator; + } else if (index == 3) { + n = gnutls_srp_2048_group_prime; + g = gnutls_srp_2048_group_generator; + } else if (index == 4) { + n = gnutls_srp_3072_group_prime; + g = gnutls_srp_3072_group_generator; + } else if (index == 5) { + n = gnutls_srp_4096_group_prime; + g = gnutls_srp_4096_group_generator; + } else { + fprintf(stderr, "Unknown index: %d\n", index); + return -1; + } + + printf("\nGroup %d, of %d bits:\n", index, n.size * 8); + print_num("Generator", &g); + print_num("Prime", &n); + + if (gnutls_srp_base64_encode_alloc(&n, &str_n) < 0) { + fprintf(stderr, "Could not encode\n"); + return -1; + } + + if (gnutls_srp_base64_encode_alloc(&g, &str_g) < 0) { + fprintf(stderr, "Could not encode\n"); + return -1; + } + + sprintf(line, "%d:%s:%s\n", index, str_n.data, str_g.data); + + gnutls_free(str_n.data); + gnutls_free(str_g.data); + + fwrite(line, 1, strlen(line), fd); + + } + + fclose(fd); + + return 0; } @@ -161,521 +143,482 @@ generate_create_conf (const char *tpasswd_conf) * index is the index of the prime-generator pair in tpasswd.conf */ static int -_verify_passwd_int (const char *username, const char *passwd, - char *verifier, const char *salt, - const gnutls_datum_t * g, const gnutls_datum_t * n) +_verify_passwd_int(const char *username, const char *passwd, + char *verifier, const char *salt, + const gnutls_datum_t * g, const gnutls_datum_t * n) { - char _salt[1024]; - gnutls_datum_t tmp, raw_salt, new_verifier; - size_t salt_size; - char *pos; - - if (salt == NULL || verifier == NULL) - return -1; - - if (strlen(salt) >= sizeof(_salt)) - { - fprintf (stderr, "Too long salt.\n"); - return -1; - } - - /* copy salt, and null terminate after the ':' */ - strcpy (_salt, salt); - pos = strchr (_salt, ':'); - if (pos != NULL) - *pos = 0; - - /* convert salt to binary. */ - tmp.data = (void*)_salt; - tmp.size = strlen (_salt); - - if (gnutls_srp_base64_decode_alloc (&tmp, &raw_salt) < 0) - { - fprintf (stderr, "Could not decode salt.\n"); - return -1; - } - - if (gnutls_srp_verifier - (username, passwd, &raw_salt, g, n, &new_verifier) < 0) - { - fprintf (stderr, "Could not make the verifier\n"); - return -1; - } - - free (raw_salt.data); - - /* encode the verifier into _salt */ - salt_size = sizeof (_salt); - memset (_salt, 0, salt_size); - if (gnutls_srp_base64_encode (&new_verifier, _salt, &salt_size) < 0) - { - fprintf (stderr, "Encoding error\n"); - return -1; - } - - free (new_verifier.data); - - if (strncmp (verifier, _salt, strlen (_salt)) == 0) - { - fprintf (stderr, "Password verified\n"); - return 0; - } - else - { - fprintf (stderr, "Password does NOT match\n"); - } - return -1; + char _salt[1024]; + gnutls_datum_t tmp, raw_salt, new_verifier; + size_t salt_size; + char *pos; + + if (salt == NULL || verifier == NULL) + return -1; + + if (strlen(salt) >= sizeof(_salt)) { + fprintf(stderr, "Too long salt.\n"); + return -1; + } + + /* copy salt, and null terminate after the ':' */ + strcpy(_salt, salt); + pos = strchr(_salt, ':'); + if (pos != NULL) + *pos = 0; + + /* convert salt to binary. */ + tmp.data = (void *) _salt; + tmp.size = strlen(_salt); + + if (gnutls_srp_base64_decode_alloc(&tmp, &raw_salt) < 0) { + fprintf(stderr, "Could not decode salt.\n"); + return -1; + } + + if (gnutls_srp_verifier + (username, passwd, &raw_salt, g, n, &new_verifier) < 0) { + fprintf(stderr, "Could not make the verifier\n"); + return -1; + } + + free(raw_salt.data); + + /* encode the verifier into _salt */ + salt_size = sizeof(_salt); + memset(_salt, 0, salt_size); + if (gnutls_srp_base64_encode(&new_verifier, _salt, &salt_size) < 0) { + fprintf(stderr, "Encoding error\n"); + return -1; + } + + free(new_verifier.data); + + if (strncmp(verifier, _salt, strlen(_salt)) == 0) { + fprintf(stderr, "Password verified\n"); + return 0; + } else { + fprintf(stderr, "Password does NOT match\n"); + } + return -1; } -static int -filecopy (const char *src, const char *dst) +static int filecopy(const char *src, const char *dst) { - FILE *fd, *fd2; - char line[5 * 1024]; - char *p; - - fd = fopen (dst, "w"); - if (fd == NULL) - { - fprintf (stderr, "Cannot open '%s' for write\n", dst); - return -1; - } - - fd2 = fopen (src, "r"); - if (fd2 == NULL) - { - /* empty file */ - fclose (fd); - return 0; - } - - line[sizeof (line) - 1] = 0; - do - { - p = fgets (line, sizeof (line) - 1, fd2); - if (p == NULL) - break; - - fputs (line, fd); - } - while (1); - - fclose (fd); - fclose (fd2); - - return 0; + FILE *fd, *fd2; + char line[5 * 1024]; + char *p; + + fd = fopen(dst, "w"); + if (fd == NULL) { + fprintf(stderr, "Cannot open '%s' for write\n", dst); + return -1; + } + + fd2 = fopen(src, "r"); + if (fd2 == NULL) { + /* empty file */ + fclose(fd); + return 0; + } + + line[sizeof(line) - 1] = 0; + do { + p = fgets(line, sizeof(line) - 1, fd2); + if (p == NULL) + break; + + fputs(line, fd); + } + while (1); + + fclose(fd); + fclose(fd2); + + return 0; } /* accepts password file */ -static int -find_strchr (const char *username, const char *file) +static int find_strchr(const char *username, const char *file) { - FILE *fd; - char *pos; - char line[5 * 1024]; - unsigned int i; - - fd = fopen (file, "r"); - if (fd == NULL) - { - fprintf (stderr, "Cannot open file '%s'\n", file); - return -1; - } - - while (fgets (line, sizeof (line), fd) != NULL) - { - /* move to first ':' */ - i = 0; - while ((line[i] != ':') && (line[i] != '\0') && (i < sizeof (line))) - { - i++; - } - if (strncmp (username, line, MAX (i, strlen (username))) == 0) - { - /* find the index */ - pos = strrchr (line, ':'); - pos++; - fclose (fd); - return atoi (pos); - } - } - - fclose (fd); - return -1; + FILE *fd; + char *pos; + char line[5 * 1024]; + unsigned int i; + + fd = fopen(file, "r"); + if (fd == NULL) { + fprintf(stderr, "Cannot open file '%s'\n", file); + return -1; + } + + while (fgets(line, sizeof(line), fd) != NULL) { + /* move to first ':' */ + i = 0; + while ((line[i] != ':') && (line[i] != '\0') + && (i < sizeof(line))) { + i++; + } + if (strncmp(username, line, MAX(i, strlen(username))) == 0) { + /* find the index */ + pos = strrchr(line, ':'); + pos++; + fclose(fd); + return atoi(pos); + } + } + + fclose(fd); + return -1; } /* Parses the tpasswd files, in order to verify the given * username/password pair. */ static int -verify_passwd (const char *conffile, const char *tpasswd, - const char *username, const char *passwd) +verify_passwd(const char *conffile, const char *tpasswd, + const char *username, const char *passwd) { - FILE *fd; - char line[5 * 1024]; - unsigned int i; - gnutls_datum_t g, n; - int iindex; - char *p, *pos; - - iindex = find_strchr (username, tpasswd); - if (iindex == -1) - { - fprintf (stderr, "Cannot find '%s' in %s\n", username, tpasswd); - return -1; - } - - fd = fopen (conffile, "r"); - if (fd == NULL) - { - fprintf (stderr, "Cannot find %s\n", conffile); - return -1; - } - - do - { - p = fgets (line, sizeof (line) - 1, fd); - } - while (p != NULL && atoi (p) != iindex); - - if (p == NULL) - { - fprintf (stderr, "Cannot find entry in %s\n", conffile); - return -1; - } - line[sizeof (line) - 1] = 0; - - fclose (fd); - - if ((iindex = read_conf_values (&g, &n, line)) < 0) - { - fprintf (stderr, "Cannot parse conf file '%s'\n", conffile); - return -1; - } - - fd = fopen (tpasswd, "r"); - if (fd == NULL) - { - fprintf (stderr, "Cannot open file '%s'\n", tpasswd); - return -1; - } - - while (fgets (line, sizeof (line), fd) != NULL) - { - /* move to first ':' - * This is the actual verifier. - */ - i = 0; - while ((line[i] != ':') && (line[i] != '\0') && (i < sizeof (line))) - { - i++; - } - if (strncmp (username, line, MAX (i, strlen (username))) == 0) - { - char *verifier_pos, *salt_pos; - - pos = strchr (line, ':'); - fclose (fd); - if (pos == NULL) - { - fprintf (stderr, "Cannot parse conf file '%s'\n", conffile); - return -1; - } - pos++; - verifier_pos = pos; - - /* Move to the salt */ - pos = strchr (pos, ':'); - if (pos == NULL) - { - fprintf (stderr, "Cannot parse conf file '%s'\n", conffile); - return -1; - } - pos++; - salt_pos = pos; - - return _verify_passwd_int (username, passwd, - verifier_pos, salt_pos, &g, &n); - } - } - - fclose (fd); - return -1; + FILE *fd; + char line[5 * 1024]; + unsigned int i; + gnutls_datum_t g, n; + int iindex; + char *p, *pos; + + iindex = find_strchr(username, tpasswd); + if (iindex == -1) { + fprintf(stderr, "Cannot find '%s' in %s\n", username, + tpasswd); + return -1; + } + + fd = fopen(conffile, "r"); + if (fd == NULL) { + fprintf(stderr, "Cannot find %s\n", conffile); + return -1; + } + + do { + p = fgets(line, sizeof(line) - 1, fd); + } + while (p != NULL && atoi(p) != iindex); + + if (p == NULL) { + fprintf(stderr, "Cannot find entry in %s\n", conffile); + return -1; + } + line[sizeof(line) - 1] = 0; + + fclose(fd); + + if ((iindex = read_conf_values(&g, &n, line)) < 0) { + fprintf(stderr, "Cannot parse conf file '%s'\n", conffile); + return -1; + } + + fd = fopen(tpasswd, "r"); + if (fd == NULL) { + fprintf(stderr, "Cannot open file '%s'\n", tpasswd); + return -1; + } + + while (fgets(line, sizeof(line), fd) != NULL) { + /* move to first ':' + * This is the actual verifier. + */ + i = 0; + while ((line[i] != ':') && (line[i] != '\0') + && (i < sizeof(line))) { + i++; + } + if (strncmp(username, line, MAX(i, strlen(username))) == 0) { + char *verifier_pos, *salt_pos; + + pos = strchr(line, ':'); + fclose(fd); + if (pos == NULL) { + fprintf(stderr, + "Cannot parse conf file '%s'\n", + conffile); + return -1; + } + pos++; + verifier_pos = pos; + + /* Move to the salt */ + pos = strchr(pos, ':'); + if (pos == NULL) { + fprintf(stderr, + "Cannot parse conf file '%s'\n", + conffile); + return -1; + } + pos++; + salt_pos = pos; + + return _verify_passwd_int(username, passwd, + verifier_pos, salt_pos, + &g, &n); + } + } + + fclose(fd); + return -1; } #define KPASSWD "/etc/tpasswd" #define KPASSWD_CONF "/etc/tpasswd.conf" -static void -tls_log_func (int level, const char *str) +static void tls_log_func(int level, const char *str) { - fprintf (stderr, "|<%d>| %s", level, str); + fprintf(stderr, "|<%d>| %s", level, str); } -int main (int argc, char **argv) +int main(int argc, char **argv) { - const char *passwd; - int salt_size, ret; - int optct; - const char* fpasswd, *fpasswd_conf; - const char* username; + const char *passwd; + int salt_size, ret; + int optct; + const char *fpasswd, *fpasswd_conf; + const char *username; #ifndef _WIN32 - struct passwd *pwd; + struct passwd *pwd; #endif - if ((ret = gnutls_global_init ()) < 0) - { - fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret)); - exit (1); - } + if ((ret = gnutls_global_init()) < 0) { + fprintf(stderr, "global_init: %s\n", gnutls_strerror(ret)); + exit(1); + } - umask (066); + umask(066); - optct = optionProcess( &srptoolOptions, argc, argv); - argc -= optct; - argv += optct; + optct = optionProcess(&srptoolOptions, argc, argv); + argc -= optct; + argv += optct; - gnutls_global_set_log_function (tls_log_func); - gnutls_global_set_log_level (OPT_VALUE_DEBUG); + gnutls_global_set_log_function(tls_log_func); + gnutls_global_set_log_level(OPT_VALUE_DEBUG); - if (HAVE_OPT(CREATE_CONF)) - { - return generate_create_conf (OPT_ARG(CREATE_CONF)); - } + if (HAVE_OPT(CREATE_CONF)) { + return generate_create_conf(OPT_ARG(CREATE_CONF)); + } - if (HAVE_OPT(PASSWD)) - fpasswd = OPT_ARG(PASSWD); - else - fpasswd = (char *) KPASSWD; + if (HAVE_OPT(PASSWD)) + fpasswd = OPT_ARG(PASSWD); + else + fpasswd = (char *) KPASSWD; - if (HAVE_OPT(PASSWD_CONF)) - fpasswd_conf = OPT_ARG(PASSWD_CONF); - else - fpasswd_conf = (char *) KPASSWD_CONF; + if (HAVE_OPT(PASSWD_CONF)) + fpasswd_conf = OPT_ARG(PASSWD_CONF); + else + fpasswd_conf = (char *) KPASSWD_CONF; - if (HAVE_OPT(USERNAME)) - username = OPT_ARG(USERNAME); - else - { + if (HAVE_OPT(USERNAME)) + username = OPT_ARG(USERNAME); + else { #ifndef _WIN32 - pwd = getpwuid (getuid ()); + pwd = getpwuid(getuid()); - if (pwd == NULL) - { - fprintf (stderr, "No such user\n"); - return -1; - } + if (pwd == NULL) { + fprintf(stderr, "No such user\n"); + return -1; + } - username = pwd->pw_name; + username = pwd->pw_name; #else - fprintf (stderr, "Please specify a user\n"); - return -1; + fprintf(stderr, "Please specify a user\n"); + return -1; #endif - } + } - salt_size = 16; + salt_size = 16; - passwd = getpass ("Enter password: "); - if (passwd == NULL) - { - fprintf (stderr, "Please specify a password\n"); - return -1; - } + passwd = getpass("Enter password: "); + if (passwd == NULL) { + fprintf(stderr, "Please specify a password\n"); + return -1; + } /* not ready yet */ - if (HAVE_OPT(VERIFY)) - { - return verify_passwd (fpasswd_conf, fpasswd, - username, passwd); - } + if (HAVE_OPT(VERIFY)) { + return verify_passwd(fpasswd_conf, fpasswd, + username, passwd); + } - return crypt_int (username, passwd, salt_size, - fpasswd_conf, fpasswd, OPT_VALUE_INDEX); + return crypt_int(username, passwd, salt_size, + fpasswd_conf, fpasswd, OPT_VALUE_INDEX); } -static char * -_srp_crypt (const char *username, const char *passwd, int salt_size, - const gnutls_datum_t * g, const gnutls_datum_t * n) +static char *_srp_crypt(const char *username, const char *passwd, + int salt_size, const gnutls_datum_t * g, + const gnutls_datum_t * n) { - unsigned char salt[128]; - static char result[1024]; - gnutls_datum_t dat_salt, txt_salt; - gnutls_datum_t verifier, txt_verifier; - - if ((unsigned) salt_size > sizeof (salt)) - return NULL; - - /* generate the salt - */ - if (gnutls_rnd (GNUTLS_RND_NONCE, salt, salt_size) < 0) - { - fprintf (stderr, "Could not create nonce\n"); - return NULL; - } - - dat_salt.data = salt; - dat_salt.size = salt_size; - - if (gnutls_srp_verifier (username, passwd, &dat_salt, g, n, &verifier) < 0) - { - fprintf (stderr, "Error getting verifier\n"); - return NULL; - } - - /* base64 encode the verifier */ - if (gnutls_srp_base64_encode_alloc (&verifier, &txt_verifier) < 0) - { - fprintf (stderr, "Error encoding\n"); - free (verifier.data); - return NULL; - } - - free (verifier.data); - - if (gnutls_srp_base64_encode_alloc (&dat_salt, &txt_salt) < 0) - { - fprintf (stderr, "Error encoding\n"); - return NULL; - } - - sprintf (result, "%s:%s", txt_verifier.data, txt_salt.data); - free (txt_salt.data); - free (txt_verifier.data); - - return result; + unsigned char salt[128]; + static char result[1024]; + gnutls_datum_t dat_salt, txt_salt; + gnutls_datum_t verifier, txt_verifier; + + if ((unsigned) salt_size > sizeof(salt)) + return NULL; + + /* generate the salt + */ + if (gnutls_rnd(GNUTLS_RND_NONCE, salt, salt_size) < 0) { + fprintf(stderr, "Could not create nonce\n"); + return NULL; + } + + dat_salt.data = salt; + dat_salt.size = salt_size; + + if (gnutls_srp_verifier + (username, passwd, &dat_salt, g, n, &verifier) < 0) { + fprintf(stderr, "Error getting verifier\n"); + return NULL; + } + + /* base64 encode the verifier */ + if (gnutls_srp_base64_encode_alloc(&verifier, &txt_verifier) < 0) { + fprintf(stderr, "Error encoding\n"); + free(verifier.data); + return NULL; + } + + free(verifier.data); + + if (gnutls_srp_base64_encode_alloc(&dat_salt, &txt_salt) < 0) { + fprintf(stderr, "Error encoding\n"); + return NULL; + } + + sprintf(result, "%s:%s", txt_verifier.data, txt_salt.data); + free(txt_salt.data); + free(txt_verifier.data); + + return result; } int -crypt_int (const char *username, const char *passwd, int salt_size, - const char *tpasswd_conf, const char *tpasswd, int uindex) +crypt_int(const char *username, const char *passwd, int salt_size, + const char *tpasswd_conf, const char *tpasswd, int uindex) { - FILE *fd; - char *cr; - gnutls_datum_t g, n; - char line[5 * 1024]; - char *p, *pp; - int iindex; - char tmpname[1024]; - - fd = fopen (tpasswd_conf, "r"); - if (fd == NULL) - { - fprintf (stderr, "Cannot find %s\n", tpasswd_conf); - return -1; - } - - do - { /* find the specified uindex in file */ - p = fgets (line, sizeof (line) - 1, fd); - } - while (p != NULL && (iindex = atoi (p)) != uindex); - - if (p == NULL) - { - fprintf (stderr, "Cannot find entry in %s\n", tpasswd_conf); - return -1; - } - line[sizeof (line) - 1] = 0; - - fclose (fd); - if ((iindex = read_conf_values (&g, &n, line)) < 0) - { - fprintf (stderr, "Cannot parse conf file '%s'\n", tpasswd_conf); - return -1; - } - - cr = _srp_crypt (username, passwd, salt_size, &g, &n); - if (cr == NULL) - { - fprintf (stderr, "Cannot _srp_crypt()...\n"); - return -1; - } - else - { - /* delete previous entry */ - struct stat st; - FILE *fd2; - int put; - - if (strlen (tpasswd) + 5 > sizeof (tmpname)) - { - fprintf (stderr, "file '%s' is tooooo long\n", tpasswd); - return -1; - } - - snprintf(tmpname, sizeof(tmpname), "%s.tmp", tpasswd); - - if (stat (tmpname, &st) != -1) - { - fprintf (stderr, "file '%s' is locked\n", tpasswd); - return -1; - } - - if (filecopy (tpasswd, tmpname) != 0) - { - fprintf (stderr, "Cannot copy '%s' to '%s'\n", tpasswd, tmpname); - return -1; - } - - fd = fopen (tpasswd, "w"); - if (fd == NULL) - { - fprintf (stderr, "Cannot open '%s' for write\n", tpasswd); - remove (tmpname); - return -1; - } - - fd2 = fopen (tmpname, "r"); - if (fd2 == NULL) - { - fprintf (stderr, "Cannot open '%s' for read\n", tmpname); - remove (tmpname); - return -1; - } - - put = 0; - do - { - p = fgets (line, sizeof (line) - 1, fd2); - if (p == NULL) - break; - - pp = strchr (line, ':'); - if (pp == NULL) - continue; - - if (strncmp (p, username, - MAX (strlen (username), (unsigned int) (pp - p))) == 0) - { - put = 1; - fprintf (fd, "%s:%s:%u\n", username, cr, iindex); - } - else - { - fputs (line, fd); - } - } - while (1); - - if (put == 0) - { - fprintf (fd, "%s:%s:%u\n", username, cr, iindex); - } - - fclose (fd); - fclose (fd2); - - remove (tmpname); - - } - - - return 0; + FILE *fd; + char *cr; + gnutls_datum_t g, n; + char line[5 * 1024]; + char *p, *pp; + int iindex; + char tmpname[1024]; + + fd = fopen(tpasswd_conf, "r"); + if (fd == NULL) { + fprintf(stderr, "Cannot find %s\n", tpasswd_conf); + return -1; + } + + do { /* find the specified uindex in file */ + p = fgets(line, sizeof(line) - 1, fd); + } + while (p != NULL && (iindex = atoi(p)) != uindex); + + if (p == NULL) { + fprintf(stderr, "Cannot find entry in %s\n", tpasswd_conf); + return -1; + } + line[sizeof(line) - 1] = 0; + + fclose(fd); + if ((iindex = read_conf_values(&g, &n, line)) < 0) { + fprintf(stderr, "Cannot parse conf file '%s'\n", + tpasswd_conf); + return -1; + } + + cr = _srp_crypt(username, passwd, salt_size, &g, &n); + if (cr == NULL) { + fprintf(stderr, "Cannot _srp_crypt()...\n"); + return -1; + } else { + /* delete previous entry */ + struct stat st; + FILE *fd2; + int put; + + if (strlen(tpasswd) + 5 > sizeof(tmpname)) { + fprintf(stderr, "file '%s' is tooooo long\n", + tpasswd); + return -1; + } + + snprintf(tmpname, sizeof(tmpname), "%s.tmp", tpasswd); + + if (stat(tmpname, &st) != -1) { + fprintf(stderr, "file '%s' is locked\n", tpasswd); + return -1; + } + + if (filecopy(tpasswd, tmpname) != 0) { + fprintf(stderr, "Cannot copy '%s' to '%s'\n", + tpasswd, tmpname); + return -1; + } + + fd = fopen(tpasswd, "w"); + if (fd == NULL) { + fprintf(stderr, "Cannot open '%s' for write\n", + tpasswd); + remove(tmpname); + return -1; + } + + fd2 = fopen(tmpname, "r"); + if (fd2 == NULL) { + fprintf(stderr, "Cannot open '%s' for read\n", + tmpname); + remove(tmpname); + return -1; + } + + put = 0; + do { + p = fgets(line, sizeof(line) - 1, fd2); + if (p == NULL) + break; + + pp = strchr(line, ':'); + if (pp == NULL) + continue; + + if (strncmp(p, username, + MAX(strlen(username), + (unsigned int) (pp - p))) == 0) { + put = 1; + fprintf(fd, "%s:%s:%u\n", username, cr, + iindex); + } else { + fputs(line, fd); + } + } + while (1); + + if (put == 0) { + fprintf(fd, "%s:%s:%u\n", username, cr, iindex); + } + + fclose(fd); + fclose(fd2); + + remove(tmpname); + + } + + + return 0; } @@ -684,61 +627,56 @@ crypt_int (const char *username, const char *passwd, int salt_size, * int(index):base64(n):base64(g) */ static int -read_conf_values (gnutls_datum_t * g, gnutls_datum_t * n, char *str) +read_conf_values(gnutls_datum_t * g, gnutls_datum_t * n, char *str) { - char *p; - int len; - int index, ret; - gnutls_datum_t dat; - - index = atoi (str); - - p = strrchr (str, ':'); /* we have g */ - if (p == NULL) - { - return -1; - } - - *p = '\0'; - p++; - - /* read the generator */ - len = strlen (p); - if (p[len - 1] == '\n') - len--; - - dat.data = (void*)p; - dat.size = len; - ret = gnutls_srp_base64_decode_alloc (&dat, g); - - if (ret < 0) - { - fprintf (stderr, "Decoding error\n"); - return -1; - } - - /* now go for n - modulo */ - p = strrchr (str, ':'); /* we have n */ - if (p == NULL) - { - return -1; - } - - *p = '\0'; - p++; - - dat.data = (void*)p; - dat.size = strlen (p); - - ret = gnutls_srp_base64_decode_alloc (&dat, n); - - if (ret < 0) - { - fprintf (stderr, "Decoding error\n"); - free (g->data); - return -1; - } - - return index; -} + char *p; + int len; + int index, ret; + gnutls_datum_t dat; + + index = atoi(str); + + p = strrchr(str, ':'); /* we have g */ + if (p == NULL) { + return -1; + } + + *p = '\0'; + p++; + + /* read the generator */ + len = strlen(p); + if (p[len - 1] == '\n') + len--; + dat.data = (void *) p; + dat.size = len; + ret = gnutls_srp_base64_decode_alloc(&dat, g); + + if (ret < 0) { + fprintf(stderr, "Decoding error\n"); + return -1; + } + + /* now go for n - modulo */ + p = strrchr(str, ':'); /* we have n */ + if (p == NULL) { + return -1; + } + + *p = '\0'; + p++; + + dat.data = (void *) p; + dat.size = strlen(p); + + ret = gnutls_srp_base64_decode_alloc(&dat, n); + + if (ret < 0) { + fprintf(stderr, "Decoding error\n"); + free(g->data); + return -1; + } + + return index; +} diff --git a/src/tests.c b/src/tests.c index 4aeaa0f3ed..6f8ccdd427 100644 --- a/src/tests.c +++ b/src/tests.c @@ -53,57 +53,53 @@ static size_t session_data_size = 0, session_id_size = 0; static int sfree = 0; static int handshake_output = 0; -static int -do_handshake (gnutls_session_t session) +static int do_handshake(gnutls_session_t session) { - int ret, alert; - - do - { - ret = gnutls_handshake (session); - } - while (ret < 0 && gnutls_error_is_fatal(ret) == 0); - - handshake_output = ret; - - if (ret < 0 && verbose > 1) - { - if (ret == GNUTLS_E_FATAL_ALERT_RECEIVED) - { - alert = gnutls_alert_get (session); - printf ("\n"); - printf ("*** Received alert [%d]: %s\n", - alert, gnutls_alert_get_name (alert)); - } - } - - if (ret < 0) - return TEST_FAILED; - - gnutls_session_get_data (session, NULL, &session_data_size); - - if (sfree != 0) - { - free (session_data); - sfree = 0; - } - session_data = malloc (session_data_size); - sfree = 1; - if (session_data == NULL) - { - fprintf (stderr, "Memory error\n"); - exit (1); - } - gnutls_session_get_data (session, session_data, &session_data_size); - - session_id_size = sizeof (session_id); - gnutls_session_get_id (session, session_id, &session_id_size); - - return TEST_SUCCEED; + int ret, alert; + + do { + ret = gnutls_handshake(session); + } + while (ret < 0 && gnutls_error_is_fatal(ret) == 0); + + handshake_output = ret; + + if (ret < 0 && verbose > 1) { + if (ret == GNUTLS_E_FATAL_ALERT_RECEIVED) { + alert = gnutls_alert_get(session); + printf("\n"); + printf("*** Received alert [%d]: %s\n", + alert, gnutls_alert_get_name(alert)); + } + } + + if (ret < 0) + return TEST_FAILED; + + gnutls_session_get_data(session, NULL, &session_data_size); + + if (sfree != 0) { + free(session_data); + sfree = 0; + } + session_data = malloc(session_data_size); + sfree = 1; + if (session_data == NULL) { + fprintf(stderr, "Memory error\n"); + exit(1); + } + gnutls_session_get_data(session, session_data, &session_data_size); + + session_id_size = sizeof(session_id); + gnutls_session_get_id(session, session_id, &session_id_size); + + return TEST_SUCCEED; } -char protocol_str[] = "+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0"; -char protocol_all_str[] = "+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0"; +char protocol_str[] = + "+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0"; +char protocol_all_str[] = + "+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0"; char prio_str[512] = ""; #define ALL_CIPHERS "+3DES-CBC:+ARCFOUR-128:+ARCFOUR-40" @@ -116,1019 +112,978 @@ char prio_str[512] = ""; char rest[128] = "%UNSAFE_RENEGOTIATION:+SIGN-ALL:+CURVE-ALL"; static inline void -_gnutls_priority_set_direct (gnutls_session_t session, const char *str) +_gnutls_priority_set_direct(gnutls_session_t session, const char *str) { - const char *err; - int ret = gnutls_priority_set_direct (session, str, &err); - - if (ret < 0) - { - fprintf (stderr, "Error with string %s\n", str); - fprintf (stderr, "Error at %s: %s\n", err, gnutls_strerror (ret)); - exit (1); - } + const char *err; + int ret = gnutls_priority_set_direct(session, str, &err); + + if (ret < 0) { + fprintf(stderr, "Error with string %s\n", str); + fprintf(stderr, "Error at %s: %s\n", err, + gnutls_strerror(ret)); + exit(1); + } } -test_code_t -test_server (gnutls_session_t session) +test_code_t test_server(gnutls_session_t session) { - int ret, i = 0; - char buf[5 * 1024]; - char *p; - const char snd_buf[] = "GET / HTTP/1.0\n\n"; - - if (verbose == 0) - return TEST_UNSURE; - - buf[sizeof (buf) - 1] = 0; - - sprintf (prio_str, INIT_STR - ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS ":" - ALL_KX ":" "%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); - - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); - - ret = do_handshake (session); - if (ret != TEST_SUCCEED) - return TEST_FAILED; - - gnutls_record_send (session, snd_buf, sizeof (snd_buf) - 1); - ret = gnutls_record_recv (session, buf, sizeof (buf) - 1); - if (ret < 0) - return TEST_FAILED; - - p = strstr (buf, "Server:"); - if (p != NULL) - p = strchr (p, ':'); - if (p != NULL) - { - p++; - while (*p != 0 && *p != '\r' && *p != '\n') - { - putc (*p, stdout); - p++; - i++; - if (i > 128) - break; - } - } - - return TEST_SUCCEED; + int ret, i = 0; + char buf[5 * 1024]; + char *p; + const char snd_buf[] = "GET / HTTP/1.0\n\n"; + + if (verbose == 0) + return TEST_UNSURE; + + buf[sizeof(buf) - 1] = 0; + + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS + ":" ALL_KX ":" "%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = do_handshake(session); + if (ret != TEST_SUCCEED) + return TEST_FAILED; + + gnutls_record_send(session, snd_buf, sizeof(snd_buf) - 1); + ret = gnutls_record_recv(session, buf, sizeof(buf) - 1); + if (ret < 0) + return TEST_FAILED; + + p = strstr(buf, "Server:"); + if (p != NULL) + p = strchr(p, ':'); + if (p != NULL) { + p++; + while (*p != 0 && *p != '\r' && *p != '\n') { + putc(*p, stdout); + p++; + i++; + if (i > 128) + break; + } + } + + return TEST_SUCCEED; } static gnutls_datum_t pubkey = { NULL, 0 }; + static gnutls_ecc_curve_t curve = GNUTLS_ECC_CURVE_INVALID; -test_code_t -test_dhe (gnutls_session_t session) +test_code_t test_dhe(gnutls_session_t session) { - int ret; + int ret; - sprintf (prio_str, INIT_STR - ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":+DHE-RSA:+DHE-DSS:%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS + ":+DHE-RSA:+DHE-DSS:%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); + ret = do_handshake(session); - gnutls_dh_get_pubkey (session, &pubkey); + gnutls_dh_get_pubkey(session, &pubkey); - return ret; + return ret; } -test_code_t test_ecdhe (gnutls_session_t session) +test_code_t test_ecdhe(gnutls_session_t session) { - int ret; + int ret; - sprintf (prio_str, INIT_STR - ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":+ECDHE-RSA:+ECDHE-ECDSA:+CURVE-ALL:%s", protocol_all_str, rest); - _gnutls_priority_set_direct (session, prio_str); + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS + ":+ECDHE-RSA:+ECDHE-ECDSA:+CURVE-ALL:%s", protocol_all_str, + rest); + _gnutls_priority_set_direct(session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); + ret = do_handshake(session); - curve = gnutls_ecc_curve_get(session); + curve = gnutls_ecc_curve_get(session); - return ret; + return ret; } -test_code_t -test_safe_renegotiation (gnutls_session_t session) +test_code_t test_safe_renegotiation(gnutls_session_t session) { - int ret; + int ret; - sprintf (prio_str, INIT_STR - ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS ":" - ALL_KX ":%%SAFE_RENEGOTIATION", protocol_str); - _gnutls_priority_set_direct (session, prio_str); + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS + ":" ALL_KX ":%%SAFE_RENEGOTIATION", protocol_str); + _gnutls_priority_set_direct(session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); + ret = do_handshake(session); - return ret; + return ret; } -test_code_t -test_safe_renegotiation_scsv (gnutls_session_t session) +test_code_t test_safe_renegotiation_scsv(gnutls_session_t session) { - int ret; + int ret; - sprintf (prio_str, INIT_STR - ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":+VERS-SSL3.0:" - ALL_MACS ":" ALL_KX ":%%SAFE_RENEGOTIATION"); - _gnutls_priority_set_direct (session, prio_str); + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":+VERS-SSL3.0:" + ALL_MACS ":" ALL_KX ":%%SAFE_RENEGOTIATION"); + _gnutls_priority_set_direct(session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); + ret = do_handshake(session); - return ret; + return ret; } -test_code_t -test_dhe_group (gnutls_session_t session) +test_code_t test_dhe_group(gnutls_session_t session) { - int ret, ret2; - gnutls_datum_t gen, prime, pubkey2; - const char *print; - - if (verbose == 0 || pubkey.data == NULL) - return TEST_IGNORE; - - sprintf (prio_str, INIT_STR - ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":+DHE-RSA:+DHE-DSS:%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); - - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); - - ret = do_handshake (session); - - ret2 = gnutls_dh_get_group (session, &gen, &prime); - if (ret2 >= 0) - { - printf ("\n"); - - print = raw_to_string (gen.data, gen.size); - if (print) - printf (" Generator [%d bits]: %s\n", gen.size * 8, print); - - print = raw_to_string (prime.data, prime.size); - if (print) - printf (" Prime [%d bits]: %s\n", prime.size * 8, print); - - gnutls_dh_get_pubkey (session, &pubkey2); - print = raw_to_string (pubkey2.data, pubkey2.size); - if (print) - printf (" Pubkey [%d bits]: %s\n", pubkey2.size * 8, print); - - if (pubkey2.data && pubkey2.size == pubkey.size && - memcmp (pubkey.data, pubkey2.data, pubkey.size) == 0) - { - printf (" (public key seems to be static among sessions)\n"); - } - } - return ret; + int ret, ret2; + gnutls_datum_t gen, prime, pubkey2; + const char *print; + + if (verbose == 0 || pubkey.data == NULL) + return TEST_IGNORE; + + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS + ":+DHE-RSA:+DHE-DSS:%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = do_handshake(session); + + ret2 = gnutls_dh_get_group(session, &gen, &prime); + if (ret2 >= 0) { + printf("\n"); + + print = raw_to_string(gen.data, gen.size); + if (print) + printf(" Generator [%d bits]: %s\n", gen.size * 8, + print); + + print = raw_to_string(prime.data, prime.size); + if (print) + printf(" Prime [%d bits]: %s\n", prime.size * 8, + print); + + gnutls_dh_get_pubkey(session, &pubkey2); + print = raw_to_string(pubkey2.data, pubkey2.size); + if (print) + printf(" Pubkey [%d bits]: %s\n", pubkey2.size * 8, + print); + + if (pubkey2.data && pubkey2.size == pubkey.size && + memcmp(pubkey.data, pubkey2.data, pubkey.size) == 0) { + printf + (" (public key seems to be static among sessions)\n"); + } + } + return ret; } -test_code_t -test_ecdhe_curve (gnutls_session_t session) +test_code_t test_ecdhe_curve(gnutls_session_t session) { - if (curve == GNUTLS_ECC_CURVE_INVALID) - return TEST_IGNORE; + if (curve == GNUTLS_ECC_CURVE_INVALID) + return TEST_IGNORE; - printf ("\n Curve %s", gnutls_ecc_curve_get_name(curve)); + printf("\n Curve %s", gnutls_ecc_curve_get_name(curve)); - return TEST_SUCCEED; + return TEST_SUCCEED; } -test_code_t -test_ssl3 (gnutls_session_t session) +test_code_t test_ssl3(gnutls_session_t session) { - int ret; - sprintf (prio_str, INIT_STR - ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":+VERS-SSL3.0:" - ALL_MACS ":" ALL_KX ":%s", rest); - _gnutls_priority_set_direct (session, prio_str); + int ret; + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":+VERS-SSL3.0:" + ALL_MACS ":" ALL_KX ":%s", rest); + _gnutls_priority_set_direct(session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); - if (ret == TEST_SUCCEED) - ssl3_ok = 1; + ret = do_handshake(session); + if (ret == TEST_SUCCEED) + ssl3_ok = 1; - return ret; + return ret; } static int alrm = 0; -static void -got_alarm (int k) +static void got_alarm(int k) { - alrm = 1; + alrm = 1; } -test_code_t -test_bye (gnutls_session_t session) +test_code_t test_bye(gnutls_session_t session) { - int ret; - char data[20]; - int secs = 6; + int ret; + char data[20]; + int secs = 6; #ifndef _WIN32 - int old; + int old; - signal (SIGALRM, got_alarm); + signal(SIGALRM, got_alarm); #endif - sprintf (prio_str, INIT_STR - ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS ":" - ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS + ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); - if (ret == TEST_FAILED) - return ret; + ret = do_handshake(session); + if (ret == TEST_FAILED) + return ret; - ret = gnutls_bye (session, GNUTLS_SHUT_WR); - if (ret < 0) - return TEST_FAILED; + ret = gnutls_bye(session, GNUTLS_SHUT_WR); + if (ret < 0) + return TEST_FAILED; #ifndef _WIN32 - old = siginterrupt (SIGALRM, 1); - alarm (secs); + old = siginterrupt(SIGALRM, 1); + alarm(secs); #else - setsockopt ((int) gnutls_transport_get_ptr (session), SOL_SOCKET, - SO_RCVTIMEO, (char *) &secs, sizeof (int)); + setsockopt((int) gnutls_transport_get_ptr(session), SOL_SOCKET, + SO_RCVTIMEO, (char *) &secs, sizeof(int)); #endif - do - { - ret = gnutls_record_recv (session, data, sizeof (data)); - } - while (ret > 0); + do { + ret = gnutls_record_recv(session, data, sizeof(data)); + } + while (ret > 0); #ifndef _WIN32 - siginterrupt (SIGALRM, old); + siginterrupt(SIGALRM, old); #else - if (WSAGetLastError () == WSAETIMEDOUT || - WSAGetLastError () == WSAECONNABORTED) - alrm = 1; + if (WSAGetLastError() == WSAETIMEDOUT || + WSAGetLastError() == WSAECONNABORTED) + alrm = 1; #endif - if (ret == 0) - return TEST_SUCCEED; + if (ret == 0) + return TEST_SUCCEED; - if (alrm == 0) - return TEST_UNSURE; + if (alrm == 0) + return TEST_UNSURE; - return TEST_FAILED; + return TEST_FAILED; } -test_code_t -test_aes (gnutls_session_t session) +test_code_t test_aes(gnutls_session_t session) { - int ret; + int ret; - sprintf (prio_str, INIT_STR - "+AES-128-CBC:" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); + sprintf(prio_str, INIT_STR + "+AES-128-CBC:" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS + ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); - return ret; + ret = do_handshake(session); + return ret; } -test_code_t test_aes_gcm (gnutls_session_t session) +test_code_t test_aes_gcm(gnutls_session_t session) { - int ret; + int ret; - sprintf (prio_str, INIT_STR - "+AES-128-GCM:+AES-256-GCM:+AEAD:" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":" ALL_KX ":%s", protocol_all_str, rest); - _gnutls_priority_set_direct (session, prio_str); + sprintf(prio_str, INIT_STR + "+AES-128-GCM:+AES-256-GCM:+AEAD:" ALL_COMP ":" + ALL_CERTTYPES ":%s:" ALL_MACS ":" ALL_KX ":%s", + protocol_all_str, rest); + _gnutls_priority_set_direct(session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); - return ret; + ret = do_handshake(session); + return ret; } -test_code_t -test_camellia (gnutls_session_t session) +test_code_t test_camellia(gnutls_session_t session) { - int ret; + int ret; - sprintf (prio_str, - INIT_STR "+CAMELLIA-128-CBC:" ALL_COMP ":" ALL_CERTTYPES ":%s:" - ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); + sprintf(prio_str, + INIT_STR "+CAMELLIA-128-CBC:" ALL_COMP ":" ALL_CERTTYPES + ":%s:" ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); - return ret; + ret = do_handshake(session); + return ret; } -test_code_t -test_openpgp1 (gnutls_session_t session) +test_code_t test_openpgp1(gnutls_session_t session) { - int ret; + int ret; - sprintf (prio_str, - INIT_STR ALL_CIPHERS ":" ALL_COMP ":+CTYPE-OPENPGP:%s:" ALL_MACS - ":" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":+CTYPE-OPENPGP:%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); - if (ret == TEST_FAILED) - return ret; + ret = do_handshake(session); + if (ret == TEST_FAILED) + return ret; - if (gnutls_certificate_type_get (session) == GNUTLS_CRT_OPENPGP) - return TEST_SUCCEED; + if (gnutls_certificate_type_get(session) == GNUTLS_CRT_OPENPGP) + return TEST_SUCCEED; - return TEST_FAILED; + return TEST_FAILED; } -test_code_t -test_unknown_ciphersuites (gnutls_session_t session) +test_code_t test_unknown_ciphersuites(gnutls_session_t session) { - int ret; + int ret; - sprintf (prio_str, - INIT_STR "+AES-128-CBC:" ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES - ":%s:" ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); + sprintf(prio_str, + INIT_STR "+AES-128-CBC:" ALL_CIPHERS ":" ALL_COMP ":" + ALL_CERTTYPES ":%s:" ALL_MACS ":" ALL_KX ":%s", + protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); - return ret; + ret = do_handshake(session); + return ret; } -test_code_t -test_md5 (gnutls_session_t session) +test_code_t test_md5(gnutls_session_t session) { - int ret; + int ret; - sprintf (prio_str, - INIT_STR "+AES-128-CBC:" ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES - ":%s:+MD5:" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); + sprintf(prio_str, + INIT_STR "+AES-128-CBC:" ALL_CIPHERS ":" ALL_COMP ":" + ALL_CERTTYPES ":%s:+MD5:" ALL_KX ":%s", protocol_str, + rest); + _gnutls_priority_set_direct(session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); - return ret; + ret = do_handshake(session); + return ret; } #ifdef HAVE_LIBZ -test_code_t -test_zlib (gnutls_session_t session) +test_code_t test_zlib(gnutls_session_t session) { - int ret; + int ret; - sprintf (prio_str, - INIT_STR ALL_CIPHERS ":+COMP-DEFLATE:" ALL_CERTTYPES ":%s:" ALL_MACS - ":" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":+COMP-DEFLATE:" ALL_CERTTYPES ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); - return ret; + ret = do_handshake(session); + return ret; } #endif -test_code_t -test_sha (gnutls_session_t session) +test_code_t test_sha(gnutls_session_t session) { - int ret; + int ret; - sprintf (prio_str, - INIT_STR "+AES-128-CBC:" ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES - ":%s:+SHA1:" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + sprintf(prio_str, + INIT_STR "+AES-128-CBC:" ALL_CIPHERS ":" ALL_COMP ":" + ALL_CERTTYPES ":%s:+SHA1:" ALL_KX ":%s", protocol_str, + rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); - return ret; + ret = do_handshake(session); + return ret; } -test_code_t -test_sha256 (gnutls_session_t session) +test_code_t test_sha256(gnutls_session_t session) { - int ret; + int ret; - sprintf (prio_str, - INIT_STR "+AES-128-CBC:" ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES - ":%s:+SHA256:" ALL_KX ":%s", protocol_all_str, rest); - _gnutls_priority_set_direct (session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + sprintf(prio_str, + INIT_STR "+AES-128-CBC:" ALL_CIPHERS ":" ALL_COMP ":" + ALL_CERTTYPES ":%s:+SHA256:" ALL_KX ":%s", + protocol_all_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); - return ret; + ret = do_handshake(session); + return ret; } -test_code_t -test_3des (gnutls_session_t session) +test_code_t test_3des(gnutls_session_t session) { - int ret; + int ret; - sprintf (prio_str, - INIT_STR "+3DES-CBC:" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + sprintf(prio_str, + INIT_STR "+3DES-CBC:" ALL_COMP ":" ALL_CERTTYPES ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); - return ret; + ret = do_handshake(session); + return ret; } -test_code_t -test_arcfour (gnutls_session_t session) +test_code_t test_arcfour(gnutls_session_t session) { - int ret; + int ret; - sprintf (prio_str, - INIT_STR "+ARCFOUR-128:" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + sprintf(prio_str, + INIT_STR "+ARCFOUR-128:" ALL_COMP ":" ALL_CERTTYPES ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); - return ret; + ret = do_handshake(session); + return ret; } -test_code_t -test_tls1 (gnutls_session_t session) +test_code_t test_tls1(gnutls_session_t session) { - int ret; + int ret; - sprintf (prio_str, - INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES - ":+VERS-TLS1.0:" ALL_MACS ":" ALL_KX ":%s", rest); - _gnutls_priority_set_direct (session, prio_str); + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES + ":+VERS-TLS1.0:" ALL_MACS ":" ALL_KX ":%s", rest); + _gnutls_priority_set_direct(session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); - if (ret == TEST_SUCCEED) - tls1_ok = 1; + ret = do_handshake(session); + if (ret == TEST_SUCCEED) + tls1_ok = 1; - return ret; + return ret; } -test_code_t -test_record_padding (gnutls_session_t session) +test_code_t test_record_padding(gnutls_session_t session) { - int ret; - - sprintf (prio_str, - INIT_STR BLOCK_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES - ":+VERS-TLS1.0:" ALL_MACS ":" ALL_KX ":%s", rest); - _gnutls_priority_set_direct (session, prio_str); - - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); - if (ret == TEST_SUCCEED) - { - tls1_ok = 1; - } - else - { - strcat (rest, ":%COMPAT"); - } - - return ret; + int ret; + + sprintf(prio_str, + INIT_STR BLOCK_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES + ":+VERS-TLS1.0:" ALL_MACS ":" ALL_KX ":%s", rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + ret = do_handshake(session); + if (ret == TEST_SUCCEED) { + tls1_ok = 1; + } else { + strcat(rest, ":%COMPAT"); + } + + return ret; } -test_code_t -test_tls1_2 (gnutls_session_t session) +test_code_t test_tls1_2(gnutls_session_t session) { - int ret; + int ret; - sprintf (prio_str, - INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES - ":+VERS-TLS1.2:" ALL_MACS ":" ALL_KX ":%s", rest); - _gnutls_priority_set_direct (session, prio_str); + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES + ":+VERS-TLS1.2:" ALL_MACS ":" ALL_KX ":%s", rest); + _gnutls_priority_set_direct(session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); - if (ret == TEST_SUCCEED) - tls1_2_ok = 1; + ret = do_handshake(session); + if (ret == TEST_SUCCEED) + tls1_2_ok = 1; - return ret; + return ret; } -test_code_t -test_tls1_1 (gnutls_session_t session) +test_code_t test_tls1_1(gnutls_session_t session) { - int ret; + int ret; - sprintf (prio_str, - INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES - ":+VERS-TLS1.1:" ALL_MACS ":" ALL_KX ":%s", rest); - _gnutls_priority_set_direct (session, prio_str); + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES + ":+VERS-TLS1.1:" ALL_MACS ":" ALL_KX ":%s", rest); + _gnutls_priority_set_direct(session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); - if (ret == TEST_SUCCEED) - tls1_1_ok = 1; + ret = do_handshake(session); + if (ret == TEST_SUCCEED) + tls1_1_ok = 1; - return ret; + return ret; } -test_code_t -test_tls1_1_fallback (gnutls_session_t session) +test_code_t test_tls1_1_fallback(gnutls_session_t session) { - int ret; - if (tls1_1_ok) - return TEST_IGNORE; + int ret; + if (tls1_1_ok) + return TEST_IGNORE; - sprintf (prio_str, - INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES - ":+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0:" ALL_MACS ":" ALL_KX - ":%s", rest); - _gnutls_priority_set_direct (session, prio_str); + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES + ":+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0:" ALL_MACS ":" + ALL_KX ":%s", rest); + _gnutls_priority_set_direct(session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); - if (ret != TEST_SUCCEED) - return TEST_FAILED; + ret = do_handshake(session); + if (ret != TEST_SUCCEED) + return TEST_FAILED; - if (gnutls_protocol_get_version (session) == GNUTLS_TLS1) - return TEST_SUCCEED; - else if (gnutls_protocol_get_version (session) == GNUTLS_SSL3) - return TEST_UNSURE; + if (gnutls_protocol_get_version(session) == GNUTLS_TLS1) + return TEST_SUCCEED; + else if (gnutls_protocol_get_version(session) == GNUTLS_SSL3) + return TEST_UNSURE; - return TEST_FAILED; + return TEST_FAILED; } /* Advertize both TLS 1.0 and SSL 3.0. If the connection fails, * but the previous SSL 3.0 test succeeded then disable TLS 1.0. */ -test_code_t -test_tls_disable0 (gnutls_session_t session) +test_code_t test_tls_disable0(gnutls_session_t session) { - int ret; - if (tls1_ok != 0) - return TEST_IGNORE; - - sprintf (prio_str, - INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); - - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); - - ret = do_handshake (session); - if (ret == TEST_FAILED) - { - /* disable TLS 1.0 */ - if (ssl3_ok != 0) - { - strcpy (protocol_str, "+VERS-SSL3.0"); - } - } - return ret; + int ret; + if (tls1_ok != 0) + return TEST_IGNORE; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = do_handshake(session); + if (ret == TEST_FAILED) { + /* disable TLS 1.0 */ + if (ssl3_ok != 0) { + strcpy(protocol_str, "+VERS-SSL3.0"); + } + } + return ret; } -test_code_t -test_tls_disable1 (gnutls_session_t session) +test_code_t test_tls_disable1(gnutls_session_t session) { - int ret; - - if (tls1_1_ok != 0) - return TEST_IGNORE; - - sprintf (prio_str, - INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); - - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); - - ret = do_handshake (session); - if (ret == TEST_FAILED) - { - protocol_str[0] = 0; - /* disable TLS 1.1 */ - if (tls1_ok != 0) - { - strcat (protocol_str, "+VERS-TLS1.0"); - } - if (ssl3_ok != 0) - { - if (protocol_str[0] != 0) - strcat (protocol_str, ":+VERS-SSL3.0"); - else - strcat (protocol_str, "+VERS-SSL3.0"); - } - } - return ret; + int ret; + + if (tls1_1_ok != 0) + return TEST_IGNORE; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = do_handshake(session); + if (ret == TEST_FAILED) { + protocol_str[0] = 0; + /* disable TLS 1.1 */ + if (tls1_ok != 0) { + strcat(protocol_str, "+VERS-TLS1.0"); + } + if (ssl3_ok != 0) { + if (protocol_str[0] != 0) + strcat(protocol_str, ":+VERS-SSL3.0"); + else + strcat(protocol_str, "+VERS-SSL3.0"); + } + } + return ret; } -test_code_t -test_tls_disable2 (gnutls_session_t session) +test_code_t test_tls_disable2(gnutls_session_t session) { - int ret; - - if (tls1_2_ok != 0) - return TEST_IGNORE; - - sprintf (prio_str, - INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); - - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); - - ret = do_handshake (session); - if (ret == TEST_FAILED) - { - /* disable TLS 1.2 */ - protocol_str[0] = 0; - if (tls1_1_ok != 0) - { - strcat (protocol_str, "+VERS-TLS1.1"); - } - if (tls1_ok != 0) - { - if (protocol_str[0] != 0) - strcat (protocol_str, ":+VERS-TLS1.0"); - else - strcat (protocol_str, "+VERS-TLS1.0"); - } - if (ssl3_ok != 0) - { - if (protocol_str[0] != 0) - strcat (protocol_str, ":+VERS-SSL3.0"); - else - strcat (protocol_str, "+VERS-SSL3.0"); - } - } - return ret; + int ret; + + if (tls1_2_ok != 0) + return TEST_IGNORE; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = do_handshake(session); + if (ret == TEST_FAILED) { + /* disable TLS 1.2 */ + protocol_str[0] = 0; + if (tls1_1_ok != 0) { + strcat(protocol_str, "+VERS-TLS1.1"); + } + if (tls1_ok != 0) { + if (protocol_str[0] != 0) + strcat(protocol_str, ":+VERS-TLS1.0"); + else + strcat(protocol_str, "+VERS-TLS1.0"); + } + if (ssl3_ok != 0) { + if (protocol_str[0] != 0) + strcat(protocol_str, ":+VERS-SSL3.0"); + else + strcat(protocol_str, "+VERS-SSL3.0"); + } + } + return ret; } -test_code_t -test_rsa_pms (gnutls_session_t session) +test_code_t test_rsa_pms(gnutls_session_t session) { - int ret; - - /* here we enable both SSL 3.0 and TLS 1.0 - * and try to connect and use rsa authentication. - * If the server is old, buggy and only supports - * SSL 3.0 then the handshake will fail. - */ - sprintf (prio_str, - INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":+RSA:%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); - - ret = do_handshake (session); - if (ret == TEST_FAILED) - return TEST_FAILED; - - if (gnutls_protocol_get_version (session) == GNUTLS_TLS1) - return TEST_SUCCEED; - return TEST_UNSURE; + int ret; + + /* here we enable both SSL 3.0 and TLS 1.0 + * and try to connect and use rsa authentication. + * If the server is old, buggy and only supports + * SSL 3.0 then the handshake will fail. + */ + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" + ALL_MACS ":+RSA:%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = do_handshake(session); + if (ret == TEST_FAILED) + return TEST_FAILED; + + if (gnutls_protocol_get_version(session) == GNUTLS_TLS1) + return TEST_SUCCEED; + return TEST_UNSURE; } -test_code_t -test_max_record_size (gnutls_session_t session) +test_code_t test_max_record_size(gnutls_session_t session) { - int ret; - sprintf (prio_str, - INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); - gnutls_record_set_max_size (session, 512); - - ret = do_handshake (session); - if (ret == TEST_FAILED) - return ret; - - ret = gnutls_record_get_max_size (session); - if (ret == 512) - return TEST_SUCCEED; - - return TEST_FAILED; + int ret; + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_record_set_max_size(session, 512); + + ret = do_handshake(session); + if (ret == TEST_FAILED) + return ret; + + ret = gnutls_record_get_max_size(session); + if (ret == 512) + return TEST_SUCCEED; + + return TEST_FAILED; } -test_code_t -test_hello_extension (gnutls_session_t session) +test_code_t test_hello_extension(gnutls_session_t session) { - int ret; + int ret; - sprintf (prio_str, - INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); - gnutls_record_set_max_size (session, 4096); + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_record_set_max_size(session, 4096); - ret = do_handshake (session); + ret = do_handshake(session); - return ret; + return ret; } -test_code_t -test_heartbeat_extension (gnutls_session_t session) +test_code_t test_heartbeat_extension(gnutls_session_t session) { - sprintf (prio_str, - INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); - gnutls_record_set_max_size (session, 4096); - - gnutls_heartbeat_enable (session, GNUTLS_HB_PEER_ALLOWED_TO_SEND); - do_handshake (session); - - switch (gnutls_heartbeat_allowed (session, 1)) { - case 1: return TEST_SUCCEED; - case 0: return TEST_FAILED; - default: return TEST_UNSURE; - } + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_record_set_max_size(session, 4096); + + gnutls_heartbeat_enable(session, GNUTLS_HB_PEER_ALLOWED_TO_SEND); + do_handshake(session); + + switch (gnutls_heartbeat_allowed(session, 1)) { + case 1: + return TEST_SUCCEED; + case 0: + return TEST_FAILED; + default: + return TEST_UNSURE; + } } -test_code_t -test_small_records (gnutls_session_t session) +test_code_t test_small_records(gnutls_session_t session) { - int ret; + int ret; - sprintf (prio_str, - INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); - gnutls_record_set_max_size (session, 512); + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_record_set_max_size(session, 512); - ret = do_handshake (session); - return ret; + ret = do_handshake(session); + return ret; } -void _gnutls_record_set_default_version (gnutls_session_t session, - unsigned char major, - unsigned char minor); +void _gnutls_record_set_default_version(gnutls_session_t session, + unsigned char major, + unsigned char minor); -test_code_t -test_version_rollback (gnutls_session_t session) +test_code_t test_version_rollback(gnutls_session_t session) { - int ret; - if (tls1_ok == 0) - return TEST_IGNORE; - - /* here we enable both SSL 3.0 and TLS 1.0 - * and we connect using a 3.1 client hello version, - * and a 3.0 record version. Some implementations - * are buggy (and vulnerable to man in the middle - * attacks which allow a version downgrade) and this - * connection will fail. - */ - sprintf (prio_str, - INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); - _gnutls_record_set_default_version (session, 3, 0); - - ret = do_handshake (session); - if (ret != TEST_SUCCEED) - return ret; - - if (tls1_ok != 0 && gnutls_protocol_get_version (session) == GNUTLS_SSL3) - return TEST_FAILED; - - return TEST_SUCCEED; + int ret; + if (tls1_ok == 0) + return TEST_IGNORE; + + /* here we enable both SSL 3.0 and TLS 1.0 + * and we connect using a 3.1 client hello version, + * and a 3.0 record version. Some implementations + * are buggy (and vulnerable to man in the middle + * attacks which allow a version downgrade) and this + * connection will fail. + */ + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + _gnutls_record_set_default_version(session, 3, 0); + + ret = do_handshake(session); + if (ret != TEST_SUCCEED) + return ret; + + if (tls1_ok != 0 + && gnutls_protocol_get_version(session) == GNUTLS_SSL3) + return TEST_FAILED; + + return TEST_SUCCEED; } /* See if the server tolerates out of bounds * record layer versions in the first client hello * message. */ -test_code_t -test_version_oob (gnutls_session_t session) +test_code_t test_version_oob(gnutls_session_t session) { - int ret; - /* here we enable both SSL 3.0 and TLS 1.0 - * and we connect using a 5.5 record version. - */ - sprintf (prio_str, - INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); - _gnutls_record_set_default_version (session, 5, 5); - - ret = do_handshake (session); - return ret; + int ret; + /* here we enable both SSL 3.0 and TLS 1.0 + * and we connect using a 5.5 record version. + */ + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + _gnutls_record_set_default_version(session, 5, 5); + + ret = do_handshake(session); + return ret; } -void _gnutls_rsa_pms_set_version (gnutls_session_t session, - unsigned char major, unsigned char minor); +void _gnutls_rsa_pms_set_version(gnutls_session_t session, + unsigned char major, unsigned char minor); -test_code_t -test_rsa_pms_version_check (gnutls_session_t session) +test_code_t test_rsa_pms_version_check(gnutls_session_t session) { - int ret; - /* here we use an arbitary version in the RSA PMS - * to see whether to server will check this version. - * - * A normal server would abort this handshake. - */ - sprintf (prio_str, - INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); - _gnutls_rsa_pms_set_version (session, 5, 5); /* use SSL 5.5 version */ - - ret = do_handshake (session); - return ret; + int ret; + /* here we use an arbitary version in the RSA PMS + * to see whether to server will check this version. + * + * A normal server would abort this handshake. + */ + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + _gnutls_rsa_pms_set_version(session, 5, 5); /* use SSL 5.5 version */ + + ret = do_handshake(session); + return ret; } #ifdef ENABLE_ANON -test_code_t -test_anonymous (gnutls_session_t session) +test_code_t test_anonymous(gnutls_session_t session) { - int ret; + int ret; - sprintf (prio_str, - INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":+ANON-DH:+ANON-ECDH:+CURVE-ALL:%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_ANON, anon_cred); + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" + ALL_MACS ":+ANON-DH:+ANON-ECDH:+CURVE-ALL:%s", + protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_ANON, anon_cred); - ret = do_handshake (session); + ret = do_handshake(session); - if (ret == TEST_SUCCEED) - gnutls_dh_get_pubkey (session, &pubkey); + if (ret == TEST_SUCCEED) + gnutls_dh_get_pubkey(session, &pubkey); - return ret; + return ret; } #endif -test_code_t -test_session_resume2 (gnutls_session_t session) +test_code_t test_session_resume2(gnutls_session_t session) { - int ret; - char tmp_session_id[32]; - size_t tmp_session_id_size; + int ret; + char tmp_session_id[32]; + size_t tmp_session_id_size; - if (session == NULL) - return TEST_IGNORE; + if (session == NULL) + return TEST_IGNORE; - sprintf (prio_str, - INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); - gnutls_credentials_set (session, GNUTLS_CRD_ANON, anon_cred); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_credentials_set(session, GNUTLS_CRD_ANON, anon_cred); - gnutls_session_set_data (session, session_data, session_data_size); + gnutls_session_set_data(session, session_data, session_data_size); - memcpy (tmp_session_id, session_id, session_id_size); - tmp_session_id_size = session_id_size; + memcpy(tmp_session_id, session_id, session_id_size); + tmp_session_id_size = session_id_size; - ret = do_handshake (session); - if (ret == TEST_FAILED) - return ret; + ret = do_handshake(session); + if (ret == TEST_FAILED) + return ret; - /* check if we actually resumed the previous session */ + /* check if we actually resumed the previous session */ - session_id_size = sizeof (session_id); - gnutls_session_get_id (session, session_id, &session_id_size); + session_id_size = sizeof(session_id); + gnutls_session_get_id(session, session_id, &session_id_size); - if (session_id_size == 0) - return TEST_FAILED; + if (session_id_size == 0) + return TEST_FAILED; - if (gnutls_session_is_resumed (session)) - return TEST_SUCCEED; + if (gnutls_session_is_resumed(session)) + return TEST_SUCCEED; - if (tmp_session_id_size == session_id_size && - memcmp (tmp_session_id, session_id, tmp_session_id_size) == 0) - return TEST_SUCCEED; - else - return TEST_FAILED; + if (tmp_session_id_size == session_id_size && + memcmp(tmp_session_id, session_id, tmp_session_id_size) == 0) + return TEST_SUCCEED; + else + return TEST_FAILED; } extern char *hostname; -test_code_t -test_certificate (gnutls_session_t session) +test_code_t test_certificate(gnutls_session_t session) { - int ret; + int ret; - if (verbose == 0) - return TEST_IGNORE; + if (verbose == 0) + return TEST_IGNORE; - sprintf (prio_str, - INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - ret = do_handshake (session); - if (ret == TEST_FAILED) - return ret; + ret = do_handshake(session); + if (ret == TEST_FAILED) + return ret; - printf ("\n"); - print_cert_info (session, GNUTLS_CRT_PRINT_FULL, verbose); + printf("\n"); + print_cert_info(session, GNUTLS_CRT_PRINT_FULL, verbose); - return TEST_SUCCEED; + return TEST_SUCCEED; } /* A callback function to be used at the certificate selection time. */ static int -cert_callback (gnutls_session_t session, - const gnutls_datum_t * req_ca_rdn, int nreqs, - const gnutls_pk_algorithm_t * sign_algos, - int sign_algos_length, gnutls_retr2_st * st) +cert_callback(gnutls_session_t session, + const gnutls_datum_t * req_ca_rdn, int nreqs, + const gnutls_pk_algorithm_t * sign_algos, + int sign_algos_length, gnutls_retr2_st * st) { - char issuer_dn[256]; - int i, ret; - size_t len; - - if (verbose == 0) - return -1; - - /* Print the server's trusted CAs - */ - printf ("\n"); - if (nreqs > 0) - printf ("- Server's trusted authorities:\n"); - else - printf ("- Server did not send us any trusted authorities names.\n"); - - /* print the names (if any) */ - for (i = 0; i < nreqs; i++) - { - len = sizeof (issuer_dn); - ret = gnutls_x509_rdn_get (&req_ca_rdn[i], issuer_dn, &len); - if (ret >= 0) - { - printf (" [%d]: ", i); - printf ("%s\n", issuer_dn); - } - } - - return -1; + char issuer_dn[256]; + int i, ret; + size_t len; + + if (verbose == 0) + return -1; + + /* Print the server's trusted CAs + */ + printf("\n"); + if (nreqs > 0) + printf("- Server's trusted authorities:\n"); + else + printf + ("- Server did not send us any trusted authorities names.\n"); + + /* print the names (if any) */ + for (i = 0; i < nreqs; i++) { + len = sizeof(issuer_dn); + ret = gnutls_x509_rdn_get(&req_ca_rdn[i], issuer_dn, &len); + if (ret >= 0) { + printf(" [%d]: ", i); + printf("%s\n", issuer_dn); + } + } + + return -1; } /* Prints the trusted server's CAs. This is only * if the server sends a certificate request packet. */ -test_code_t -test_server_cas (gnutls_session_t session) +test_code_t test_server_cas(gnutls_session_t session) { - int ret; + int ret; - if (verbose == 0) - return TEST_IGNORE; + if (verbose == 0) + return TEST_IGNORE; - sprintf (prio_str, - INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS - ":" ALL_KX ":%s", protocol_str, rest); - _gnutls_priority_set_direct (session, prio_str); + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); - gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); - gnutls_certificate_set_retrieve_function (xcred, cert_callback); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_certificate_set_retrieve_function(xcred, cert_callback); - ret = do_handshake (session); - gnutls_certificate_set_retrieve_function (xcred, NULL); + ret = do_handshake(session); + gnutls_certificate_set_retrieve_function(xcred, NULL); - if (ret == TEST_FAILED) - return ret; - return TEST_SUCCEED; + if (ret == TEST_FAILED) + return ret; + return TEST_SUCCEED; } diff --git a/src/tests.h b/src/tests.h index 6119a24d8f..9f0e348f50 100644 --- a/src/tests.h +++ b/src/tests.h @@ -18,51 +18,50 @@ * <http://www.gnu.org/licenses/>. */ -typedef enum -{ - TEST_SUCCEED, TEST_FAILED, TEST_UNSURE, TEST_IGNORE +typedef enum { + TEST_SUCCEED, TEST_FAILED, TEST_UNSURE, TEST_IGNORE } test_code_t; -test_code_t test_server (gnutls_session_t state); -test_code_t test_record_padding (gnutls_session_t state); -test_code_t test_hello_extension (gnutls_session_t state); -test_code_t test_heartbeat_extension (gnutls_session_t state); -test_code_t test_small_records (gnutls_session_t state); -test_code_t test_dhe (gnutls_session_t state); -test_code_t test_dhe_group (gnutls_session_t state); -test_code_t test_ssl3 (gnutls_session_t state); -test_code_t test_aes (gnutls_session_t state); -test_code_t test_camellia (gnutls_session_t state); -test_code_t test_md5 (gnutls_session_t state); -test_code_t test_sha (gnutls_session_t state); -test_code_t test_3des (gnutls_session_t state); -test_code_t test_arcfour (gnutls_session_t state); -test_code_t test_tls1 (gnutls_session_t state); -test_code_t test_safe_renegotiation (gnutls_session_t state); -test_code_t test_safe_renegotiation_scsv (gnutls_session_t state); -test_code_t test_tls1_1 (gnutls_session_t state); -test_code_t test_tls1_2 (gnutls_session_t state); -test_code_t test_tls1_1_fallback (gnutls_session_t state); -test_code_t test_tls_disable0 (gnutls_session_t state); -test_code_t test_tls_disable1 (gnutls_session_t state); -test_code_t test_tls_disable2 (gnutls_session_t state); -test_code_t test_rsa_pms (gnutls_session_t state); -test_code_t test_max_record_size (gnutls_session_t state); -test_code_t test_version_rollback (gnutls_session_t state); -test_code_t test_anonymous (gnutls_session_t state); -test_code_t test_unknown_ciphersuites (gnutls_session_t state); -test_code_t test_openpgp1 (gnutls_session_t state); -test_code_t test_bye (gnutls_session_t state); -test_code_t test_certificate (gnutls_session_t state); -test_code_t test_server_cas (gnutls_session_t state); -test_code_t test_session_resume2 (gnutls_session_t state); -test_code_t test_rsa_pms_version_check (gnutls_session_t session); -test_code_t test_version_oob (gnutls_session_t session); -test_code_t test_zlib (gnutls_session_t session); -int _test_srp_username_callback (gnutls_session_t session, - char **username, char **password); +test_code_t test_server(gnutls_session_t state); +test_code_t test_record_padding(gnutls_session_t state); +test_code_t test_hello_extension(gnutls_session_t state); +test_code_t test_heartbeat_extension(gnutls_session_t state); +test_code_t test_small_records(gnutls_session_t state); +test_code_t test_dhe(gnutls_session_t state); +test_code_t test_dhe_group(gnutls_session_t state); +test_code_t test_ssl3(gnutls_session_t state); +test_code_t test_aes(gnutls_session_t state); +test_code_t test_camellia(gnutls_session_t state); +test_code_t test_md5(gnutls_session_t state); +test_code_t test_sha(gnutls_session_t state); +test_code_t test_3des(gnutls_session_t state); +test_code_t test_arcfour(gnutls_session_t state); +test_code_t test_tls1(gnutls_session_t state); +test_code_t test_safe_renegotiation(gnutls_session_t state); +test_code_t test_safe_renegotiation_scsv(gnutls_session_t state); +test_code_t test_tls1_1(gnutls_session_t state); +test_code_t test_tls1_2(gnutls_session_t state); +test_code_t test_tls1_1_fallback(gnutls_session_t state); +test_code_t test_tls_disable0(gnutls_session_t state); +test_code_t test_tls_disable1(gnutls_session_t state); +test_code_t test_tls_disable2(gnutls_session_t state); +test_code_t test_rsa_pms(gnutls_session_t state); +test_code_t test_max_record_size(gnutls_session_t state); +test_code_t test_version_rollback(gnutls_session_t state); +test_code_t test_anonymous(gnutls_session_t state); +test_code_t test_unknown_ciphersuites(gnutls_session_t state); +test_code_t test_openpgp1(gnutls_session_t state); +test_code_t test_bye(gnutls_session_t state); +test_code_t test_certificate(gnutls_session_t state); +test_code_t test_server_cas(gnutls_session_t state); +test_code_t test_session_resume2(gnutls_session_t state); +test_code_t test_rsa_pms_version_check(gnutls_session_t session); +test_code_t test_version_oob(gnutls_session_t session); +test_code_t test_zlib(gnutls_session_t session); +int _test_srp_username_callback(gnutls_session_t session, + char **username, char **password); -test_code_t test_ecdhe_curve (gnutls_session_t session); -test_code_t test_ecdhe (gnutls_session_t session); -test_code_t test_aes_gcm (gnutls_session_t session); -test_code_t test_sha256 (gnutls_session_t session); +test_code_t test_ecdhe_curve(gnutls_session_t session); +test_code_t test_ecdhe(gnutls_session_t session); +test_code_t test_aes_gcm(gnutls_session_t session); +test_code_t test_sha256(gnutls_session_t session); diff --git a/src/tpmtool.c b/src/tpmtool.c index 9b2168e349..0ce6bfb4b4 100644 --- a/src/tpmtool.c +++ b/src/tpmtool.c @@ -46,11 +46,12 @@ #include "certtool-common.h" #include "tpmtool-args.h" -static void cmd_parser (int argc, char **argv); -static void tpm_generate(FILE* outfile, unsigned int key_type, unsigned int bits, unsigned int flags); -static void tpm_pubkey(const char* url, FILE* outfile); -static void tpm_delete(const char* url, FILE* outfile); -static void tpm_list(FILE* outfile); +static void cmd_parser(int argc, char **argv); +static void tpm_generate(FILE * outfile, unsigned int key_type, + unsigned int bits, unsigned int flags); +static void tpm_pubkey(const char *url, FILE * outfile); +static void tpm_delete(const char *url, FILE * outfile); +static void tpm_list(FILE * outfile); static gnutls_x509_crt_fmt_t incert_format, outcert_format; static gnutls_tpmkey_fmt_t inkey_format, outkey_format; @@ -59,252 +60,226 @@ static FILE *outfile; static FILE *infile; int batch = 0; -static void -tls_log_func (int level, const char *str) +static void tls_log_func(int level, const char *str) { - fprintf (stderr, "|<%d>| %s", level, str); + fprintf(stderr, "|<%d>| %s", level, str); } -int -main (int argc, char **argv) +int main(int argc, char **argv) { - cmd_parser (argc, argv); + cmd_parser(argc, argv); - return 0; + return 0; } -static void -cmd_parser (int argc, char **argv) +static void cmd_parser(int argc, char **argv) { - int ret, debug = 0; - unsigned int optct; - unsigned int key_type = GNUTLS_PK_UNKNOWN; - unsigned int bits = 0; - unsigned int genflags = 0; - /* Note that the default sec-param is legacy because several TPMs - * cannot handle larger keys. - */ - const char* sec_param = "legacy"; - - optct = optionProcess( &tpmtoolOptions, argc, argv); - argc += optct; - argv += optct; - - if (HAVE_OPT(DEBUG)) - debug = OPT_VALUE_DEBUG; - - if (HAVE_OPT(INDER)) - { - incert_format = GNUTLS_X509_FMT_DER; - inkey_format = GNUTLS_TPMKEY_FMT_DER; - } - else - { - incert_format = GNUTLS_X509_FMT_PEM; - inkey_format = GNUTLS_TPMKEY_FMT_CTK_PEM; - } - - if (HAVE_OPT(OUTDER)) - { - outcert_format = GNUTLS_X509_FMT_DER; - outkey_format = GNUTLS_TPMKEY_FMT_DER; - } - else - { - outcert_format = GNUTLS_X509_FMT_PEM; - outkey_format = GNUTLS_TPMKEY_FMT_CTK_PEM; - } - - if (HAVE_OPT(REGISTER)) - genflags |= GNUTLS_TPM_REGISTER_KEY; - if (!HAVE_OPT(LEGACY)) - genflags |= GNUTLS_TPM_KEY_SIGNING; - if (HAVE_OPT(USER)) - genflags |= GNUTLS_TPM_KEY_USER; - - gnutls_global_set_log_function (tls_log_func); - gnutls_global_set_log_level (debug); - if (debug > 1) - printf ("Setting log level to %d\n", debug); - - if ((ret = gnutls_global_init ()) < 0) - { - fprintf (stderr, "global_init: %s", gnutls_strerror (ret)); - exit(1); - } - - if (HAVE_OPT(OUTFILE)) - { - outfile = safe_open_rw (OPT_ARG(OUTFILE), 0); - if (outfile == NULL) - { - fprintf (stderr, "%s", OPT_ARG(OUTFILE)); - exit(1); - } - } - else - outfile = stdout; - - if (HAVE_OPT(INFILE)) - { - infile = fopen (OPT_ARG(INFILE), "rb"); - if (infile == NULL) - { - fprintf (stderr, "%s", OPT_ARG(INFILE)); - exit(1); - } - } - else - infile = stdin; - - if (HAVE_OPT(SEC_PARAM)) - sec_param = OPT_ARG(SEC_PARAM); - if (HAVE_OPT(BITS)) - bits = OPT_VALUE_BITS; - - - if (HAVE_OPT(GENERATE_RSA)) - { - key_type = GNUTLS_PK_RSA; - bits = get_bits (key_type, bits, sec_param, 0); - tpm_generate (outfile, key_type, bits, genflags); - } - else if (HAVE_OPT(PUBKEY)) - { - tpm_pubkey (OPT_ARG(PUBKEY), outfile); - } - else if (HAVE_OPT(DELETE)) - { - tpm_delete (OPT_ARG(DELETE), outfile); - } - else if (HAVE_OPT(LIST)) - { - tpm_list (outfile); - } - else - { - USAGE(1); - } - - fclose (outfile); - - gnutls_global_deinit (); + int ret, debug = 0; + unsigned int optct; + unsigned int key_type = GNUTLS_PK_UNKNOWN; + unsigned int bits = 0; + unsigned int genflags = 0; + /* Note that the default sec-param is legacy because several TPMs + * cannot handle larger keys. + */ + const char *sec_param = "legacy"; + + optct = optionProcess(&tpmtoolOptions, argc, argv); + argc += optct; + argv += optct; + + if (HAVE_OPT(DEBUG)) + debug = OPT_VALUE_DEBUG; + + if (HAVE_OPT(INDER)) { + incert_format = GNUTLS_X509_FMT_DER; + inkey_format = GNUTLS_TPMKEY_FMT_DER; + } else { + incert_format = GNUTLS_X509_FMT_PEM; + inkey_format = GNUTLS_TPMKEY_FMT_CTK_PEM; + } + + if (HAVE_OPT(OUTDER)) { + outcert_format = GNUTLS_X509_FMT_DER; + outkey_format = GNUTLS_TPMKEY_FMT_DER; + } else { + outcert_format = GNUTLS_X509_FMT_PEM; + outkey_format = GNUTLS_TPMKEY_FMT_CTK_PEM; + } + + if (HAVE_OPT(REGISTER)) + genflags |= GNUTLS_TPM_REGISTER_KEY; + if (!HAVE_OPT(LEGACY)) + genflags |= GNUTLS_TPM_KEY_SIGNING; + if (HAVE_OPT(USER)) + genflags |= GNUTLS_TPM_KEY_USER; + + gnutls_global_set_log_function(tls_log_func); + gnutls_global_set_log_level(debug); + if (debug > 1) + printf("Setting log level to %d\n", debug); + + if ((ret = gnutls_global_init()) < 0) { + fprintf(stderr, "global_init: %s", gnutls_strerror(ret)); + exit(1); + } + + if (HAVE_OPT(OUTFILE)) { + outfile = safe_open_rw(OPT_ARG(OUTFILE), 0); + if (outfile == NULL) { + fprintf(stderr, "%s", OPT_ARG(OUTFILE)); + exit(1); + } + } else + outfile = stdout; + + if (HAVE_OPT(INFILE)) { + infile = fopen(OPT_ARG(INFILE), "rb"); + if (infile == NULL) { + fprintf(stderr, "%s", OPT_ARG(INFILE)); + exit(1); + } + } else + infile = stdin; + + if (HAVE_OPT(SEC_PARAM)) + sec_param = OPT_ARG(SEC_PARAM); + if (HAVE_OPT(BITS)) + bits = OPT_VALUE_BITS; + + + if (HAVE_OPT(GENERATE_RSA)) { + key_type = GNUTLS_PK_RSA; + bits = get_bits(key_type, bits, sec_param, 0); + tpm_generate(outfile, key_type, bits, genflags); + } else if (HAVE_OPT(PUBKEY)) { + tpm_pubkey(OPT_ARG(PUBKEY), outfile); + } else if (HAVE_OPT(DELETE)) { + tpm_delete(OPT_ARG(DELETE), outfile); + } else if (HAVE_OPT(LIST)) { + tpm_list(outfile); + } else { + USAGE(1); + } + + fclose(outfile); + + gnutls_global_deinit(); } -static void tpm_generate(FILE* outfile, unsigned int key_type, unsigned int bits, unsigned int flags) +static void tpm_generate(FILE * outfile, unsigned int key_type, + unsigned int bits, unsigned int flags) { - int ret; - char* srk_pass, *key_pass = NULL; - gnutls_datum_t privkey, pubkey; - - srk_pass = getpass ("Enter SRK password: "); - if (srk_pass != NULL) - srk_pass = strdup(srk_pass); - - if (!(flags & GNUTLS_TPM_REGISTER_KEY)) - { - key_pass = getpass ("Enter key password: "); - if (key_pass != NULL) - key_pass = strdup(srk_pass); - } - - ret = gnutls_tpm_privkey_generate(key_type, bits, srk_pass, key_pass, - outkey_format, outcert_format, - &privkey, &pubkey, - flags); - - free(key_pass); - free(srk_pass); - - if (ret < 0) - { - fprintf (stderr, "gnutls_tpm_privkey_generate: %s", gnutls_strerror (ret)); - exit(1); - } + int ret; + char *srk_pass, *key_pass = NULL; + gnutls_datum_t privkey, pubkey; + + srk_pass = getpass("Enter SRK password: "); + if (srk_pass != NULL) + srk_pass = strdup(srk_pass); + + if (!(flags & GNUTLS_TPM_REGISTER_KEY)) { + key_pass = getpass("Enter key password: "); + if (key_pass != NULL) + key_pass = strdup(srk_pass); + } + + ret = + gnutls_tpm_privkey_generate(key_type, bits, srk_pass, key_pass, + outkey_format, outcert_format, + &privkey, &pubkey, flags); + + free(key_pass); + free(srk_pass); + + if (ret < 0) { + fprintf(stderr, "gnutls_tpm_privkey_generate: %s", + gnutls_strerror(ret)); + exit(1); + } /* fwrite (pubkey.data, 1, pubkey.size, outfile); fputs ("\n", outfile);*/ - fwrite (privkey.data, 1, privkey.size, outfile); - fputs ("\n", outfile); - - gnutls_free(privkey.data); - gnutls_free(pubkey.data); + fwrite(privkey.data, 1, privkey.size, outfile); + fputs("\n", outfile); + + gnutls_free(privkey.data); + gnutls_free(pubkey.data); } -static void tpm_delete(const char* url, FILE* outfile) +static void tpm_delete(const char *url, FILE * outfile) { - int ret; - char* srk_pass; - - srk_pass = getpass ("Enter SRK password: "); - - ret = gnutls_tpm_privkey_delete(url, srk_pass); - if (ret < 0) - { - fprintf (stderr, "gnutls_tpm_privkey_delete: %s", gnutls_strerror (ret)); - exit(1); - } - - fprintf (outfile, "Key %s deleted\n", url); + int ret; + char *srk_pass; + + srk_pass = getpass("Enter SRK password: "); + + ret = gnutls_tpm_privkey_delete(url, srk_pass); + if (ret < 0) { + fprintf(stderr, "gnutls_tpm_privkey_delete: %s", + gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "Key %s deleted\n", url); } -static void tpm_list(FILE* outfile) +static void tpm_list(FILE * outfile) { - int ret; - gnutls_tpm_key_list_t list; - unsigned int i; - char* url; - - ret = gnutls_tpm_get_registered (&list); - if (ret < 0) - { - fprintf (stderr, "gnutls_tpm_get_registered: %s", gnutls_strerror (ret)); - exit(1); - } - - fprintf(outfile, "Available keys:\n"); - for (i=0;;i++) - { - ret = gnutls_tpm_key_list_get_url(list, i, &url, 0); - if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) - break; - else if (ret < 0) - { - fprintf (stderr, "gnutls_tpm_key_list_get_url: %s", gnutls_strerror (ret)); - exit(1); - } - - fprintf(outfile, "\t%u: %s\n", i, url); - gnutls_free(url); - } - - fputs ("\n", outfile); + int ret; + gnutls_tpm_key_list_t list; + unsigned int i; + char *url; + + ret = gnutls_tpm_get_registered(&list); + if (ret < 0) { + fprintf(stderr, "gnutls_tpm_get_registered: %s", + gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "Available keys:\n"); + for (i = 0;; i++) { + ret = gnutls_tpm_key_list_get_url(list, i, &url, 0); + if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) + break; + else if (ret < 0) { + fprintf(stderr, "gnutls_tpm_key_list_get_url: %s", + gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "\t%u: %s\n", i, url); + gnutls_free(url); + } + + fputs("\n", outfile); } -static void tpm_pubkey(const char* url, FILE* outfile) +static void tpm_pubkey(const char *url, FILE * outfile) { - int ret; - char* srk_pass; - gnutls_pubkey_t pubkey; - - srk_pass = getpass ("Enter SRK password: "); - if (srk_pass != NULL) - srk_pass = strdup(srk_pass); + int ret; + char *srk_pass; + gnutls_pubkey_t pubkey; + + srk_pass = getpass("Enter SRK password: "); + if (srk_pass != NULL) + srk_pass = strdup(srk_pass); - gnutls_pubkey_init(&pubkey); + gnutls_pubkey_init(&pubkey); - ret = gnutls_pubkey_import_tpm_url(pubkey, url, srk_pass, 0); + ret = gnutls_pubkey_import_tpm_url(pubkey, url, srk_pass, 0); - free(srk_pass); + free(srk_pass); - if (ret < 0) - { - fprintf (stderr, "gnutls_pubkey_import_tpm_url: %s", gnutls_strerror (ret)); - exit(1); - } + if (ret < 0) { + fprintf(stderr, "gnutls_pubkey_import_tpm_url: %s", + gnutls_strerror(ret)); + exit(1); + } - _pubkey_info(outfile, GNUTLS_CRT_PRINT_FULL, pubkey); + _pubkey_info(outfile, GNUTLS_CRT_PRINT_FULL, pubkey); - gnutls_pubkey_deinit(pubkey); + gnutls_pubkey_deinit(pubkey); } diff --git a/src/udp-serv.c b/src/udp-serv.c index 08d2677a88..f9cb420ffe 100644 --- a/src/udp-serv.c +++ b/src/udp-serv.c @@ -21,13 +21,13 @@ #include <stdio.h> #if HAVE_SYS_SOCKET_H -# include <sys/socket.h> +#include <sys/socket.h> #elif HAVE_WS2TCPIP_H -# include <ws2tcpip.h> +#include <ws2tcpip.h> #endif #include <arpa/inet.h> #ifndef _WIN32 -# include <netinet/in.h> +#include <netinet/in.h> #endif #include <sys/select.h> #include <stdlib.h> @@ -39,232 +39,264 @@ #include "list.h" typedef struct { - gnutls_session_t session; - int fd; - struct sockaddr * cli_addr; - socklen_t cli_addr_size; + gnutls_session_t session; + int fd; + struct sockaddr *cli_addr; + socklen_t cli_addr_size; } priv_data_st; static int pull_timeout_func(gnutls_transport_ptr_t ptr, unsigned int ms); -static ssize_t push_func (gnutls_transport_ptr_t p, const void * data, size_t size); -static ssize_t pull_func(gnutls_transport_ptr_t p, void * data, size_t size); +static ssize_t push_func(gnutls_transport_ptr_t p, const void *data, + size_t size); +static ssize_t pull_func(gnutls_transport_ptr_t p, void *data, + size_t size); -#define MAX_BUFFER 255 /* Longest string to echo */ +#define MAX_BUFFER 255 /* Longest string to echo */ -void udp_server(const char* name, int port, int mtu) +void udp_server(const char *name, int port, int mtu) { - int sock, ret; - struct sockaddr_in cli_addr; - socklen_t cli_addr_size; - char buffer[MAX_BUFFER]; - priv_data_st priv; - gnutls_session_t session; - gnutls_datum_t cookie_key; - gnutls_dtls_prestate_st prestate; - unsigned char sequence[8]; - - ret = gnutls_key_generate(&cookie_key, GNUTLS_COOKIE_KEY_SIZE); - if (ret < 0) - { - fprintf(stderr, "Cannot generate key\n"); - exit(1); - } - - ret = listen_socket (name, port, SOCK_DGRAM); - if (ret < 0) - { - fprintf(stderr, "Cannot listen\n"); - exit (1); - } - - for (;;) - { - printf("Waiting for connection...\n"); - sock = wait_for_connection(); - if (sock < 0) - continue; - - cli_addr_size = sizeof(cli_addr); - ret = recvfrom(sock, buffer, sizeof(buffer), MSG_PEEK, (struct sockaddr*)&cli_addr, &cli_addr_size); - if (ret > 0) - { - memset(&prestate, 0, sizeof(prestate)); - ret = gnutls_dtls_cookie_verify(&cookie_key, &cli_addr, sizeof(cli_addr), buffer, ret, &prestate); - if (ret < 0) /* cookie not valid */ - { - priv_data_st s; - - memset(&s,0,sizeof(s)); - s.fd = sock; - s.cli_addr = (void*)&cli_addr; - s.cli_addr_size = sizeof(cli_addr); - - printf("Sending hello verify request to %s\n", human_addr ((struct sockaddr *) - &cli_addr, sizeof(cli_addr), buffer, sizeof(buffer))); - gnutls_dtls_cookie_send(&cookie_key, &cli_addr, sizeof(cli_addr), &prestate, (gnutls_transport_ptr_t)&s, push_func); - - /* discard peeked data*/ - recvfrom(sock, buffer, sizeof(buffer), 0, (struct sockaddr*)&cli_addr, &cli_addr_size); - continue; - } - printf ("Accepted connection from %s\n", - human_addr ((struct sockaddr *) - &cli_addr, sizeof(cli_addr), buffer, - sizeof (buffer))); - } - else - continue; - - session = initialize_session(1); - gnutls_dtls_prestate_set(session, &prestate); - if (mtu) gnutls_dtls_set_mtu(session, mtu); - - priv.session = session; - priv.fd = sock; - priv.cli_addr = (struct sockaddr *)&cli_addr; - priv.cli_addr_size = sizeof(cli_addr); - - gnutls_transport_set_ptr (session, &priv); - gnutls_transport_set_push_function (session, push_func); - gnutls_transport_set_pull_function (session, pull_func); - gnutls_transport_set_pull_timeout_function (session, pull_timeout_func); - - do - { - ret = gnutls_handshake(session); - } - while(ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); - - if (ret < 0) - { - fprintf(stderr, "Error in handshake(): %s\n", gnutls_strerror(ret)); - gnutls_deinit(session); - continue; - } - - for(;;) - { - do - { - ret = gnutls_record_recv_seq(session, buffer, MAX_BUFFER, sequence); - if (ret == GNUTLS_E_HEARTBEAT_PING_RECEIVED) - gnutls_heartbeat_pong(session, 0); - } - while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_HEARTBEAT_PING_RECEIVED); - - if (ret == GNUTLS_E_REHANDSHAKE) - { - fprintf (stderr, "*** Received hello message\n"); - do - { - ret = gnutls_handshake (session); - } - while (ret == GNUTLS_E_INTERRUPTED || - ret == GNUTLS_E_AGAIN); - - if (ret == 0) continue; - } - if (ret < 0) - { - fprintf(stderr, "Error in recv(): %s\n", gnutls_strerror(ret)); - break; - } - if (ret == 0) - { - printf("EOF\n\n"); - break; - } - - buffer[ret] = 0; - printf("received[%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x]: %s\n", sequence[0], sequence[1], sequence[2], - sequence[3], sequence[4], sequence[5], sequence[6], sequence[7], buffer); - - if (check_command(session, buffer) == 0) - { - /* reply back */ - ret = gnutls_record_send(session, buffer, ret); - if (ret < 0) - { - fprintf(stderr, "Error in send(): %s\n", gnutls_strerror(ret)); - break; - } - } - } - } - gnutls_deinit(session); + int sock, ret; + struct sockaddr_in cli_addr; + socklen_t cli_addr_size; + char buffer[MAX_BUFFER]; + priv_data_st priv; + gnutls_session_t session; + gnutls_datum_t cookie_key; + gnutls_dtls_prestate_st prestate; + unsigned char sequence[8]; + + ret = gnutls_key_generate(&cookie_key, GNUTLS_COOKIE_KEY_SIZE); + if (ret < 0) { + fprintf(stderr, "Cannot generate key\n"); + exit(1); + } + + ret = listen_socket(name, port, SOCK_DGRAM); + if (ret < 0) { + fprintf(stderr, "Cannot listen\n"); + exit(1); + } + + for (;;) { + printf("Waiting for connection...\n"); + sock = wait_for_connection(); + if (sock < 0) + continue; + + cli_addr_size = sizeof(cli_addr); + ret = + recvfrom(sock, buffer, sizeof(buffer), MSG_PEEK, + (struct sockaddr *) &cli_addr, + &cli_addr_size); + if (ret > 0) { + memset(&prestate, 0, sizeof(prestate)); + ret = + gnutls_dtls_cookie_verify(&cookie_key, + &cli_addr, + sizeof(cli_addr), + buffer, ret, + &prestate); + if (ret < 0) { /* cookie not valid */ + priv_data_st s; + + memset(&s, 0, sizeof(s)); + s.fd = sock; + s.cli_addr = (void *) &cli_addr; + s.cli_addr_size = sizeof(cli_addr); + + printf + ("Sending hello verify request to %s\n", + human_addr((struct sockaddr *) + &cli_addr, + sizeof(cli_addr), buffer, + sizeof(buffer))); + gnutls_dtls_cookie_send(&cookie_key, + &cli_addr, + sizeof(cli_addr), + &prestate, + (gnutls_transport_ptr_t) + & s, push_func); + + /* discard peeked data */ + recvfrom(sock, buffer, sizeof(buffer), 0, + (struct sockaddr *) &cli_addr, + &cli_addr_size); + continue; + } + printf("Accepted connection from %s\n", + human_addr((struct sockaddr *) + &cli_addr, sizeof(cli_addr), + buffer, sizeof(buffer))); + } else + continue; + + session = initialize_session(1); + gnutls_dtls_prestate_set(session, &prestate); + if (mtu) + gnutls_dtls_set_mtu(session, mtu); + + priv.session = session; + priv.fd = sock; + priv.cli_addr = (struct sockaddr *) &cli_addr; + priv.cli_addr_size = sizeof(cli_addr); + + gnutls_transport_set_ptr(session, &priv); + gnutls_transport_set_push_function(session, push_func); + gnutls_transport_set_pull_function(session, pull_func); + gnutls_transport_set_pull_timeout_function(session, + pull_timeout_func); + + do { + ret = gnutls_handshake(session); + } + while (ret == GNUTLS_E_AGAIN + || ret == GNUTLS_E_INTERRUPTED); + + if (ret < 0) { + fprintf(stderr, "Error in handshake(): %s\n", + gnutls_strerror(ret)); + gnutls_deinit(session); + continue; + } + + for (;;) { + do { + ret = + gnutls_record_recv_seq(session, buffer, + MAX_BUFFER, + sequence); + if (ret == + GNUTLS_E_HEARTBEAT_PING_RECEIVED) + gnutls_heartbeat_pong(session, 0); + } + while (ret == GNUTLS_E_INTERRUPTED + || ret == GNUTLS_E_AGAIN + || ret == GNUTLS_E_HEARTBEAT_PING_RECEIVED); + + if (ret == GNUTLS_E_REHANDSHAKE) { + fprintf(stderr, + "*** Received hello message\n"); + do { + ret = gnutls_handshake(session); + } + while (ret == GNUTLS_E_INTERRUPTED || + ret == GNUTLS_E_AGAIN); + + if (ret == 0) + continue; + } + if (ret < 0) { + fprintf(stderr, "Error in recv(): %s\n", + gnutls_strerror(ret)); + break; + } + if (ret == 0) { + printf("EOF\n\n"); + break; + } + + buffer[ret] = 0; + printf + ("received[%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x]: %s\n", + sequence[0], sequence[1], sequence[2], + sequence[3], sequence[4], sequence[5], + sequence[6], sequence[7], buffer); + + if (check_command(session, buffer) == 0) { + /* reply back */ + ret = + gnutls_record_send(session, buffer, + ret); + if (ret < 0) { + fprintf(stderr, + "Error in send(): %s\n", + gnutls_strerror(ret)); + break; + } + } + } + } + gnutls_deinit(session); } /* Wait for data to be received within a timeout period in milliseconds */ static int pull_timeout_func(gnutls_transport_ptr_t ptr, unsigned int ms) { -fd_set rfds; -struct timeval tv; -priv_data_st *priv = ptr; -struct sockaddr_in cli_addr; -socklen_t cli_addr_size; -int ret; -char c; - - FD_ZERO(&rfds); - FD_SET(priv->fd, &rfds); - - tv.tv_sec = 0; - tv.tv_usec = ms * 1000; - - while(tv.tv_usec >= 1000000) - { - tv.tv_usec -= 1000000; - tv.tv_sec++; - } - - ret = select(priv->fd+1, &rfds, NULL, NULL, &tv); - - if (ret <= 0) - return ret; - - /* only report ok if the next message is from the peer we expect - * from - */ - cli_addr_size = sizeof(cli_addr); - ret = recvfrom(priv->fd, &c, 1, MSG_PEEK, (struct sockaddr*)&cli_addr, &cli_addr_size); - if (ret > 0) - { - if (cli_addr_size == priv->cli_addr_size && memcmp(&cli_addr, priv->cli_addr, sizeof(cli_addr))==0) - return 1; - } - - return 0; + fd_set rfds; + struct timeval tv; + priv_data_st *priv = ptr; + struct sockaddr_in cli_addr; + socklen_t cli_addr_size; + int ret; + char c; + + FD_ZERO(&rfds); + FD_SET(priv->fd, &rfds); + + tv.tv_sec = 0; + tv.tv_usec = ms * 1000; + + while (tv.tv_usec >= 1000000) { + tv.tv_usec -= 1000000; + tv.tv_sec++; + } + + ret = select(priv->fd + 1, &rfds, NULL, NULL, &tv); + + if (ret <= 0) + return ret; + + /* only report ok if the next message is from the peer we expect + * from + */ + cli_addr_size = sizeof(cli_addr); + ret = + recvfrom(priv->fd, &c, 1, MSG_PEEK, + (struct sockaddr *) &cli_addr, &cli_addr_size); + if (ret > 0) { + if (cli_addr_size == priv->cli_addr_size + && memcmp(&cli_addr, priv->cli_addr, + sizeof(cli_addr)) == 0) + return 1; + } + + return 0; } -static ssize_t push_func (gnutls_transport_ptr_t p, const void * data, size_t size) +static ssize_t push_func(gnutls_transport_ptr_t p, const void *data, + size_t size) { -priv_data_st *priv = p; + priv_data_st *priv = p; - return sendto(priv->fd, data, size, 0, priv->cli_addr, priv->cli_addr_size); + return sendto(priv->fd, data, size, 0, priv->cli_addr, + priv->cli_addr_size); } -static ssize_t pull_func(gnutls_transport_ptr_t p, void * data, size_t size) +static ssize_t pull_func(gnutls_transport_ptr_t p, void *data, size_t size) { -priv_data_st *priv = p; -struct sockaddr_in cli_addr; -socklen_t cli_addr_size; -char buffer[64]; -int ret; - - cli_addr_size = sizeof(cli_addr); - ret = recvfrom(priv->fd, data, size, 0, (struct sockaddr*)&cli_addr, &cli_addr_size); - if (ret == -1) - return ret; - - if (cli_addr_size == priv->cli_addr_size && memcmp(&cli_addr, priv->cli_addr, sizeof(cli_addr))==0) - return ret; - - printf ("Denied connection from %s\n", - human_addr ((struct sockaddr *) - &cli_addr, sizeof(cli_addr), buffer, - sizeof (buffer))); - - gnutls_transport_set_errno(priv->session, EAGAIN); - return -1; + priv_data_st *priv = p; + struct sockaddr_in cli_addr; + socklen_t cli_addr_size; + char buffer[64]; + int ret; + + cli_addr_size = sizeof(cli_addr); + ret = + recvfrom(priv->fd, data, size, 0, + (struct sockaddr *) &cli_addr, &cli_addr_size); + if (ret == -1) + return ret; + + if (cli_addr_size == priv->cli_addr_size + && memcmp(&cli_addr, priv->cli_addr, sizeof(cli_addr)) == 0) + return ret; + + printf("Denied connection from %s\n", + human_addr((struct sockaddr *) + &cli_addr, sizeof(cli_addr), buffer, + sizeof(buffer))); + + gnutls_transport_set_errno(priv->session, EAGAIN); + return -1; } diff --git a/src/udp-serv.h b/src/udp-serv.h index ae0b39503b..d956f87789 100644 --- a/src/udp-serv.h +++ b/src/udp-serv.h @@ -19,9 +19,9 @@ #include <gnutls/dtls.h> -void udp_server(const char* name, int port, int mtu); -gnutls_session_t initialize_session (int dtls); -const char * human_addr (const struct sockaddr *sa, socklen_t salen, - char *buf, size_t buflen); +void udp_server(const char *name, int port, int mtu); +gnutls_session_t initialize_session(int dtls); +const char *human_addr(const struct sockaddr *sa, socklen_t salen, + char *buf, size_t buflen); int wait_for_connection(void); -int listen_socket (const char *name, int listen_port, int socktype); +int listen_socket(const char *name, int listen_port, int socktype); |