Пример #1
0
/* Reads a private key from a token.
 */
static int
read_key_url(gnutls_certificate_credentials_t res, const char *url, gnutls_privkey_t *rkey)
{
	int ret;
	gnutls_privkey_t pkey = NULL;

	/* allocate space for the pkey list
	 */
	ret = gnutls_privkey_init(&pkey);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	if (res->pin.cb)
		gnutls_privkey_set_pin_function(pkey, res->pin.cb,
						res->pin.data);

	ret = gnutls_privkey_import_url(pkey, url, 0);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	*rkey = pkey;

	return 0;

      cleanup:
	if (pkey)
		gnutls_privkey_deinit(pkey);

	return ret;
}
Пример #2
0
void doit(void)
{
	int ret, status;
	const char *lib;
	gnutls_privkey_t pkey;
	pid_t pid;

	signal(SIGPIPE, SIG_IGN);

	gnutls_pkcs11_set_pin_function(pin_func, NULL);
	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(4711);

	lib = getenv("P11MOCKLIB1");
	if (lib == NULL)
		lib = P11LIB;

	ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
	if (ret != 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pkcs11_add_provider(lib, NULL);
	if (ret != 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	assert(gnutls_privkey_init(&pkey) == 0);

	ret = gnutls_privkey_import_url(pkey, "pkcs11:object=test", GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
	if (ret < 0) {
		fprintf(stderr, "error in %d: %s\n", __LINE__, gnutls_strerror(ret));
		exit(1);
	}

	/* fork to force PKCS#11 reinitialization */
	pid = fork();
	if (pid == -1) {
		exit(1);
	} else if (pid) {
                waitpid(pid, &status, 0);
                check_wait_status(status);
                goto cleanup;
	}

	do_thread_stuff(pkey);

 cleanup:
	gnutls_privkey_deinit(pkey);
}
Пример #3
0
static gnutls_privkey_t _load_url_privkey(const char* url)
{
int ret;
gnutls_privkey_t key;

  ret = gnutls_privkey_init (&key);
  if (ret < 0)
    error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));

  ret = gnutls_privkey_import_url(key, url, 0);
  if (ret < 0)
    error (EXIT_FAILURE, 0, "importing key: %s: %s",
           url, gnutls_strerror (ret));

  return key;
}
Пример #4
0
static gnutls_privkey_t _load_url_privkey(const char *url)
{
	int ret;
	gnutls_privkey_t key;

	ret = gnutls_privkey_init(&key);
	if (ret < 0) {
		fprintf(stderr, "privkey_init: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_privkey_import_url(key, url, 0);
	if (ret < 0) {
		fprintf(stderr, "importing key: %s: %s\n",
			url, gnutls_strerror(ret));
		exit(1);
	}

	return key;
}
Пример #5
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);
	}
}
Пример #6
0
void doit(void)
{
	int ret;
	const char *lib;
	gnutls_privkey_t key;
	gnutls_pkcs11_obj_t obj;
	gnutls_datum_t sig = {NULL, 0}, data;
	unsigned flags = 0;

	lib = getenv("P11MOCKLIB1");
	if (lib == NULL)
		lib = P11LIB;

	{
		void *dl;
		unsigned int *pflags;

		dl = dlopen(lib, RTLD_NOW);
		if (dl == NULL) {
			fail("could not dlopen %s\n", lib);
			exit(1);
		}

		pflags = dlsym(dl, "pkcs11_mock_flags");
		if (pflags == NULL) {
			fail("could find pkcs11_mock_flags\n");
			exit(1);
		}

		*pflags = MOCK_FLAG_ALWAYS_AUTH;
	}

	data.data = (void*)"\x38\x17\x0c\x08\xcb\x45\x8f\xd4\x87\x9c\x34\xb6\xf6\x08\x29\x4c\x50\x31\x2b\xbb";
	data.size = 20;

	ret = global_init();
	if (ret != 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(4711);

	ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
	if (ret != 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pkcs11_add_provider(lib, NULL);
	if (ret != 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pkcs11_obj_init(&obj);
	assert(ret>=0);

	gnutls_pkcs11_obj_set_pin_function(obj, pin_func, NULL);

	ret = gnutls_pkcs11_obj_import_url(obj, "pkcs11:object=test;type=private", GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
	assert(ret>=0);

	ret = gnutls_pkcs11_obj_get_flags(obj, &flags);
	assert(ret>=0);

	if (!(flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_ALWAYS_AUTH)) {
		fail("key object doesn't have the always authenticate flag\n");
	}
	gnutls_pkcs11_obj_deinit(obj);


	ret = gnutls_privkey_init(&key);
	assert(ret>=0);

	gnutls_privkey_set_pin_function(key, pin_func, NULL);

	ret = gnutls_privkey_import_url(key, "pkcs11:object=test", GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
	if (ret < 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	pin_called = 0;

	ret = gnutls_privkey_sign_hash(key, GNUTLS_DIG_SHA1, 0, &data, &sig);
	if (ret < 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	if (pin_called == 0) {
		fail("PIN function wasn't called!\n");
	}
	pin_called = 0;

	gnutls_free(sig.data);

	/* call again - should re-authenticate */
	ret = gnutls_privkey_sign_hash(key, GNUTLS_DIG_SHA1, 0, &data, &sig);
	if (ret < 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	if (pin_called == 0) {
		fail("PIN function wasn't called twice!\n");
	}
	pin_called = 0;

	gnutls_free(sig.data);

	if (debug)
		printf("done\n\n\n");

	gnutls_privkey_deinit(key);
	gnutls_pkcs11_deinit();
	gnutls_global_deinit();
}
Пример #7
0
void doit(void)
{
	int ret;
	const char *lib;
	gnutls_privkey_t key;
	gnutls_pubkey_t pub;
	gnutls_datum_t m1, e1;
	gnutls_datum_t m2, e2;

	ret = global_init();
	if (ret != 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(4711);

	lib = getenv("P11MOCKLIB1");
	if (lib == NULL)
		lib = P11LIB;

	ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
	if (ret != 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pkcs11_add_provider(lib, NULL);
	if (ret != 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_privkey_init(&key);
	assert(ret>=0);
	ret = gnutls_pubkey_init(&pub);
	assert(ret>=0);

	gnutls_privkey_set_pin_function(key, pin_func, NULL);

	ret = gnutls_privkey_import_url(key, "pkcs11:object=test", GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
	if (ret < 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pubkey_import_privkey(pub, key, 0, 0);
	if (ret < 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pubkey_export_rsa_raw(pub, &m1, &e1);
	if (ret < 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	gnutls_pubkey_deinit(pub);
	gnutls_privkey_deinit(key);

	/* try again using gnutls_pubkey_import_url */	
	ret = gnutls_pubkey_init(&pub);
	assert(ret>=0);

	ret = gnutls_pubkey_import_url(pub, "pkcs11:object=test;type=public", 0);
	if (ret < 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pubkey_export_rsa_raw(pub, &m2, &e2);
	if (ret < 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	assert(m1.size == m2.size);
	assert(e1.size == e2.size);
	assert(memcmp(e1.data, e2.data, e2.size)==0);
	assert(memcmp(m1.data, m2.data, m2.size)==0);

	gnutls_pubkey_deinit(pub);
	gnutls_free(m1.data);
	gnutls_free(e1.data);
	gnutls_free(m2.data);
	gnutls_free(e2.data);
	gnutls_pkcs11_deinit();
	gnutls_global_deinit();
}
Пример #8
0
void
pkcs11_test_sign(FILE * outfile, const char *url, unsigned int flags,
	    common_info_st * info)
{
	gnutls_privkey_t privkey;
	gnutls_pubkey_t pubkey;
	int ret;
	gnutls_datum_t data, sig = {NULL, 0};
	int pk;

	pkcs11_common(info);

	FIX(url, outfile, 0, info);

	data.data = (void*)TEST_DATA;
	data.size = sizeof(TEST_DATA)-1;

	ret = gnutls_privkey_init(&privkey);
	if (ret < 0) {
		fprintf(stderr, "Error in %s:%d: %s\n", __func__,
			__LINE__, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pubkey_init(&pubkey);
	if (ret < 0) {
		fprintf(stderr, "Error in %s:%d: %s\n", __func__,
			__LINE__, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_privkey_import_url(privkey, url, flags);
	if (ret < 0) {
		fprintf(stderr, "Cannot import private key: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pubkey_import_privkey(pubkey, privkey, GNUTLS_KEY_DIGITAL_SIGNATURE, flags);
	if (ret < 0) {
		fprintf(stderr, "Cannot import public key: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA1, 0, &data, &sig);
	if (ret < 0) {
		fprintf(stderr, "Cannot sign data: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	pk = gnutls_pubkey_get_pk_algorithm(pubkey, NULL);

	fprintf(stderr, "Verifying against private key parameters... ");
	ret = gnutls_pubkey_verify_data2(pubkey, gnutls_pk_to_sign(pk, GNUTLS_DIG_SHA1),
		0, &data, &sig);
	if (ret < 0) {
		fprintf(stderr, "Cannot verify signed data: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	fprintf(stderr, "ok\n");

	/* now try to verify against a public key within the token */
	gnutls_pubkey_deinit(pubkey);
	ret = gnutls_pubkey_init(&pubkey);
	if (ret < 0) {
		fprintf(stderr, "Error in %s:%d: %s\n", __func__,
			__LINE__, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pubkey_import_url(pubkey, url, flags);
	if (ret < 0) {
		fprintf(stderr, "Cannot find a corresponding public key object in token: %s\n",
			gnutls_strerror(ret));
		if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
			exit(0);
		exit(1);
	}

	fprintf(stderr, "Verifying against public key in the token... ");
	ret = gnutls_pubkey_verify_data2(pubkey, gnutls_pk_to_sign(pk, GNUTLS_DIG_SHA1),
		0, &data, &sig);
	if (ret < 0) {
		fprintf(stderr, "Cannot verify signed data: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	fprintf(stderr, "ok\n");

	gnutls_free(sig.data);
	gnutls_pubkey_deinit(pubkey);
	gnutls_privkey_deinit(privkey);
	UNFIX;
}
Пример #9
0
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;
}
Пример #10
0
void doit(void)
{
	int ret;
	const char *lib;
	gnutls_privkey_t key;
	gnutls_datum_t sig = {NULL, 0}, data;
	pid_t pid;

	data.data = (void*)"\x38\x17\x0c\x08\xcb\x45\x8f\xd4\x87\x9c\x34\xb6\xf6\x08\x29\x4c\x50\x31\x2b\xbb";
	data.size = 20;

	ret = global_init();
	if (ret != 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(4711);

	lib = getenv("P11MOCKLIB1");
	if (lib == NULL)
		lib = P11LIB;

	ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
	if (ret != 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pkcs11_add_provider(lib, NULL);
	if (ret != 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_privkey_init(&key);
	assert(ret>=0);

	gnutls_privkey_set_pin_function(key, pin_func, NULL);

	ret = gnutls_privkey_import_url(key, "pkcs11:object=test", GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
	if (ret < 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_privkey_sign_hash(key, GNUTLS_DIG_SHA1, 0, &data, &sig);
	if (ret < 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	gnutls_free(sig.data);

	pid = fork();
	if (pid != 0) {
		int status;
		assert(waitpid(pid, &status, 0) >= 0);

		if (WEXITSTATUS(status) != 0) {
			fail("child return status was unexpected: %d\n", WEXITSTATUS(status));
			exit(1);
		}
	} else { /* child */

		ret = gnutls_pkcs11_reinit();
		assert(ret == 0);

		ret = gnutls_privkey_sign_hash(key, GNUTLS_DIG_SHA1, 0, &data, &sig);
		if (ret < 0) {
			fail("%d: %s\n", ret, gnutls_strerror(ret));
			exit(1);
		}

		gnutls_free(sig.data);		
		gnutls_privkey_deinit(key);
		gnutls_pkcs11_deinit();
		gnutls_global_deinit();
		exit(0);
	}

	if (debug)
		printf("done\n\n\n");

	gnutls_privkey_deinit(key);
	gnutls_pkcs11_deinit();
	gnutls_global_deinit();
}
Пример #11
0
/* 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

}