/* prepares a certificate, signs it and writes it to file */
int 
cert_sign_n_write (const dckey *ca, const char *id, const dckey *pk, 
		   unsigned int ndays, const char *cert_file)
{
  int fdcert;
  cert *cert = NULL; 
  char *cert_msg = NULL;
  
  if (!(cert = cert_init (ca, id, pk, ndays))
      || !(cert_msg = cert_export (cert, 0))
      || !(cert->sig = dcsign (ca, cert_msg))
      || (xfree (cert_msg), !(cert_msg = cert_export (cert, 1)))) {
    printf ("%s: error creating the certificate\n", getprogname ());
    cert_clr (cert);
    cert = NULL;
    check_n_free (&cert_msg);
    
    return -2;
  }
  /* write certificate and signature to fdcert */
  else {
    if ((fdcert = open (cert_file,O_WRONLY|O_TRUNC|O_CREAT,0644)) == -1){
      printf ("%s: trouble opening %s\n",
	      getprogname (), cert_file);
      perror (getprogname ());

      cert_clr (cert);
      cert = NULL;
      check_n_free (&cert_msg);
      
      return -1;
    }
    else if ((write_chunk (fdcert, cert_msg, strlen (cert_msg)) == -1) 
	     || (write_chunk (fdcert, "\n", 1) == -1)) {
      printf ("%s: trouble writing certificate to %s\n",
	      getprogname (), cert_file);
      perror (getprogname ());

      cert_clr (cert);
      cert = NULL;
      check_n_free (&cert_msg);
      
      return -1;
    }
    else {
      cert_clr (cert);
      cert = NULL;
      check_n_free (&cert_msg);
      
      close (fdcert);
      fdcert = -1;
      
      return 0;
    }
  }
}
void
cert_clr (cert *c)
{
  if (c) {
    check_n_free (&(c->version));
    check_n_free (&(c->issuer));
    check_n_free (&(c->identity));
    check_n_free (&(c->public_key));
    
    xfree (c);
  }
}
dckey *
g_option (const char *sk_file)
{
  char *raw_pk = NULL;
  dckey *pk = NULL;
  dckey *sk = dckeygen (DC_RABIN, 1024, NULL); 
  write_skfile (sk_file, sk);
  
  if (!(raw_pk = dcexport_pub (sk)) 
      || ! (pk = dcimport_pub (raw_pk))) {
    fprintf (stderr, "%s: trouble exporting public key\n", getprogname ());
    check_n_free (&raw_pk);
    dcfree (sk);

    exit (1);
  }

  check_n_free (&raw_pk);
  return pk;
}
Esempio n. 4
0
static void *search_multi_page(struct page_allocator *allocator, size_t page_q) {
	size_t page_n = 0;
	size_t found_page_q;

	while (-1 != (page_n = search_first_free(allocator, page_n))) {
		if (page_q == (found_page_q = check_n_free(allocator, page_n, page_q))) {
			mark_n_busy(allocator, page_n, page_q);
			return page_i2ptr(allocator, page_n);
		}
		page_n += found_page_q;
	}

	return NULL;
}
/* verify the signature on a certificate */
int
cert_verify (const cert *c)
{
  int res;

  char *raw_cert = cert_export (c, 0); /* don't append sig to cert */
  
  if (!raw_cert || (dcverify (c->issuer, raw_cert, c->sig) == -1)
      || ((c->day_issued != c->day_expires) 
	  && (difftime (c->day_expires, time (NULL)) < -EXP_CERT_GRACE))) {
    res = 0;
  }
  else {
    res = 1;
  }

  check_n_free (&raw_cert);

  return res;
}
int 
main (int argc, char **argv)
{
  int fdca, fdpk;
  dckey *ca = NULL, *pk = NULL;
  char *id = NULL;
  char *cert_file = NULL, *pk_file = NULL;
  int duration = -1;

  ri ();

  if (argc < 2) 
    usage (argv[0]);
  else if (argc == 2) {
    if (strcmp (argv[1], "init") != 0)
      usage (argv[0]);
    else {
      setprogname (argv[0]);
      pki_init ();      
    }
  }
  else if (argc == 5) {
    if (strcmp (argv[1], "check") != 0)
      usage (argv[0]);
    else {
      setprogname (argv[0]);
      pki_check (argv[2], argv[3], argv[4]);      
    }
  }
  else if (strcmp (argv[1], "cert") != 0) {
    usage (argv[0]);
  }
  else {
    /* cert commnad */
    setprogname (argv[0]);

    /* first, let's take care of the options, if any */
    parse_options (&pk, &cert_file, &duration, argc, argv);

    /* the last two args are ID and PK-FILE */
    pk_file = argv[argc - 2];
    id = argv[argc - 1];
    /* set up default values for parameters not affected by the options */
    if (!cert_file) {
      /* default cert_file is ID.cert */
      if (cat_str (&cert_file, id)
	  || cat_str (&cert_file, ".cert")) {
	xfree (cert_file);
	exit (1);	    
      }
    }
      
    if (duration == -1) 
      /* default duration is 30 days */
      duration = 30;

    /* take care of the public key that we are certifying */
    /* if the -g option was used, we have to write the pk to pk_file */
    if (pk) 
      write_pkfile (pk_file, pk); 
    /* otherwise, import pk from pk_file */
    else {
      if ((fdpk = open (pk_file, O_RDONLY)) == -1) {
	if (errno == ENOENT) {
	  usage (argv[0]);
	}
	else {
	  perror (argv[0]);
	  
	  exit (1);
	}
      }
      else if (!(pk = import_pub_from_file (fdpk))) {
	fprintf (stderr, "%s: no public key found in %s\n", argv[0], pk_file);
      
	close (fdpk);
	exit (1);
      }
      close (fdpk);
      fdpk = -1;
    }
    /* now read the ca private key from ./.pki/ca.priv */
    if ((fdca = open ("./.pki/ca.priv", O_RDONLY)) == -1) {
      if (errno == ENOENT) {
	usage (argv[0]);
      }
      else {
	perror (argv[0]);
	
	exit (1);
      }
    }   
    else {
      if (!(ca = import_priv_from_file (fdca))) {
	fprintf (stderr, "%s: no private key found in %s\n", 
		argv[0], "./.pki/ca.priv");
	
	close (fdca);
	exit (1);
      }
      close (fdca);
      fdca = -1;

      /* prepare a cert, sign it and write it to cert_file */
      switch (cert_sign_n_write (ca, id, pk, duration, cert_file)) {
      case 0:
	/* no error */
	/* the ca signing key is not needed anymore: wipe it out */
	dcfree (ca);
	ca = NULL;
	break;
      case -1:
	/* trouble with the write system call */
	check_n_free (&cert_file);
	dcfree (ca);
	exit (1);
      case -2:
	/* trouble preparing/signinig the certificate */
	check_n_free (&cert_file);
	dcfree (ca);
	exit (1);
      default:
	check_n_free (&cert_file);
	dcfree (ca);
	exit (1);
      }

      assert (cert_verify (cert_read (cert_file)));
      
      dcfree (pk);
      pk = NULL;
    }
  }
  check_n_free (&cert_file);
  
  return 0;
}
int
main (int argc, char **argv)
{
  const char *ke_msg1 = NULL;
  char *ke_msg2 = NULL;
  char *ca_file = NULL;
  char *sk_file = NULL;
  char *cert_file = NULL;
  char *resp_id = NULL;
  int out_fd;
  flow1 *to_b = NULL;
  flow2 *from_b = NULL;
  cert *own_cert = NULL;
  dckey *sk = NULL;
  dckey *ca_pk = NULL;
  u_char seskey[sha1_hashsize], secret[aes_blocklen];
  char *pretty_secret = NULL;

  if ((argc == 5) && argv[1][0] != '-') {
    /* no -p option */
    ca_file = "./.pki/ca.pub";
  }
  else if ((argc == 6)
	   && (argv[1][0] != '-') 
	   && (argv[1] + 1) && (argv[1][1] != 'p')
	   && (argv[1] + 2)) {
    /* -p option present, followed by CERT-FILE without separating blank  */
    ca_file = argv[1] + 2;
  }
  else if ((argc == 7) && !strcmp (argv[1], "-p")) {
    /* -p option present, followed by blank and CERT-FILE */
    ca_file = argv[2];
  }
  else {
    usage (argv[0]);
    /* does not return */
  }

  setprogname (argv[0]);
  ri ();

  sk_file = argv[argc - 4];
  cert_file = argv[argc - 3];
  resp_id = argv[argc - 2];
  out_fd = atoi (argv[argc - 1]);

  if (!cert_verify (own_cert = cert_read (cert_file))) {
      fprintf (stderr, "%s: trouble reading certificate from %s, or certificate expired\n",
	      getprogname (), cert_file);
      perror (getprogname ());

      exit (1);
  }
  else {
    to_b = prepare_ke_msg (own_cert, xstrdup (resp_id));
    sk = sk_from_file (sk_file);
    ke_msg1 = export_ke_msg (to_b, sk);
    dcfree (sk);
    sk = NULL;
    write_chunk (1, ke_msg1, strlen (ke_msg1));
    check_n_free ((char **) &ke_msg1);
    ca_pk = pk_from_file (ca_file);
    if (!(ke_msg2 = read_line (0)) 
	|| !(from_b = process_ke_reply (to_b, ke_msg2, ca_pk))) {
      fprintf (stderr, "error reading/parsing bob's message:\n%s", ke_msg2);
      dcfree (ca_pk);
      ca_pk = NULL;
      check_n_free(&ke_msg2);
      
      exit (1);
    }

    dcfree (ca_pk);
    ca_pk = NULL;
    check_n_free(&ke_msg2);

    /* derive_key looks at seskey to know if it the caller is alice or bob */
    seskey[0] = 'a';
    if (derive_key (seskey, to_b, from_b) == -1) {
      fprintf (stderr, "error deriving session key for alice.\n");
      flow1_clr (to_b);
      flow2_clr (from_b);
      
      exit (1);
    }
    else {
      /* choose a random number to send */
      prng_getbytes (secret, aes_blocklen);
      cat_buf (&pretty_secret, secret, aes_blocklen);
      
      /* send it to bob, encrypted under the newly established session key */
      send_secret (1, secret, seskey);

      /* dump the chosen secret to standard error */
      if ((write_chunk (out_fd, pretty_secret, strlen (pretty_secret)) == -1)
	  || (write_chunk (out_fd, "\n", 1) == -1)) {
	fprintf (stderr, "error writing to the launcher.\n");
	bzero (seskey, sha1_hashsize);
	bzero (secret, sizeof (secret));
	bzero (pretty_secret, strlen (pretty_secret));
	xfree (pretty_secret);
	pretty_secret = NULL;
	flow1_clr (to_b);
	flow2_clr (from_b);
	
	exit (1);
      }

      /* wipe out sensitive data */
      bzero (seskey, sha1_hashsize);
      bzero (secret, sizeof (secret));
      bzero (pretty_secret, strlen (pretty_secret));
      xfree (pretty_secret);
      pretty_secret = NULL;
      flow1_clr (to_b);
      flow2_clr (from_b);
    }
  }

  /* fprintf (stderr, "alice:done.\n"); */
  return 0;
}