static int getnextcert(DIR **dirp, gnutls_datum_t *der, int *exp_ret) { struct dirent *d; char path[256]; char cert_dir[256]; const char *src; int ret; gnutls_datum_t local; src = getenv("srcdir"); if (src == NULL) src = "."; snprintf(cert_dir, sizeof(cert_dir), "%s/%s", src, CERT_DIR); if (*dirp == NULL) { *dirp = opendir(cert_dir); if (*dirp == NULL) return -1; } do { d = readdir(*dirp); if (d != NULL #ifdef _DIRENT_HAVE_D_TYPE && d->d_type == DT_REG #endif ) { if (strstr(d->d_name, ".der") == 0) continue; if (strstr(d->d_name, ".err") != 0) continue; snprintf(path, sizeof(path), "%s/%s", cert_dir, d->d_name); success("Loading %s\n", path); ret = gnutls_load_file(path, der); if (ret < 0) { return -1; } snprintf(path, sizeof(path), "%s/%s.err", cert_dir, d->d_name); success("Loading errfile %s\n", path); ret = gnutls_load_file(path, &local); if (ret < 0) { /* not found assume success */ *exp_ret = 0; } else { *exp_ret = atoi((char*)local.data); success("expecting error code %d\n", *exp_ret); gnutls_free(local.data); local.data = NULL; } return 0; } } while(d != NULL); closedir(*dirp); return -1; /* finished */ }
/* Load the certificate and the private key. * (This code is largely taken from GnuTLS). */ static void load_keys(const char *hostname, const char *CERT_FILE, const char *KEY_FILE) { int ret; gnutls_datum_t data; struct Hosts *host; host = malloc (sizeof (struct Hosts)); if (NULL == host) abort (); host->hostname = hostname; host->next = hosts; hosts = host; ret = gnutls_load_file (CERT_FILE, &data); if (ret < 0) { fprintf (stderr, "*** Error loading certificate file %s.\n", CERT_FILE); exit (1); } ret = gnutls_pcert_import_x509_raw (&host->pcrt, &data, GNUTLS_X509_FMT_PEM, 0); if (ret < 0) { fprintf (stderr, "*** Error loading certificate file: %s\n", gnutls_strerror (ret)); exit (1); } gnutls_free (data.data); ret = gnutls_load_file (KEY_FILE, &data); if (ret < 0) { fprintf (stderr, "*** Error loading key file %s.\n", KEY_FILE); exit (1); } gnutls_privkey_init (&host->key); ret = gnutls_privkey_import_x509_raw (host->key, &data, GNUTLS_X509_FMT_PEM, NULL, 0); if (ret < 0) { fprintf (stderr, "*** Error loading key file: %s\n", gnutls_strerror (ret)); exit (1); } gnutls_free (data.data); }
int Key::import_file(const QString& File) { gnutls_datum_t contents = { NULL, 0 }; if (File.isEmpty() == true) { return -1; } if (this->imported != false) { this->clear(); } if (is_url(File) == true) { this->url = File; imported = true; return 0; } /* normal file */ int ret = gnutls_load_file(File.toLatin1().data(), &contents); if (ret < 0) { this->last_err = gnutls_strerror(ret); return -1; } ret = import_Key(this->w, &this->privkey, &contents); gnutls_free(contents.data); if (ret < 0) { this->last_err = gnutls_strerror(ret); return -1; } imported = true; return 0; }
/** * gnutls_pubkey_import_tpm_url: * @pkey: The public key * @url: The URL of the TPM key to be imported * @srk_password: The password for the SRK key (optional) * @flags: should be zero * * This function will import the given private key to the abstract * #gnutls_privkey_t type. * * Note that unless %GNUTLS_PUBKEY_DISABLE_CALLBACKS * is specified, if incorrect (or NULL) passwords are given * the PKCS11 callback functions will be used to obtain the * correct passwords. Otherwise if the SRK password is wrong * %GNUTLS_E_TPM_SRK_PASSWORD_ERROR is returned. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 3.1.0 * **/ int gnutls_pubkey_import_tpm_url(gnutls_pubkey_t pkey, const char *url, const char *srk_password, unsigned int flags) { struct tpmkey_url_st durl; gnutls_datum_t fdata = { NULL, 0 }; int ret; CHECK_INIT; ret = decode_tpmkey_url(url, &durl); if (ret < 0) return gnutls_assert_val(ret); if (durl.filename) { ret = gnutls_load_file(durl.filename, &fdata); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = gnutls_pubkey_import_tpm_raw(pkey, &fdata, GNUTLS_TPMKEY_FMT_CTK_PEM, srk_password, flags); if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) ret = gnutls_pubkey_import_tpm_raw(pkey, &fdata, GNUTLS_TPMKEY_FMT_RAW, srk_password, flags); if (ret < 0) { gnutls_assert(); goto cleanup; } } else if (durl.uuid_set) { if (flags & GNUTLS_PUBKEY_DISABLE_CALLBACKS) ret = import_tpm_pubkey(pkey, NULL, 0, &durl.uuid, durl.storage, srk_password); else ret = import_tpm_pubkey_cb(pkey, NULL, 0, &durl.uuid, durl.storage, srk_password); if (ret < 0) { gnutls_assert(); goto cleanup; } } ret = 0; cleanup: gnutls_free(fdata.data); clear_tpmkey_url(&durl); return ret; }
/* Helper functions to load a certificate and key * files into memory. */ static gnutls_datum_t load_file(const char *file) { gnutls_datum_t loaded_file = { NULL, 0 }; gnutls_load_file(file, &loaded_file); return loaded_file; }
/* Load the certificate and the private key. */ static void load_keys (void) { int ret; gnutls_datum_t data; ret = gnutls_load_file (CERT_FILE, &data); if (ret < 0) { fprintf (stderr, "*** Error loading certificate file.\n"); exit (1); } ret = gnutls_pcert_import_x509_raw (&pcrt, &data, GNUTLS_X509_FMT_PEM, 0); if (ret < 0) { fprintf (stderr, "*** Error loading certificate file: %s\n", gnutls_strerror (ret)); exit (1); } gnutls_free(data.data); ret = gnutls_load_file (KEY_FILE, &data); if (ret < 0) { fprintf (stderr, "*** Error loading key file.\n"); exit (1); } gnutls_privkey_init (&key); ret = gnutls_privkey_import_x509_raw (key, &data, GNUTLS_X509_FMT_PEM, NULL, 0); if (ret < 0) { fprintf (stderr, "*** Error loading key file: %s\n", gnutls_strerror (ret)); exit (1); } gnutls_free(data.data); }
static int file_ocsp_func(gnutls_session_t session, void *ptr, gnutls_datum_t * ocsp_response) { int ret; gnutls_certificate_credentials_t sc = ptr; ret = gnutls_load_file(sc->ocsp_response_file, ocsp_response); if (ret < 0) return gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_STATUS); return 0; }
int Cert::import_file(const QString& File) { if (File.isEmpty() == true) { return -1; } if (this->imported != false) { this->clear(); } if (is_url(File)) { gnutls_x509_crt_init(&this->crt); int ret = gnutls_x509_crt_import_pkcs11_url(this->crt, File.toLatin1().data(), 0); if (ret < 0) { ret = gnutls_x509_crt_import_pkcs11_url(this->crt, File.toLatin1().data(), GNUTLS_PKCS11_OBJ_FLAG_LOGIN); } if (ret < 0) { this->last_err = gnutls_strerror(ret); return -1; } this->imported = true; return 0; } /* normal file */ gnutls_datum_t contents = { nullptr, 0 }; int ret = gnutls_load_file(File.toLatin1().data(), &contents); if (ret < 0) { this->last_err = gnutls_strerror(ret); return -1; } ret = import_cert(&this->crt, &contents, 0); gnutls_free(contents.data); if (ret < 0) { this->last_err = gnutls_strerror(ret); return -1; } this->imported = true; return 0; }
gboolean li_gnutls_ocsp_add(liServer *srv, liGnuTLSOCSP *ocsp, const char* filename) { int r; gnutls_datum_t file = { NULL, 0 }; gnutls_datum_t decoded = { NULL, 0 }; gnutls_datum_t* der_data; gboolean result = FALSE; if (GNUTLS_E_SUCCESS > (r = gnutls_load_file(filename, &file))) { ERROR(srv, "Failed to load OCSP file '%s' (%s): %s", filename, gnutls_strerror_name(r), gnutls_strerror(r)); goto error; } /* decode pem "-----BEGIN OCSP RESPONSE-----", otherwise expect DER */ if (file.size > 20 && 0 == memcmp(file.data, CONST_STR_LEN("-----BEGIN "))) { r = gnutls_pem_base64_decode_alloc("OCSP RESPONSE", &file, &decoded); if (GNUTLS_E_SUCCESS > r) { ERROR(srv, "gnutls_pem_base64_decode_alloc failed to decode OCSP RESPONSE from '%s' (%s): %s", filename, gnutls_strerror_name(r), gnutls_strerror(r)); goto error; } der_data = &decoded; } else { der_data = &file; } result = add_response(srv, ocsp, der_data); if (!result) { ERROR(srv, "Failed loading OCSP response from '%s'", filename); } error: gnutls_free(file.data); gnutls_free(decoded.data); return result; }
gboolean li_gnutls_ocsp_search(liServer *srv, liGnuTLSOCSP *ocsp, const char* filename) { int r; gnutls_datum_t file = { NULL, 0 }; gnutls_datum_t decoded = { NULL, 0 }; gboolean result = FALSE; if (GNUTLS_E_SUCCESS > (r = gnutls_load_file(filename, &file))) { ERROR(srv, "Failed to load OCSP file '%s' (%s): %s", filename, gnutls_strerror_name(r), gnutls_strerror(r)); goto error; } r = gnutls_pem_base64_decode_alloc("OCSP RESPONSE", &file, &decoded); if (GNUTLS_E_SUCCESS <= r) { result = add_response(srv, ocsp, &decoded); if (!result) { ERROR(srv, "Failed loading OCSP response from '%s'", filename); goto error; } } else if (GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR == r) { /* ignore GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR */ } else { ERROR(srv, "gnutls_pem_base64_decode_alloc failed to decode OCSP RESPONSE from '%s' (%s): %s", filename, gnutls_strerror_name(r), gnutls_strerror(r)); /* continue anyway */ } result = TRUE; error: gnutls_free(file.data); gnutls_free(decoded.data); return result; }
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 = 1; 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 del = 0; unsigned vflags = DANE_VFLAG_FAIL_IF_NOT_CHECKED; const char *cstr; char *str; gnutls_x509_crt_t *clist = NULL; unsigned int clist_size = 0; gnutls_datum_t certs[MAX_CLIST_SIZE]; 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; if (!cinfo->cert) { const char *app_proto = NULL; if (HAVE_OPT(APP_PROTO)) app_proto = OPT_ARG(APP_PROTO); cinfo->cert = obtain_cert(host, proto, port, app_proto, HAVE_OPT(QUIET)); del = 1; } if (!HAVE_OPT(QUIET)) fprintf(stderr, "Querying DNS for %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)); retcode = 1; goto error; } 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)); retcode = 1; goto error; } } ret = dane_query_tlsa(s, &q, host, proto, port); if (ret < 0) { fprintf(stderr, "dane_query_tlsa: %s\n", dane_strerror(ret)); retcode = 1; goto error; } if (ENABLED_OPT(PRINT_RAW)) { gnutls_datum_t t; char **dane_data; int *dane_data_len; int secure; int bogus; ret = dane_query_to_raw_tlsa(q, &entries, &dane_data, &dane_data_len, &secure, &bogus); if (ret < 0) { fprintf(stderr, "dane_query_to_raw_tlsa: %s\n", dane_strerror(ret)); retcode = 1; goto error; } for (i=0;i<entries;i++) { size_t str_size; t.data = (void*)dane_data[i]; t.size = dane_data_len[i]; str_size = t.size * 2 + 1; str = gnutls_malloc(str_size); ret = gnutls_hex_encode(&t, str, &str_size); if (ret < 0) { fprintf(stderr, "gnutls_hex_encode: %s\n", dane_strerror(ret)); retcode = 1; goto error; } fprintf(outfile, "[%u]: %s\n", i, str); gnutls_free(str); } fprintf(outfile, "\n"); } if (cinfo->cert) { ret = gnutls_load_file(cinfo->cert, &file); if (ret < 0) { fprintf(stderr, "gnutls_load_file: %s\n", gnutls_strerror(ret)); retcode = 1; goto error; } 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)); retcode = 1; goto error; } if (clist_size > 0) { for (i = 0; i < MIN(MAX_CLIST_SIZE,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)); retcode = 1; goto error; } } } } 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)); retcode = 1; goto error; } size = lbuffer_size; ret = gnutls_hex_encode(&data, (void *) lbuffer, &size); if (ret < 0) { fprintf(stderr, "gnutls_hex_encode: %s\n", dane_strerror(ret)); retcode = 1; goto error; } if (entries > 1 && !HAVE_OPT(QUIET)) fprintf(outfile, "\n==== Entry %d ====\n", i + 1); fprintf(outfile, "_%u._%s.%s. IN TLSA ( %.2x %.2x %.2x %s )\n", port, proto, host, usage, type, match, lbuffer); if (!HAVE_OPT(QUIET)) { cstr = dane_cert_usage_name(usage); if (cstr == NULL) cstr= "Unknown"; fprintf(outfile, "Certificate usage: %s (%.2x)\n", cstr, usage); cstr = dane_cert_type_name(type); if (cstr == NULL) cstr= "Unknown"; fprintf(outfile, "Certificate type: %s (%.2x)\n", cstr, type); cstr = dane_match_type_name(match); if (cstr == NULL) cstr= "Unknown"; fprintf(outfile, "Contents: %s (%.2x)\n", cstr, match); fprintf(outfile, "Data: %s\n", lbuffer); } /* Verify the DANE data */ if (cinfo->cert) { unsigned int status; gnutls_datum_t out; 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)); retcode = 1; goto error; } ret = dane_verification_status_print(status, &out, 0); if (ret < 0) { fprintf(stderr, "dane_verification_status_print: %s\n", dane_strerror(ret)); retcode = 1; goto error; } if (!HAVE_OPT(QUIET)) fprintf(outfile, "\nVerification: %s\n", out.data); gnutls_free(out.data); /* if there is at least one correct accept */ if (status == 0) retcode = 0; } else { fprintf(stderr, "\nCertificate could not be obtained. You can explicitly load the certificate using --load-certificate.\n"); } } if (clist_size > 0) { for (i = 0; i < clist_size; i++) { gnutls_free(certs[i].data); gnutls_x509_crt_deinit(clist[i]); } gnutls_free(clist); } dane_query_deinit(q); dane_state_deinit(s); error: if (del != 0 && cinfo->cert) { remove(cinfo->cert); } exit(retcode); #else fprintf(stderr, "This functionality is disabled (GnuTLS was not compiled with support for DANE).\n"); return; #endif }
void doit(void) { #ifdef ENABLE_NON_SUITEB_CURVES const char *filename, *password = "******"; gnutls_pkcs12_t pkcs12; gnutls_datum_t data; gnutls_x509_crt_t *chain, *extras; unsigned int chain_size = 0, extras_size = 0, i; gnutls_x509_privkey_t pkey; int ret; ret = global_init(); if (ret < 0) fail("global_init failed %d\n", ret); gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(2); ret = gnutls_pkcs12_init(&pkcs12); if (ret < 0) fail("initialization failed: %s\n", gnutls_strerror(ret)); filename = getenv("PKCS12_MANY_CERTS_FILE"); if (!filename) filename = "pkcs12-decode/pkcs12_5certs.p12"; if (debug) success ("Reading PKCS#12 blob from `%s' using password `%s'.\n", filename, password); ret = gnutls_load_file(filename, &data); if (ret < 0) fail("cannot open file"); ret = gnutls_pkcs12_import(pkcs12, &data, GNUTLS_X509_FMT_DER, 0); if (ret < 0) fail("pkcs12_import failed %d: %s\n", ret, gnutls_strerror(ret)); if (debug) success("Read file OK\n"); ret = gnutls_pkcs12_simple_parse(pkcs12, password, &pkey, &chain, &chain_size, &extras, &extras_size, NULL, 0); if (ret < 0) fail("pkcs12_simple_parse failed %d: %s\n", ret, gnutls_strerror(ret)); if (chain_size != 1) fail("chain size (%u) should have been 1\n", chain_size); if (extras_size != 4) fail("extras size (%u) should have been 4\n", extras_size); if (debug) { char dn[512]; size_t dn_size; dn_size = sizeof(dn); ret = gnutls_x509_crt_get_dn(chain[0], dn, &dn_size); if (ret < 0) fail("crt_get_dn failed %d: %s\n", ret, gnutls_strerror(ret)); success("dn: %s\n", dn); dn_size = sizeof(dn); ret = gnutls_x509_crt_get_issuer_dn(chain[0], dn, &dn_size); if (ret < 0) fail("crt_get_dn failed %d: %s\n", ret, gnutls_strerror(ret)); success("issuer dn: %s\n", dn); } gnutls_pkcs12_deinit(pkcs12); gnutls_x509_privkey_deinit(pkey); for (i = 0; i < chain_size; i++) gnutls_x509_crt_deinit(chain[i]); gnutls_free(chain); for (i = 0; i < extras_size; i++) gnutls_x509_crt_deinit(extras[i]); gnutls_free(extras); /* Try gnutls_x509_privkey_import2() */ ret = gnutls_x509_privkey_init(&pkey); if (ret < 0) fail("gnutls_x509_privkey_init failed %d: %s\n", ret, gnutls_strerror(ret)); ret = gnutls_x509_privkey_import2(pkey, &data, GNUTLS_X509_FMT_DER, password, 0); if (ret < 0) fail("gnutls_x509_privkey_import2 failed %d: %s\n", ret, gnutls_strerror(ret)); gnutls_x509_privkey_deinit(pkey); free(data.data); gnutls_global_deinit(); #else exit(77); #endif }
int main(int argc, char *argv[]) { int ret = 1; int i; gnutls_pubkey_t pubkey = NULL; gnutls_x509_privkey_t sigkey = NULL; gnutls_x509_crt_t sigcert = NULL; gnutls_x509_crt_t crt = NULL; const char *pubkey_filename = NULL; const char *sigkey_filename = NULL; const char *cert_filename = NULL; const char *modulus_str = NULL; const char *issuercert_filename = NULL; unsigned char *modulus_bin = NULL; int modulus_len = 0; gnutls_datum_t datum = { NULL, 0}, out = { NULL, 0}; int serial = 1; time_t now; int err; FILE *cert_file; char *subject = NULL; const char *error = NULL; int days = 365; char *sigkeypass = NULL; uint32_t ser_number; long int exponent = 0x10001; bool write_pem = false; uint8_t id[512]; size_t id_size = sizeof(id); enum cert_type_t certtype = CERT_TYPE_EK; const char *oid; unsigned int key_usage; char *tpm_manufacturer = NULL; char *tpm_version = NULL; char *tpm_model = NULL; char *platf_manufacturer = NULL; char *platf_version = NULL; char *platf_model = NULL; i = 1; while (i < argc) { if (!strcmp(argv[i], "--pubkey")) { i++; if (i == argc) { fprintf(stderr, "Missing argument for --pubkey.\n"); goto cleanup; } pubkey_filename = argv[i]; } else if (!strcmp(argv[i], "--modulus")) { i++; if (i == argc) { fprintf(stderr, "Missing argument for --modulus.\n"); goto cleanup; } modulus_str = argv[i]; if (!(modulus_bin = hex_str_to_bin(modulus_str, &modulus_len))) { goto cleanup; } } else if (!strcmp(argv[i], "--exponent")) { i++; if (i == argc) { fprintf(stderr, "Missing argument for --exponent.\n"); goto cleanup; } exponent = strtol(argv[i], NULL, 0); if (exponent == 0) { fprintf(stderr, "Exponent is wrong and cannot be 0.\n"); goto cleanup; } if (exponent > UINT_MAX) { fprintf(stderr, "Exponent must fit into 32bits.\n"); goto cleanup; } } else if (!strcmp(argv[i], "--signkey")) { i++; if (i == argc) { fprintf(stderr, "Missing argument for --signkey.\n"); goto cleanup; } sigkey_filename = argv[i]; } else if (!strcmp(argv[i], "--signkey-password")) { i++; if (i == argc) { fprintf(stderr, "Missing argument for --signkey-password.\n"); goto cleanup; } sigkeypass = argv[i]; } else if (!strcmp(argv[i], "--issuercert")) { i++; if (i == argc) { fprintf(stderr, "Missing argument for --issuercert.\n"); goto cleanup; } issuercert_filename = argv[i]; } else if (!strcmp(argv[i], "--out-cert")) { i++; if (i == argc) { fprintf(stderr, "Missing argument for --out-cert.\n"); goto cleanup; } cert_filename = argv[i]; } else if (!strcmp(argv[i], "--subject")) { i++; if (i == argc) { fprintf(stderr, "Missing argument for --subject.\n"); goto cleanup; } subject = argv[i]; } else if (!strcmp(argv[i], "--days")) { i++; if (i == argc) { fprintf(stderr, "Missing argument for --days.\n"); goto cleanup; } days = atoi(argv[i]); } else if (!strcmp(argv[i], "--serial")) { i++; if (i == argc) { fprintf(stderr, "Missing argument for --serial.\n"); goto cleanup; } serial = atoi(argv[i]); } else if (!strcmp(argv[i], "--type")) { i++; if (i == argc) { fprintf(stderr, "Missing argument for --type.\n"); goto cleanup; } if (!strcasecmp(argv[i], "ek")) { certtype = CERT_TYPE_EK; } else if (!strcasecmp(argv[i], "platform")) { certtype = CERT_TYPE_PLATFORM; // } else if (!strcasecmp(argv[i], "aik")) { // /* AIK cert needs EK cert as input */ // certtype = CERT_TYPE_AIK; } else { fprintf(stderr, "Unknown certificate type '%s'.\n", argv[i]); goto cleanup; } } else if (!strcmp(argv[i], "--tpm-manufacturer")) { i++; if (i == argc) { fprintf(stderr, "Missing argument for --tpm-manufacturer.\n"); goto cleanup; } tpm_manufacturer = argv[i]; } else if (!strcmp(argv[i], "--tpm-model")) { i++; if (i == argc) { fprintf(stderr, "Missing argument for --tpm-model.\n"); goto cleanup; } tpm_model = argv[i]; } else if (!strcmp(argv[i], "--tpm-version")) { i++; if (i == argc) { fprintf(stderr, "Missing argument for --tpm-version.\n"); goto cleanup; } tpm_version = argv[i]; } else if (!strcmp(argv[i], "--platform-manufacturer")) { i++; if (i == argc) { fprintf(stderr, "Missing argument for --platform-manufacturer.\n"); goto cleanup; } platf_manufacturer = argv[i]; } else if (!strcmp(argv[i], "--platform-model")) { i++; if (i == argc) { fprintf(stderr, "Missing argument for --platform-model.\n"); goto cleanup; } platf_model = argv[i]; } else if (!strcmp(argv[i], "--platform-version")) { i++; if (i == argc) { fprintf(stderr, "Missing argument for --platform-version.\n"); goto cleanup; } platf_version = argv[i]; } else if (!strcmp(argv[i], "--pem")) { write_pem = true; } else if (!strcmp(argv[i], "--help")) { usage(argv[0]); exit(0); } else { fprintf(stderr, "Unknown command line parameter '%s'.\n", argv[i]); usage(argv[0]); exit(1); } i++; } ser_number = htonl(serial); if (pubkey_filename == NULL && modulus_bin == NULL) { fprintf(stderr, "Missing public EK file and modulus.\n"); usage(argv[0]); goto cleanup; } if (issuercert_filename == NULL) { fprintf(stderr, "The issuer certificate name is required.\n"); goto cleanup; } switch (certtype) { case CERT_TYPE_EK: case CERT_TYPE_PLATFORM: if (tpm_manufacturer == NULL || tpm_model == NULL || tpm_version == NULL) { fprintf(stderr, "--tpm-manufacturer and --tpm-model and " "--tpm version " "must all be provided\n"); goto cleanup; } break; case CERT_TYPE_AIK: break; } switch (certtype) { case CERT_TYPE_PLATFORM: if (platf_manufacturer == NULL || platf_model == NULL || platf_version == NULL) { fprintf(stderr, "--platform-manufacturer and --platform-model and " "--platform version " "must all be provided\n"); goto cleanup; } break; case CERT_TYPE_EK: case CERT_TYPE_AIK: break; } err = gnutls_global_init(); if (err < 0) { fprintf(stderr, "gnutls_global_init failed.\n"); goto cleanup; } gnutls_x509_privkey_init(&sigkey); if (pubkey_filename) { gnutls_pubkey_init(&pubkey); err = gnutls_load_file(pubkey_filename, &datum); if (err != GNUTLS_E_SUCCESS) { fprintf(stderr, "Could not open file for EK public key: %s\n", strerror(errno)); goto cleanup; } err = gnutls_pubkey_import(pubkey, &datum, GNUTLS_X509_FMT_PEM); gnutls_free(datum.data); datum.data = NULL; if (err != GNUTLS_E_SUCCESS) { fprintf(stderr, "Could not import EK.\n"); goto cleanup; } } else { pubkey = create_rsa_from_modulus(modulus_bin, modulus_len, exponent); free(modulus_bin); modulus_bin = NULL; if (pubkey == NULL) goto cleanup; } /* all types of keys must have pubkey set now otherwise the signing will not work */ if (sigkey_filename == NULL) { fprintf(stderr, "Missing signature key.\n"); usage(argv[0]); exit(1); } #define CHECK_GNUTLS_ERROR(_err, _msg, ...) \ if (_err != GNUTLS_E_SUCCESS) { \ fprintf(stderr, _msg, __VA_ARGS__); \ goto cleanup; \ } err = gnutls_load_file(sigkey_filename, &datum); CHECK_GNUTLS_ERROR(err, "Could not read signing key from file %s: %s\n", sigkey_filename, gnutls_strerror(err)); if (sigkeypass) { err = gnutls_x509_privkey_import2(sigkey, &datum, GNUTLS_X509_FMT_PEM, sigkeypass, 0); } else { err = gnutls_x509_privkey_import(sigkey, &datum, GNUTLS_X509_FMT_PEM); } gnutls_free(datum.data); datum.data = NULL; CHECK_GNUTLS_ERROR(err, "Could not import signing key : %s\n", gnutls_strerror(err)); err = gnutls_load_file(issuercert_filename, &datum); CHECK_GNUTLS_ERROR(err, "Could not read certificate from file %s : %s\n", issuercert_filename, gnutls_strerror(err)); gnutls_x509_crt_init(&sigcert); err = gnutls_x509_crt_import(sigcert, &datum, GNUTLS_X509_FMT_PEM); gnutls_free(datum.data); datum.data = NULL; CHECK_GNUTLS_ERROR(err, "Could not import issuer certificate: %s\n", gnutls_strerror(err)); err = gnutls_x509_crt_init(&crt); CHECK_GNUTLS_ERROR(err, "CRT init failed: %s\n", gnutls_strerror(err)) /* 3.5.1 Version */ err = gnutls_x509_crt_set_version(crt, 3); CHECK_GNUTLS_ERROR(err, "Could not set version on CRT: %s\n", gnutls_strerror(err)) /* 3.5.2 Serial Number */ err = gnutls_x509_crt_set_serial(crt, &ser_number, sizeof(ser_number)); CHECK_GNUTLS_ERROR(err, "Could not set serial on CRT: %s\n", gnutls_strerror(err)) /* 3.5.5 Validity */ now = time(NULL); err = gnutls_x509_crt_set_activation_time(crt, now); CHECK_GNUTLS_ERROR(err, "Could not set activation time on CRT: %s\n", gnutls_strerror(err)) err = gnutls_x509_crt_set_expiration_time(crt, now + (time_t)days * 24 * 60 * 60); CHECK_GNUTLS_ERROR(err, "Could not set expiration time on CRT: %s\n", gnutls_strerror(err)) /* 3.5.6 Subject -- should be empty, but we allow it anyway */ if (subject) { err = gnutls_x509_crt_set_dn(crt, subject, &error); CHECK_GNUTLS_ERROR(err, "Could not set DN on CRT: %s\n" "DN '%s must be fault after %s\n.'", gnutls_strerror(err), subject, error) } /* 3.5.7 Public Key Info */ switch (certtype) { case CERT_TYPE_EK: oid = "1.2.840.113549.1.1.7"; break; case CERT_TYPE_PLATFORM: oid = NULL; break; case CERT_TYPE_AIK: oid = "1.2.840.113549.1.1.1"; break; default: fprintf(stderr, "Internal error: unhandle case in line %d\n", __LINE__); goto cleanup; } if (oid) { err = gnutls_x509_crt_set_key_purpose_oid(crt, oid, 0); CHECK_GNUTLS_ERROR(err, "Could not set key purpose on CRT: %s\n", gnutls_strerror(err)) } /* 3.5.8 Certificate Policies -- skip since not mandated */ /* 3.5.9 Subject Alternative Names -- missing code */ err = create_tpm_manufacturer_info(tpm_manufacturer, tpm_model, tpm_version, &datum); if (!err && datum.size > 0) { /* * GNUTLS's write_new_general_name can only handle a few GNUTLS_SAN_* * -> we have to use GNUTLS_SAN_URI */ err = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_URI, datum.data, datum.size, GNUTLS_FSAN_SET); CHECK_GNUTLS_ERROR(err, "Could not set subject alt name: %s\n", gnutls_strerror(err)) }
/* Loads a x509 private key list */ 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; }
/* Run an HMAC using the key above on the library binary data. * Returns true on success and false on error. */ static unsigned check_binary_integrity(const char* libname, const char* symbol) { int ret; unsigned prev; char mac_file[GNUTLS_PATH_MAX]; char file[GNUTLS_PATH_MAX]; uint8_t hmac[HMAC_SIZE]; uint8_t new_hmac[HMAC_SIZE]; size_t hmac_size; gnutls_datum_t data; ret = get_library_path(libname, symbol, file, sizeof(file)); if (ret < 0) { _gnutls_debug_log("Could not get path for library %s\n", libname); return 0; } _gnutls_debug_log("Loading: %s\n", file); ret = gnutls_load_file(file, &data); if (ret < 0) { _gnutls_debug_log("Could not load: %s\n", file); return gnutls_assert_val(0); } prev = _gnutls_get_lib_state(); _gnutls_switch_lib_state(LIB_STATE_OPERATIONAL); ret = gnutls_hmac_fast(HMAC_ALGO, FIPS_KEY, sizeof(FIPS_KEY)-1, data.data, data.size, new_hmac); _gnutls_switch_lib_state(prev); gnutls_free(data.data); if (ret < 0) return gnutls_assert_val(0); /* now open the .hmac file and compare */ get_hmac_file(mac_file, sizeof(mac_file), file); ret = gnutls_load_file(mac_file, &data); if (ret < 0) { get_hmac_file2(mac_file, sizeof(mac_file), file); ret = gnutls_load_file(mac_file, &data); if (ret < 0) { _gnutls_debug_log("Could not open %s for MAC testing: %s\n", mac_file, gnutls_strerror(ret)); return gnutls_assert_val(0); } } hmac_size = hex_data_size(data.size); ret = gnutls_hex_decode(&data, hmac, &hmac_size); gnutls_free(data.data); if (ret < 0) { _gnutls_debug_log("Could not convert hex data to binary for MAC testing for %s.\n", libname); return gnutls_assert_val(0); } if (hmac_size != sizeof(hmac) || memcmp(hmac, new_hmac, sizeof(hmac)) != 0) { _gnutls_debug_log("Calculated MAC for %s does not match\n", libname); return gnutls_assert_val(0); } _gnutls_debug_log("Successfully verified MAC for %s (%s)\n", mac_file, libname); return 1; }
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); #else fprintf(stderr, "This functionality was disabled (GnuTLS was not compiled with support for DANE).\n"); return; #endif }
static int load_keys(sec_mod_st *sec, unsigned force) { unsigned i, need_reload = 0; int ret; struct pin_st pins; static time_t last_access = 0; for (i = 0; i < sec->perm_config->key_size; i++) { if (need_file_reload(sec->perm_config->key[i], last_access) != 0) { need_reload = 1; break; } } if (need_reload == 0) return 0; last_access = time(0); ret = load_pins(sec->perm_config, &pins); if (ret < 0) { seclog(sec, LOG_ERR, "error loading PIN files"); exit(1); } /* Reminder: the number of private keys or their filenames cannot be changed on reload */ if (sec->key == NULL) { sec->key_size = sec->perm_config->key_size; sec->key = talloc_zero_size(sec, sizeof(*sec->key) * sec->perm_config->key_size); if (sec->key == NULL) { seclog(sec, LOG_ERR, "error in memory allocation"); exit(1); } } /* read private keys */ for (i = 0; i < sec->key_size; i++) { gnutls_privkey_t p; ret = gnutls_privkey_init(&p); CHECK_LOOP_ERR(ret); /* load the private key */ if (gnutls_url_is_supported(sec->perm_config->key[i]) != 0) { gnutls_privkey_set_pin_function(p, pin_callback, &pins); ret = gnutls_privkey_import_url(p, sec->perm_config->key[i], 0); CHECK_LOOP_ERR(ret); } else { gnutls_datum_t data; ret = gnutls_load_file(sec->perm_config->key[i], &data); if (ret < 0) { seclog(sec, LOG_ERR, "error loading file '%s'", sec->perm_config->key[i]); CHECK_LOOP_ERR(ret); } ret = gnutls_privkey_import_x509_raw(p, &data, GNUTLS_X509_FMT_PEM, NULL, 0); if (ret == GNUTLS_E_DECRYPTION_FAILED && pins.pin[0]) { ret = gnutls_privkey_import_x509_raw(p, &data, GNUTLS_X509_FMT_PEM, pins.pin, 0); } CHECK_LOOP_ERR(ret); gnutls_free(data.data); } if (sec->key[i] != NULL) { gnutls_privkey_deinit(sec->key[i]); } sec->key[i] = p; } return 0; }
void sec_mod_server(struct cfg_st* config, const char* socket_file) { struct sockaddr_un sa; socklen_t sa_len; int cfd, ret, e; unsigned i, buffer_size, type; gnutls_privkey_t *key; uint8_t *buffer; unsigned key_size = config->key_size; struct pin_st pins; gnutls_datum_t data, out; uint16_t length; struct iovec iov[2]; int sd; #if defined(SO_PEERCRED) && defined(HAVE_STRUCT_UCRED) struct ucred cr; socklen_t cr_len; #endif ocsignal(SIGHUP, SIG_IGN); ocsignal(SIGINT, SIG_DFL); ocsignal(SIGTERM, SIG_DFL); #ifdef HAVE_PKCS11 ret = gnutls_pkcs11_reinit(); if (ret < 0) { syslog(LOG_WARNING, "error in PKCS #11 reinitialization: %s", gnutls_strerror(ret)); } #endif buffer_size = 8*1024; buffer = malloc(buffer_size); if (buffer == NULL) { syslog(LOG_ERR, "error in memory allocation"); exit(1); } memset(&sa, 0, sizeof(sa)); sa.sun_family = AF_UNIX; snprintf(sa.sun_path, sizeof(sa.sun_path), "%s", socket_file); remove(socket_file); sd = socket(AF_UNIX, SOCK_STREAM, 0); if (sd == -1) { e = errno; syslog(LOG_ERR, "could not create socket '%s': %s", socket_file, strerror(e)); exit(1); } umask(066); ret = bind(sd, (struct sockaddr *)&sa, SUN_LEN(&sa)); if (ret == -1) { e = errno; syslog(LOG_ERR, "could not bind socket '%s': %s", socket_file, strerror(e)); exit(1); } ret = chown(socket_file, config->uid, config->gid); if (ret == -1) { e = errno; syslog(LOG_ERR, "could not chown socket '%s': %s", socket_file, strerror(e)); } ret = listen(sd, 1024); if (ret == -1) { e = errno; syslog(LOG_ERR, "could not listen to socket '%s': %s", socket_file, strerror(e)); exit(1); } ret = load_pins(config, &pins); if (ret < 0) { syslog(LOG_ERR, "error loading PIN files"); exit(1); } key = malloc(sizeof(*key)*config->key_size); if (key == NULL) { syslog(LOG_ERR, "error in memory allocation"); exit(1); } /* read private keys */ for (i=0;i<key_size;i++) { ret = gnutls_privkey_init(&key[i]); GNUTLS_FATAL_ERR(ret); /* load the private key */ if (gnutls_url_is_supported(config->key[i]) != 0) { gnutls_privkey_set_pin_function (key[i], pin_callback, &pins); ret = gnutls_privkey_import_url(key[i], config->key[i], 0); GNUTLS_FATAL_ERR(ret); } else { ret = gnutls_load_file(config->key[i], &data); if (ret < 0) { syslog(LOG_ERR, "error loading file '%s'", config->key[i]); GNUTLS_FATAL_ERR(ret); } ret = gnutls_privkey_import_x509_raw(key[i], &data, GNUTLS_X509_FMT_PEM, NULL, 0); GNUTLS_FATAL_ERR(ret); gnutls_free(data.data); } } syslog(LOG_INFO, "sec-mod initialized (socket: %s)", socket_file); for (;;) { sa_len = sizeof(sa); cfd = accept(sd, (struct sockaddr *)&sa, &sa_len); if (cfd == -1) { e = errno; syslog(LOG_ERR, "sec-mod error accepting connection: %s", strerror(e)); continue; } #if defined(SO_PEERCRED) && defined(HAVE_STRUCT_UCRED) cr_len = sizeof(cr); ret = getsockopt(cfd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len); if (ret == -1) { e = errno; syslog(LOG_ERR, "sec-mod error obtaining peer credentials: %s", strerror(e)); goto cont; } syslog(LOG_DEBUG, "sec-mod received request from pid %u and uid %u", (unsigned)cr.pid, (unsigned)cr.uid); if (cr.uid != config->uid || cr.gid != config->gid) { syslog(LOG_ERR, "sec-mod received unauthorized request from pid %u and uid %u", (unsigned)cr.pid, (unsigned)cr.uid); goto cont; } #endif /* read request */ ret = recv(cfd, buffer, buffer_size, 0); if (ret == 0) goto cont; else if (ret <= 2) { e = errno; syslog(LOG_ERR, "error receiving sec-mod data: %s", strerror(e)); goto cont; } /* calculate */ i = buffer[0]; type = buffer[1]; if (i >= key_size) { syslog(LOG_ERR, "sec-mod received out-of-bounds key index"); goto cont; } data.data = &buffer[2]; data.size = ret - 2; if (type == 'S') { #if GNUTLS_VERSION_NUMBER >= 0x030200 ret = gnutls_privkey_sign_hash(key[i], 0, GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA, &data, &out); #else ret = gnutls_privkey_sign_raw_data(key[i], 0, &data, &out); #endif } else if (type == 'D') { ret = gnutls_privkey_decrypt_data(key[i], 0, &data, &out); } else { syslog(LOG_ERR, "unknown type 0x%.2x", type); goto cont; } if (ret < 0) { syslog(LOG_ERR, "sec-mod error in crypto operation: %s", gnutls_strerror(ret)); goto cont; } /* write reply */ length = out.size; iov[0].iov_base = &length; iov[0].iov_len = 2; iov[1].iov_base = out.data; iov[1].iov_len = out.size; ret = writev(cfd, iov, 2); if (ret == -1) { e = errno; syslog(LOG_ERR, "sec-mod error in writev: %s", strerror(e)); } gnutls_free(out.data); cont: close(cfd); } }
/* Load the certificate and the private key. */ 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) { #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); } #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"); } #endif }