Ejemplo n.º 1
0
/* Reads a certificate file
 */
static int
read_cert_file(gnutls_certificate_credentials_t res,
	       gnutls_privkey_t key,
	       const char *certfile, gnutls_x509_crt_fmt_t type)
{
	int ret;
	size_t size;
	char *data;

	if (gnutls_url_is_supported(certfile)) {
		return read_cert_url(res, key, certfile);
	}

	data = read_binary_file(certfile, &size);

	if (data == NULL) {
		gnutls_assert();
		return GNUTLS_E_FILE_ERROR;
	}

	ret = read_cert_mem(res, key, data, size, type);
	free(data);

	return ret;

}
Ejemplo n.º 2
0
/* Load the CA's private key.
 */
gnutls_privkey_t load_ca_private_key(common_info_st * info)
{
	gnutls_privkey_t key;
	gnutls_datum_t dat;
	size_t size;

	if (info->ca_privkey == NULL) {
		fprintf(stderr, "missing --load-ca-privkey\n");
		exit(1);
	}

	if (gnutls_url_is_supported(info->ca_privkey) != 0)
		return _load_url_privkey(info->ca_privkey);

	dat.data = (void *) read_binary_file(info->ca_privkey, &size);
	dat.size = size;

	if (!dat.data) {
		fprintf(stderr, "reading --load-ca-privkey: %s\n",
			info->ca_privkey);
		exit(1);
	}

	key = _load_privkey(&dat, info);

	free(dat.data);

	return key;
}
Ejemplo n.º 3
0
/* Load the CA's private key.
 */
gnutls_privkey_t
load_ca_private_key (common_info_st * info)
{
  gnutls_privkey_t key;
  gnutls_datum_t dat;
  size_t size;

  if (info->ca_privkey == NULL)
    error (EXIT_FAILURE, 0, "missing --load-ca-privkey");

  if (gnutls_url_is_supported(info->ca_privkey) != 0)
    return _load_url_privkey(info->ca_privkey);

  dat.data = (void*)read_binary_file (info->ca_privkey, &size);
  dat.size = size;

  if (!dat.data)
    error (EXIT_FAILURE, errno, "reading --load-ca-privkey: %s",
           info->ca_privkey);

  key = _load_privkey(&dat, info);

  free (dat.data);

  return key;
}
Ejemplo n.º 4
0
/* Load a public key.
 * @mand should be non zero if it is required to read a public key.
 */
gnutls_pubkey_t load_pubkey(int mand, common_info_st * info)
{
	gnutls_pubkey_t key;
	int ret;
	gnutls_datum_t dat;
	size_t size;

	if (!info->pubkey && !mand)
		return NULL;

	if (info->pubkey == NULL) {
		fprintf(stderr, "missing --load-pubkey\n");
		exit(1);
	}

	if (gnutls_url_is_supported(info->pubkey) != 0)
		return _load_url_pubkey(info->pubkey);

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

	dat.data = (void *) read_binary_file(info->pubkey, &size);
	dat.size = size;

	if (!dat.data) {
		fprintf(stderr, "reading --load-pubkey: %s\n", info->pubkey);
		exit(1);
	}

	ret = gnutls_pubkey_import(key, &dat, info->incert_format);

	free(dat.data);

	if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) {
		fprintf(stderr,
			"import error: could not find a valid PEM header; "
			"check if your key has the PUBLIC KEY header\n");
		exit(1);
	}

	if (ret < 0) {
		fprintf(stderr, "importing --load-pubkey: %s: %s\n",
			info->pubkey, gnutls_strerror(ret));
		exit(1);
	}

	return key;
}
Ejemplo n.º 5
0
/* Reads PKCS-1 RSA private key file or a DSA file (in the format openssl
 * stores it).
 */
int
_gnutls_read_key_file(gnutls_certificate_credentials_t res,
	      const char *keyfile, gnutls_x509_crt_fmt_t type,
	      const char *pass, unsigned int flags,
	      gnutls_privkey_t *rkey)
{
	int ret;
	size_t size;
	char *data;

	if (_gnutls_url_is_known(keyfile)) {
		if (gnutls_url_is_supported(keyfile)) {
			/* if no PIN function is specified, and we have a PIN,
			 * specify one */
			if (pass != NULL && res->pin.cb == NULL) {
				snprintf(res->pin_tmp, sizeof(res->pin_tmp), "%s", pass);
				gnutls_certificate_set_pin_function(res, tmp_pin_cb, res->pin_tmp);
			}

			return read_key_url(res, keyfile, rkey);
		} else
			return
			    gnutls_assert_val
			    (GNUTLS_E_UNIMPLEMENTED_FEATURE);
	}

	data = read_binary_file(keyfile, &size);

	if (data == NULL) {
		gnutls_assert();
		return GNUTLS_E_FILE_ERROR;
	}

	ret = _gnutls_read_key_mem(res, data, size, type, pass, flags, rkey);
	free(data);

	return ret;
}
Ejemplo n.º 6
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);
	}
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
Archivo: cli.c Proyecto: 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

}