Skip to content

Instantly share code, notes, and snippets.

@stbuehler
Last active December 17, 2015 23:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stbuehler/5693466 to your computer and use it in GitHub Desktop.
Save stbuehler/5693466 to your computer and use it in GitHub Desktop.
List ciphers and other details from GnuTLS priority string
/*
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