void pkcs11_get_random(FILE * outfile, const char *url, unsigned bytes, common_info_st * info) { int ret; uint8_t *output; pkcs11_common(info); FIX(url, outfile, 0, info); 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); } fwrite(output, 1, bytes, outfile); return; }
void pkcs11_mechanism_list(FILE * outfile, const char *url, unsigned int flags, common_info_st * info) { int ret; int idx; unsigned long mechanism; const char *str; pkcs11_common(info); FIX(url, outfile, 0, info); 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_init(FILE * outfile, const char *url, const char *label, common_info_st * info) { int ret; const char *pin; char so_pin[32]; pkcs11_common(info); if (url == NULL) { fprintf(stderr, "error: no token URL given to initialize!\n"); exit(1); } if (info->so_pin != NULL) pin = info->so_pin; else { pin = getenv("GNUTLS_SO_PIN"); if (pin == NULL && info->batch == 0) pin = getpass("Enter Security Officer's PIN: "); if (pin == NULL) exit(1); } if (strlen(pin) >= sizeof(so_pin) || pin[0] == '\n') exit(1); strcpy(so_pin, pin); if (info->so_pin != NULL) { pin = info->pin; } else { pin = getenv("GNUTLS_PIN"); if (pin == NULL && info->batch == 0) pin = getpass("Enter new User's PIN: "); if (pin == NULL) exit(1); } if (pin[0] == '\n') 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; }
void pkcs11_generate(FILE * outfile, const char *url, gnutls_pk_algorithm_t pk, unsigned int bits, const char *label, const char *id, int detailed, unsigned int flags, common_info_st * info) { int ret; gnutls_datum_t pubkey; gnutls_datum_t cid = {NULL, 0}; unsigned char raw_id[128]; size_t raw_id_size; pkcs11_common(info); FIX(url, outfile, detailed, info); CHECK_LOGIN_FLAG(flags); if (id != NULL) { raw_id_size = sizeof(raw_id); ret = gnutls_hex2bin(id, strlen(id), raw_id, &raw_id_size); if (ret < 0) { fprintf(stderr, "Error converting hex: %s\n", gnutls_strerror(ret)); exit(1); } cid.data = raw_id; cid.size = raw_id_size; } if (outfile == stderr || outfile == stdout) { fprintf(stderr, "warning: no --outfile was specified and the generated public key will be printed on screen.\n"); } if (label == NULL && info->batch == 0) { label = read_str("warning: Label was not specified.\nLabel: "); } ret = gnutls_pkcs11_privkey_generate3(url, pk, bits, label, &cid, GNUTLS_X509_FMT_PEM, &pubkey, info->key_usage, flags); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); if (bits != 1024 && pk == GNUTLS_PK_RSA) fprintf(stderr, "note: several smart cards do not support arbitrary size keys; try --bits 1024 or 2048.\n"); exit(1); } fwrite(pubkey.data, 1, pubkey.size, outfile); gnutls_free(pubkey.data); UNFIX; return; }
void pkcs11_set_pin(FILE * outfile, const char *url, common_info_st * info, unsigned so) { int ret; const char *pin; pkcs11_common(info); if (url == NULL) { fprintf(stderr, "error: no token URL given to initialize!\n"); exit(1); } fprintf(stderr, "Setting token's user PIN...\n"); if (so) { if (info->so_pin != NULL) { pin = info->so_pin; } else { pin = getenv("GNUTLS_SO_PIN"); if (pin == NULL && info->batch == 0) pin = getpass("Enter Administrators's new PIN: "); if (pin == NULL) exit(1); } } else { if (info->pin != NULL) { pin = info->pin; } else { pin = getenv("GNUTLS_PIN"); if (pin == NULL && info->batch == 0) pin = getpass("Enter User's new PIN: "); if (pin == NULL) exit(1); } } if (pin == NULL || pin[0] == '\n') exit(1); ret = gnutls_pkcs11_token_set_pin(url, NULL, pin, (so!=0)?GNUTLS_PIN_SO:GNUTLS_PIN_USER); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } return; }
void pkcs11_export_pubkey(FILE * outfile, const char *url, int detailed, unsigned int flags, common_info_st * info) { int ret; gnutls_datum_t pubkey; gnutls_pkcs11_privkey_t pkey; pkcs11_common(info); FIX(url, outfile, detailed, info); CHECK_LOGIN_FLAG(flags); if (outfile == stderr || outfile == stdout) { fprintf(stderr, "warning: no --outfile was specified and the public key will be printed on screen.\n"); sleep(3); } ret = gnutls_pkcs11_privkey_init(&pkey); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } ret = gnutls_pkcs11_privkey_import_url(pkey, url, 0); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } ret = gnutls_pkcs11_privkey_export_pubkey(pkey, GNUTLS_X509_FMT_PEM, &pubkey, flags); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } gnutls_pkcs11_privkey_deinit(pkey); fwrite(pubkey.data, 1, pubkey.size, outfile); gnutls_free(pubkey.data); UNFIX; return; }
void pkcs11_init(FILE * outfile, const char *url, const char *label, common_info_st * info) { int ret; const char *pin; char so_pin[32]; pkcs11_common(info); if (url == NULL) { fprintf(stderr, "error: no token URL given to initialize!\n"); exit(1); } if (label == NULL) { fprintf(stderr, "error: no label provided for token initialization!\n"); exit(1); } if (info->so_pin != NULL) pin = info->so_pin; else { pin = getenv("GNUTLS_SO_PIN"); if (pin == NULL && info->batch == 0) pin = getpass("Enter Security Officer's PIN: "); if (pin == NULL) exit(1); } if (strlen(pin) >= sizeof(so_pin) || pin[0] == '\n') exit(1); strcpy(so_pin, pin); fprintf(stderr, "Initializing token... "); ret = gnutls_pkcs11_token_init(url, so_pin, label); if (ret < 0) { fprintf(stderr, "\nError in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } fprintf(stderr, "done\n"); fprintf(stderr, "\nToken was successfully initialized; use --initialize-pin and --initialize-so-pin to set or reset PINs\n"); return; }
void pkcs11_export(FILE * outfile, const char *url, unsigned int flags, common_info_st * info) { gnutls_pkcs11_obj_t obj; gnutls_datum_t t; int ret; unsigned int obj_flags = flags; pkcs11_common(info); FIX(url, outfile, 0, info); ret = gnutls_pkcs11_obj_init(&obj); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } ret = gnutls_pkcs11_obj_import_url(obj, url, obj_flags); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } ret = gnutls_pkcs11_obj_export3(obj, info->outcert_format, &t); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } fwrite(t.data, 1, t.size, outfile); gnutls_free(t.data); if (info->outcert_format == GNUTLS_X509_FMT_PEM) fputs("\n\n", outfile); gnutls_pkcs11_obj_deinit(obj); UNFIX; return; }
/* If there is a single token only present, return its URL. */ static char *get_single_token_url(common_info_st * info) { int ret; char *url = NULL, *t = NULL; pkcs11_common(info); ret = gnutls_pkcs11_token_get_url(0, 0, &url); if (ret < 0) return NULL; ret = gnutls_pkcs11_token_get_url(1, 0, &t); if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { gnutls_free(t); gnutls_free(url); return NULL; } return url; }
static void pkcs11_set_val(FILE * outfile, const char *url, int detailed, unsigned int flags, common_info_st * info, gnutls_pkcs11_obj_info_t val_type, const char *val) { int ret; gnutls_pkcs11_obj_t obj; pkcs11_common(info); FIX(url, outfile, detailed, info); CHECK_LOGIN_FLAG(flags); ret = gnutls_pkcs11_obj_init(&obj); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } ret = gnutls_pkcs11_obj_import_url(obj, url, flags); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } ret = gnutls_pkcs11_obj_set_info(obj, val_type, val, strlen(val), flags); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } gnutls_pkcs11_obj_deinit(obj); return; }
/* lists certificates from a token */ void pkcs11_list(FILE * outfile, const char *url, int type, unsigned int flags, unsigned int detailed, common_info_st * info) { gnutls_pkcs11_obj_t *crt_list; unsigned int crt_list_size = 0, i, j; int ret, otype; char *output, *str; int attrs, print_exts = 0; gnutls_x509_ext_st *exts; unsigned exts_size; unsigned int obj_flags = flags; pkcs11_common(info); FIX(url, outfile, detailed, info); gnutls_pkcs11_token_get_flags(url, &flags); if (flags & GNUTLS_PKCS11_TOKEN_TRUSTED) print_exts = 1; 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; if (print_exts != 0) print_exts++; } else if (type == PKCS11_TYPE_PRIVKEY) { attrs = GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY; } else if (type == PKCS11_TYPE_INFO) { attrs = GNUTLS_PKCS11_OBJ_ATTR_MATCH; } 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(2); } for (i = 0; i < crt_list_size; i++) { char buf[128]; size_t size; unsigned int oflags; 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); } if (info->only_urls) { fprintf(outfile, "%s\n", output); gnutls_free(output); continue; } else { fprintf(outfile, "Object %d:\n\tURL: %s\n", i, output); gnutls_free(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); oflags = 0; ret = gnutls_pkcs11_obj_get_flags(crt_list[i], &oflags); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } str = gnutls_pkcs11_obj_flags_get_str(oflags); if (str != NULL) { fprintf(outfile, "\tFlags: %s\n", str); gnutls_free(str); } 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", buf); if (otype == GNUTLS_PKCS11_OBJ_X509_CRT && print_exts > 0) { ret = gnutls_pkcs11_obj_get_exts(crt_list[i], &exts, &exts_size, 0); if (ret >= 0 && exts_size > 0) { gnutls_datum_t txt; if (print_exts > 1) { fprintf(outfile, "\tAttached extensions:\n"); ret = gnutls_x509_ext_print(exts, exts_size, 0, &txt); if (ret >= 0) { fprintf(outfile, "%s", (char*)txt.data); gnutls_free(txt.data); } } else { fprintf(outfile, "\tAttached extensions:"); for (j=0;j<exts_size;j++) { fprintf(outfile, "%s%s", exts[j].oid, (j!=exts_size-1)?",":" "); } } for (j=0;j<exts_size;j++) { gnutls_x509_ext_deinit(&exts[j]); } gnutls_free(exts); fprintf(outfile, "\n"); } } fprintf(outfile, "\n"); } UNFIX; return; }
void 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; }
/* 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) { gnutls_pkcs11_obj_t *crt_list; gnutls_x509_crt_t xcrt; unsigned int crt_list_size = 0; int ret; char *output; int i, 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. */ crt_list_size = 128; crt_list = malloc (sizeof (*crt_list) * crt_list_size); if (crt_list == NULL) { fprintf (stderr, "Memory error\n"); exit (1); } ret = gnutls_pkcs11_obj_list_import_url (crt_list, &crt_list_size, url, attrs, obj_flags); if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) { 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); } if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { crt_list = realloc (crt_list, sizeof (*crt_list) * crt_list_size); if (crt_list == NULL) { fprintf (stderr, "Memory error\n"); exit (1); } ret = gnutls_pkcs11_obj_list_import_url (crt_list, &crt_list_size, url, attrs, obj_flags); if (ret < 0) { fprintf (stderr, "Error in crt_list_import: %s\n", gnutls_strerror (ret)); exit (1); } } 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); fprintf (outfile, "\tType: %s\n", gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_get_type (crt_list[i]))); 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); if (attrs == GNUTLS_PKCS11_OBJ_ATTR_ALL || attrs == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY) continue; 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_list[i]); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } #if 0 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); fputs ("\n\n", outfile); #endif gnutls_x509_crt_deinit (xcrt); } return; }
void pkcs11_write(FILE * outfile, const char *url, const char *label, const char *id, unsigned flags, common_info_st * info) { gnutls_x509_crt_t xcrt; gnutls_x509_privkey_t xkey; gnutls_pubkey_t xpubkey; int ret; gnutls_datum_t *secret_key; unsigned key_usage = 0; unsigned char raw_id[128]; size_t raw_id_size; gnutls_datum_t cid = {NULL, 0}; pkcs11_common(info); FIX(url, outfile, 0, info); CHECK_LOGIN_FLAG(flags); if (label == NULL && info->batch == 0) { label = read_str("warning: The object's label was not specified.\nLabel: "); } if (id != NULL) { raw_id_size = sizeof(raw_id); ret = gnutls_hex2bin(id, strlen(id), raw_id, &raw_id_size); if (ret < 0) { fprintf(stderr, "Error converting hex: %s\n", gnutls_strerror(ret)); exit(1); } cid.data = raw_id; cid.size = raw_id_size; } secret_key = load_secret_key(0, info); if (secret_key != NULL) { ret = gnutls_pkcs11_copy_secret_key(url, secret_key, label, info->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); } } xcrt = load_cert(0, info); if (xcrt != NULL) { ret = gnutls_pkcs11_copy_x509_crt2(url, xcrt, label, &cid, flags); if (ret < 0) { fprintf(stderr, "Error writing certificate: %s\n", gnutls_strerror(ret)); if (((flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_CA) || (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED)) && (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN_SO) == 0) fprintf(stderr, "note: some tokens may require security officer login for this operation\n"); exit(1); } gnutls_x509_crt_get_key_usage(xcrt, &key_usage, NULL); gnutls_x509_crt_deinit(xcrt); } xkey = load_x509_private_key(0, info); if (xkey != NULL) { ret = gnutls_pkcs11_copy_x509_privkey2(url, xkey, label, &cid, key_usage|info->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); } gnutls_x509_privkey_deinit(xkey); } xpubkey = load_pubkey(0, info); if (xpubkey != NULL) { ret = gnutls_pkcs11_copy_pubkey(url, xpubkey, label, &cid, 0, flags); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } gnutls_pubkey_deinit(xpubkey); } if (xkey == NULL && xcrt == NULL && secret_key == NULL && xpubkey == NULL) { fprintf(stderr, "You must use --load-privkey, --load-certificate, --load-pubkey or --secret-key to load the file to be copied\n"); exit(1); } UNFIX; return; }
void pkcs11_token_list(FILE * outfile, unsigned int detailed, common_info_st * info, unsigned brief) { int ret; int i; char *url; char buf[128]; size_t size; unsigned flags; pkcs11_common(info); 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); } if (brief != 0) { fprintf(outfile, "%s\n", url); goto cont; } else { 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); ret = gnutls_pkcs11_token_get_flags(url, &flags); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); } else { print_type(outfile, flags); } 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); size = sizeof(buf); ret = gnutls_pkcs11_token_get_info(url, GNUTLS_PKCS11_TOKEN_MODNAME, buf, &size); if (ret >= 0) { fprintf(outfile, "\tModule: %s\n", buf); } fprintf(outfile, "\n\n"); cont: gnutls_free(url); } return; }
void pkcs11_test_sign(FILE * outfile, const char *url, unsigned int flags, common_info_st * info) { gnutls_privkey_t privkey; gnutls_pubkey_t pubkey; int ret; gnutls_datum_t data, sig = {NULL, 0}; int pk; pkcs11_common(info); FIX(url, outfile, 0, info); data.data = (void*)TEST_DATA; data.size = sizeof(TEST_DATA)-1; ret = gnutls_privkey_init(&privkey); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } 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_privkey_import_url(privkey, url, flags); if (ret < 0) { fprintf(stderr, "Cannot import private key: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_pubkey_import_privkey(pubkey, privkey, GNUTLS_KEY_DIGITAL_SIGNATURE, flags); if (ret < 0) { fprintf(stderr, "Cannot import public key: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA1, 0, &data, &sig); if (ret < 0) { fprintf(stderr, "Cannot sign data: %s\n", gnutls_strerror(ret)); exit(1); } pk = gnutls_pubkey_get_pk_algorithm(pubkey, NULL); fprintf(stderr, "Verifying against private key parameters... "); ret = gnutls_pubkey_verify_data2(pubkey, gnutls_pk_to_sign(pk, GNUTLS_DIG_SHA1), 0, &data, &sig); if (ret < 0) { fprintf(stderr, "Cannot verify signed data: %s\n", gnutls_strerror(ret)); exit(1); } fprintf(stderr, "ok\n"); /* now try to verify against a public key within the token */ gnutls_pubkey_deinit(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_url(pubkey, url, flags); if (ret < 0) { fprintf(stderr, "Cannot find a corresponding public key object in token: %s\n", gnutls_strerror(ret)); if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) exit(0); exit(1); } fprintf(stderr, "Verifying against public key in the token... "); ret = gnutls_pubkey_verify_data2(pubkey, gnutls_pk_to_sign(pk, GNUTLS_DIG_SHA1), 0, &data, &sig); if (ret < 0) { fprintf(stderr, "Cannot verify signed data: %s\n", gnutls_strerror(ret)); exit(1); } fprintf(stderr, "ok\n"); gnutls_free(sig.data); gnutls_pubkey_deinit(pubkey); gnutls_privkey_deinit(privkey); UNFIX; }
int main (int argc, char **argv) { int ret; int ii, i, inp; char buffer[MAX_BUF + 1]; char *session_data = NULL; char *session_id = NULL; size_t session_data_size; size_t session_id_size = 0; int user_term = 0, retval = 0; socket_st hd; ssize_t bytes; set_program_name (argv[0]); gaa_parser (argc, argv); gnutls_global_set_log_function (tls_log_func); gnutls_global_set_log_level (info.debug); if ((ret = gnutls_global_init ()) < 0) { fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret)); exit (1); } #ifdef ENABLE_PKCS11 pkcs11_common (); #endif if (hostname == NULL) { fprintf (stderr, "No hostname given\n"); exit (1); } sockets_init (); #ifndef _WIN32 signal (SIGPIPE, SIG_IGN); #endif init_global_tls_stuff (); socket_open (&hd, hostname, service); socket_connect (&hd); hd.session = init_tls_session (hostname); if (starttls) goto after_handshake; for (i = 0; i < 2; i++) { if (i == 1) { 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, "*** Handshake has failed\n"); gnutls_perror (ret); gnutls_deinit (hd.session); return 1; } else { printf ("- Handshake was completed\n"); if (gnutls_session_is_resumed (hd.session) != 0) printf ("*** This is a resumed session\n"); } if (resume != 0 && i == 0) { gnutls_session_get_data (hd.session, NULL, &session_data_size); session_data = malloc (session_data_size); gnutls_session_get_data (hd.session, session_data, &session_data_size); gnutls_session_get_id (hd.session, NULL, &session_id_size); session_id = malloc (session_id_size); gnutls_session_get_id (hd.session, session_id, &session_id_size); /* print some information */ print_info (hd.session, hostname, info.insecure); printf ("- Disconnecting\n"); socket_bye (&hd); printf ("\n\n- Connecting again- trying to resume previous session\n"); socket_open (&hd, hostname, service); socket_connect (&hd); } else { break; } } after_handshake: /* 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) { ret = do_handshake (&hd); if (ret < 0) { fprintf (stderr, "*** ReHandshake has failed\n"); gnutls_perror (ret); gnutls_deinit (hd.session); return 1; } else { printf ("- ReHandshake was completed\n"); } } #ifndef _WIN32 signal (SIGALRM, &starttls_alarm); #endif fflush (stdout); fflush (stderr); /* do not buffer */ #if !(defined _WIN32 || defined __WIN32__) setbuf (stdin, NULL); #endif setbuf (stdout, NULL); setbuf (stderr, NULL); 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++; } } ret = socket_send (&hd, buffer, bytes); if (ret > 0) { if (verbose != 0) printf ("- Sent: %d bytes\n", ret); } else handle_error (&hd, ret); } } 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); #endif #ifdef ENABLE_PSK if (psk_cred) gnutls_psk_free_client_credentials (psk_cred); #endif gnutls_certificate_free_credentials (xcred); #ifdef ENABLE_ANON gnutls_anon_free_client_credentials (anon_cred); #endif gnutls_global_deinit (); return retval; }
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); } #ifdef ENABLE_PKCS11 pkcs11_common(NULL); #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; } else { if (HAVE_OPT(STARTTLS_PROTO)) port = starttls_proto_to_port(OPT_ARG(STARTTLS_PROTO)); } 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(); #endif gnutls_global_deinit(); }
void pkcs11_export_chain(FILE * outfile, const char *url, unsigned int flags, common_info_st * info) { gnutls_pkcs11_obj_t obj; gnutls_x509_crt_t xcrt; gnutls_datum_t t; int ret; unsigned int obj_flags = flags; pkcs11_common(info); FIX(url, outfile, 0, info); ret = gnutls_pkcs11_obj_init(&obj); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } ret = gnutls_pkcs11_obj_import_url(obj, url, obj_flags); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } /* make a 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, obj); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } ret = gnutls_pkcs11_obj_export3(obj, GNUTLS_X509_FMT_PEM, &t); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } fwrite(t.data, 1, t.size, outfile); fputs("\n\n", outfile); gnutls_free(t.data); gnutls_pkcs11_obj_deinit(obj); do { ret = gnutls_pkcs11_get_raw_issuer(url, xcrt, &t, GNUTLS_X509_FMT_PEM, 0); 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); } fwrite(t.data, 1, t.size, outfile); fputs("\n\n", outfile); gnutls_x509_crt_deinit(xcrt); 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(xcrt, &t, GNUTLS_X509_FMT_PEM); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } gnutls_free(t.data); ret = gnutls_x509_crt_check_issuer(xcrt, xcrt); if (ret != 0) { /* self signed */ break; } } while(1); UNFIX; return; }