Ejemplo n.º 1
0
static int
srp_username_callback (gnutls_session_t session,
		       char **username, char **password)
{
  if (srp_username == NULL || srp_passwd == NULL)
    {
      return -1;
    }

  *username = gnutls_strdup (srp_username);
  *password = gnutls_strdup (srp_passwd);

  return 0;
}
Ejemplo n.º 2
0
/**
 * gnutls_psk_set_server_credentials_file - Used to set the password files, in a gnutls_psk_server_credentials_t structure
 * @res: is a #gnutls_psk_server_credentials_t structure.
 * @password_file: is the PSK password file (passwd.psk)
 *
 * This function sets the password file, in a
 * %gnutls_psk_server_credentials_t structure.  This password file
 * holds usernames and keys and will be used for PSK authentication.
 *
 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
 **/
int
gnutls_psk_set_server_credentials_file (gnutls_psk_server_credentials_t
					res, const char *password_file)
{

  if (password_file == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  /* Check if the files can be opened */
  if (_gnutls_file_exists (password_file) != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_FILE_ERROR;
    }

  res->password_file = gnutls_strdup (password_file);
  if (res->password_file == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  return 0;
}
Ejemplo n.º 3
0
/**
 * gnutls_ext_register:
 * @name: the name of the extension to register
 * @type: the numeric id of the extension
 * @parse_type: the parse type of the extension (see gnutls_ext_parse_type_t)
 * @recv_func: a function to receive the data
 * @send_func: a function to send the data
 * @deinit_func: a function deinitialize any private data
 * @pack_func: a function which serializes the extension's private data (used on session packing for resumption)
 * @unpack_func: a function which will deserialize the extension's private data
 *
 * This function will register a new extension type. The extension will remain
 * registered until gnutls_global_deinit() is called. If the extension type
 * is already registered then %GNUTLS_E_ALREADY_REGISTERED will be returned.
 *
 * Each registered extension can store temporary data into the gnutls_session_t
 * structure using gnutls_ext_set_data(), and they can be retrieved using
 * gnutls_ext_get_data().
 *
 * This function is not thread safe.
 *
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
 *
 * Since: 3.4.0
 **/
int 
gnutls_ext_register(const char *name, int type, gnutls_ext_parse_type_t parse_type,
		    gnutls_ext_recv_func recv_func, gnutls_ext_send_func send_func, 
		    gnutls_ext_deinit_data_func deinit_func, gnutls_ext_pack_func pack_func,
		    gnutls_ext_unpack_func unpack_func)
{
	extension_entry_st tmp_mod;
	int ret;
	unsigned i;

	for (i = 0; i < extfunc_size; i++) {
		if (extfunc[i].type == type)
			return gnutls_assert_val(GNUTLS_E_ALREADY_REGISTERED);
	}

	memset(&tmp_mod, 0, sizeof(tmp_mod));

	tmp_mod.name = gnutls_strdup(name);
	tmp_mod.free_name = 1;
	tmp_mod.type = type;
	tmp_mod.parse_type = parse_type;
	tmp_mod.recv_func = recv_func;
	tmp_mod.send_func = send_func;
	tmp_mod.deinit_func = deinit_func;
	tmp_mod.pack_func = pack_func;
	tmp_mod.unpack_func = unpack_func;

	ret = ext_register(&tmp_mod);
	if (ret < 0) {
		gnutls_free((void*)tmp_mod.name);
	}
	return ret;
}
Ejemplo n.º 4
0
/**
  * gnutls_pkcs12_bag_set_friendly_name - This function sets a friendly name into the bag element
  * @bag: The bag
  * @indx: The bag's element to add the id
  * @name: the name
  *
  * This function will add the given key friendly name, to the specified, by the index, bag
  * element. The name will be encoded as a 'Friendly name' bag attribute,
  * which is usually used to set a user name to the local private key and the certificate pair.
  * 
  * Returns 0 on success, or a negative value on error.
  *
  **/
int
gnutls_pkcs12_bag_set_friendly_name (gnutls_pkcs12_bag_t bag, int indx,
				     const char *name)
{
  if (bag == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  if (indx > bag->bag_elements - 1)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  bag->element[indx].friendly_name = gnutls_strdup (name);

  if (name == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  return 0;
}
Ejemplo n.º 5
0
/**
 * gnutls_psk_set_server_credentials_hint - Set a identity hint, in a %gnutls_psk_server_credentials_t structure
 * @res: is a #gnutls_psk_server_credentials_t structure.
 * @hint: is the PSK identity hint string
 *
 * This function sets the identity hint, in a
 * %gnutls_psk_server_credentials_t structure.  This hint is sent to
 * the client to help it chose a good PSK credential (i.e., username
 * and password).
 *
 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
 *
 * Since: 2.4.0
 **/
int
gnutls_psk_set_server_credentials_hint (gnutls_psk_server_credentials_t res,
					const char *hint)
{
  res->hint = gnutls_strdup (hint);
  if (res->hint == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  return 0;
}
Ejemplo n.º 6
0
/**
 * gnutls_certificate_set_ocsp_status_request_file:
 * @session: is a #gnutls_session_t structure.
 * @response_file: a filename of the OCSP response
 * @flags: should be zero
 *
 * This function sets the filename of an OCSP response, that will be
 * sent to the client if requests an OCSP certificate status. This is
 * a convenience function which is inefficient on busy servers since
 * the file is opened on every access. Use 
 * gnutls_certificate_set_ocsp_status_request_function() to fine-tune
 * file accesses.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
 *   otherwise a negative error code is returned.
 *
 * Since: 3.1.3
 **/
int
gnutls_certificate_set_ocsp_status_request_file
(gnutls_certificate_credentials_t sc, const char *response_file,
 unsigned int flags)
{
	sc->ocsp_func = file_ocsp_func;
	sc->ocsp_func_ptr = sc;
	sc->ocsp_response_file = gnutls_strdup(response_file);
	if (sc->ocsp_response_file == NULL)
		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);

	return 0;
}
Ejemplo n.º 7
0
/**
 * gnutls_srp_set_client_credentials:
 * @res: is a #gnutls_srp_client_credentials_t type.
 * @username: is the user's userid
 * @password: is the user's password
 *
 * This function sets the username and password, in a
 * #gnutls_srp_client_credentials_t type.  Those will be used in
 * SRP authentication.  @username and @password should be ASCII
 * strings or UTF-8 strings prepared using the "SASLprep" profile of
 * "stringprep".
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or an
 *   error code.
 **/
int
gnutls_srp_set_client_credentials(gnutls_srp_client_credentials_t res,
				  const char *username,
				  const char *password)
{

	if (username == NULL || password == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	res->username = gnutls_strdup(username);
	if (res->username == NULL)
		return GNUTLS_E_MEMORY_ERROR;

	res->password = gnutls_strdup(password);
	if (res->password == NULL) {
		gnutls_free(res->username);
		return GNUTLS_E_MEMORY_ERROR;
	}

	return 0;
}
Ejemplo n.º 8
0
static int
srp_username_callback (gnutls_session session,
		       unsigned int times, char **username, char **password)
{
  if (srp_username == NULL || srp_passwd == NULL)
    {
      return -1;
    }

  /* We should ask here the user for his SRP username
   * and password.
   */
  if (times == 1)
    {
      *username = gnutls_strdup (srp_username);
      *password = gnutls_strdup (srp_passwd);

      return 0;
    }
  else
    /* At the first time return username and password, if
     * the kx_priority[0] is an SRP method.
     */
  if (times == 0 && (kx_priority[0] == GNUTLS_KX_SRP ||
		       kx_priority[0] ==
		       GNUTLS_KX_SRP_RSA
		       || kx_priority[0] == GNUTLS_KX_SRP_DSS))
    {

      *username = gnutls_strdup (srp_username);
      *password = gnutls_strdup (srp_passwd);

      return 0;
    }

  return -1;
}
Ejemplo n.º 9
0
static krb5_principal_data *name_to_principal(const char *_name)
{
	krb5_principal_data *princ;
	char *p, *p2, *sp;
	unsigned pos = 0;
	char *name = NULL;

	princ = gnutls_calloc(1, sizeof(struct krb5_principal_data));
	if (princ == NULL)
		return NULL;

	name = gnutls_strdup(_name);
	if (name == NULL) {
		gnutls_assert();
		goto fail;
	}

	p = strrchr(name, '@');
	p2 = strchr(name, '@');
	if (p == NULL) {
		/* unknown name type */
		gnutls_assert();
		goto fail;
	}

	princ->realm = gnutls_strdup(p + 1);
	if (princ->realm == NULL) {
		gnutls_assert();
		goto fail;
	}
	*p = 0;

	if (p == p2) {
		p = strtok_r(name, "/", &sp);
		while (p) {
			if (pos == MAX_COMPONENTS) {
				_gnutls_debug_log
				    ("%s: Cannot parse names with more than %d components\n",
				     __func__, MAX_COMPONENTS);
				goto fail;
			}

			princ->data[pos] = gnutls_strdup(p);
			if (princ->data[pos] == NULL) {
				gnutls_assert();
				goto fail;
			}

			princ->length++;
			pos++;

			p = strtok_r(NULL, "/", &sp);
		}

		if ((princ->length == 2)
		    && (strcmp(princ->data[0], "krbtgt") == 0)) {
			princ->type = 2;	/* KRB_NT_SRV_INST */
		} else {
			princ->type = 1;	/* KRB_NT_PRINCIPAL */
		}
	} else {		/* enterprise */
		princ->data[0] = gnutls_strdup(name);
		if (princ->data[0] == NULL) {
			gnutls_assert();
			goto fail;
		}

		princ->length++;
		princ->type = 10;	/* KRB_NT_ENTERPRISE */
	}

	goto cleanup;
 fail:
	cleanup_principal(princ);
	princ = NULL;

 cleanup:
	gnutls_free(name);
	return princ;
}
Ejemplo n.º 10
0
static int
psk_callback (gnutls_session_t session, char **username, gnutls_datum_t * key)
{
  const char *hint = gnutls_psk_client_get_hint (session);
  char *passwd;
  int ret;

  printf ("- PSK client callback. ");
  if (hint)
    printf ("PSK hint '%s'\n", hint);
  else
    printf ("No PSK hint\n");

  if (info.psk_username)
    *username = gnutls_strdup (info.psk_username);
  else
    {
      char *tmp = NULL;
      size_t n;
      ssize_t len;

      printf ("Enter PSK identity: ");
      fflush (stdout);
      len = getline (&tmp, &n, stdin);

      if (tmp == NULL)
	{
	  fprintf (stderr, "No username given, aborting...\n");
	  return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
	}

      if (tmp[strlen (tmp) - 1] == '\n')
	tmp[strlen (tmp) - 1] = '\0';
      if (tmp[strlen (tmp) - 1] == '\r')
	tmp[strlen (tmp) - 1] = '\0';

      *username = gnutls_strdup (tmp);
      free (tmp);
    }
  if (!*username)
    return GNUTLS_E_MEMORY_ERROR;

  passwd = getpass ("Enter password: "******"No password given, aborting...\n");
      return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
    }

  ret = gnutls_psk_netconf_derive_key (passwd,
				       *username, hint ? hint : "", key);
  if (ret < 0)
    {
      fprintf (stderr, "Error deriving password: %s\n",
	       gnutls_strerror (ret));
      gnutls_free (*username);
      return ret;
    }

  if (info.debug)
    {
      char hexkey[41];
      size_t res_size = sizeof (hexkey);
      gnutls_hex_encode (key, hexkey, &res_size);
      fprintf (stderr, "PSK username: %s\n", *username);
      fprintf (stderr, "PSK hint: %s\n", hint);
      fprintf (stderr, "PSK key: %s\n", hexkey);
    }

  return 0;
}
Ejemplo n.º 11
0
/* this function parses tpasswd.conf file. Format is:
 * string(username):base64(v):base64(salt):int(index)
 */
static int
pwd_put_values (SRP_PWD_ENTRY * entry, char *str)
{
  char *p;
  int len, ret;
  opaque *verifier;
  size_t verifier_size;
  int indx;

  p = strrchr (str, ':');       /* we have index */
  if (p == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_SRP_PWD_PARSING_ERROR;
    }

  *p = '\0';
  p++;

  indx = atoi (p);
  if (indx == 0)
    {
      gnutls_assert ();
      return GNUTLS_E_SRP_PWD_PARSING_ERROR;
    }

  /* now go for salt */
  p = strrchr (str, ':');       /* we have salt */
  if (p == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_SRP_PWD_PARSING_ERROR;
    }

  *p = '\0';
  p++;

  len = strlen (p);

  entry->salt.size = _gnutls_sbase64_decode (p, len, &entry->salt.data);

  if (entry->salt.size <= 0)
    {
      gnutls_assert ();
      return GNUTLS_E_SRP_PWD_PARSING_ERROR;
    }

  /* now go for verifier */
  p = strrchr (str, ':');       /* we have verifier */
  if (p == NULL)
    {
      _gnutls_free_datum (&entry->salt);
      return GNUTLS_E_SRP_PWD_PARSING_ERROR;
    }

  *p = '\0';
  p++;

  len = strlen (p);
  ret = _gnutls_sbase64_decode (p, len, &verifier);
  if (ret <= 0)
    {
      gnutls_assert ();
      _gnutls_free_datum (&entry->salt);
      return GNUTLS_E_SRP_PWD_PARSING_ERROR;
    }

  verifier_size = ret;
  entry->v.data = verifier;
  entry->v.size = verifier_size;

  /* now go for username */
  *p = '\0';

  entry->username = gnutls_strdup (str);
  if (entry->username == NULL)
    {
      _gnutls_free_datum (&entry->salt);
      _gnutls_free_datum (&entry->v);
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  return indx;
}
Ejemplo n.º 12
0
/**
  * gnutls_priority_init - Sets priorities for the cipher suites supported by gnutls.
  * @priority_cache: is a #gnutls_prioritity_t structure.
  * @priorities: is a string describing priorities
  * @err_pos: In case of an error this will have the position in the string the error occured
  *
  * Sets priorities for the ciphers, key exchange methods, macs and
  * compression methods. This is to avoid using the
  * gnutls_*_priority() functions.
  *
  * The #priorities option allows you to specify a semi-colon
  * separated list of the cipher priorities to enable.
  *
  * Unless the first keyword is "NONE" the defaults are:
  * Protocols: TLS1.1, TLS1.0, and SSL3.0.
  * Compression: NULL.
  * Certificate types: X.509, OpenPGP.
  *
  * You can also use predefined sets of ciphersuites: "PERFORMANCE"
  * all the "secure" ciphersuites are enabled, limited to 128 bit
  * ciphers and sorted by terms of speed performance.
  *
  * "NORMAL" option enables all "secure" ciphersuites. The 256-bit ciphers
  * are included as a fallback only. The ciphers are sorted by security margin.
  *
  * "SECURE128" flag enables all "secure" ciphersuites with ciphers up to 
  * 128 bits, sorted by security margin.
  *
  * "SECURE256" flag enables all "secure" ciphersuites including the 256 bit
  * ciphers, sorted by security margin.
  *
  * "EXPORT" all the ciphersuites are enabled, including the
  * low-security 40 bit ciphers.
  *
  * "NONE" nothing is enabled. This disables even protocols and
  * compression methods.
  *
  * Special keywords:
  * '!' or '-' appended with an algorithm will remove this algorithm.
  * '+' appended with an algorithm will add this algorithm.
  * '%COMPAT' will enable compatibility features for a server.
  *
  * To avoid collisions in order to specify a compression algorithm in
  * this string you have to prefix it with "COMP-", protocol versions
  * with "VERS-" and certificate types with "CTYPE-". All other
  * algorithms don't need a prefix.
  *
  * For key exchange algorithms when in NORMAL or SECURE levels the
  * perfect forward secrecy algorithms take precendence of the other
  * protocols.  In all cases all the supported key exchange algorithms
  * are enabled (except for the RSA-EXPORT which is only enabled in
  * EXPORT level).
  *
  * Note that although one can select very long key sizes (such as 256 bits) 
  * for symmetric algorithms, to actually increase security the public key
  * algorithms have to use longer key sizes as well.
  *
  * Examples: "NORMAL:!AES-128-CBC",
  * "EXPORT:!VERS-TLS1.0:+COMP-DEFLATE:+CTYPE-OPENPGP",
  * "NONE:+VERS-TLS1.0:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL", "NORMAL",
  * "NORMAL:%COMPAT".
  *
  * Returns: On syntax error GNUTLS_E_INVALID_REQUEST is returned and
  * 0 on success.
  **/
int
gnutls_priority_init (gnutls_priority_t * priority_cache,
		      const char *priorities, const char **err_pos)
{
  char *broken_list[MAX_ELEMENTS];
  int broken_list_size, i, j;
  char *darg;
  int algo;
  rmadd_func *fn;

  *priority_cache = gnutls_calloc (1, sizeof (struct gnutls_priority_st));
  if (*priority_cache == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  if (priorities == NULL)
    priorities = "NORMAL";

  darg = gnutls_strdup (priorities);
  if (darg == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  break_comma_list (darg, broken_list, &broken_list_size, MAX_ELEMENTS, ':');

  /* This is our default set of protocol version, certificate types and
   * compression methods.
   */
  if (strcasecmp (broken_list[0], "NONE") != 0)
    {
      _set_priority (&(*priority_cache)->protocol, protocol_priority);
      _set_priority (&(*priority_cache)->compression, comp_priority);
      _set_priority (&(*priority_cache)->cert_type, cert_type_priority);
    }

  for (i = 0; i < broken_list_size; i++)
    {
      if (strcasecmp (broken_list[i], "PERFORMANCE") == 0)
	{
	  _set_priority (&(*priority_cache)->cipher,
			 cipher_priority_performance);
	  _set_priority (&(*priority_cache)->kx, kx_priority_performance);
	  _set_priority (&(*priority_cache)->mac, mac_priority_performance);
	}
      else if (strcasecmp (broken_list[i], "NORMAL") == 0)
	{
	  _set_priority (&(*priority_cache)->cipher, cipher_priority_normal);
	  _set_priority (&(*priority_cache)->kx, kx_priority_secure);
	  _set_priority (&(*priority_cache)->mac, mac_priority_secure);
	}
      else if (strcasecmp (broken_list[i], "SECURE256") == 0 || strcasecmp (broken_list[i], "SECURE") == 0)
	{
	  _set_priority (&(*priority_cache)->cipher, cipher_priority_secure256);
	  _set_priority (&(*priority_cache)->kx, kx_priority_secure);
	  _set_priority (&(*priority_cache)->mac, mac_priority_secure);
	}
      else if (strcasecmp (broken_list[i], "SECURE128") == 0)
	{
	  _set_priority (&(*priority_cache)->cipher, cipher_priority_secure128);
	  _set_priority (&(*priority_cache)->kx, kx_priority_secure);
	  _set_priority (&(*priority_cache)->mac, mac_priority_secure);
	}
      else if (strcasecmp (broken_list[i], "EXPORT") == 0)
	{
	  _set_priority (&(*priority_cache)->cipher, cipher_priority_export);
	  _set_priority (&(*priority_cache)->kx, kx_priority_export);
	  _set_priority (&(*priority_cache)->mac, mac_priority_secure);
	}			/* now check if the element is something like -ALGO */
      else if (broken_list[i][0] == '!' || broken_list[i][0] == '+'
	       || broken_list[i][0] == '-')
	{
	  if (broken_list[i][0] == '+')
	    fn = prio_add;
	  else
	    fn = prio_remove;

	  if ((algo =
	       gnutls_mac_get_id (&broken_list[i][1])) != GNUTLS_MAC_UNKNOWN)
	    fn (&(*priority_cache)->mac, algo);
	  else if ((algo = gnutls_cipher_get_id (&broken_list[i][1])) !=
		   GNUTLS_CIPHER_UNKNOWN)
	    fn (&(*priority_cache)->cipher, algo);
	  else if ((algo = gnutls_kx_get_id (&broken_list[i][1])) !=
		   GNUTLS_KX_UNKNOWN)
	    fn (&(*priority_cache)->kx, algo);
	  else if (strncasecmp (&broken_list[i][1], "VERS-", 5) == 0)
	    {
	      if ((algo =
		   gnutls_protocol_get_id (&broken_list[i][6])) !=
		  GNUTLS_VERSION_UNKNOWN)
		fn (&(*priority_cache)->protocol, algo);
	    }			/* now check if the element is something like -ALGO */
	  else if (strncasecmp (&broken_list[i][1], "COMP-", 5) == 0)
	    {
	      if ((algo =
		   gnutls_compression_get_id (&broken_list[i][6])) !=
		  GNUTLS_COMP_UNKNOWN)
		fn (&(*priority_cache)->compression, algo);
	    }			/* now check if the element is something like -ALGO */
	  else if (strncasecmp (&broken_list[i][1], "CTYPE-", 6) == 0)
	    {
	      if ((algo =
		   gnutls_certificate_type_get_id (&broken_list[i][7])) !=
		  GNUTLS_CRT_UNKNOWN)
		fn (&(*priority_cache)->cert_type, algo);
	    }			/* now check if the element is something like -ALGO */
	  else
	    goto error;
	}
      else if (broken_list[i][0] == '%')
	{
	  if (strcasecmp (&broken_list[i][1], "COMPAT") == 0)
	    (*priority_cache)->no_padding = 1;
	  else
	    goto error;
	}
      else
	goto error;
    }

  gnutls_free (darg);
  return 0;

error:
  if (err_pos != NULL && i < broken_list_size)
    {
      *err_pos = priorities;
      for (j = 0; j < i; j++)
	{
	  (*err_pos) += strlen (broken_list[j]) + 1;
	}
    }
  gnutls_free (darg);

  return GNUTLS_E_INVALID_REQUEST;

}
Ejemplo n.º 13
0
/**
 * gnutls_x509_trust_list_add_trust_file:
 * @list: The list
 * @ca_file: A file containing a list of CAs (optional)
 * @crl_file: A file containing a list of CRLs (optional)
 * @type: The format of the certificates
 * @tl_flags: flags from %gnutls_trust_list_flags_t
 * @tl_vflags: gnutls_certificate_verify_flags if flags specifies GNUTLS_TL_VERIFY_CRL
 *
 * This function will add the given certificate authorities
 * to the trusted list. PKCS #11 URLs are also accepted, instead
 * of files, by this function. A PKCS #11 URL implies a trust
 * database (a specially marked module in p11-kit); the URL "pkcs11:"
 * implies all trust databases in the system. Only a single URL specifying
 * trust databases can be set; they cannot be stacked with multiple calls.
 *
 * Returns: The number of added elements is returned.
 *
 * Since: 3.1
 **/
int
gnutls_x509_trust_list_add_trust_file(gnutls_x509_trust_list_t list,
				      const char *ca_file,
				      const char *crl_file,
				      gnutls_x509_crt_fmt_t type,
				      unsigned int tl_flags,
				      unsigned int tl_vflags)
{
	gnutls_datum_t cas = { NULL, 0 };
	gnutls_datum_t crls = { NULL, 0 };
	size_t size;
	int ret;

	if (ca_file != NULL) {
#ifdef ENABLE_PKCS11
		if (strncmp(ca_file, "pkcs11:", 7) == 0) {
			unsigned pcrt_list_size = 0;

			/* in case of a token URL import it as a PKCS #11 token,
			 * otherwise import the individual certificates.
			 */
			if (is_pkcs11_url_object(ca_file) != 0) {
				return add_trust_list_pkcs11_object_url(list, ca_file, tl_flags);
			} else { /* token */
				if (list->pkcs11_token != NULL)
					return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
				list->pkcs11_token = gnutls_strdup(ca_file);

				/* enumerate the certificates */
				ret = gnutls_pkcs11_obj_list_import_url(NULL, &pcrt_list_size,
					ca_file, 
					(GNUTLS_PKCS11_OBJ_FLAG_CRT|GNUTLS_PKCS11_OBJ_FLAG_MARK_CA|GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED),
					0);
				if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
					return gnutls_assert_val(ret);

				return pcrt_list_size;
			}
		} else
#endif
		{
			cas.data = (void *) read_binary_file(ca_file, &size);
			if (cas.data == NULL) {
				gnutls_assert();
				return GNUTLS_E_FILE_ERROR;
			}
			cas.size = size;
		}
	}

	if (crl_file) {
		crls.data = (void *) read_binary_file(crl_file, &size);
		if (crls.data == NULL) {
			gnutls_assert();
			return GNUTLS_E_FILE_ERROR;
		}
		crls.size = size;
	}

	ret =
	    gnutls_x509_trust_list_add_trust_mem(list, &cas, &crls, type,
						 tl_flags, tl_vflags);
	free(crls.data);
	free(cas.data);

	return ret;
}
Ejemplo n.º 14
0
/* extract the proxyCertInfo from the DER encoded extension
 */
int
_gnutls_x509_ext_extract_proxyCertInfo (int *pathLenConstraint,
                                        char **policyLanguage,
                                        char **policy,
                                        size_t * sizeof_policy,
                                        uint8_t * extnValue, int extnValueLen)
{
  ASN1_TYPE ext = ASN1_TYPE_EMPTY;
  int result;
  gnutls_datum_t value;

  if ((result = asn1_create_element
       (_gnutls_get_pkix (), "PKIX1.ProxyCertInfo", &ext)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  result = asn1_der_decoding (&ext, extnValue, extnValueLen, NULL);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      asn1_delete_structure (&ext);
      return _gnutls_asn2err (result);
    }

  if (pathLenConstraint)
    {
      result = _gnutls_x509_read_uint (ext, "pCPathLenConstraint",
                                       (unsigned int*)pathLenConstraint);
      if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
        *pathLenConstraint = -1;
      else if (result != GNUTLS_E_SUCCESS)
        {
          asn1_delete_structure (&ext);
          return _gnutls_asn2err (result);
        }
    }

  result = _gnutls_x509_read_value (ext, "proxyPolicy.policyLanguage",
                                    &value);
  if (result < 0)
    {
      gnutls_assert ();
      asn1_delete_structure (&ext);
      return result;
    }

  if (policyLanguage)
    *policyLanguage = gnutls_strdup ((char*)value.data);

  result = _gnutls_x509_read_value (ext, "proxyPolicy.policy", &value);
  if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
    {
      if (policy)
        *policy = NULL;
      if (sizeof_policy)
        *sizeof_policy = 0;
    }
  else if (result < 0)
    {
      gnutls_assert ();
      asn1_delete_structure (&ext);
      return result;
    }
  else
    {
      if (policy)
        *policy = (char*)value.data;
      if (sizeof_policy)
        *sizeof_policy = value.size;
    }

  asn1_delete_structure (&ext);

  return 0;
}
Ejemplo n.º 15
0
static int
psk_callback (gnutls_session_t session, char **username, gnutls_datum_t * key)
{
  const char *hint = gnutls_psk_client_get_hint (session);
  unsigned char *rawkey;
  char *passwd;
  int ret;
  size_t res_size;
  gnutls_datum_t tmp;

  printf ("- PSK client callback. ");
  if (hint)
    printf ("PSK hint '%s'\n", hint);
  else
    printf ("No PSK hint\n");

  if (info.psk_username)
    *username = gnutls_strdup (info.psk_username);
  else
    {
      char *tmp = NULL;
      size_t n;

      printf ("Enter PSK identity: ");
      fflush (stdout);
      getline (&tmp, &n, stdin);

      if (tmp == NULL)
        {
          fprintf (stderr, "No username given, aborting...\n");
          return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
        }

      if (tmp[strlen (tmp) - 1] == '\n')
        tmp[strlen (tmp) - 1] = '\0';
      if (tmp[strlen (tmp) - 1] == '\r')
        tmp[strlen (tmp) - 1] = '\0';

      *username = gnutls_strdup (tmp);
      free (tmp);
    }
  if (!*username)
    return GNUTLS_E_MEMORY_ERROR;

  passwd = getpass ("Enter key: ");
  if (passwd == NULL)
    {
      fprintf (stderr, "No key given, aborting...\n");
      return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
    }

  tmp.data = passwd;
  tmp.size = strlen (passwd);

  res_size = tmp.size / 2 + 1;
  rawkey = gnutls_malloc (res_size);
  if (rawkey == NULL)
    return GNUTLS_E_MEMORY_ERROR;

  ret = gnutls_hex_decode (&tmp, rawkey, &res_size);
  if (ret < 0)
    {
      fprintf (stderr, "Error deriving password: %s\n",
               gnutls_strerror (ret));
      gnutls_free (*username);
      return ret;
    }

  key->data = rawkey;
  key->size = res_size;

  if (info.debug)
    {
      char hexkey[41];
      res_size = sizeof (hexkey);
      gnutls_hex_encode (key, hexkey, &res_size);
      fprintf (stderr, "PSK username: %s\n", *username);
      fprintf (stderr, "PSK hint: %s\n", hint);
      fprintf (stderr, "PSK key: %s\n", hexkey);
    }

  return 0;
}
Ejemplo n.º 16
0
/**
 * gnutls_utf8_password_normalize:
 * @password: contain the UTF-8 formatted password
 * @plen: the length of the provided password
 * @out: the result in an null-terminated allocated string
 * @flags: should be zero
 *
 * This function will convert the provided UTF-8 password according
 * to the normalization rules in RFC7613.
 *
 * If the flag %GNUTLS_UTF8_IGNORE_ERRS is specified, any UTF-8 encoding
 * errors will be ignored, and in that case the output will be a copy of the input.
 *
 * Returns: %GNUTLS_E_INVALID_UTF8_STRING on invalid UTF-8 data, or 0 on success.
 *
 * Since: 3.5.7
 **/
int gnutls_utf8_password_normalize(const unsigned char *password, unsigned plen,
				   gnutls_datum_t *out, unsigned flags)
{
	size_t ucs4_size = 0, nrm_size = 0;
	size_t final_size = 0;
	uint8_t *final = NULL;
	uint32_t *ucs4 = NULL;
	uint32_t *nrm = NULL;
	uint8_t *nrmu8 = NULL;
	int ret;

	if (plen == 0) {
		out->data = (uint8_t*)gnutls_strdup("");
		out->size = 0;
		if (out->data == NULL)
			return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
		return 0;
	}

	/* check for invalid UTF-8 */
	if (u8_check((uint8_t*)password, plen) != NULL) {
		gnutls_assert();
		if (flags & GNUTLS_UTF8_IGNORE_ERRS) {
 raw_copy:
			out->data = gnutls_malloc(plen+1);
			if (out->data == NULL)
				return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
			out->size = plen;
			memcpy(out->data, password, plen);
			out->data[plen] = 0;
			return 0;
		} else {
			return GNUTLS_E_INVALID_UTF8_STRING;
		}
	}

	/* convert to UTF-32 */
	ucs4 = u8_to_u32((uint8_t*)password, plen, NULL, &ucs4_size);
	if (ucs4 == NULL) {
		gnutls_assert();
		ret = GNUTLS_E_PARSING_ERROR;
		goto fail;
	}

	ret = check_for_valid_freeformclass(ucs4, ucs4_size);
	if (ret < 0) {
		gnutls_assert();
		if (flags & GNUTLS_UTF8_IGNORE_ERRS) {
			free(ucs4);
			goto raw_copy;
		}
		if (ret == GNUTLS_E_INVALID_UTF8_STRING)
			ret = GNUTLS_E_INVALID_PASSWORD_STRING;
		goto fail;
	}

	/* normalize to NFC */
	nrm = u32_normalize(UNINORM_NFC, ucs4, ucs4_size, NULL, &nrm_size);
	if (nrm == NULL) {
		gnutls_assert();
		ret = GNUTLS_E_INVALID_PASSWORD_STRING;
		goto fail;
	}

	/* convert back to UTF-8 */
	final_size = 0;
	nrmu8 = u32_to_u8(nrm, nrm_size, NULL, &final_size);
	if (nrmu8 == NULL) {
		gnutls_assert();
		ret = GNUTLS_E_INVALID_PASSWORD_STRING;
		goto fail;
	}

	/* copy to output with null terminator */
	final = gnutls_malloc(final_size+1);
Ejemplo n.º 17
0
/**
 * gnutls_pkcs11_privkey_import_url:
 * @pkey: The private key
 * @url: a PKCS 11 url identifying the key
 * @flags: Or sequence of GNUTLS_PKCS11_OBJ_* flags
 *
 * This function will "import" a PKCS 11 URL identifying a private
 * key to the #gnutls_pkcs11_privkey_t type. In reality since
 * in most cases keys cannot be exported, the private key structure
 * is being associated with the available operations on the token.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_pkcs11_privkey_import_url(gnutls_pkcs11_privkey_t pkey,
				 const char *url, unsigned int flags)
{
	int ret;
	struct ck_attribute *attr;
	struct ck_attribute a[4];
	ck_key_type_t key_type;
	ck_bool_t reauth = 0;

	PKCS11_CHECK_INIT;

	memset(&pkey->sinfo, 0, sizeof(pkey->sinfo));

	if (pkey->url) {
		gnutls_free(pkey->url);
		pkey->url = NULL;
	}

	if (pkey->uinfo) {
		p11_kit_uri_free(pkey->uinfo);
		pkey->uinfo = NULL;
	}

	pkey->url = gnutls_strdup(url);
	if (pkey->url == NULL)
		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);

	ret = pkcs11_url_to_info(pkey->url, &pkey->uinfo, flags|GNUTLS_PKCS11_OBJ_FLAG_EXPECT_PRIVKEY);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	pkey->flags = flags;

	attr = p11_kit_uri_get_attribute(pkey->uinfo, CKA_CLASS);
	if (!attr || attr->value_len != sizeof(ck_object_class_t) ||
	    *(ck_object_class_t *) attr->value != CKO_PRIVATE_KEY) {
		gnutls_assert();
		ret = GNUTLS_E_INVALID_REQUEST;
		goto cleanup;
	}

	attr = p11_kit_uri_get_attribute(pkey->uinfo, CKA_ID);
	if (!attr) {
		attr = p11_kit_uri_get_attribute(pkey->uinfo, CKA_LABEL);
		if (!attr) {
			gnutls_assert();
			ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
			goto cleanup;
		}
	}

	FIND_OBJECT(pkey);

	pkey->pk_algorithm = GNUTLS_PK_UNKNOWN;
	a[0].type = CKA_KEY_TYPE;
	a[0].value = &key_type;
	a[0].value_len = sizeof(key_type);

	if (pkcs11_get_attribute_value(pkey->sinfo.module, pkey->sinfo.pks, pkey->ref, a, 1)
	    == CKR_OK) {
		pkey->pk_algorithm = key_type_to_pk(key_type);
	}

	if (pkey->pk_algorithm == GNUTLS_PK_UNKNOWN) {
		_gnutls_debug_log
		    ("Cannot determine PKCS #11 key algorithm\n");
		ret = GNUTLS_E_UNKNOWN_ALGORITHM;
		goto cleanup;
	}

	a[0].type = CKA_ALWAYS_AUTHENTICATE;
	a[0].value = &reauth;
	a[0].value_len = sizeof(reauth);

	if (pkcs11_get_attribute_value(pkey->sinfo.module, pkey->sinfo.pks, pkey->ref, a, 1)
	    == CKR_OK) {
		pkey->reauth = reauth;
	}

	ret = 0;

	return ret;

      cleanup:
	if (pkey->uinfo != NULL) {
		p11_kit_uri_free(pkey->uinfo);
		pkey->uinfo = NULL;
	}
	gnutls_free(pkey->url);
	pkey->url = NULL;

	return ret;
}
Ejemplo n.º 18
0
/**
 * gnutls_priority_init:
 * @priority_cache: is a #gnutls_prioritity_t structure.
 * @priorities: is a string describing priorities
 * @err_pos: In case of an error this will have the position in the string the error occured
 *
 * Sets priorities for the ciphers, key exchange methods, macs and
 * compression methods.
 *
 * The #priorities option allows you to specify a colon
 * separated list of the cipher priorities to enable.
 * Some keywords are defined to provide quick access
 * to common preferences.
 *
 * Unless there is a special need, using "NORMAL" or "NORMAL:%COMPAT" for compatibility 
 * is recommended.
 *
 * "PERFORMANCE" means all the "secure" ciphersuites are enabled,
 * limited to 128 bit ciphers and sorted by terms of speed
 * performance.
 *
 * "NORMAL" means all "secure" ciphersuites. The 256-bit ciphers are
 * included as a fallback only.  The ciphers are sorted by security
 * margin.
 *
 * "PFS" means all "secure" ciphersuites that support perfect forward secrecy. 
 * The 256-bit ciphers are included as a fallback only.  
 * The ciphers are sorted by security margin.
 *
 * "SECURE128" means all "secure" ciphersuites of security level 128-bit
 * or more.
 *
 * "SECURE192" means all "secure" ciphersuites of security level 192-bit
 * or more.
 *
 * "SUITEB128" means all the NSA SuiteB ciphersuites with security level
 * of 128.
 *
 * "SUITEB192" means all the NSA SuiteB ciphersuites with security level
 * of 192.
 *
 * "EXPORT" means all ciphersuites are enabled, including the
 * low-security 40 bit ciphers.
 *
 * "NONE" means nothing is enabled.  This disables even protocols and
 * compression methods.
 *
 * Special keywords are "!", "-" and "+".
 * "!" or "-" appended with an algorithm will remove this algorithm.
 * "+" appended with an algorithm will add this algorithm.
 *
 * Check the GnuTLS manual section "Priority strings" for detailed
 * information.
 *
 * Examples:
 *
 * "NONE:+VERS-TLS-ALL:+MAC-ALL:+RSA:+AES-128-CBC:+SIGN-ALL:+COMP-NULL"
 *
 * "NORMAL:-ARCFOUR-128" means normal ciphers except for ARCFOUR-128.
 *
 * "SECURE128:-VERS-SSL3.0:+COMP-DEFLATE" means that only secure ciphers are
 * enabled, SSL3.0 is disabled, and libz compression enabled.
 *
 * "NONE:+VERS-TLS-ALL:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL:+SIGN-RSA-SHA1", 
 *
 * "NONE:+VERS-TLS-ALL:+AES-128-CBC:+ECDHE-RSA:+SHA1:+COMP-NULL:+SIGN-RSA-SHA1:+CURVE-SECP256R1", 
 *
 * "SECURE256:+SECURE128",
 *
 * Note that "NORMAL:%COMPAT" is the most compatible mode.
 *
 * Returns: On syntax error %GNUTLS_E_INVALID_REQUEST is returned,
 * %GNUTLS_E_SUCCESS on success, or an error code.
 **/
int
gnutls_priority_init(gnutls_priority_t * priority_cache,
		     const char *priorities, const char **err_pos)
{
	char *broken_list[MAX_ELEMENTS];
	int broken_list_size = 0, i = 0, j;
	char *darg = NULL;
	unsigned ikeyword_set = 0;
	int algo;
	rmadd_func *fn;
	bulk_rmadd_func *bulk_fn;

	*priority_cache =
	    gnutls_calloc(1, sizeof(struct gnutls_priority_st));
	if (*priority_cache == NULL) {
		gnutls_assert();
		return GNUTLS_E_MEMORY_ERROR;
	}

	if (err_pos)
		*err_pos = priorities;

	/* for now unsafe renegotiation is default on everyone. To be removed
	 * when we make it the default.
	 */
	(*priority_cache)->sr = SR_PARTIAL;
	(*priority_cache)->ssl3_record_version = 1;


	(*priority_cache)->max_empty_records = DEFAULT_MAX_EMPTY_RECORDS;

	if (priorities == NULL)
		priorities = LEVEL_NORMAL;

	darg = gnutls_strdup(priorities);
	if (darg == NULL) {
		gnutls_assert();
		goto error;
	}

	break_comma_list(darg, broken_list, &broken_list_size,
			 MAX_ELEMENTS, ':');
	/* This is our default set of protocol version, certificate types and
	 * compression methods.
	 */
	if (strcasecmp(broken_list[0], LEVEL_NONE) != 0) {
		_set_priority(&(*priority_cache)->protocol,
			      protocol_priority);
		_set_priority(&(*priority_cache)->compression,
			      comp_priority);
		_set_priority(&(*priority_cache)->cert_type,
			      cert_type_priority_default);
		_set_priority(&(*priority_cache)->sign_algo,
			      sign_priority_default);
		_set_priority(&(*priority_cache)->supported_ecc,
			      supported_ecc_normal);
		i = 0;
	} else {
		ikeyword_set = 1;
		i = 1;
	}

	for (; i < broken_list_size; i++) {
		if (check_level(broken_list[i], *priority_cache, ikeyword_set) != 0) {
			ikeyword_set = 1;
			continue;
		} else if (broken_list[i][0] == '!'
			   || broken_list[i][0] == '+'
			   || broken_list[i][0] == '-') {
			if (broken_list[i][0] == '+') {
				fn = prio_add;
				bulk_fn = _add_priority;
			} else {
				fn = prio_remove;
				bulk_fn = _clear_priorities;
			}

			if (broken_list[i][0] == '+'
			    && check_level(&broken_list[i][1],
					   *priority_cache, 1) != 0) {
				continue;
			} else if ((algo =
				    gnutls_mac_get_id(&broken_list[i][1]))
				   != GNUTLS_MAC_UNKNOWN)
				fn(&(*priority_cache)->mac, algo);
			else if ((algo =
				  gnutls_cipher_get_id(&broken_list[i][1]))
				 != GNUTLS_CIPHER_UNKNOWN)
				fn(&(*priority_cache)->cipher, algo);
			else if ((algo =
				  gnutls_kx_get_id(&broken_list[i][1])) !=
				 GNUTLS_KX_UNKNOWN)
				fn(&(*priority_cache)->kx, algo);
			else if (strncasecmp
				 (&broken_list[i][1], "VERS-", 5) == 0) {
				if (strncasecmp
				    (&broken_list[i][1], "VERS-TLS-ALL",
				     12) == 0) {
					bulk_fn(&(*priority_cache)->
						protocol,
						protocol_priority);
				} else
				    if (strncasecmp
					(&broken_list[i][1],
					 "VERS-DTLS-ALL", 13) == 0) {
					bulk_fn(&(*priority_cache)->
						protocol,
						dtls_protocol_priority);
				} else {
					if ((algo =
					     gnutls_protocol_get_id
					     (&broken_list[i][6])) !=
					    GNUTLS_VERSION_UNKNOWN)
						fn(&(*priority_cache)->
						   protocol, algo);
					else
						goto error;

				}
			} /* now check if the element is something like -ALGO */
			else if (strncasecmp
				 (&broken_list[i][1], "COMP-", 5) == 0) {
				if (strncasecmp
				    (&broken_list[i][1], "COMP-ALL",
				     8) == 0) {
					bulk_fn(&(*priority_cache)->
						compression,
						comp_priority);
				} else {
					if ((algo =
					     gnutls_compression_get_id
					     (&broken_list[i][6])) !=
					    GNUTLS_COMP_UNKNOWN)
						fn(&(*priority_cache)->
						   compression, algo);
					else
						goto error;
				}
			} /* now check if the element is something like -ALGO */
			else if (strncasecmp
				 (&broken_list[i][1], "CURVE-", 6) == 0) {
				if (strncasecmp
				    (&broken_list[i][1], "CURVE-ALL",
				     9) == 0) {
					bulk_fn(&(*priority_cache)->
						supported_ecc,
						supported_ecc_normal);
				} else {
					if ((algo =
					     _gnutls_ecc_curve_get_id
					     (&broken_list[i][7])) !=
					    GNUTLS_ECC_CURVE_INVALID)
						fn(&(*priority_cache)->
						   supported_ecc, algo);
					else
						goto error;
				}
			} /* now check if the element is something like -ALGO */
			else if (strncasecmp
				 (&broken_list[i][1], "CTYPE-", 6) == 0) {
				if (strncasecmp
				    (&broken_list[i][1], "CTYPE-ALL",
				     9) == 0) {
					bulk_fn(&(*priority_cache)->
						cert_type,
						cert_type_priority_all);
				} else {
					if ((algo =
					     gnutls_certificate_type_get_id
					     (&broken_list[i][7])) !=
					    GNUTLS_CRT_UNKNOWN)
						fn(&(*priority_cache)->
						   cert_type, algo);
					else
						goto error;
				}
			} /* now check if the element is something like -ALGO */
			else if (strncasecmp
				 (&broken_list[i][1], "SIGN-", 5) == 0) {
				if (strncasecmp
				    (&broken_list[i][1], "SIGN-ALL",
				     8) == 0) {
					bulk_fn(&(*priority_cache)->
						sign_algo,
						sign_priority_default);
				} else {
					if ((algo =
					     gnutls_sign_get_id
					     (&broken_list[i][6])) !=
					    GNUTLS_SIGN_UNKNOWN)
						fn(&(*priority_cache)->
						   sign_algo, algo);
					else
						goto error;
				}
			} else
			    if (strncasecmp
				(&broken_list[i][1], "MAC-ALL", 7) == 0) {
				bulk_fn(&(*priority_cache)->mac,
					mac_priority_normal);
			} else
			    if (strncasecmp
				(&broken_list[i][1], "CIPHER-ALL",
				 10) == 0) {
				bulk_fn(&(*priority_cache)->cipher,
					cipher_priority_normal);
			} else
			    if (strncasecmp
				(&broken_list[i][1], "KX-ALL", 6) == 0) {
				bulk_fn(&(*priority_cache)->kx,
					kx_priority_secure);
			} else
				goto error;
		} else if (broken_list[i][0] == '%') {
			if (strcasecmp(&broken_list[i][1], "COMPAT") == 0) {
				ENABLE_COMPAT((*priority_cache));
			} else
			  if (strcasecmp(&broken_list[i][1], "DUMBFW") == 0) {
				(*priority_cache)->dumbfw = 1;
			} else
			    if (strcasecmp
				(&broken_list[i][1],
				 "NO_EXTENSIONS") == 0) {
				(*priority_cache)->no_extensions = 1;
			} else
			    if (strcasecmp
				(&broken_list[i][1],
				 "STATELESS_COMPRESSION") == 0) {
				(*priority_cache)->stateless_compression =
				    1;
			} else
			    if (strcasecmp
				(&broken_list[i][1],
				 "VERIFY_ALLOW_SIGN_RSA_MD5") == 0) {
				prio_add(&(*priority_cache)->sign_algo,
					 GNUTLS_SIGN_RSA_MD5);
				(*priority_cache)->
				    additional_verify_flags |=
				    GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5;
			} else
			    if (strcasecmp
				(&broken_list[i][1],
				 "VERIFY_DISABLE_CRL_CHECKS") == 0) {
				(*priority_cache)->
				    additional_verify_flags |=
				    GNUTLS_VERIFY_DISABLE_CRL_CHECKS;
			} else
			    if (strcasecmp
				(&broken_list[i][1],
				 "SSL3_RECORD_VERSION") == 0)
				(*priority_cache)->ssl3_record_version = 1;
			else if (strcasecmp(&broken_list[i][1],
					    "LATEST_RECORD_VERSION") == 0)
				(*priority_cache)->ssl3_record_version = 0;
			else if (strcasecmp(&broken_list[i][1],
					    "VERIFY_ALLOW_X509_V1_CA_CRT")
				 == 0)
				(*priority_cache)->
				    additional_verify_flags |=
				    GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
			else if (strcasecmp
				 (&broken_list[i][1],
				  "UNSAFE_RENEGOTIATION") == 0) {
				(*priority_cache)->sr = SR_UNSAFE;
			} else
			    if (strcasecmp
				(&broken_list[i][1],
				 "SAFE_RENEGOTIATION") == 0) {
				(*priority_cache)->sr = SR_SAFE;
			} else if (strcasecmp(&broken_list[i][1],
					      "PARTIAL_RENEGOTIATION") ==
				   0) {
				(*priority_cache)->sr = SR_PARTIAL;
			} else if (strcasecmp(&broken_list[i][1],
					      "DISABLE_SAFE_RENEGOTIATION")
				   == 0) {
				(*priority_cache)->sr = SR_DISABLED;
			} else if (strcasecmp(&broken_list[i][1],
					      "SERVER_PRECEDENCE") == 0) {
				(*priority_cache)->server_precedence = 1;
			} else if (strcasecmp(&broken_list[i][1],
					      "NEW_PADDING") == 0) {
				(*priority_cache)->new_record_padding = 1;
			} else
				goto error;
		} else
			goto error;
	}

	gnutls_free(darg);
	return 0;

      error:
	if (err_pos != NULL && i < broken_list_size) {
		*err_pos = priorities;
		for (j = 0; j < i; j++) {
			(*err_pos) += strlen(broken_list[j]) + 1;
		}
	}
	gnutls_free(darg);
	gnutls_free(*priority_cache);
	*priority_cache = NULL;

	return GNUTLS_E_INVALID_REQUEST;

}
Ejemplo n.º 19
0
static
int pkcs8_key_info(const gnutls_datum_t * raw_key,
		   const struct pkcs_cipher_schema_st **p,
		   struct pbkdf2_params *kdf_params,
		   char **oid)
{
	int result, len;
	char enc_oid[MAX_OID_SIZE*2];
	int params_start, params_end, params_len;
	struct pbe_enc_params enc_params;
	schema_id schema;
	ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY;

	memset(&enc_params, 0, sizeof(enc_params));

	result = check_for_decrypted(raw_key);
	if (result == 0)
		return GNUTLS_E_INVALID_REQUEST;

	if ((result =
	     asn1_create_element(_gnutls_get_pkix(),
				 "PKIX1.pkcs-8-EncryptedPrivateKeyInfo",
				 &pkcs8_asn)) != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	result =
	    _asn1_strict_der_decode(&pkcs8_asn, raw_key->data, raw_key->size,
			      NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	/* Check the encryption schema OID
	 */
	len = sizeof(enc_oid);
	result =
	    asn1_read_value(pkcs8_asn, "encryptionAlgorithm.algorithm",
			    enc_oid, &len);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		goto error;
	}

	if (oid) {
		*oid = gnutls_strdup(enc_oid);
	}

	if ((result = _gnutls_check_pkcs_cipher_schema(enc_oid)) < 0) {
		gnutls_assert();
		goto error;
	}

	schema = result;

	/* Get the DER encoding of the parameters.
	 */
	result =
	    asn1_der_decoding_startEnd(pkcs8_asn, raw_key->data,
				       raw_key->size,
				       "encryptionAlgorithm.parameters",
				       &params_start, &params_end);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}
	params_len = params_end - params_start + 1;

	result =
	    _gnutls_read_pkcs_schema_params(&schema, NULL,
				    &raw_key->data[params_start],
				    params_len, kdf_params, &enc_params);

	if (result < 0) {
		gnutls_assert();
		if (oid && enc_params.pbes2_oid[0] != 0) {
			snprintf(enc_oid, sizeof(enc_oid), "%s/%s", *oid, enc_params.pbes2_oid);
			gnutls_free(*oid);
			*oid = gnutls_strdup(enc_oid);
		}
		goto error;
	}

	*p = _gnutls_pkcs_schema_get(schema);
	if (*p == NULL) {
		gnutls_assert();
		result = GNUTLS_E_UNKNOWN_CIPHER_TYPE;
		goto error;
	}

	result = 0;

      error:
	asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
	return result;
}