Last active
December 17, 2015 23:59
-
-
Save stbuehler/5693466 to your computer and use it in GitHub Desktop.
List ciphers and other details from GnuTLS priority string
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
gcc -o gnutls-priority gnutls-priority.c `pkg-config gnutls --cflags --libs` -DTRY_INTERNALS | |
With -DTRY_INTERNALS it will try to show internal stuff, but the internal API might change | |
and the feature break. | |
Example call: | |
./gnutls-priority "NORMAL:-MAC-ALL:+AEAD" | |
also check gnutls-cli -c | |
*/ | |
/* This example code is placed in the public domain. */ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <gnutls/gnutls.h> | |
#define CHECK_RET(func, ret) do { \ | |
if (ret < 0) { \ | |
fprintf(stderr, "%s failed: %s\n", func, gnutls_strerror(ret)); \ | |
exit(1); \ | |
} \ | |
} while (0) | |
#ifdef TRY_INTERNALS | |
/* this is taken from gnutls 3.2.2 (lib/gnutls_int.h), might break with other versions */ | |
typedef struct | |
{ | |
unsigned int priority[GNUTLS_MAX_ALGORITHM_NUM]; | |
unsigned int algorithms; | |
} priority_st; | |
struct gnutls_priority_st | |
{ | |
priority_st cipher; | |
priority_st mac; | |
priority_st kx; | |
priority_st compression; | |
priority_st protocol; | |
priority_st cert_type; | |
priority_st sign_algo; | |
priority_st supported_ecc; | |
/* omitted remaining stuff */ | |
}; | |
#endif | |
static void print_cipher_suite_list(const char* priorities) { | |
size_t i; | |
int ret; | |
unsigned int idx; | |
const char *name; | |
const char *err; | |
unsigned char id[2]; | |
gnutls_protocol_t version; | |
gnutls_priority_t pcache; | |
const unsigned int* list; | |
if (priorities == NULL) return; | |
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); | |
CHECK_RET("gnutls_priority_init", ret); | |
} | |
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) { | |
/* > It might be that a valid priorities index does not correspond | |
* > to a ciphersuite and in that case GNUTLS_E_UNKNOWN_CIPHER_SUITE | |
* > will be returned. */ | |
/* printf("Unknown cipher suite %i\n", idx); */ | |
continue; | |
} | |
CHECK_RET("gnutls_priority_get_cipher_suite_index", ret); | |
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("Certificate types:\n"); | |
ret = gnutls_priority_certificate_type_list(pcache, &list); | |
CHECK_RET("gnutls_priority_certificate_type_list", ret); | |
for (i = 0; i < ret; ++i) { | |
name = gnutls_certificate_type_get_name(list[i]); | |
printf("%20s\t0x%02x\n", name ? name : "<unknown>", list[i]); | |
} | |
printf("Compression methods:\n"); | |
ret = gnutls_priority_compression_list(pcache, &list); | |
CHECK_RET("gnutls_priority_compression_list", ret); | |
for (i = 0; i < ret; ++i) { | |
name = gnutls_compression_get_name(list[i]); | |
printf("%20s\t0x%02x\n", name ? name : "<unknown>", list[i]); | |
} | |
printf("Elliptic curves:\n"); | |
ret = gnutls_priority_ecc_curve_list(pcache, &list); | |
CHECK_RET("gnutls_priority_ecc_curve_list", ret); | |
for (i = 0; i < ret; ++i) { | |
name = gnutls_ecc_curve_get_name(list[i]); | |
printf("%20s\t0x%02x\n", name ? name : "<unknown>", list[i]); | |
} | |
printf("Protocols:\n"); | |
ret = gnutls_priority_protocol_list(pcache, &list); | |
CHECK_RET("gnutls_priority_protocol_list", ret); | |
for (i = 0; i < ret; ++i) { | |
name = gnutls_protocol_get_name(list[i]); | |
printf("%20s\t0x%02x\n", name ? name : "<unknown>", list[i]); | |
} | |
printf("signature algorithms:\n"); | |
ret = gnutls_priority_sign_list(pcache, &list); | |
CHECK_RET("gnutls_priority_sign_list", ret); | |
for (i = 0; i < ret; ++i) { | |
name = gnutls_sign_get_name(list[i]); | |
printf("%20s\t0x%02x\n", name ? name : "<unknown>", list[i]); | |
} | |
#ifdef TRY_INTERNALS | |
/* not official api */ | |
printf("\nStuff from internals\n"); | |
printf("cipher algorithms:\n"); | |
for (i = 0; i < GNUTLS_MAX_ALGORITHM_NUM; ++i) { | |
name = gnutls_cipher_get_name(pcache->cipher.priority[i]); | |
if (i >= pcache->cipher.algorithms) { | |
if (pcache->cipher.priority[i] != 0) { | |
printf("%20s\t0x%02x\tat index %i after list end\n", name ? name : "<unknown>", pcache->cipher.priority[i], i); | |
} | |
} else { | |
printf("%20s\t0x%02x\n", name ? name : "<unknown>", pcache->cipher.priority[i]); | |
} | |
} | |
printf("MAC algorithms:\n"); | |
for (i = 0; i < GNUTLS_MAX_ALGORITHM_NUM; ++i) { | |
name = gnutls_mac_get_name(pcache->mac.priority[i]); | |
if (i >= pcache->mac.algorithms) { | |
if (pcache->mac.priority[i] != 0) { | |
printf("%20s\t0x%02x\tat index %i after list end\n", name ? name : "<unknown>", pcache->mac.priority[i], i); | |
} | |
} else { | |
printf("%20s\t0x%02x\n", name ? name : "<unknown>", pcache->mac.priority[i]); | |
} | |
} | |
printf("key exchange algorithms:\n"); | |
for (i = 0; i < GNUTLS_MAX_ALGORITHM_NUM; ++i) { | |
name = gnutls_kx_get_name(pcache->kx.priority[i]); | |
if (i >= pcache->kx.algorithms) { | |
if (pcache->kx.priority[i] != 0) { | |
printf("%20s\t0x%02x\tat index %i after list end\n", name ? name : "<unknown>", pcache->kx.priority[i], i); | |
} | |
} else { | |
printf("%20s\t0x%02x\n", name ? name : "<unknown>", pcache->kx.priority[i]); | |
} | |
} | |
#endif | |
} | |
int main(int argc, char** argv) { | |
if (argc > 1) print_cipher_suite_list(argv[1]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment