Пример #1
0
/*
 * Produce the signature for an assertion.
 */
char *
kn_sign_assertion(char *buf, int buflen, char *key, char *sigalg, int vflag)
{
    int i, alg, hashtype, encoding, internalenc;
    struct keynote_deckey dc;
    struct assertion *as;
    char *s, *sig;

    keynote_errno = 0;
    s = NULL;

    if (sigalg == NULL || buf == NULL || key == NULL)
    {
	keynote_errno = ERROR_NOTFOUND;
	return NULL;
    }

    if (sigalg[0] == '\0' || sigalg[strlen(sigalg) - 1] != ':')
    {
	keynote_errno = ERROR_SYNTAX;
	return NULL;
    }

    /* We're using a different format for X509 private keys, so... */
    alg = keynote_get_sig_algorithm(sigalg, &hashtype, &encoding,
				    &internalenc);
    if (alg != KEYNOTE_ALGORITHM_X509)
    {
	/* Parse the private key */
	s = keynote_get_private_key(key);
	if (s == NULL)
	  return NULL;

	/* Decode private key */
	i = kn_decode_key(&dc, s, KEYNOTE_PRIVATE_KEY);
	if (i == -1)
	{
	    free(s);
	    return NULL;
	}
    }
    else /* X509 private key */
    {
	dc.dec_key = key;
	dc.dec_algorithm = alg;
    }

    as = keynote_parse_assertion(buf, buflen, ASSERT_FLAG_SIGGEN);
    if (as == NULL)
    {
	if (alg != KEYNOTE_ALGORITHM_X509)
	{
	    keynote_free_key(dc.dec_key, dc.dec_algorithm);
	    free(s);
	}
	return NULL;
    }

    sig = keynote_sign_assertion(as, sigalg, dc.dec_key, dc.dec_algorithm,
				 vflag);
    if (alg != KEYNOTE_ALGORITHM_X509)
      keynote_free_key(dc.dec_key, dc.dec_algorithm);
    keynote_free_assertion(as);
    if (s != NULL)
      free(s);
    return sig;
}
Пример #2
0
/*
 * Find and decode the configured key (pre-shared or public) for the
 * peer denoted by ID.  Stash the len in KEYLEN.
 */
static void *
ike_auth_get_key (int type, char *id, char *local_id, size_t *keylen)
{
  char *key, *buf;
#if defined (USE_X509) || defined (USE_KEYNOTE)
  char *keyfile;
#if defined (USE_X509)
  BIO *keyh;
  RSA *rsakey;
  size_t fsize;
#endif
#endif

  switch (type)
    {
    case IKE_AUTH_PRE_SHARED:
      /* Get the pre-shared key for our peer.  */
      key = conf_get_str (id, "Authentication");
      if (!key && local_id)
	key = conf_get_str (local_id, "Authentication");

      if (!key)
        {
	  log_print ("ike_auth_get_key: "
		     "no key found for peer \"%s\" or local ID \"%s\"",
		     id, local_id);
	  return 0;
	}

      /* If the key starts with 0x it is in hex format.  */
      if (strncasecmp (key, "0x", 2) == 0)
	{
	  *keylen = (strlen (key) - 1) / 2;
	  buf = malloc (*keylen);
	  if (!buf)
	    {
	      log_print ("ike_auth_get_key: malloc (%lu) failed",
		(unsigned long)*keylen);
	      return 0;
	    }
	  if (hex2raw (key + 2, (unsigned char *)buf, *keylen))
	    {
	      free (buf);
	      log_print ("ike_auth_get_key: invalid hex key %s", key);
	      return 0;
	    }
	  key = buf;
	}
      else
	*keylen = strlen (key);
      break;

    case IKE_AUTH_RSA_SIG:
#if defined (USE_X509) || defined (USE_KEYNOTE)
#if defined (USE_KEYNOTE)
      if (local_id &&
	  (keyfile = conf_get_str ("KeyNote", "Credential-directory")) != 0)
        {
	  struct stat sb;
	  struct keynote_deckey dc;
	  char *privkeyfile, *buf2;
	  int fd, pkflen;
	  size_t size;

	  pkflen = strlen (keyfile) + strlen (local_id) +
	    sizeof PRIVATE_KEY_FILE + sizeof "//" - 1;
	  privkeyfile = calloc (pkflen, sizeof (char));
	  if (!privkeyfile)
	    {
	      log_print ("ike_auth_get_key: failed to allocate %d bytes",
			 pkflen);
	      return 0;
	    }

	  snprintf (privkeyfile, pkflen, "%s/%s/%s", keyfile, local_id,
		   PRIVATE_KEY_FILE);
	  keyfile = privkeyfile;

	  if (stat (keyfile, &sb) < 0)
	    {
	      free (keyfile);
	      goto ignorekeynote;
	    }
	  size = (size_t)sb.st_size;

	  fd = open (keyfile, O_RDONLY, 0);
	  if (fd < 0)
	    {
	      log_print ("ike_auth_get_key: failed opening \"%s\"", keyfile);
	      free (keyfile);
	      return 0;
	    }

	  buf = calloc (size + 1, sizeof (char));
	  if (!buf)
	    {
	      log_print ("ike_auth_get_key: failed allocating %lu bytes",
			 (unsigned long)size + 1);
	      free (keyfile);
	      return 0;
	    }

	  if (read (fd, buf, size) != size)
	    {
	      free (buf);
	      log_print ("ike_auth_get_key: "
			 "failed reading %lu bytes from \"%s\"",
			(unsigned long)size, keyfile);
	      free (keyfile);
	      return 0;
	    }

	  close (fd);

	  /* Parse private key string */
	  buf2 = kn_get_string (buf);
	  free (buf);

	  if (kn_decode_key (&dc, buf2, KEYNOTE_PRIVATE_KEY) == -1)
	    {
	      free (buf2);
	      log_print ("ike_auth_get_key: failed decoding key in \"%s\"",
			 keyfile);
	      free (keyfile);
	      return 0;
	    }

	  free (buf2);

	  if (dc.dec_algorithm != KEYNOTE_ALGORITHM_RSA)
	    {
	      log_print ("ike_auth_get_key: wrong algorithm type %d in \"%s\"",
			 dc.dec_algorithm, keyfile);
	      free (keyfile);
	      kn_free_key (&dc);
	      return 0;
	    }

	  free (keyfile);
	  return dc.dec_key;
	}

    ignorekeynote:
#endif /* USE_KEYNOTE */
#ifdef USE_X509
      /* Otherwise, try X.509 */
      keyfile = conf_get_str ("X509-certificates", "Private-key");

      if (check_file_secrecy (keyfile, &fsize))
	return 0;

      keyh = BIO_new (BIO_s_file ());
      if (keyh == NULL)
	{
	  log_print ("ike_auth_get_key: "
		     "BIO_new (BIO_s_file ()) failed");
	  return 0;
	}
      if (BIO_read_filename (keyh, keyfile) == -1)
	{
	  log_print ("ike_auth_get_key: "
		     "BIO_read_filename (keyh, \"%s\") failed",
		     keyfile);
	  BIO_free (keyh);
	  return 0;
	}

#if SSLEAY_VERSION_NUMBER >= 0x00904100L
      rsakey = PEM_read_bio_RSAPrivateKey (keyh, NULL, NULL, NULL);
#else
      rsakey = PEM_read_bio_RSAPrivateKey (keyh, NULL, NULL);
#endif
      BIO_free (keyh);
      if (!rsakey)
	{
	  log_print ("ike_auth_get_key: PEM_read_bio_RSAPrivateKey failed");
	  return 0;
	}

      return rsakey;
#endif /* USE_X509 */
#endif /* USE_X509 || USE_KEYNOTE */

    default:
      log_print ("ike_auth_get_key: unknown key type %d", type);
      return 0;
    }

  return key;
}