示例#1
0
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 */
}
示例#2
0
/* 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);
}
示例#3
0
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;
}
示例#4
0
文件: tpm.c 项目: gnutls/gnutls
/**
 * 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;
}
示例#5
0
/* 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;
}
示例#6
0
/* 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);
}
示例#7
0
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;
}
示例#8
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;
}
示例#9
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;
}
示例#10
0
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;
}
示例#11
0
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
}
示例#12
0
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
}
示例#13
0
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))
    }
示例#14
0
/* 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;
}
示例#15
0
/* 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;
}
示例#16
0
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
}
示例#17
0
文件: sec-mod.c 项目: xyz12810/ocserv
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;
}
示例#18
0
文件: sec-mod.c 项目: cernekee/ocserv
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);
	}
}
示例#19
0
文件: cli.c 项目: nobled/gnutls
/* 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

}