Example #1
0
static int
gather_faked( void (*add)(const void*, size_t, int), int requester,
	      size_t length, int level )
{
    static int initialized=0;
    size_t n;
    char *buffer, *p;

    if( !initialized ) {
	log_info(_("WARNING: using insecure random number generator!!\n"));
	tty_printf(_("The random number generator is only a kludge to let\n"
		   "it run - it is in no way a strong RNG!\n\n"
		   "DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n\n"));
	initialized=1;
      #ifdef HAVE_RAND
	srand(make_timestamp()*getpid());
      #else
	srandom(make_timestamp()*getpid());
      #endif
    }

    p = buffer = m_alloc( length );
    n = length;
  #ifdef HAVE_RAND
    while( n-- )
	*p++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1);
  #else
    while( n-- )
	*p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1);
  #endif
    add_randomness( buffer, length, requester );
    m_free(buffer);
    return 0; /* okay */
}
Example #2
0
/* Allocator function */
static void stored_item_add(pqi inst, int id, int uses, const char* file, int tsec, int tusec)
{
	psi ret;
	GDesktopAppInfo* dai = g_desktop_app_info_new_from_filename(file);
	
	if (!dai)
		return;
	
	ret = (psi)malloc(sizeof(stored_item));
	ret->id = id;
	ret->uses = uses;
	ret->file = file;
	ret->lastaccess = make_timestamp();
	
	if (inst->items)
		ret->prev = inst->lastitem,
		inst->lastitem->next = ret,
		inst->lastitem = ret;
	else
		inst->items = inst->lastitem = ret,
		ret->prev = NULL;
	
	ret->dfile = dai;
	ret->next = NULL;
	
	ret->lastaccess = (((long long)tsec << 32) | (long long)tusec);
	
	ret->parent = inst;
}
Example #3
0
/****************
 * Print a list of all defined owner trust value.
 */
void
export_ownertrust (ctrl_t ctrl)
{
  TRUSTREC rec;
  ulong recnum;
  int i;
  byte *p;

  init_trustdb (ctrl, 0);
  es_printf (_("# List of assigned trustvalues, created %s\n"
               "# (Use \"gpg --import-ownertrust\" to restore them)\n"),
             asctimestamp( make_timestamp() ) );
  for (recnum=0; !tdbio_read_record (recnum, &rec, 0); recnum++ )
    {
      if (rec.rectype == RECTYPE_TRUST)
        {
          if (!rec.r.trust.ownertrust)
            continue;
          p = rec.r.trust.fingerprint;
          for (i=0; i < 20; i++, p++ )
            es_printf("%02X", *p );
          es_printf (":%u:\n", (unsigned int)rec.r.trust.ownertrust );
	}
    }
}
Example #4
0
/* This function launches whatever item is selected in the menu deployed by the function below. */
void menu_launch(GtkMenuItem *unused, gpointer data)
{
	psi const si = (psi)data; GError *err = NULL;
	g_app_info_launch((GAppInfo*)si->dfile,NULL,NULL,&err);
	si->uses++; si->lastaccess = make_timestamp();
	resolve_item_order(((psi)data)->parent);
	save_current_list(((psi)data)->parent);
}
Example #5
0
/****************
 * The filter is used to report progress to the user.
 */
static int
progress_filter (void *opaque, int control,
		 IOBUF a, byte *buf, size_t *ret_len)
{
  int rc = 0;
  progress_filter_context_t *pfx = opaque;

  if (control == IOBUFCTRL_INIT)
    {
      pfx->last = 0;
      pfx->offset = 0;
      pfx->last_time = make_timestamp ();

      write_status_progress (pfx->what, pfx->offset, pfx->total);
    }
  else if (control == IOBUFCTRL_UNDERFLOW)
    {
      u32 timestamp = make_timestamp ();
      int len = iobuf_read (a, buf, *ret_len);

      if (len >= 0)
	{
	  pfx->offset += len;
	  *ret_len = len;
	}
      else
	{
	  *ret_len = 0;
	  rc = -1;
	}
      if ((len == -1 && pfx->offset != pfx->last)
	  || timestamp - pfx->last_time > 0)
	{
          write_status_progress (pfx->what, pfx->offset, pfx->total);
	  pfx->last = pfx->offset;
	  pfx->last_time = timestamp;
	}
    }
  else if (control == IOBUFCTRL_FREE)
    {
      release_progress_context (pfx);
    }
  else if (control == IOBUFCTRL_DESC)
    mem2str (buf, "progress_filter", *ret_len);
  return rc;
}
Example #6
0
/* This function launches the first item on our list; the one we're displaying in the panel. */
void menu_launch_first(pqi inst)
{
	GError *err = NULL;
	if (inst && inst->items)
	{
		g_app_info_launch((GAppInfo*)inst->items->dfile,NULL,NULL,&err);
		inst->items->uses++; inst->items->lastaccess = make_timestamp();
		resolve_item_order(inst);
		save_current_list(inst);
	}
}
Example #7
0
void logger::log_last_line() {
  event tmp{CAF_LOG_LEVEL_INFO,
            CAF_LOG_COMPONENT,
            CAF_PRETTY_FUN,
            __FILE__,
            __LINE__,
            "EOF",
            std::this_thread::get_id(),
            0,
            make_timestamp()};
  handle_event(tmp);
}
Example #8
0
void logger::start() {
#if CAF_LOG_LEVEL >= 0
  parent_thread_ = std::this_thread::get_id();
  if (level_ == CAF_LOG_LEVEL_QUIET)
    return;
  t0_ = make_timestamp();
  auto f = get_or(system_.config(), "logger.file-name",
                  defaults::logger::file_name);
  if (f.empty()) {
    // No need to continue if console and log file are disabled.
    if (has(console_output_flag))
      return;
  } else {
    // Replace placeholders.
    const char pid[] = "[PID]";
    auto i = std::search(f.begin(), f.end(), std::begin(pid),
                         std::end(pid) - 1);
    if (i != f.end()) {
      auto id = std::to_string(detail::get_process_id());
      f.replace(i, i + sizeof(pid) - 1, id);
    }
    const char ts[] = "[TIMESTAMP]";
    i = std::search(f.begin(), f.end(), std::begin(ts), std::end(ts) - 1);
    if (i != f.end()) {
      auto t0_str = timestamp_to_string(t0_);
      f.replace(i, i + sizeof(ts) - 1, t0_str);
    }
    const char node[] = "[NODE]";
    i = std::search(f.begin(), f.end(), std::begin(node), std::end(node) - 1);
    if (i != f.end()) {
      auto nid = to_string(system_.node());
      f.replace(i, i + sizeof(node) - 1, nid);
    }
    file_.open(f, std::ios::out | std::ios::app);
    if (!file_) {
      std::cerr << "unable to open log file " << f << std::endl;
      return;
    }
  }
  if (has(inline_output_flag))
    log_first_line();
  else
    thread_ = std::thread{[this] {
      this->system_.thread_started();
      this->run();
      this->system_.thread_terminates();
    }};
#endif
}
Example #9
0
int add_timestamps(json_t *object, const char *created, const char *modified,
                   const char *replicate, baton_error_t *error) {
    json_t *iso_created  = NULL; // Ref to be stolen by result
    json_t *iso_modified = NULL; // Ref to be stolen by result
    json_t *timestamps;

    init_baton_error(error);

    if (!json_is_object(object)) {
        set_baton_error(error, -1, "Failed to add timestamp data: "
                        "target not a JSON object");
        goto error;
    }

    iso_created = make_timestamp(JSON_CREATED_KEY, created,
                                 ISO8601_FORMAT, replicate, error);
    if (error->code != 0) goto error;

    iso_modified = make_timestamp(JSON_MODIFIED_KEY, modified,
                                  ISO8601_FORMAT, replicate, error);
    if (error->code != 0) goto error;

    timestamps = json_pack("[o, o]", iso_created, iso_modified);
    if (!timestamps) {
        set_baton_error(error, -1, "Failed to pack timestamp array");
        goto error;
    }

    return json_object_set_new(object, JSON_TIMESTAMPS_KEY, timestamps);

error:
    if (iso_created)  json_decref(iso_created);
    if (iso_modified) json_decref(iso_modified);

    return error->code;
}
Example #10
0
void logger::log_first_line() {
  std::string msg = "level = ";
  msg += to_string(get_or(system_.config(), "logger.verbosity",
                          defaults::logger::verbosity));
  msg += ", node = ";
  msg += to_string(system_.node());
  event tmp{CAF_LOG_LEVEL_INFO,
            CAF_LOG_COMPONENT,
            CAF_PRETTY_FUN,
            __FILE__,
            __LINE__,
            std::move(msg),
            std::this_thread::get_id(),
            0,
            make_timestamp()};
  handle_event(tmp);
}
Example #11
0
static void gen_message(Octstr *out) {
	static int send_seq = 0;
	unsigned char dest[21];
	unsigned char orig[21];
	unsigned char scts[TIMESTAMP_MAXLEN];
	unsigned char message[481];
	unsigned char udh[281];

	if (awaiting_response == 1)
		return;

	random_address(dest, sizeof(dest));
	random_address(orig, sizeof(orig));
	make_timestamp(scts, time(NULL));
	random_message(message, sizeof(message));
	if (random() % 2 == 0)
		random_hex(udh, sizeof(udh));
	else
		*udh = 0;

	if (logging == LOG_packets)
		printf("SND: Deliver message (random)\n");

	if (*udh) {
		send_packet(out, 20, send_seq,
			21, dest,
			23, orig,
			60, scts,
			32, udh,
			33, message,
			0);
	} else {
		send_packet(out, 20, send_seq,
			21, dest,
			23, orig,
			60, scts,
			33, message,
			0);
	}

	send_seq += 2;
	if (send_seq > 255)
		send_seq = 0;

	awaiting_response = 1;
}
Example #12
0
static
size_t audit_log_audit_record(char *buf, size_t buflen,
                              const char *name, time_t t)
{
  char id_str[MAX_RECORD_ID_SIZE];
  char timestamp[MAX_TIMESTAMP_SIZE];
  char arg_buf[512];
  const char *format_string[] = {
                     "<AUDIT_RECORD\n"
                     "  NAME=\"%s\"\n"
                     "  RECORD=\"%s\"\n"
                     "  TIMESTAMP=\"%s\"\n"
                     "  MYSQL_VERSION=\"%s\"\n"
                     "  STARTUP_OPTIONS=\"%s\"\n"
                     "  OS_VERSION=\""MACHINE_TYPE"-"SYSTEM_TYPE"\"\n"
                     "/>\n",

                     "<AUDIT_RECORD>\n"
                     "  <NAME>%s</NAME>\n"
                     "  <RECORD>%s</RECORD>\n"
                     "  <TIMESTAMP>%s</TIMESTAMP>\n"
                     "  <MYSQL_VERSION>%s</MYSQL_VERSION>\n"
                     "  <STARTUP_OPTIONS>%s</STARTUP_OPTIONS>\n"
                     "  <OS_VERSION>"MACHINE_TYPE"-"SYSTEM_TYPE"</OS_VERSION>\n"
                     "</AUDIT_RECORD>\n",

                     "{\"audit_record\":{\"name\":\"%s\",\"record\":\"%s\","
                     "\"timestamp\":\"%s\",\"mysql_version\":\"%s\","
                     "\"startup_optionsi\":\"%s\","
                     "\"os_version\":\""MACHINE_TYPE"-"SYSTEM_TYPE"\"}}\n",

                     "\"%s\",\"%s\",\"%s\",\"%s\",\"%s\","
                     "\""MACHINE_TYPE"-"SYSTEM_TYPE"\"\n" };

  return my_snprintf(buf, buflen,
                     format_string[audit_log_format],
                     name,
                     make_record_id(id_str, sizeof(id_str)),
                     make_timestamp(timestamp, sizeof(timestamp), t),
                     server_version,
                     make_argv(arg_buf, sizeof(arg_buf),
                               orig_argc - 1, orig_argv + 1));
}
Example #13
0
static void handle_get(Octstr *packet, Octstr *out, int sequence) {
	long number = eat_int_parm(packet, 500, 3);

	if (logging == LOG_packets)
		printf("RCV: Get parameter #%ld\n", number);

	if (number == INT_MIN) {
		send_error(out, 59, sequence, "900", "missing parameter");
	} else if (number == 501) {
		unsigned char buf[TIMESTAMP_MAXLEN];
		make_timestamp(buf, time(NULL));
		if (logging == LOG_packets)
			printf("SND: OK, SMSC timestamp is '%s'\n", buf);
		send_packet(out, 59, sequence,
			    501, buf,
			    0);
	} else {
		send_error(out, 59, sequence, "900", "unknown parameter");
	}
}
/* Caller must sync */
int
tdbio_update_version_record (void)
{
  TRUSTREC rec;
  int rc;

  memset( &rec, 0, sizeof rec );

  rc=tdbio_read_record( 0, &rec, RECTYPE_VER);
  if(rc==0)
    {
      rec.r.ver.created     = make_timestamp();
      rec.r.ver.marginals   = opt.marginals_needed;
      rec.r.ver.completes   = opt.completes_needed;
      rec.r.ver.cert_depth  = opt.max_cert_depth;
      rec.r.ver.trust_model = opt.trust_model;
      rc=tdbio_write_record(&rec);
    }

  return rc;
}
static int
create_version_record (void)
{
  TRUSTREC rec;
  int rc;
  
  memset( &rec, 0, sizeof rec );
  rec.r.ver.version     = 3;
  rec.r.ver.created     = make_timestamp();
  rec.r.ver.marginals   = opt.marginals_needed;
  rec.r.ver.completes   = opt.completes_needed;
  rec.r.ver.cert_depth  = opt.max_cert_depth;
  if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
    rec.r.ver.trust_model = opt.trust_model;
  else
    rec.r.ver.trust_model = TM_PGP;
  rec.rectype = RECTYPE_VER;
  rec.recnum = 0;
  rc = tdbio_write_record( &rec );
  if( !rc )
    tdbio_sync();
  return rc;
}
Example #16
0
static gpg_error_t
get_it (ctrl_t ctrl,
        PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
{
  gpg_error_t err;
  byte *frame = NULL;
  unsigned int n;
  size_t nframe;
  u16 csum, csum2;
  int padding;
  gcry_sexp_t s_data;
  char *desc;
  char *keygrip;
  byte fp[MAX_FINGERPRINT_LEN];
  size_t fpn;

  if (DBG_CLOCK)
    log_clock ("decryption start");

  /* Get the keygrip.  */
  err = hexkeygrip_from_pk (sk, &keygrip);
  if (err)
    goto leave;

  /* Convert the data to an S-expression.  */
  if (sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL
      || sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E)
    {
      if (!enc->data[0] || !enc->data[1])
        err = gpg_error (GPG_ERR_BAD_MPI);
      else
        err = gcry_sexp_build (&s_data, NULL, "(enc-val(elg(a%m)(b%m)))",
                               enc->data[0], enc->data[1]);
    }
  else if (sk->pubkey_algo == PUBKEY_ALGO_RSA
           || sk->pubkey_algo == PUBKEY_ALGO_RSA_E)
    {
      if (!enc->data[0])
        err = gpg_error (GPG_ERR_BAD_MPI);
      else
        err = gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))",
                               enc->data[0]);
    }
  else if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
    {
      if (!enc->data[0] || !enc->data[1])
        err = gpg_error (GPG_ERR_BAD_MPI);
      else
        err = gcry_sexp_build (&s_data, NULL, "(enc-val(ecdh(s%m)(e%m)))",
                               enc->data[1], enc->data[0]);
    }
  else
    err = gpg_error (GPG_ERR_BUG);

  if (err)
    goto leave;

  if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
    {
      fingerprint_from_pk (sk, fp, &fpn);
      log_assert (fpn == 20);
    }

  /* Decrypt. */
  desc = gpg_format_keydesc (ctrl, sk, FORMAT_KEYDESC_NORMAL, 1);
  err = agent_pkdecrypt (NULL, keygrip,
                         desc, sk->keyid, sk->main_keyid, sk->pubkey_algo,
                         s_data, &frame, &nframe, &padding);
  xfree (desc);
  gcry_sexp_release (s_data);
  if (err)
    goto leave;

  /* Now get the DEK (data encryption key) from the frame
   *
   * Old versions encode the DEK in this format (msb is left):
   *
   *     0  1  DEK(16 bytes)  CSUM(2 bytes)  0  RND(n bytes) 2
   *
   * Later versions encode the DEK like this:
   *
   *     0  2  RND(n bytes)  0  A  DEK(k bytes)  CSUM(2 bytes)
   *
   * (mpi_get_buffer already removed the leading zero).
   *
   * RND are non-zero randow bytes.
   * A   is the cipher algorithm
   * DEK is the encryption key (session key) with length k
   * CSUM
   */
  if (DBG_CRYPTO)
    log_printhex (frame, nframe, "DEK frame:");
  n = 0;

  if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
    {
      gcry_mpi_t shared_mpi;
      gcry_mpi_t decoded;

      /* At the beginning the frame are the bytes of shared point MPI.  */
      err = gcry_mpi_scan (&shared_mpi, GCRYMPI_FMT_USG, frame, nframe, NULL);
      if (err)
        {
          err = gpg_error (GPG_ERR_WRONG_SECKEY);
          goto leave;
        }

      err = pk_ecdh_decrypt (&decoded, fp, enc->data[1]/*encr data as an MPI*/,
                             shared_mpi, sk->pkey);
      mpi_release (shared_mpi);
      if(err)
        goto leave;

      xfree (frame);
      err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &frame, &nframe, decoded);
      mpi_release (decoded);
      if (err)
        goto leave;

      /* Now the frame are the bytes decrypted but padded session key.  */

      /* Allow double padding for the benefit of DEK size concealment.
         Higher than this is wasteful. */
      if (!nframe || frame[nframe-1] > 8*2 || nframe <= 8
          || frame[nframe-1] > nframe)
        {
          err = gpg_error (GPG_ERR_WRONG_SECKEY);
          goto leave;
        }
      nframe -= frame[nframe-1]; /* Remove padding.  */
      log_assert (!n); /* (used just below) */
    }
  else
    {
      if (padding)
        {
          if (n + 7 > nframe)
            {
              err = gpg_error (GPG_ERR_WRONG_SECKEY);
              goto leave;
            }
          if (frame[n] == 1 && frame[nframe - 1] == 2)
            {
              log_info (_("old encoding of the DEK is not supported\n"));
              err = gpg_error (GPG_ERR_CIPHER_ALGO);
              goto leave;
            }
          if (frame[n] != 2) /* Something went wrong.  */
            {
              err = gpg_error (GPG_ERR_WRONG_SECKEY);
              goto leave;
            }
          for (n++; n < nframe && frame[n]; n++) /* Skip the random bytes.  */
            ;
          n++; /* Skip the zero byte.  */
        }
    }

  if (n + 4 > nframe)
    {
      err = gpg_error (GPG_ERR_WRONG_SECKEY);
      goto leave;
    }

  dek->keylen = nframe - (n + 1) - 2;
  dek->algo = frame[n++];
  err = openpgp_cipher_test_algo (dek->algo);
  if (err)
    {
      if (!opt.quiet && gpg_err_code (err) == GPG_ERR_CIPHER_ALGO)
        {
          log_info (_("cipher algorithm %d%s is unknown or disabled\n"),
                    dek->algo,
                    dek->algo == CIPHER_ALGO_IDEA ? " (IDEA)" : "");
        }
      dek->algo = 0;
      goto leave;
    }
  if (dek->keylen != openpgp_cipher_get_algo_keylen (dek->algo))
    {
      err = gpg_error (GPG_ERR_WRONG_SECKEY);
      goto leave;
    }

  /* Copy the key to DEK and compare the checksum.  */
  csum = buf16_to_u16 (frame+nframe-2);
  memcpy (dek->key, frame + n, dek->keylen);
  for (csum2 = 0, n = 0; n < dek->keylen; n++)
    csum2 += dek->key[n];
  if (csum != csum2)
    {
      err = gpg_error (GPG_ERR_WRONG_SECKEY);
      goto leave;
    }
  if (DBG_CLOCK)
    log_clock ("decryption ready");
  if (DBG_CRYPTO)
    log_printhex (dek->key, dek->keylen, "DEK is:");

  /* Check that the algo is in the preferences and whether it has
   * expired.  Also print a status line with the key's fingerprint.  */
  {
    PKT_public_key *pk = NULL;
    PKT_public_key *mainpk = NULL;
    KBNODE pkb = get_pubkeyblock (ctrl, keyid);

    if (!pkb)
      {
        err = -1;
        log_error ("oops: public key not found for preference check\n");
      }
    else if (pkb->pkt->pkt.public_key->selfsigversion > 3
             && dek->algo != CIPHER_ALGO_3DES
             && !opt.quiet
             && !is_algo_in_prefs (pkb, PREFTYPE_SYM, dek->algo))
      log_info (_("WARNING: cipher algorithm %s not found in recipient"
                  " preferences\n"), openpgp_cipher_algo_name (dek->algo));

    if (!err)
      {
        kbnode_t k;
        int first = 1;

        for (k = pkb; k; k = k->next)
          {
            if (k->pkt->pkttype == PKT_PUBLIC_KEY
                || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
              {
                u32 aki[2];

                if (first)
                  {
                    first = 0;
                    mainpk = k->pkt->pkt.public_key;
                  }

                keyid_from_pk (k->pkt->pkt.public_key, aki);
                if (aki[0] == keyid[0] && aki[1] == keyid[1])
                  {
                    pk = k->pkt->pkt.public_key;
                    break;
                  }
              }
          }
        if (!pk)
          BUG ();
        if (pk->expiredate && pk->expiredate <= make_timestamp ())
          {
            log_info (_("Note: secret key %s expired at %s\n"),
                      keystr (keyid), asctimestamp (pk->expiredate));
          }
      }

    if (pk && pk->flags.revoked)
      {
        log_info (_("Note: key has been revoked"));
        log_printf ("\n");
        show_revocation_reason (ctrl, pk, 1);
      }

    if (is_status_enabled () && pk && mainpk)
      {
        char pkhex[MAX_FINGERPRINT_LEN*2+1];
        char mainpkhex[MAX_FINGERPRINT_LEN*2+1];

        hexfingerprint (pk, pkhex, sizeof pkhex);
        hexfingerprint (mainpk, mainpkhex, sizeof mainpkhex);

        /* Note that we do not want to create a trustdb just for
         * getting the ownertrust: If there is no trustdb there can't
         * be ulitmately trusted key anyway and thus the ownertrust
         * value is irrelevant.  */
        write_status_printf (STATUS_DECRYPTION_KEY, "%s %s %c",
                             pkhex, mainpkhex,
                             get_ownertrust_info (ctrl, mainpk, 1));

      }

    release_kbnode (pkb);
    err = 0;
  }

 leave:
  xfree (frame);
  xfree (keygrip);
  return err;
}
Example #17
0
/* Returns a keyrec (which must be freed) once a key is complete, and
   NULL otherwise.  Call with a NULL keystring once key parsing is
   complete to return any unfinished keys. */
static struct keyrec *
parse_keyrec(char *keystring)
{
  /* FIXME: Remove the static and put the data into the parms we use
     for the caller anyway.  */
  static struct keyrec *work=NULL;
  struct keyrec *ret=NULL;
  char *record;
  int i;

  if(keystring==NULL)
    {
      if(work==NULL)
	return NULL;
      else if(work->desc.mode==KEYDB_SEARCH_MODE_NONE)
	{
	  xfree(work);
	  return NULL;
	}
      else
	{
	  ret=work;
	  work=NULL;
	  return ret;
	}
    }

  if(work==NULL)
    {
      work=xmalloc_clear(sizeof(struct keyrec));
      work->uidbuf=iobuf_temp();
    }

  trim_trailing_ws (keystring, strlen (keystring));

  if((record=strsep(&keystring,":"))==NULL)
    return ret;

  if(ascii_strcasecmp("pub",record)==0)
    {
      char *tok;
      gpg_error_t err;

      if(work->desc.mode)
	{
	  ret=work;
	  work=xmalloc_clear(sizeof(struct keyrec));
	  work->uidbuf=iobuf_temp();
	}

      if((tok=strsep(&keystring,":"))==NULL)
	return ret;

      err = classify_user_id (tok, &work->desc, 1);
      if (err || (work->desc.mode    != KEYDB_SEARCH_MODE_SHORT_KID
                  && work->desc.mode != KEYDB_SEARCH_MODE_LONG_KID
                  && work->desc.mode != KEYDB_SEARCH_MODE_FPR16
                  && work->desc.mode != KEYDB_SEARCH_MODE_FPR20))
	{
	  work->desc.mode=KEYDB_SEARCH_MODE_NONE;
	  return ret;
	}

      /* Note all items after this are optional.  This allows us to
         have a pub line as simple as pub:keyid and nothing else. */

      work->lines++;

      if((tok=strsep(&keystring,":"))==NULL)
	return ret;

      work->type=atoi(tok);

      if((tok=strsep(&keystring,":"))==NULL)
	return ret;

      work->size=atoi(tok);

      if((tok=strsep(&keystring,":"))==NULL)
	return ret;

      if(atoi(tok)<=0)
	work->createtime=0;
      else
	work->createtime=atoi(tok);

      if((tok=strsep(&keystring,":"))==NULL)
	return ret;

      if(atoi(tok)<=0)
	work->expiretime=0;
      else
	{
	  work->expiretime=atoi(tok);
	  /* Force the 'e' flag on if this key is expired. */
	  if(work->expiretime<=make_timestamp())
	    work->flags|=4;
	}

      if((tok=strsep(&keystring,":"))==NULL)
	return ret;

      while(*tok)
	switch(*tok++)
	  {
	  case 'r':
	  case 'R':
	    work->flags|=1;
	    break;

	  case 'd':
	  case 'D':
	    work->flags|=2;
	    break;

	  case 'e':
	  case 'E':
	    work->flags|=4;
	    break;
	  }
    }
  else if(ascii_strcasecmp("uid",record)==0 && work->desc.mode)
    {
      char *userid,*tok,*decoded;

      if((tok=strsep(&keystring,":"))==NULL)
	return ret;

      if(strlen(tok)==0)
	return ret;

      userid=tok;

      /* By definition, de-%-encoding is always smaller than the
         original string so we can decode in place. */

      i=0;

      while(*tok)
	if(tok[0]=='%' && tok[1] && tok[2])
	  {
            int c;

	    userid[i] = (c=hextobyte(&tok[1])) == -1 ? '?' : c;
	    i++;
	    tok+=3;
	  }
	else
	  userid[i++]=*tok++;

      /* We don't care about the other info provided in the uid: line
         since no keyserver supports marking userids with timestamps
         or revoked/expired/disabled yet. */

      /* No need to check for control characters, as utf8_to_native
	 does this for us. */

      decoded=utf8_to_native(userid,i,0);
      if(strlen(decoded)>opt.screen_columns-10)
	decoded[opt.screen_columns-10]='\0';
      iobuf_writestr(work->uidbuf,decoded);
      xfree(decoded);
      iobuf_writestr(work->uidbuf,"\n\t");
      work->lines++;
    }

  /* Ignore any records other than "pri" and "uid" for easy future
     growth. */

  return ret;
}
Example #18
0
void packet_loop(void) {
    sensor_data_t packet;
    char c, filename[128], msg[160];
    struct timeval tv;
    char t_hour[3], t_min[3], t_sec[3];
    uint64_t timestamp;
    uint8_t groundstation_id;

    while (1) {
        sleep(1);
        memset(&packet, '\0', sizeof(sensor_data_t));
        
        #ifdef TESTMODE
        gettimeofday(&tv, NULL);;
        strftime(t_hour, 3,"%H", localtime(&tv.tv_sec));
        strftime(t_min, 3,"%M", localtime(&tv.tv_sec));
        strftime(t_sec, 3,"%S", localtime(&tv.tv_sec));
        packet.rtc.tm_hour = atoi(t_hour);
        packet.rtc.tm_min = atoi(t_min);
        packet.rtc.tm_sec = atoi(t_sec);
    
        packet.imu.gx = packet.imu.gy = packet.imu.ax = packet.imu.ay = packet.imu.az = 512;
        
        packet.bmp.raw_pressure = 10;
        packet.bmp.raw_temperature = 512;
        
        packet.gps.f_latitude = 38.10;
        packet.gps.f_longitude = -6.7;
        packet.gps.u_altitude = 25000;
        packet.gps.u_satellites = 7;
        
        packet.internal_temp = 2500;
        packet.extern_temp = -5000;
        packet.humidity = 40;
        
        #else
        read(serial_port, &c, 1);
        if (c != 'A')
            continue;

        printf("GOT START\n");

        // RTC
        myread(serial_port, &packet.rtc.tm_hour, 2);
        myread(serial_port, &packet.rtc.tm_min, 2);
        myread(serial_port, &packet.rtc.tm_sec, 2);

        // IMU
        myread(serial_port, &packet.imu.gx, 2);
        myread(serial_port, &packet.imu.gy, 2);
        myread(serial_port, &packet.imu.ax, 2);
        myread(serial_port, &packet.imu.ay, 2);
        myread(serial_port, &packet.imu.az, 2);

        // SCP
        myread(serial_port, &packet.bmp.raw_pressure, 4);
        myread(serial_port, &packet.bmp.raw_temperature, 2);

        // GPS
        myread(serial_port, &packet.gps.f_latitude, 4);
        myread(serial_port, &packet.gps.f_longitude, 4);
        myread(serial_port, &packet.gps.u_altitude, 2);
        myread(serial_port, &packet.gps.u_valid, 1);
        myread(serial_port, &packet.gps.u_satellites, 1);

        myread(serial_port, &packet.humidity, 2);
        myread(serial_port, &packet.bearing, 2);
        myread(serial_port, &packet.light, 2);
        myread(serial_port, &packet.internal_temp, 2);
        myread(serial_port, &packet.extern_temp, 2);

        myread(serial_port, &packet.gsm_registered, 1);
        myread(serial_port, &packet.gsm_ready, 1);
        
        // 46 bytes

        myread(serial_port, &c, 1);
        if (c != 'Z') {
            printf("malformed packet\n");
            continue;
        }
        #endif

        // get a timestamp for our filename
        timestamp = make_timestamp();

        // make filename
        #ifndef TESTMODE
        sprintf(filename, "/sdcard/spacebits/new/%llu.txt", timestamp);
        #else
        sprintf(filename, "%llu.txt", timestamp);
        #endif

        // make groundstation id
        groundstation_id = 0;
#ifdef GROUNDSTATIONID
        groundstation_id = GROUNDSTATIONID;
#endif
        
        //R,ground_stations_id,ballon_id,lat,lon,alt,nstats,pressure,int_temp,ext_temp,humidity
        sprintf(msg, "%s R,%u,%u,%f,%f,%u,%u,%d,%hd,%hd,%u", "+351968252265", 
                groundstation_id, balloon_id,
                packet.gps.f_latitude, packet.gps.f_longitude, packet.gps.u_altitude, packet.gps.u_satellites,
                packet.bmp.raw_pressure, packet.internal_temp, packet.extern_temp, packet.humidity);

        // open file for writing
        FILE *sendsms;
        if ((sendsms = fopen(filename, "wt")) == NULL) {
            perror("could not open new sms file for writing");
            // act all christ here. we're _sure_ someOne will respawn us
            return;
        }

        // write message to file
        fprintf(sendsms, "%s\n", msg);

        // close, debug
        fclose(sendsms);
        printf("Wrote packet to file\n");
    }
}
Example #19
0
/* We don't want to use use_seskey yet because older gnupg versions
   can't handle it, and there isn't really any point unless we're
   making a message that can be decrypted by a public key or
   passphrase. */
static int
encrypt_simple (const char *filename, int mode, int use_seskey)
{
  iobuf_t inp, out;
  PACKET pkt;
  PKT_plaintext *pt = NULL;
  STRING2KEY *s2k = NULL;
  void *enckey = NULL;
  size_t enckeylen = 0;
  int rc = 0;
  u32 filesize;
  cipher_filter_context_t cfx;
  armor_filter_context_t  *afx = NULL;
  compress_filter_context_t zfx;
  text_filter_context_t tfx;
  progress_filter_context_t *pfx;
  int do_compress = !!default_compress_algo();

  if (!gnupg_rng_is_compliant (opt.compliance))
    {
      rc = gpg_error (GPG_ERR_FORBIDDEN);
      log_error (_("%s is not compliant with %s mode\n"),
                 "RNG",
                 gnupg_compliance_option_string (opt.compliance));
      write_status_error ("random-compliance", rc);
      return rc;
    }

  pfx = new_progress_context ();
  memset( &cfx, 0, sizeof cfx);
  memset( &zfx, 0, sizeof zfx);
  memset( &tfx, 0, sizeof tfx);
  init_packet(&pkt);

  /* Prepare iobufs. */
  inp = iobuf_open(filename);
  if (inp)
    iobuf_ioctl (inp, IOBUF_IOCTL_NO_CACHE, 1, NULL);
  if (inp && is_secured_file (iobuf_get_fd (inp)))
    {
      iobuf_close (inp);
      inp = NULL;
      gpg_err_set_errno (EPERM);
    }
  if (!inp)
    {
      rc = gpg_error_from_syserror ();
      log_error(_("can't open '%s': %s\n"), filename? filename: "[stdin]",
                strerror(errno) );
      release_progress_context (pfx);
      return rc;
    }

  handle_progress (pfx, inp, filename);

  if (opt.textmode)
    iobuf_push_filter( inp, text_filter, &tfx );

  cfx.dek = NULL;
  if ( mode )
    {
      int canceled;
      aead_algo_t aead_algo;

      s2k = xmalloc_clear( sizeof *s2k );
      s2k->mode = opt.s2k_mode;
      s2k->hash_algo = S2K_DIGEST_ALGO;
      cfx.dek = passphrase_to_dek (default_cipher_algo (), s2k, 1, 0,
                                   NULL, &canceled);
      if ( !cfx.dek || !cfx.dek->keylen )
        {
          rc = gpg_error (canceled? GPG_ERR_CANCELED:GPG_ERR_INV_PASSPHRASE);
          xfree (cfx.dek);
          xfree (s2k);
          iobuf_close (inp);
          log_error (_("error creating passphrase: %s\n"), gpg_strerror (rc));
          release_progress_context (pfx);
          return rc;
        }
      if (use_seskey && s2k->mode != 1 && s2k->mode != 3)
        {
          use_seskey = 0;
          log_info (_("can't use a symmetric ESK packet "
                      "due to the S2K mode\n"));
        }

      /* See whether we want to use AEAD.  */
      aead_algo = use_aead (NULL, cfx.dek->algo);

      if ( use_seskey )
        {
          DEK *dek = NULL;

          rc = encrypt_seskey (cfx.dek, aead_algo, &dek, &enckey, &enckeylen);
          if (rc)
            {
              xfree (cfx.dek);
              xfree (s2k);
              iobuf_close (inp);
              release_progress_context (pfx);
              return rc;
            }
          /* Replace key in DEK.  */
          xfree (cfx.dek);
          cfx.dek = dek;
        }

      if (aead_algo)
        cfx.dek->use_aead = aead_algo;
      else
        cfx.dek->use_mdc = !!use_mdc (NULL, cfx.dek->algo);

      if (opt.verbose)
        log_info(_("using cipher %s.%s\n"),
                 openpgp_cipher_algo_name (cfx.dek->algo),
                 cfx.dek->use_aead? openpgp_aead_algo_name (cfx.dek->use_aead)
                 /**/             : "CFB");
    }

  if (do_compress
      && cfx.dek
      && (cfx.dek->use_mdc || cfx.dek->use_aead)
      && is_file_compressed(filename, &rc))
    {
      if (opt.verbose)
        log_info(_("'%s' already compressed\n"), filename);
      do_compress = 0;
    }

  if ( rc || (rc = open_outfile (-1, filename, opt.armor? 1:0, 0, &out )))
    {
      iobuf_cancel (inp);
      xfree (cfx.dek);
      xfree (s2k);
      release_progress_context (pfx);
      return rc;
    }

  if ( opt.armor )
    {
      afx = new_armor_context ();
      push_armor_filter (afx, out);
    }

  if ( s2k )
    {
      /* Fixme: This is quite similar to write_symkey_enc.  */
      PKT_symkey_enc *enc = xmalloc_clear (sizeof *enc + enckeylen);
      enc->version = cfx.dek->use_aead ? 5 : 4;
      enc->cipher_algo = cfx.dek->algo;
      enc->aead_algo = cfx.dek->use_aead;
      enc->s2k = *s2k;
      if (enckeylen)
        {
          enc->seskeylen = enckeylen;
          memcpy (enc->seskey, enckey, enckeylen);
        }
      pkt.pkttype = PKT_SYMKEY_ENC;
      pkt.pkt.symkey_enc = enc;
      if ((rc = build_packet( out, &pkt )))
        log_error("build symkey packet failed: %s\n", gpg_strerror (rc) );
      xfree (enc);
      xfree (enckey);
      enckey = NULL;
    }

  if (!opt.no_literal)
    pt = setup_plaintext_name (filename, inp);

  /* Note that PGP 5 has problems decrypting symmetrically encrypted
     data if the file length is in the inner packet. It works when
     only partial length headers are use.  In the past, we always used
     partial body length here, but since PGP 2, PGP 6, and PGP 7 need
     the file length, and nobody should be using PGP 5 nowadays
     anyway, this is now set to the file length.  Note also that this
     only applies to the RFC-1991 style symmetric messages, and not
     the RFC-2440 style.  PGP 6 and 7 work with either partial length
     or fixed length with the new style messages. */

  if ( !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
    {
      off_t tmpsize;
      int overflow;

      if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
           && !overflow && opt.verbose)
        log_info(_("WARNING: '%s' is an empty file\n"), filename );
      /* We can't encode the length of very large files because
         OpenPGP uses only 32 bit for file sizes.  So if the
         size of a file is larger than 2^32 minus some bytes for
         packet headers, we switch to partial length encoding. */
      if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
        filesize = tmpsize;
      else
        filesize = 0;
    }
  else
    filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */

  if (!opt.no_literal)
    {
      /* Note that PT has been initialized above in !no_literal mode.  */
      pt->timestamp = make_timestamp();
      pt->mode = opt.mimemode? 'm' : opt.textmode? 't' : 'b';
      pt->len = filesize;
      pt->new_ctb = !pt->len;
      pt->buf = inp;
      pkt.pkttype = PKT_PLAINTEXT;
      pkt.pkt.plaintext = pt;
      cfx.datalen = filesize && !do_compress ? calc_packet_length( &pkt ) : 0;
    }
  else
    {
      cfx.datalen = filesize && !do_compress ? filesize : 0;
      pkt.pkttype = 0;
      pkt.pkt.generic = NULL;
    }

  /* Register the cipher filter. */
  if (mode)
    iobuf_push_filter (out,
                       cfx.dek->use_aead? cipher_filter_aead
                       /**/             : cipher_filter_cfb,
                       &cfx );

  /* Register the compress filter. */
  if ( do_compress )
    {
      if (cfx.dek && (cfx.dek->use_mdc || cfx.dek->use_aead))
        zfx.new_ctb = 1;
      push_compress_filter (out, &zfx, default_compress_algo());
    }

  /* Do the work. */
  if (!opt.no_literal)
    {
      if ( (rc = build_packet( out, &pkt )) )
        log_error("build_packet failed: %s\n", gpg_strerror (rc) );
    }
  else
    {
      /* User requested not to create a literal packet, so we copy the
         plain data.  */
    byte copy_buffer[4096];
    int  bytes_copied;
    while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
      if ( (rc=iobuf_write(out, copy_buffer, bytes_copied)) ) {
        log_error ("copying input to output failed: %s\n",
                   gpg_strerror (rc) );
        break;
      }
    wipememory (copy_buffer, 4096); /* burn buffer */
    }

  /* Finish the stuff.  */
  iobuf_close (inp);
  if (rc)
    iobuf_cancel(out);
  else
    {
      iobuf_close (out); /* fixme: check returncode */
      if (mode)
        write_status ( STATUS_END_ENCRYPTION );
    }
  if (pt)
    pt->buf = NULL;
  free_packet (&pkt, NULL);
  xfree (enckey);
  xfree (cfx.dek);
  xfree (s2k);
  release_armor_context (afx);
  release_progress_context (pfx);
  return rc;
}
Example #20
0
static
size_t audit_log_connection_record(char *buf, size_t buflen,
                                   const char *name, time_t t,
                                   const struct mysql_event_connection *event)
{
  char id_str[MAX_RECORD_ID_SIZE];
  char timestamp[MAX_TIMESTAMP_SIZE];
  char tmp[128];
  char *endptr= tmp, *endtmp= tmp + sizeof(tmp);
  const char *format_string[] = {
                     "<AUDIT_RECORD\n"
                     "  NAME=\"%s\"\n"
                     "  RECORD=\"%s\"\n"
                     "  TIMESTAMP=\"%s\"\n"
                     "  CONNECTION_ID=\"%lu\"\n"
                     "  STATUS=\"%d\"\n"
                     "  USER=\"%s\"\n"
                     "  PRIV_USER=\"%s\"\n"
                     "  OS_LOGIN=\"%s\"\n"
                     "  PROXY_USER=\"%s\"\n"
                     "  HOST=\"%s\"\n"
                     "  IP=\"%s\"\n"
                     "  DB=\"%s\"\n"
                     "/>\n",

                     "<AUDIT_RECORD>\n"
                     "  <NAME>%s</NAME>\n"
                     "  <RECORD>%s</RECORD>\n"
                     "  <TIMESTAMP>%s</TIMESTAMP>\n"
                     "  <CONNECTION_ID>%lu</CONNECTION_ID>\n"
                     "  <STATUS>%d</STATUS>\n"
                     "  <USER>%s</USER>\n"
                     "  <PRIV_USER>%s</PRIV_USER>\n"
                     "  <OS_LOGIN>%s</OS_LOGIN>\n"
                     "  <PROXY_USER>%s</PROXY_USER>\n"
                     "  <HOST>%s</HOST>\n"
                     "  <IP>%s</IP>\n"
                     "  <DB>%s</DB>\n"
                     "</AUDIT_RECORD>\n",

                     "{\"audit_record\":"
                       "{\"name\":\"%s\","
                       "\"record\":\"%s\","
                       "\"timestamp\":\"%s\","
                       "\"connection_id\":\"%lu\","
                       "\"status\":%d,"
                       "\"user\":\"%s\","
                       "\"priv_user\":\"%s\","
                       "\"os_login\":\"%s\","
                       "\"proxy_user\":\"%s\","
                       "\"host\":\"%s\","
                       "\"ip\":\"%s\","
                       "\"db\":\"%s\"}}\n",

                     "\"%s\",\"%s\",\"%s\",\"%lu\",%d,\"%s\",\"%s\",\"%s\","
                     "\"%s\",\"%s\",\"%s\",\"%s\"\n" };

  return my_snprintf(buf, buflen,
                     format_string[audit_log_format],
                     name,
                     make_record_id(id_str, sizeof(id_str)),
                     make_timestamp(timestamp, sizeof(timestamp), t),
                     event->thread_id,
                     event->status,
                     escape_string(event->user,
                                   event->user_length,
                                   endptr, endtmp - endptr, &endptr),
                     escape_string(event->priv_user,
                                   event->priv_user_length,
                                   endptr, endtmp - endptr, &endptr),
                     escape_string(event->external_user,
                                   event->external_user_length,
                                   endptr, endtmp - endptr, &endptr),
                     escape_string(event->proxy_user,
                                   event->proxy_user_length,
                                   endptr, endtmp - endptr, &endptr),
                     escape_string(event->host,
                                   event->host_length,
                                   endptr, endtmp - endptr, &endptr),
                     escape_string(event->ip,
                                   event->ip_length,
                                   endptr, endtmp - endptr, &endptr),
                     escape_string(event->database,
                                   event->database_length,
                                   endptr, endtmp - endptr, &endptr));
}
Example #21
0
static
size_t audit_log_general_record(char *buf, size_t buflen,
                                const char *name, time_t t, int status,
                                const struct mysql_event_general *event)
{
  char id_str[MAX_RECORD_ID_SIZE];
  char timestamp[MAX_TIMESTAMP_SIZE];
  char query[512], tmp[128];
  char *endptr= tmp, *endtmp= tmp + sizeof(tmp);
  const char *format_string[] = {
                     "<AUDIT_RECORD\n"
                     "  NAME=\"%s\"\n"
                     "  RECORD=\"%s\"\n"
                     "  TIMESTAMP=\"%s\"\n"
                     "  COMMAND_CLASS=\"%s\"\n"
                     "  CONNECTION_ID=\"%lu\"\n"
                     "  STATUS=\"%d\"\n"
                     "  SQLTEXT=\"%s\"\n"
                     "  USER=\"%s\"\n"
                     "  HOST=\"%s\"\n"
                     "  OS_USER=\"%s\"\n"
                     "  IP=\"%s\"\n"
                     "/>\n",

                     "<AUDIT_RECORD>\n"
                     "  <NAME>%s</NAME>\n"
                     "  <RECORD>%s</RECORD>\n"
                     "  <TIMESTAMP>%s</TIMESTAMP>\n"
                     "  <COMMAND_CLASS>%s</COMMAND_CLASS>\n"
                     "  <CONNECTION_ID>%lu</CONNECTION_ID>\n"
                     "  <STATUS>%d</STATUS>\n"
                     "  <SQLTEXT>%s</SQLTEXT>\n"
                     "  <USER>%s</USER>\n"
                     "  <HOST>%s</HOST>\n"
                     "  <OS_USER>%s</OS_USER>\n"
                     "  <IP>%s</IP>\n"
                     "</AUDIT_RECORD>\n",

                     "{\"audit_record\":"
                       "{\"name\":\"%s\","
                       "\"record\":\"%s\","
                       "\"timestamp\":\"%s\","
                       "\"command_class\":\"%s\","
                       "\"connection_id\":\"%lu\","
                       "\"status\":%d,"
                       "\"sqltext\":\"%s\","
                       "\"user\":\"%s\","
                       "\"host\":\"%s\","
                       "\"os_user\":\"%s\","
                       "\"ip\":\"%s\"}}\n",

                     "\"%s\",\"%s\",\"%s\",\"%s\",\"%lu\",%d,\"%s\",\"%s\","
                     "\"%s\",\"%s\",\"%s\"\n" };

  return my_snprintf(buf, buflen,
                     format_string[audit_log_format],
                     name,
                     make_record_id(id_str, sizeof(id_str)),
                     make_timestamp(timestamp, sizeof(timestamp), t),
                     event->general_sql_command.str,
                     event->general_thread_id,
                     status,
                     escape_string(event->general_query,
                                   event->general_query_length,
                                   query, sizeof(query), NULL),
                     escape_string(event->general_user,
                                   event->general_user_length,
                                   endptr, endtmp - endptr, &endptr),
                     escape_string(event->general_host.str,
                                   event->general_host.length,
                                   endptr, endtmp - endptr, &endptr),
                     escape_string(event->general_external_user.str,
                                   event->general_external_user.length,
                                   endptr, endtmp - endptr, &endptr),
                     escape_string(event->general_ip.str,
                                   event->general_ip.length,
                                   endptr, endtmp - endptr, &endptr));
}
Example #22
0
static void handle_submit(Octstr *packet, Octstr *out, int sequence) {
	Octstr *dest_addr = eat_string_parm(packet, 21, 20);
	Octstr *orig_addr = eat_string_parm(packet, 23, 20);
	long DCS = eat_int_parm(packet, 30, 3);
	Octstr *UDH = eat_string_parm(packet, 32, 280);
	Octstr *text = eat_string_parm(packet, 33, 480);
	Octstr *textb = eat_string_parm(packet, 34, 280);
	long valid_rel = eat_int_parm(packet, 50, 3);
	Octstr *valid_abs = eat_string_parm(packet, 51, 12);
	long proto_id = eat_int_parm(packet, 52, 3);
	long delivery_rel = eat_int_parm(packet, 53, 3);
	Octstr *delivery_abs = eat_string_parm(packet, 54, 12);
	long reply_path = eat_int_parm(packet, 55, 1);
	long SRR = eat_int_parm(packet, 56, 2);
	long cancel = eat_int_parm(packet, 58, 1);
	long tariff_class = eat_int_parm(packet, 64, 2);
	long service_desc = eat_int_parm(packet, 65, 1);
	long priority = eat_int_parm(packet, 67, 1);
	List *other_dests = list_create();
	Octstr *tmp;

	while ((tmp = eat_string_parm(packet, 21, 20)))
		list_append(other_dests, tmp);

	if (logging == LOG_packets) {
		int i;
		printf("RCV: Submit to %s", octstr_get_cstr(dest_addr));
		for (i = 0; i < list_len(other_dests); i++) {
			printf(", %s",
				octstr_get_cstr(list_get(other_dests, i)));
		}
		printf("\n");

		if (orig_addr)
			printf("    From: %s\n", octstr_get_cstr(orig_addr));
		if (DCS > INT_MIN)
			printf("    Data coding: %ld\n", DCS);
		if (UDH)
			printf("    User data header: %s\n",
				octstr_get_cstr(UDH));
		if (text)
			printf("    Text: %s\n", octstr_get_cstr(text));
		if (textb)
			printf("    Text (binary): %s\n",
				octstr_get_cstr(textb));
		if (valid_rel > INT_MIN)
			printf("    Validity period: %ld (relative)\n",
				valid_rel);
		if (valid_abs)
			printf("    Validity period: %s (absolute)\n",
				octstr_get_cstr(valid_abs));
		if (proto_id > INT_MIN)
			printf("    Protocol ID: %ld\n", proto_id);
		if (delivery_rel > INT_MIN)
			printf("    First delivery: %ld (relative)\n",
				delivery_rel);
		if (delivery_abs)
			printf("    First delivery: %s (absolute)\n",
				octstr_get_cstr(delivery_abs));
		if (reply_path == 0)
			printf("    Reply path disabled\n");
		else if (reply_path == 1)
			printf("    Reply path enabled\n");
		else if (reply_path > INT_MAX)
			printf("    Reply path: %ld\n", reply_path);
		if (SRR > INT_MAX)
			printf("    Status report flags: %ld\n", SRR);
		if (cancel == 0)
			printf("    Cancel disabled\n");
		else if (cancel == 1)
			printf("    Cancel enabled\n");
		else if (cancel > INT_MAX)
			printf("    Cancel enabled: %ld\n", cancel);
		if (tariff_class > INT_MAX)
			printf("    Tariff class: %ld\n", tariff_class);
		if (service_desc > INT_MAX)
			printf("    Service description: %ld\n", service_desc);
		if (priority > INT_MAX)
			printf("    Priority: %ld\n", priority);
	}

	if (!dest_addr) {
		send_error(out, 53, sequence, "300", "no destination");
	} else if (list_len(other_dests) > 0) {
		send_error(out, 53, sequence, "301", "too many destinations");
	/* TODO: Report many other possible errors here */
	} else {
		unsigned char buf[TIMESTAMP_MAXLEN];

		make_timestamp(buf, time(NULL));
		if (logging == LOG_packets)
			printf("SND: Submit OK\n");
		send_packet(out, 53, sequence,
		            21, octstr_get_cstr(dest_addr),
			    60, buf,
			    0);
	}

	octstr_destroy(dest_addr);
	octstr_destroy(orig_addr);
	octstr_destroy(UDH);
	octstr_destroy(text);
	octstr_destroy(textb);
	octstr_destroy(valid_abs);
	octstr_destroy(delivery_abs);
	list_destroy(other_dests, octstr_destroy_item);
}
Example #23
0
static void *encode_thr_fn(void *data)
{
    ENCODE_CALLBACK_PARAM_T *param = (ENCODE_CALLBACK_PARAM_T *) data;
    API_VENC_CHN_E eCh = param->eCh;
    char *str_profile = (tApiInitParam[eCh].eProfile == API_VENC_HEVC_MAIN_PROFILE) ? "Main" : "Main10";

    LOG("%p Channel: %d\n", param, eCh);
    LOG("Profile: %s\n", str_profile);
    
    char *str_level;
    
    struct timeval tv1, tv2, res;
    
    switch (tApiInitParam[eCh].eLevel)
    {
        case API_VENC_HEVC_LEVEL_40:
        {
            str_level = "L4.0";
            break;
        }       
        case API_VENC_HEVC_LEVEL_41:
        {
            str_level = "L4.1";
            break;
        }        
        case API_VENC_HEVC_LEVEL_50:
        {
            str_level = "L5.0";
            break;
        }        
        case API_VENC_HEVC_LEVEL_51:
        {
            str_level = "L5.1";
            break;
        }        
        default:
        {
            break;
        }
    }
    
    LOG("Level: %s\n", str_level);

    
    char *str_tier = (tApiInitParam[eCh].eTier == API_VENC_HEVC_MAIN_TIER) ? "Main Tier" : "High Tier";
    
    LOG("Tier: %s\n", str_tier);
    

    char *str_res = "Unknown";
    
    switch (tApiInitParam[eCh].eResolution)
    {
        case API_VENC_RESOLUTION_4096x2160:
        {
            str_res = RESOLUTION_DCI_4K_TEXT;

            tApiInitParam[eCh].tCrop.u32CropLeft      = 0;
            tApiInitParam[eCh].tCrop.u32CropLeft      = 0;
            tApiInitParam[eCh].tCrop.u32CropTop       = 0;
            tApiInitParam[eCh].tCrop.u32CropBottom    = 0;
            
            break;
        }
        case API_VENC_RESOLUTION_3840x2160:
        {
            str_res = RESOLUTION_4K_TEXT;

            tApiInitParam[eCh].tCrop.u32CropLeft      = 0;
            tApiInitParam[eCh].tCrop.u32CropLeft      = 0;
            tApiInitParam[eCh].tCrop.u32CropTop       = 0;
            tApiInitParam[eCh].tCrop.u32CropBottom    = 0;
            
            break;
        }        
        case API_VENC_RESOLUTION_1920x1080:
        {
            str_res = RESOLUTION_2K_TEXT;

            tApiInitParam[eCh].tCrop.u32CropLeft      = 0;
            tApiInitParam[eCh].tCrop.u32CropLeft      = 0;
            tApiInitParam[eCh].tCrop.u32CropTop       = 0;
            tApiInitParam[eCh].tCrop.u32CropBottom    = 8;
            
            break;
        }        
        case API_VENC_RESOLUTION_1280x720:
        {
            str_res = RESOLUTION_HD_TEXT;

            tApiInitParam[eCh].tCrop.u32CropLeft      = 0;
            tApiInitParam[eCh].tCrop.u32CropLeft      = 0;
            tApiInitParam[eCh].tCrop.u32CropTop       = 0;
            tApiInitParam[eCh].tCrop.u32CropBottom    = 0;
            
            break;
        }        
        case API_VENC_RESOLUTION_720x576:
        {
            str_res = RESOLUTION_SD_576_TEXT;
            
            tApiInitParam[eCh].eAspectRatioIdc = API_VENC_HEVC_ASPECT_RATIO_IDC_4;

            tApiInitParam[eCh].tCrop.u32CropLeft      = 0;
            tApiInitParam[eCh].tCrop.u32CropLeft      = 0;
            tApiInitParam[eCh].tCrop.u32CropTop       = 0;
            tApiInitParam[eCh].tCrop.u32CropBottom    = 0;
            
            break;
        }   
        case API_VENC_RESOLUTION_720x480:
        {
            str_res = RESOLUTION_SD_480_TEXT;

            tApiInitParam[eCh].eAspectRatioIdc = API_VENC_HEVC_ASPECT_RATIO_IDC_5;
            
            tApiInitParam[eCh].tCrop.u32CropLeft      = 0;
            tApiInitParam[eCh].tCrop.u32CropLeft      = 0;
            tApiInitParam[eCh].tCrop.u32CropTop       = 0;
            tApiInitParam[eCh].tCrop.u32CropBottom    = 0;
            
            break;
        }  
        default:
        {
            break;
        }
    }
    
    LOG("Resolution: %s\n", str_res);

    char *str_framerate = "Unknown";
    
    switch (tApiInitParam[eCh].eTargetFrameRate)
    {
        case API_VENC_FPS_24:
        {
            str_framerate = "24p";
            break;
        }        
        case API_VENC_FPS_25:
        {
            str_framerate = "25p";
            break;
        } 
        case API_VENC_FPS_29_97:
        {
            str_framerate = "29.97p";
            break;
        } 
        case API_VENC_FPS_30:
        {
            str_framerate = "30p";
            break;
        }
        case API_VENC_FPS_50:
        {
            str_framerate = "50p";
            break;
        }        
        case API_VENC_FPS_59_94:
        {
            str_framerate = "59.94p";
            break;
        }
        case API_VENC_FPS_60:
        {
            str_framerate = "60p";
            break;
        }        
        default:
        {
            break;
        }
    }
    
    LOG("Framerate: %s\n", str_framerate);
    
    
    guint bitrate_val;

    bitrate_val = gtk_range_get_value(GTK_RANGE(Bitrate[eCh]));
    
    LOG("Bitrate %d kbps\n", bitrate_val);
    
    tApiInitParam[eCh].u32Bitrate = bitrate_val;


    char *str_bitdepth = "Unknown";
    
    switch (tApiInitParam[eCh].eBitDepth)
    {
        case API_VENC_BIT_DEPTH_8:
        {
            str_bitdepth = "8";
            break;
        }        
        case API_VENC_BIT_DEPTH_10:
        {
            str_bitdepth = "10";
            break;
        }
        default:
        {
            break;
        }
    }
    
    LOG("bit depth: %s\n", str_bitdepth);
    
    
    char *str_chroma = (tApiInitParam[eCh].eChromaFmt == API_VENC_CHROMA_FORMAT_420) ? "420" : "422";
    
    LOG("Chroma: %s\n", str_chroma);

    {
        GSList *list; 
        GtkToggleButton *button = NULL;
        API_VENC_IMG_T *pImg = &img[eCh];
        
        list = gtk_radio_button_get_group(GTK_RADIO_BUTTON(PixFmtIntRadioButton[eCh]));
        
        while (list) // As long as we didn't reach the end of the group.
        {
            button = list->data;    // Get one of the buttons in the group.
            list = list->next;      // Next time we're going to check this one.

            if (gtk_toggle_button_get_active(button))
            {
                break;
            }
        }
        
        const gchar *val = gtk_button_get_label(GTK_BUTTON(button));
        
        if (strcmp(val, PIXEL_FMT_INTERLEAVE_TEXT) == 0)
        {
            switch (tApiInitParam[eCh].eChromaFmt)
            {
                case API_VENC_CHROMA_FORMAT_422:
                {
                    pImg->eFormat = API_VENC_IMAGE_FORMAT_NV16;
                    break;
                }
                case API_VENC_CHROMA_FORMAT_420:
                default:
                {
                    pImg->eFormat = API_VENC_IMAGE_FORMAT_NV12;
                    break;
                }
            }
        }
        else if (strcmp(val, PIXEL_FMT_PLANAR_TEXT) == 0)
        {
            pImg->eFormat = API_VENC_IMAGE_FORMAT_YUV420;
        }
        
        LOG("%s: %s selected\n", __FUNCTION__, val);
    }
    
    char *str_gop = "Unknown";

    switch (tApiInitParam[eCh].eGopType)
    {
        case API_VENC_GOP_I:
        {
            str_gop = "I";
            break;
        }
        case API_VENC_GOP_IP:
        {
            str_gop = "IP";
            break;
        }
        case API_VENC_GOP_IB:
        {
            str_gop = "IB";
            break;
        }
        case API_VENC_GOP_IPB:
        {
            str_gop = "IPB";
            break;
        }
        default:
        {
            break;
        }
    }
    
    LOG("GOP: %s\n", str_gop);

    if (tApiInitParam[eCh].eGopType != API_VENC_GOP_I)
    {
        tApiInitParam[eCh].eGopSize = atoi(gtk_entry_get_text(GTK_ENTRY(GopSizeEntry[eCh])));
    }

    LOG("GOP size=%d\n", tApiInitParam[eCh].eGopSize);

    if (tApiInitParam[eCh].eGopType != API_VENC_GOP_I)
    {
        tApiInitParam[eCh].eIDRFrameNum = atoi(gtk_entry_get_text(GTK_ENTRY(IdrIntervalEntry[eCh])));
    }

    LOG("IDR interval=%d\n", tApiInitParam[eCh].eIDRFrameNum);
    

    if ((tApiInitParam[eCh].eGopType == API_VENC_GOP_IB)
       || (tApiInitParam[eCh].eGopType == API_VENC_GOP_IPB))
    {
        guint refnum;
    
        refnum = gtk_range_get_value(GTK_RANGE(BNumScale[eCh]));
        
        tApiInitParam[eCh].eBFrameNum = (API_VENC_B_FRAME_NUM_E) refnum;

        LOG("B ref#=%u\n", refnum);
    }


    API_VENC_BOARD_E eBoard = API_VENC_BOARD_1;

    eCh = param->eCh;
    
    gettimeofday(&tv1, NULL);
    if (Api_VENC_Init(eBoard, eCh, &tApiInitParam[eCh]))
    {
        sprintf(err_msg, "%s line %d failed!", __FILE__, __LINE__);

        goto callback_encode_ret;
    }  
    LOG("HVC_ENC_Init success!\n");


    tPopEsArgs[eBoard][eCh].board_num = eBoard;
    tPopEsArgs[eBoard][eCh].channel   = eCh;
    if (Api_VENC_RegisterCallback
        (
            eBoard,
            eCh,
            ui_process_coded_frame,
            (void *) &tPopEsArgs[eBoard][eCh]
       ))
    {
        sprintf(err_msg, "%s line %d failed!", __FILE__, __LINE__);

        goto callback_encode_ret;
    }


    if (Api_VENC_Start(eBoard, eCh))
    {
        sprintf(err_msg, "%s line %d failed!", __FILE__, __LINE__);

        goto callback_encode_ret;
    }

    LOG("HVC_ENC_Start success!\n");

    char es_file_name[FILENAME_MAX];
    char timestamp[15];

    make_timestamp(timestamp, sizeof(timestamp));
    make_output_file_name(timestamp, es_file_name, FILENAME_MAX, FilenameRawYUV[eCh]);

    fd_r[eCh]  = open(FilenameRawYUV[eCh], O_RDONLY);
    fd_w[eCh]  = open(es_file_name, 
                    O_WRONLY | O_CREAT,
                    S_IRWXU);

    // update status bar
    char msg[256];
    sprintf(msg, "Output: %s", es_file_name);
    context_id = gtk_statusbar_push(GTK_STATUSBAR(statusbar), 
                     context_id, msg);
    
    uint8_t *vraw_data_buf_p = NULL;
    uint32_t frame_sz = 0;
    struct stat file_stat;
    int remain_frame = 0;

    fstat(fd_r[eCh], &file_stat);

    frame_sz = calculate_vraw_enqueue_data_size(&tApiInitParam[eCh]);
    remain_frame = ((uint64_t) file_stat.st_size / frame_sz);
    tPopEsArgs[eBoard][eCh].total_frame = remain_frame;
    tPopEsArgs[eBoard][eCh].poped_frame = 0;
    
    vraw_data_buf_p = malloc(frame_sz);

    API_VENC_IMG_T *pImg = &img[eCh];

    while (remain_frame > 0)
    {        
        read(fd_r[eCh], vraw_data_buf_p, frame_sz);

        remain_frame--;

        pImg->pu8Addr     = vraw_data_buf_p;
        pImg->u32Size     = frame_sz;
        pImg->pts         = GET_PTS_IN_MS(eCh, tPopEsArgs[eBoard][eCh].total_frame - remain_frame);
        pImg->bLastFrame  = (remain_frame == 0) ? true : false;

        if (Api_VENC_PushImage(eBoard, eCh, pImg))
        {
            sprintf(err_msg, "Error: %s PushImage failed!\n", __FILE__);

            goto callback_encode_ret;
        }
    }

    LOG("Encode done...\n");

    // try stop
    while (Api_VENC_Stop(eBoard, eCh))
    {
        usleep(1);
    }
    LOG("\n stop complete!\n");

    if (Api_VENC_Exit(eBoard, eCh))
    {
        LOG(err_msg, "%s line %d failed!", __FILE__, __LINE__);

        goto callback_encode_ret;
    }
    LOG("\n Encoder exit!\n");
    gettimeofday(&tv2, NULL);
    timersub(&tv2, &tv1, &res);
    LOG("%lu sec %lu usec\n", res.tv_sec, res.tv_usec); 
    
    gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progressbar[eCh]), 0.0);

    close(fd_w[eCh]);

callback_encode_ret:
    LOG("%s\n", err_msg);
}
/****************
 * Encrypt the file with the given userids (or ask if none
 * is supplied).
 */
int
encode_crypt( const char *filename, STRLIST remusr, int use_symkey )
{
    IOBUF inp = NULL, out = NULL;
    PACKET pkt;
    PKT_plaintext *pt = NULL;
    DEK *symkey_dek = NULL;
    STRING2KEY *symkey_s2k = NULL;
    int rc = 0, rc2 = 0;
    u32 filesize;
    cipher_filter_context_t cfx;
    armor_filter_context_t afx;
    compress_filter_context_t zfx;
    text_filter_context_t tfx;
    progress_filter_context_t pfx;
    PK_LIST pk_list,work_list;
    int do_compress = opt.compress_algo && !RFC1991;

    memset( &cfx, 0, sizeof cfx);
    memset( &afx, 0, sizeof afx);
    memset( &zfx, 0, sizeof zfx);
    memset( &tfx, 0, sizeof tfx);
    init_packet(&pkt);

    if(use_symkey
       && (rc=setup_symkey(&symkey_s2k,&symkey_dek)))
      return rc;

    if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC)) )
	return rc;

    if(PGP2) {
      for(work_list=pk_list; work_list; work_list=work_list->next)
	if(!(is_RSA(work_list->pk->pubkey_algo) &&
	     nbits_from_pk(work_list->pk)<=2048))
	  {
	    log_info(_("you can only encrypt to RSA keys of 2048 bits or "
		       "less in --pgp2 mode\n"));
	    compliance_failure();
	    break;
	  }
    }

    /* prepare iobufs */
    inp = iobuf_open(filename);
    if (inp)
      iobuf_ioctl (inp,3,1,NULL); /* disable fd caching */
    if (inp && is_secured_file (iobuf_get_fd (inp)))
      {
        iobuf_close (inp);
        inp = NULL;
        errno = EPERM;
      }
    if( !inp ) {
	log_error(_("can't open `%s': %s\n"), filename? filename: "[stdin]",
					strerror(errno) );
	rc = G10ERR_OPEN_FILE;
	goto leave;
    }
    else if( opt.verbose )
	log_info(_("reading from `%s'\n"), filename? filename: "[stdin]");

    handle_progress (&pfx, inp, filename);

    if( opt.textmode )
	iobuf_push_filter( inp, text_filter, &tfx );

    if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) )
	goto leave;

    if( opt.armor )
	iobuf_push_filter( out, armor_filter, &afx );

    /* create a session key */
    cfx.dek = xmalloc_secure_clear (sizeof *cfx.dek);
    if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
	cfx.dek->algo = select_algo_from_prefs(pk_list,PREFTYPE_SYM,-1,NULL);
	/* The only way select_algo_from_prefs can fail here is when
           mixing v3 and v4 keys, as v4 keys have an implicit
           preference entry for 3DES, and the pk_list cannot be empty.
           In this case, use 3DES anyway as it's the safest choice -
           perhaps the v3 key is being used in an OpenPGP
           implementation and we know that the implementation behind
           any v4 key can handle 3DES. */
	if( cfx.dek->algo == -1 ) {
	    cfx.dek->algo = CIPHER_ALGO_3DES;

	    if( PGP2 ) {
	      log_info(_("unable to use the IDEA cipher for all of the keys "
			 "you are encrypting to.\n"));
	      compliance_failure();
	    }
	}
    }
    else {
      if(!opt.expert &&
	 select_algo_from_prefs(pk_list,PREFTYPE_SYM,
				opt.def_cipher_algo,NULL)!=opt.def_cipher_algo)
	log_info(_("WARNING: forcing symmetric cipher %s (%d)"
		   " violates recipient preferences\n"),
		 cipher_algo_to_string(opt.def_cipher_algo),
		 opt.def_cipher_algo);

      cfx.dek->algo = opt.def_cipher_algo;
    }

    cfx.dek->use_mdc=use_mdc(pk_list,cfx.dek->algo);

    /* Only do the is-file-already-compressed check if we are using a
       MDC.  This forces compressed files to be re-compressed if we do
       not have a MDC to give some protection against chosen
       ciphertext attacks. */

    if (do_compress && cfx.dek->use_mdc && is_file_compressed(filename, &rc2) )
      {
        if (opt.verbose)
          log_info(_("`%s' already compressed\n"), filename);
        do_compress = 0;        
      }
    if (rc2)
      {
        rc = rc2;
        goto leave;
      }

    make_session_key( cfx.dek );
    if( DBG_CIPHER )
	log_hexdump("DEK is: ", cfx.dek->key, cfx.dek->keylen );

    rc = write_pubkey_enc_from_list( pk_list, cfx.dek, out );
    if( rc  )
	goto leave;

    /* We put the passphrase (if any) after any public keys as this
       seems to be the most useful on the recipient side - there is no
       point in prompting a user for a passphrase if they have the
       secret key needed to decrypt. */
    if(use_symkey && (rc=write_symkey_enc(symkey_s2k,symkey_dek,cfx.dek,out)))
      goto leave;

    if (!opt.no_literal) {
	/* setup the inner packet */
	if( filename || opt.set_filename ) {
	    char *s = make_basename( opt.set_filename ? opt.set_filename
						      : filename,
				     iobuf_get_real_fname( inp ) );
	    pt = xmalloc( sizeof *pt + strlen(s) - 1 );
	    pt->namelen = strlen(s);
	    memcpy(pt->name, s, pt->namelen );
	    xfree(s);
	}
	else { /* no filename */
	    pt = xmalloc( sizeof *pt - 1 );
	    pt->namelen = 0;
	}
    }

    if (!iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
      {
        off_t tmpsize;
        int overflow;

	if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
             && !overflow )
          log_info(_("WARNING: `%s' is an empty file\n"), filename );
        /* We can't encode the length of very large files because
           OpenPGP uses only 32 bit for file sizes.  So if the the
           size of a file is larger than 2^32 minus some bytes for
           packet headers, we switch to partial length encoding. */
        if (tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
          filesize = tmpsize;
        else
          filesize = 0;
      }
    else
      filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */

    if (!opt.no_literal) {
	pt->timestamp = make_timestamp();
	pt->mode = opt.textmode ? 't' : 'b';
	pt->len = filesize;
	pt->new_ctb = !pt->len && !RFC1991;
	pt->buf = inp;
	pkt.pkttype = PKT_PLAINTEXT;
	pkt.pkt.plaintext = pt;
	cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0;
    }
    else
	cfx.datalen = filesize && !do_compress ? filesize : 0;

    /* register the cipher filter */
    iobuf_push_filter( out, cipher_filter, &cfx );

    /* register the compress filter */
    if( do_compress ) {
	int compr_algo = opt.compress_algo;

	if(compr_algo==-1)
	  {
	    if((compr_algo=
		select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1)
	      compr_algo=DEFAULT_COMPRESS_ALGO;
	    /* Theoretically impossible to get here since uncompressed
	       is implicit. */
	  }
	else if(!opt.expert &&
		select_algo_from_prefs(pk_list,PREFTYPE_ZIP,
				       compr_algo,NULL)!=compr_algo)
	  log_info(_("WARNING: forcing compression algorithm %s (%d)"
		     " violates recipient preferences\n"),
		   compress_algo_to_string(compr_algo),compr_algo);

	/* algo 0 means no compression */
	if( compr_algo )
	  {
            if (cfx.dek && cfx.dek->use_mdc)
              zfx.new_ctb = 1;
	    push_compress_filter(out,&zfx,compr_algo);
	  }
    }

    /* do the work */
    if (!opt.no_literal) {
	if( (rc = build_packet( out, &pkt )) )
	    log_error("build_packet failed: %s\n", g10_errstr(rc) );
    }
    else {
	/* user requested not to create a literal packet, so we copy
           the plain data */
	byte copy_buffer[4096];
	int  bytes_copied;
	while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
	    if (iobuf_write(out, copy_buffer, bytes_copied) == -1) {
		rc = G10ERR_WRITE_FILE;
		log_error("copying input to output failed: %s\n",
                          g10_errstr(rc) );
		break;
	    }
	wipememory(copy_buffer, 4096); /* burn buffer */
    }

    /* finish the stuff */
  leave:
    iobuf_close(inp);
    if( rc )
	iobuf_cancel(out);
    else {
	iobuf_close(out); /* fixme: check returncode */
        write_status( STATUS_END_ENCRYPTION );
    }
    if( pt )
	pt->buf = NULL;
    free_packet(&pkt);
    xfree(cfx.dek);
    xfree(symkey_dek);
    xfree(symkey_s2k);
    release_pk_list( pk_list );
    return rc;
}
Example #25
0
/****************
 * Create or update a signature subpacket for SIG of TYPE.  This
 * functions knows where to put the data (hashed or unhashed).  The
 * function may move data from the unhashed part to the hashed one.
 * Note: All pointers into sig->[un]hashed (e.g. returned by
 * parse_sig_subpkt) are not valid after a call to this function.  The
 * data to put into the subpaket should be in a buffer with a length
 * of buflen. 
 */
void
build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
		  const byte *buffer, size_t buflen )
{
    byte *p;
    int critical, hashed;
    subpktarea_t *oldarea, *newarea;
    size_t nlen, n, n0;

    critical = (type & SIGSUBPKT_FLAG_CRITICAL);
    type &= ~SIGSUBPKT_FLAG_CRITICAL;

    /* Sanity check buffer sizes */
    if(parse_one_sig_subpkt(buffer,buflen,type)<0)
      BUG();

    switch(type)
      {
      case SIGSUBPKT_NOTATION:
      case SIGSUBPKT_POLICY:
      case SIGSUBPKT_REV_KEY:
      case SIGSUBPKT_SIGNATURE:
	/* we do allow multiple subpackets */
	break;

      default:
	/* we don't allow multiple subpackets */
	delete_sig_subpkt(sig->hashed,type);
	delete_sig_subpkt(sig->unhashed,type);
	break;
      }

    /* Any special magic that needs to be done for this type so the
       packet doesn't need to be reparsed? */
    switch(type)
      {
      case SIGSUBPKT_NOTATION:
	sig->flags.notation=1;
	break;

      case SIGSUBPKT_POLICY:
	sig->flags.policy_url=1;
	break;

      case SIGSUBPKT_PREF_KS:
	sig->flags.pref_ks=1;
	break;

      case SIGSUBPKT_EXPORTABLE:
	if(buffer[0])
	  sig->flags.exportable=1;
	else
	  sig->flags.exportable=0;
	break;

      case SIGSUBPKT_REVOCABLE:
	if(buffer[0])
	  sig->flags.revocable=1;
	else
	  sig->flags.revocable=0;
	break;

      case SIGSUBPKT_TRUST:
	sig->trust_depth=buffer[0];
	sig->trust_value=buffer[1];
	break;

      case SIGSUBPKT_REGEXP:
	sig->trust_regexp=buffer;
	break;

	/* This should never happen since we don't currently allow
	   creating such a subpacket, but just in case... */
      case SIGSUBPKT_SIG_EXPIRE:
	if(buffer_to_u32(buffer)+sig->timestamp<=make_timestamp())
	  sig->flags.expired=1;
	else
	  sig->flags.expired=0;
	break;

      default:
	break;
      }

    if( (buflen+1) >= 8384 )
	nlen = 5; /* write 5 byte length header */
    else if( (buflen+1) >= 192 )
	nlen = 2; /* write 2 byte length header */
    else
	nlen = 1; /* just a 1 byte length header */

    switch( type )
      {
	/* The issuer being unhashed is a historical oddity.  It
	   should work equally as well hashed.  Of course, if even an
	   unhashed issuer is tampered with, it makes it awfully hard
	   to verify the sig... */
      case SIGSUBPKT_ISSUER:
      case SIGSUBPKT_SIGNATURE:
        hashed = 0;
        break;
      default: 
        hashed = 1;
        break;
      }

    if( critical )
	type |= SIGSUBPKT_FLAG_CRITICAL;

    oldarea = hashed? sig->hashed : sig->unhashed;

    /* Calculate new size of the area and allocate */
    n0 = oldarea? oldarea->len : 0;
    n = n0 + nlen + 1 + buflen; /* length, type, buffer */
    if (oldarea && n <= oldarea->size) { /* fits into the unused space */
        newarea = oldarea;
        /*log_debug ("updating area for type %d\n", type );*/
    }
    else if (oldarea) {
        newarea = xrealloc (oldarea, sizeof (*newarea) + n - 1);
        newarea->size = n;
        /*log_debug ("reallocating area for type %d\n", type );*/
    }
    else {
        newarea = xmalloc (sizeof (*newarea) + n - 1);
        newarea->size = n;
        /*log_debug ("allocating area for type %d\n", type );*/
    }
    newarea->len = n;

    p = newarea->data + n0;
    if (nlen == 5) {
	*p++ = 255;
	*p++ = (buflen+1) >> 24;
	*p++ = (buflen+1) >> 16;
	*p++ = (buflen+1) >>  8;
	*p++ = (buflen+1);
	*p++ = type;
	memcpy (p, buffer, buflen);
    }
Example #26
0
static int
get_it( PKT_pubkey_enc *k, DEK *dek, PKT_secret_key *sk, u32 *keyid )
{
    int rc;
    MPI plain_dek  = NULL;
    byte *frame = NULL;
    unsigned n, nframe;
    u16 csum, csum2;

    rc = pubkey_decrypt(sk->pubkey_algo, &plain_dek, k->data, sk->skey );
    if( rc )
	goto leave;
    frame = mpi_get_buffer( plain_dek, &nframe, NULL );
    mpi_free( plain_dek ); plain_dek = NULL;

    /* Now get the DEK (data encryption key) from the frame
     *
     * Old versions encode the DEK in in this format (msb is left):
     *
     *	   0  1  DEK(16 bytes)	CSUM(2 bytes)  0  RND(n bytes) 2
     *
     * Later versions encode the DEK like this:
     *
     *	   0  2  RND(n bytes)  0  A  DEK(k bytes)  CSUM(2 bytes)
     *
     * (mpi_get_buffer already removed the leading zero).
     *
     * RND are non-zero randow bytes.
     * A   is the cipher algorithm
     * DEK is the encryption key (session key) with length k
     * CSUM
     */
    if( DBG_CIPHER )
	log_hexdump("DEK frame:", frame, nframe );
    n=0;
    if( n + 7 > nframe )
	{ rc = G10ERR_WRONG_SECKEY; goto leave; }
    if( frame[n] == 1 && frame[nframe-1] == 2 ) {
	log_info(_("old encoding of the DEK is not supported\n"));
	rc = G10ERR_CIPHER_ALGO;
	goto leave;
    }
    if( frame[n] != 2 )  /* somethink is wrong */
	{ rc = G10ERR_WRONG_SECKEY; goto leave; }
    for(n++; n < nframe && frame[n]; n++ ) /* skip the random bytes */
	;
    n++; /* and the zero byte */
    if( n + 4 > nframe )
	{ rc = G10ERR_WRONG_SECKEY; goto leave; }

    dek->keylen = nframe - (n+1) - 2;
    dek->algo = frame[n++];
    if( dek->algo ==  CIPHER_ALGO_IDEA )
	write_status(STATUS_RSA_OR_IDEA);
    rc = check_cipher_algo( dek->algo );
    if( rc ) {
	if( !opt.quiet && rc == G10ERR_CIPHER_ALGO ) {
	    log_info(_("cipher algorithm %d is unknown or disabled\n"),
							    dek->algo);
	}
	dek->algo = 0;
	goto leave;
    }
    if( (dek->keylen*8) != cipher_get_keylen( dek->algo ) ) {
	rc = G10ERR_WRONG_SECKEY;
	goto leave;
    }

    /* copy the key to DEK and compare the checksum */
    csum  = frame[nframe-2] << 8;
    csum |= frame[nframe-1];
    memcpy( dek->key, frame+n, dek->keylen );
    for( csum2=0, n=0; n < dek->keylen; n++ )
	csum2 += dek->key[n];
    if( csum != csum2 ) {
	rc = G10ERR_WRONG_SECKEY;
	goto leave;
    }
    if( DBG_CIPHER )
	log_hexdump("DEK is:", dek->key, dek->keylen );
    /* check that the algo is in the preferences and whether it has expired */
    {
	PKT_public_key *pk = m_alloc_clear( sizeof *pk );
	if( (rc = get_pubkey( pk, keyid )) )
	    log_error("public key problem: %s\n", g10_errstr(rc) );
	else if( !pk->local_id && query_trust_record(pk) )
	    log_error("can't check algorithm against preferences\n");
	else if( dek->algo != CIPHER_ALGO_3DES
	    && !is_algo_in_prefs( pk->local_id, PREFTYPE_SYM, dek->algo ) ) {
	    /* Don't print a note while we are not on verbose mode,
	     * the cipher is blowfish and the preferences have twofish
	     * listed */
	    if( opt.verbose || dek->algo != CIPHER_ALGO_BLOWFISH
		|| !is_algo_in_prefs( pk->local_id, PREFTYPE_SYM,
						    CIPHER_ALGO_TWOFISH ) )
		log_info(_(
		    "NOTE: cipher algorithm %d not found in preferences\n"),
								 dek->algo );
	}


	if( !rc && pk->expiredate && pk->expiredate <= make_timestamp() ) {
	    log_info(_("NOTE: secret key %08lX expired at %s\n"),
			   (ulong)keyid[1], asctimestamp( pk->expiredate) );
	}

	/* FIXME: check wheter the key has been revoked and display
	 * the revocation reason.  Actually the user should know this himself,
	 * but the sender might not know already and therefor the user
	 * should get a notice that an revoked key has been used to decode
	 * the message.  The user can than watch out for snakes send by
	 * one of those Eves outside his paradise :-)
	 */
	free_public_key( pk );
	rc = 0;
    }


  leave:
    mpi_free(plain_dek);
    m_free(frame);
    return rc;
}
Example #27
0
/*
 * Encrypt the file with the given userids (or ask if none is
 * supplied).  Either FILENAME or FILEFD must be given, but not both.
 * The caller may provide a checked list of public keys in
 * PROVIDED_PKS; if not the function builds a list of keys on its own.
 *
 * Note that FILEFD is currently only used by cmd_encrypt in the the
 * not yet finished server.c.
 */
int
encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
               strlist_t remusr, int use_symkey, pk_list_t provided_keys,
               int outputfd)
{
  iobuf_t inp = NULL;
  iobuf_t out = NULL;
  PACKET pkt;
  PKT_plaintext *pt = NULL;
  DEK *symkey_dek = NULL;
  STRING2KEY *symkey_s2k = NULL;
  int rc = 0, rc2 = 0;
  u32 filesize;
  cipher_filter_context_t cfx;
  armor_filter_context_t *afx = NULL;
  compress_filter_context_t zfx;
  text_filter_context_t tfx;
  progress_filter_context_t *pfx;
  PK_LIST pk_list;
  int do_compress;

  if (filefd != -1 && filename)
    return gpg_error (GPG_ERR_INV_ARG);  /* Both given.  */

  do_compress = !!opt.compress_algo;

  pfx = new_progress_context ();
  memset( &cfx, 0, sizeof cfx);
  memset( &zfx, 0, sizeof zfx);
  memset( &tfx, 0, sizeof tfx);
  init_packet(&pkt);

  if (use_symkey
      && (rc=setup_symkey(&symkey_s2k,&symkey_dek)))
    {
      release_progress_context (pfx);
      return rc;
    }

  if (provided_keys)
    pk_list = provided_keys;
  else
    {
      if ((rc = build_pk_list (ctrl, remusr, &pk_list, PUBKEY_USAGE_ENC)))
        {
          release_progress_context (pfx);
          return rc;
        }
    }

  /* Prepare iobufs. */
#ifdef HAVE_W32_SYSTEM
  if (filefd == -1)
    inp = iobuf_open_fd_or_name (GNUPG_INVALID_FD, filename, "rb");
  else
    {
      inp = NULL;
      gpg_err_set_errno (ENOSYS);
    }
#else
  inp = iobuf_open_fd_or_name (filefd, filename, "rb");
#endif
  if (inp)
    iobuf_ioctl (inp, IOBUF_IOCTL_NO_CACHE, 1, NULL);
  if (inp && is_secured_file (iobuf_get_fd (inp)))
    {
      iobuf_close (inp);
      inp = NULL;
      gpg_err_set_errno (EPERM);
    }
  if (!inp)
    {
      char xname[64];

      rc = gpg_error_from_syserror ();
      if (filefd != -1)
        snprintf (xname, sizeof xname, "[fd %d]", filefd);
      else if (!filename)
        strcpy (xname, "[stdin]");
      else
        *xname = 0;
      log_error (_("can't open '%s': %s\n"),
                 *xname? xname : filename, gpg_strerror (rc) );
      goto leave;
    }

  if (opt.verbose)
    log_info (_("reading from '%s'\n"), iobuf_get_fname_nonnull (inp));

  handle_progress (pfx, inp, filename);

  if (opt.textmode)
    iobuf_push_filter (inp, text_filter, &tfx);

  rc = open_outfile (outputfd, filename, opt.armor? 1:0, 0, &out);
  if (rc)
    goto leave;

  if (opt.armor)
    {
      afx = new_armor_context ();
      push_armor_filter (afx, out);
    }

  /* Create a session key. */
  cfx.dek = xmalloc_secure_clear (sizeof *cfx.dek);
  if (!opt.def_cipher_algo)
    {
      /* Try to get it from the prefs.  */
      cfx.dek->algo = select_algo_from_prefs (pk_list, PREFTYPE_SYM, -1, NULL);
      /* The only way select_algo_from_prefs can fail here is when
         mixing v3 and v4 keys, as v4 keys have an implicit preference
         entry for 3DES, and the pk_list cannot be empty.  In this
         case, use 3DES anyway as it's the safest choice - perhaps the
         v3 key is being used in an OpenPGP implementation and we know
         that the implementation behind any v4 key can handle 3DES. */
      if (cfx.dek->algo == -1)
        {
          cfx.dek->algo = CIPHER_ALGO_3DES;
        }

      /* In case 3DES has been selected, print a warning if any key
         does not have a preference for AES.  This should help to
         indentify why encrypting to several recipients falls back to
         3DES. */
      if (opt.verbose && cfx.dek->algo == CIPHER_ALGO_3DES)
        warn_missing_aes_from_pklist (pk_list);
    }
  else
    {
      if (!opt.expert
          && (select_algo_from_prefs (pk_list, PREFTYPE_SYM,
                                      opt.def_cipher_algo, NULL)
              != opt.def_cipher_algo))
        {
          log_info(_("WARNING: forcing symmetric cipher %s (%d)"
                     " violates recipient preferences\n"),
                   openpgp_cipher_algo_name (opt.def_cipher_algo),
                   opt.def_cipher_algo);
        }

      cfx.dek->algo = opt.def_cipher_algo;
    }

  cfx.dek->use_mdc = use_mdc (pk_list,cfx.dek->algo);

  /* Only do the is-file-already-compressed check if we are using a
     MDC.  This forces compressed files to be re-compressed if we do
     not have a MDC to give some protection against chosen ciphertext
     attacks. */

  if (do_compress && cfx.dek->use_mdc && is_file_compressed(filename, &rc2))
    {
      if (opt.verbose)
        log_info(_("'%s' already compressed\n"), filename);
      do_compress = 0;
    }
  if (rc2)
    {
      rc = rc2;
      goto leave;
    }

  make_session_key (cfx.dek);
  if (DBG_CRYPTO)
    log_printhex ("DEK is: ", cfx.dek->key, cfx.dek->keylen );

  rc = write_pubkey_enc_from_list (pk_list, cfx.dek, out);
  if (rc)
    goto leave;

  /* We put the passphrase (if any) after any public keys as this
     seems to be the most useful on the recipient side - there is no
     point in prompting a user for a passphrase if they have the
     secret key needed to decrypt.  */
  if(use_symkey && (rc = write_symkey_enc(symkey_s2k,symkey_dek,cfx.dek,out)))
    goto leave;

  if (!opt.no_literal)
    pt = setup_plaintext_name (filename, inp);

  /* Get the size of the file if possible, i.e., if it is a real file.  */
  if (filename && *filename
      && !iobuf_is_pipe_filename (filename) && !opt.textmode )
    {
      off_t tmpsize;
      int overflow;

      if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
           && !overflow && opt.verbose)
        log_info(_("WARNING: '%s' is an empty file\n"), filename );
      /* We can't encode the length of very large files because
         OpenPGP uses only 32 bit for file sizes.  So if the the size
         of a file is larger than 2^32 minus some bytes for packet
         headers, we switch to partial length encoding. */
      if (tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
        filesize = tmpsize;
      else
        filesize = 0;
    }
  else
    filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */

  if (!opt.no_literal)
    {
      pt->timestamp = make_timestamp();
      pt->mode = opt.textmode ? 't' : 'b';
      pt->len = filesize;
      pt->new_ctb = !pt->len;
      pt->buf = inp;
      pkt.pkttype = PKT_PLAINTEXT;
      pkt.pkt.plaintext = pt;
      cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0;
    }
  else
    cfx.datalen = filesize && !do_compress ? filesize : 0;

  /* Register the cipher filter. */
  iobuf_push_filter (out, cipher_filter, &cfx);

  /* Register the compress filter. */
  if (do_compress)
    {
      int compr_algo = opt.compress_algo;

      if (compr_algo == -1)
        {
          compr_algo = select_algo_from_prefs (pk_list, PREFTYPE_ZIP, -1, NULL);
          if (compr_algo == -1)
            compr_algo = DEFAULT_COMPRESS_ALGO;
          /* Theoretically impossible to get here since uncompressed
             is implicit.  */
        }
      else if (!opt.expert
               && select_algo_from_prefs(pk_list, PREFTYPE_ZIP,
                                         compr_algo, NULL) != compr_algo)
        {
          log_info (_("WARNING: forcing compression algorithm %s (%d)"
                      " violates recipient preferences\n"),
                    compress_algo_to_string(compr_algo), compr_algo);
        }

      /* Algo 0 means no compression. */
      if (compr_algo)
        {
          if (cfx.dek && cfx.dek->use_mdc)
            zfx.new_ctb = 1;
          push_compress_filter (out,&zfx,compr_algo);
        }
    }

  /* Do the work. */
  if (!opt.no_literal)
    {
      if ((rc = build_packet( out, &pkt )))
        log_error ("build_packet failed: %s\n", gpg_strerror (rc));
    }
  else
    {
      /* User requested not to create a literal packet, so we copy the
         plain data. */
      byte copy_buffer[4096];
      int  bytes_copied;
      while ((bytes_copied = iobuf_read (inp, copy_buffer, 4096)) != -1)
        {
          rc = iobuf_write (out, copy_buffer, bytes_copied);
          if (rc)
            {
              log_error ("copying input to output failed: %s\n",
                         gpg_strerror (rc));
              break;
            }
        }
      wipememory (copy_buffer, 4096); /* Burn the buffer. */
    }

  /* Finish the stuff. */
 leave:
  iobuf_close (inp);
  if (rc)
    iobuf_cancel (out);
  else
    {
      iobuf_close (out); /* fixme: check returncode */
      write_status (STATUS_END_ENCRYPTION);
    }
  if (pt)
    pt->buf = NULL;
  free_packet (&pkt);
  xfree (cfx.dek);
  xfree (symkey_dek);
  xfree (symkey_s2k);
  if (!provided_keys)
    release_pk_list (pk_list);
  release_armor_context (afx);
  release_progress_context (pfx);
  return rc;
}
Example #28
0
static gpg_error_t
get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
{
  gpg_error_t err;
  byte *frame = NULL;
  unsigned int n;
  size_t nframe;
  u16 csum, csum2;
  int card = 0;
  gcry_sexp_t s_data;
  char *desc;
  char *keygrip;
  byte fp[MAX_FINGERPRINT_LEN];
  size_t fpn;
  const int pkalgo = map_pk_openpgp_to_gcry (sk->pubkey_algo);

  /* Get the keygrip.  */
  err = hexkeygrip_from_pk (sk, &keygrip);
  if (err)
    goto leave;

  /* Convert the data to an S-expression.  */
  if (pkalgo == GCRY_PK_ELG || pkalgo == GCRY_PK_ELG_E)
    {
      if (!enc->data[0] || !enc->data[1])
        err = gpg_error (GPG_ERR_BAD_MPI);
      else
        err = gcry_sexp_build (&s_data, NULL, "(enc-val(elg(a%m)(b%m)))",
                               enc->data[0], enc->data[1]);
    }
  else if (pkalgo == GCRY_PK_RSA || pkalgo == GCRY_PK_RSA_E)
    {
      if (!enc->data[0])
        err = gpg_error (GPG_ERR_BAD_MPI);
      else
        err = gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))",
                               enc->data[0]);
    }
  else if (pkalgo == GCRY_PK_ECDH)
    {
      if (!enc->data[0] || !enc->data[1])
        err = gpg_error (GPG_ERR_BAD_MPI);
      else
        err = gcry_sexp_build (&s_data, NULL, "(enc-val(ecdh(s%m)(e%m)))",
                               enc->data[0], enc->data[1]);
    }
  else
    err = gpg_error (GPG_ERR_BUG);

  if (err)
    goto leave;

  if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
    {
      fingerprint_from_pk (sk, fp, &fpn);
      assert (fpn == 20);
    }

  /* Decrypt. */
  desc = gpg_format_keydesc (sk, 0, 1);
  err = agent_pkdecrypt (NULL, keygrip, desc, s_data, &frame, &nframe);
  xfree (desc);
  gcry_sexp_release (s_data);
  if (err)
    goto leave;

  /* Now get the DEK (data encryption key) from the frame
   *
   * Old versions encode the DEK in in this format (msb is left):
   *
   *     0  1  DEK(16 bytes)  CSUM(2 bytes)  0  RND(n bytes) 2
   *
   * Later versions encode the DEK like this:
   *
   *     0  2  RND(n bytes)  0  A  DEK(k bytes)  CSUM(2 bytes)
   *
   * (mpi_get_buffer already removed the leading zero).
   *
   * RND are non-zero randow bytes.
   * A   is the cipher algorithm
   * DEK is the encryption key (session key) with length k
   * CSUM
   */
  if (DBG_CIPHER)
    log_printhex ("DEK frame:", frame, nframe);
  n = 0;

  if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
    {
      gcry_mpi_t shared_mpi;
      gcry_mpi_t decoded;

      /* At the beginning the frame are the bytes of shared point MPI.  */
      err = gcry_mpi_scan (&shared_mpi, GCRYMPI_FMT_USG, frame, nframe, NULL);
      if (err)
        {
          err = gpg_error (GPG_ERR_WRONG_SECKEY);
          goto leave;
        }

      err = pk_ecdh_decrypt (&decoded, fp, enc->data[1]/*encr data as an MPI*/,
                             shared_mpi, sk->pkey);
      mpi_release (shared_mpi);
      if(err)
        goto leave;

      /* Reuse NFRAME, which size is sufficient to include the session key.  */
      err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &nframe, decoded);
      mpi_release (decoded);
      if (err)
        goto leave;

      /* Now the frame are the bytes decrypted but padded session key.  */

      /* Allow double padding for the benefit of DEK size concealment.
         Higher than this is wasteful. */
      if (!nframe || frame[nframe-1] > 8*2 || nframe <= 8
          || frame[nframe-1] > nframe)
        {
          err = gpg_error (GPG_ERR_WRONG_SECKEY);
          goto leave;
        }
      nframe -= frame[nframe-1]; /* Remove padding.  */
      assert (!n); /* (used just below) */
    }
  else
    {
      if (!card)
        {
          if (n + 7 > nframe)
            {
              err = gpg_error (GPG_ERR_WRONG_SECKEY);
              goto leave;
            }
          if (frame[n] == 1 && frame[nframe - 1] == 2)
            {
              log_info (_("old encoding of the DEK is not supported\n"));
              err = gpg_error (GPG_ERR_CIPHER_ALGO);
              goto leave;
            }
          if (frame[n] != 2) /* Something went wrong.  */
            {
              err = gpg_error (GPG_ERR_WRONG_SECKEY);
              goto leave;
            }
          for (n++; n < nframe && frame[n]; n++) /* Skip the random bytes.  */
            ;
          n++; /* Skip the zero byte.  */
        }
    }

  if (n + 4 > nframe)
    {
      err = gpg_error (GPG_ERR_WRONG_SECKEY);
      goto leave;
    }

  dek->keylen = nframe - (n + 1) - 2;
  dek->algo = frame[n++];
  if (dek->algo == CIPHER_ALGO_IDEA)
    write_status (STATUS_RSA_OR_IDEA);
  err = openpgp_cipher_test_algo (dek->algo);
  if (err)
    {
      if (!opt.quiet && gpg_err_code (err) == GPG_ERR_CIPHER_ALGO)
        {
          log_info (_("cipher algorithm %d%s is unknown or disabled\n"),
                    dek->algo,
                    dek->algo == CIPHER_ALGO_IDEA ? " (IDEA)" : "");
          if (dek->algo == CIPHER_ALGO_IDEA)
            idea_cipher_warn (0);
        }
      dek->algo = 0;
      goto leave;
    }
  if (dek->keylen != openpgp_cipher_get_algo_keylen (dek->algo))
    {
      err = gpg_error (GPG_ERR_WRONG_SECKEY);
      goto leave;
    }

  /* Copy the key to DEK and compare the checksum.  */
  csum = frame[nframe - 2] << 8;
  csum |= frame[nframe - 1];
  memcpy (dek->key, frame + n, dek->keylen);
  for (csum2 = 0, n = 0; n < dek->keylen; n++)
    csum2 += dek->key[n];
  if (csum != csum2)
    {
      err = gpg_error (GPG_ERR_WRONG_SECKEY);
      goto leave;
    }
  if (DBG_CIPHER)
    log_printhex ("DEK is:", dek->key, dek->keylen);

  /* Check that the algo is in the preferences and whether it has expired.  */
  {
    PKT_public_key *pk = NULL;
    KBNODE pkb = get_pubkeyblock (keyid);

    if (!pkb)
      {
        err = -1;
        log_error ("oops: public key not found for preference check\n");
      }
    else if (pkb->pkt->pkt.public_key->selfsigversion > 3
             && dek->algo != CIPHER_ALGO_3DES
             && !opt.quiet
             && !is_algo_in_prefs (pkb, PREFTYPE_SYM, dek->algo))
      log_info (_("WARNING: cipher algorithm %s not found in recipient"
                  " preferences\n"), openpgp_cipher_algo_name (dek->algo));
    if (!err)
      {
        KBNODE k;

        for (k = pkb; k; k = k->next)
          {
            if (k->pkt->pkttype == PKT_PUBLIC_KEY
                || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
              {
                u32 aki[2];
                keyid_from_pk (k->pkt->pkt.public_key, aki);

                if (aki[0] == keyid[0] && aki[1] == keyid[1])
                  {
                    pk = k->pkt->pkt.public_key;
                    break;
                  }
              }
          }
        if (!pk)
          BUG ();
        if (pk->expiredate && pk->expiredate <= make_timestamp ())
          {
            log_info (_("NOTE: secret key %s expired at %s\n"),
                      keystr (keyid), asctimestamp (pk->expiredate));
          }
      }

    if (pk && pk->flags.revoked)
      {
        log_info (_("NOTE: key has been revoked"));
        log_printf ("\n");
        show_revocation_reason (pk, 1);
      }

    release_kbnode (pkb);
    err = 0;
  }

 leave:
  xfree (frame);
  xfree (keygrip);
  return err;
}
Example #29
0
static int
get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid )
{
  int rc;
  gcry_mpi_t plain_dek  = NULL;
  byte *frame = NULL;
  unsigned int n;
  size_t nframe;
  u16 csum, csum2;
  
  int card = 0;

  if (sk->is_protected && sk->protect.s2k.mode == 1002)
    { /* Note, that we only support RSA for now. */
#ifdef ENABLE_CARD_SUPPORT
      unsigned char *rbuf;
      size_t rbuflen;
      char *snbuf;
      unsigned char *indata = NULL;
      size_t indatalen;

      snbuf = serialno_and_fpr_from_sk (sk->protect.iv, sk->protect.ivlen, sk);

      if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &indata, &indatalen, enc->data[0]))
        BUG ();

      rc = agent_scd_pkdecrypt (snbuf, indata, indatalen, &rbuf, &rbuflen);
      xfree (snbuf);
      xfree (indata);
      if (rc)
        goto leave;

      frame = rbuf;
      nframe = rbuflen;
      card = 1;
#else
      rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
      goto leave;
#endif /*!ENABLE_CARD_SUPPORT*/
    }
  else
    {
      rc = pk_decrypt (sk->pubkey_algo, &plain_dek, enc->data, sk->skey );
      if( rc )
	goto leave;
      if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &frame, &nframe, plain_dek))
        BUG();
      gcry_mpi_release (plain_dek); plain_dek = NULL;
    }

    /* Now get the DEK (data encryption key) from the frame
     *
     * Old versions encode the DEK in in this format (msb is left):
     *
     *	   0  1  DEK(16 bytes)	CSUM(2 bytes)  0  RND(n bytes) 2
     *
     * Later versions encode the DEK like this:
     *
     *	   0  2  RND(n bytes)  0  A  DEK(k bytes)  CSUM(2 bytes)
     *
     * (mpi_get_buffer already removed the leading zero).
     *
     * RND are non-zero randow bytes.
     * A   is the cipher algorithm
     * DEK is the encryption key (session key) with length k
     * CSUM
     */
    if (DBG_CIPHER)
      log_printhex ("DEK frame:", frame, nframe );
    n=0;
    if (!card)
      {
        if( n + 7 > nframe )
          { rc = G10ERR_WRONG_SECKEY; goto leave; }
        if( frame[n] == 1 && frame[nframe-1] == 2 ) {
          log_info(_("old encoding of the DEK is not supported\n"));
          rc = G10ERR_CIPHER_ALGO;
          goto leave;
        }
        if( frame[n] != 2 )  /* somethink is wrong */
          { rc = G10ERR_WRONG_SECKEY; goto leave; }
        for(n++; n < nframe && frame[n]; n++ ) /* skip the random bytes */
          ;
        n++; /* and the zero byte */
      }

    if( n + 4 > nframe )
	{ rc = G10ERR_WRONG_SECKEY; goto leave; }

    dek->keylen = nframe - (n+1) - 2;
    dek->algo = frame[n++];
    if( dek->algo ==  CIPHER_ALGO_IDEA )
	write_status(STATUS_RSA_OR_IDEA);
    rc = openpgp_cipher_test_algo (dek->algo);
    if( rc ) {
	if( !opt.quiet && gpg_err_code (rc) == GPG_ERR_CIPHER_ALGO ) {
	    log_info(_("cipher algorithm %d%s is unknown or disabled\n"),
                     dek->algo, dek->algo == CIPHER_ALGO_IDEA? " (IDEA)":"");
	    if(dek->algo==CIPHER_ALGO_IDEA)
	      idea_cipher_warn (0);
	}
	dek->algo = 0;
	goto leave;
    }
    if ( dek->keylen != openpgp_cipher_get_algo_keylen (dek->algo) ) {
	rc = GPG_ERR_WRONG_SECKEY;
	goto leave;
    }

    /* copy the key to DEK and compare the checksum */
    csum  = frame[nframe-2] << 8;
    csum |= frame[nframe-1];
    memcpy( dek->key, frame+n, dek->keylen );
    for( csum2=0, n=0; n < dek->keylen; n++ )
	csum2 += dek->key[n];
    if( csum != csum2 ) {
	rc = G10ERR_WRONG_SECKEY;
	goto leave;
    }
    if( DBG_CIPHER )
        log_printhex ("DEK is:", dek->key, dek->keylen );
    /* check that the algo is in the preferences and whether it has expired */
    {
	PKT_public_key *pk = NULL;
        KBNODE pkb = get_pubkeyblock (keyid);

	if( !pkb ) {
            rc = -1;
	    log_error("oops: public key not found for preference check\n");
        }
	else if(pkb->pkt->pkt.public_key->selfsigversion > 3
		&& dek->algo != CIPHER_ALGO_3DES
		&& !opt.quiet
		&& !is_algo_in_prefs( pkb, PREFTYPE_SYM, dek->algo ))
	  log_info (_("WARNING: cipher algorithm %s not found in recipient"
                      " preferences\n"), openpgp_cipher_algo_name (dek->algo));
        if (!rc) {
            KBNODE k;
            
            for (k=pkb; k; k = k->next) {
                if (k->pkt->pkttype == PKT_PUBLIC_KEY 
                    || k->pkt->pkttype == PKT_PUBLIC_SUBKEY){
                    u32 aki[2];
        	    keyid_from_pk(k->pkt->pkt.public_key, aki);

                    if (aki[0]==keyid[0] && aki[1]==keyid[1]) {
                        pk = k->pkt->pkt.public_key;
                        break;
                    }
                }
            }
            if (!pk)
                BUG ();
            if ( pk->expiredate && pk->expiredate <= make_timestamp() ) {
                log_info(_("NOTE: secret key %s expired at %s\n"),
                         keystr(keyid), asctimestamp( pk->expiredate) );
            }
        }

        if ( pk &&  pk->is_revoked ) {
            log_info( _("NOTE: key has been revoked") );
            log_printf ("\n");
            show_revocation_reason( pk, 1 );
        }

	release_kbnode (pkb);
	rc = 0;
    }


  leave:
    gcry_mpi_release (plain_dek);
    xfree (frame);
    return rc;
}
/* We don't want to use use_seskey yet because older gnupg versions
   can't handle it, and there isn't really any point unless we're
   making a message that can be decrypted by a public key or
   passphrase. */
static int
encode_simple( const char *filename, int mode, int use_seskey )
{
    IOBUF inp, out;
    PACKET pkt;
    PKT_plaintext *pt = NULL;
    STRING2KEY *s2k = NULL;
    byte enckey[33];
    int rc = 0;
    int seskeylen = 0;
    u32 filesize;
    cipher_filter_context_t cfx;
    armor_filter_context_t afx;
    compress_filter_context_t zfx;
    text_filter_context_t tfx;
    progress_filter_context_t pfx;
    int do_compress = !RFC1991 && default_compress_algo();

    memset( &cfx, 0, sizeof cfx);
    memset( &afx, 0, sizeof afx);
    memset( &zfx, 0, sizeof zfx);
    memset( &tfx, 0, sizeof tfx);
    init_packet(&pkt);
    
    /* prepare iobufs */
    inp = iobuf_open(filename);
    if (inp)
      iobuf_ioctl (inp,3,1,NULL); /* disable fd caching */
    if (inp && is_secured_file (iobuf_get_fd (inp)))
      {
        iobuf_close (inp);
        inp = NULL;
        errno = EPERM;
      }
    if( !inp ) {
	log_error(_("can't open `%s': %s\n"), filename? filename: "[stdin]",
                  strerror(errno) );
	return G10ERR_OPEN_FILE;
    }

    handle_progress (&pfx, inp, filename);

    if( opt.textmode )
	iobuf_push_filter( inp, text_filter, &tfx );

    /* Due the the fact that we use don't use an IV to encrypt the
       session key we can't use the new mode with RFC1991 because
       it has no S2K salt. RFC1991 always uses simple S2K. */
    if ( RFC1991 && use_seskey )
        use_seskey = 0;
    
    cfx.dek = NULL;
    if( mode ) {
	s2k = xmalloc_clear( sizeof *s2k );
	s2k->mode = RFC1991? 0:opt.s2k_mode;
	s2k->hash_algo=S2K_DIGEST_ALGO;
	cfx.dek = passphrase_to_dek( NULL, 0,
				     default_cipher_algo(), s2k, 2,
                                     NULL, NULL);
	if( !cfx.dek || !cfx.dek->keylen ) {
	    rc = G10ERR_PASSPHRASE;
	    xfree(cfx.dek);
	    xfree(s2k);
	    iobuf_close(inp);
	    log_error(_("error creating passphrase: %s\n"), g10_errstr(rc) );
	    return rc;
	}
        if (use_seskey && s2k->mode != 1 && s2k->mode != 3) {
            use_seskey = 0;
            log_info (_("can't use a symmetric ESK packet "
                        "due to the S2K mode\n"));
        }

        if ( use_seskey )
	  {
	    DEK *dek = NULL;
            seskeylen = cipher_get_keylen( default_cipher_algo() ) / 8;
            encode_seskey( cfx.dek, &dek, enckey );
            xfree( cfx.dek ); cfx.dek = dek;
	  }

	if(opt.verbose)
	  log_info(_("using cipher %s\n"),
		   cipher_algo_to_string(cfx.dek->algo));

	cfx.dek->use_mdc=use_mdc(NULL,cfx.dek->algo);
    }

    if (do_compress && cfx.dek && cfx.dek->use_mdc
	&& is_file_compressed(filename, &rc))
      {
        if (opt.verbose)
          log_info(_("`%s' already compressed\n"), filename);
        do_compress = 0;        
      }

    if( rc || (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) {
	iobuf_cancel(inp);
	xfree(cfx.dek);
	xfree(s2k);
	return rc;
    }

    if( opt.armor )
	iobuf_push_filter( out, armor_filter, &afx );

    if( s2k && !RFC1991 ) {
	PKT_symkey_enc *enc = xmalloc_clear( sizeof *enc + seskeylen + 1 );
	enc->version = 4;
	enc->cipher_algo = cfx.dek->algo;
	enc->s2k = *s2k;
        if ( use_seskey && seskeylen ) {
            enc->seskeylen = seskeylen + 1; /* algo id */
            memcpy( enc->seskey, enckey, seskeylen + 1 );
        }
	pkt.pkttype = PKT_SYMKEY_ENC;
	pkt.pkt.symkey_enc = enc;
	if( (rc = build_packet( out, &pkt )) )
	    log_error("build symkey packet failed: %s\n", g10_errstr(rc) );
	xfree(enc);
    }

    if (!opt.no_literal)
      pt=setup_plaintext_name(filename,inp);

    /* Note that PGP 5 has problems decrypting symmetrically encrypted
       data if the file length is in the inner packet. It works when
       only partial length headers are use.  In the past, we always
       used partial body length here, but since PGP 2, PGP 6, and PGP
       7 need the file length, and nobody should be using PGP 5
       nowadays anyway, this is now set to the file length.  Note also
       that this only applies to the RFC-1991 style symmetric
       messages, and not the RFC-2440 style.  PGP 6 and 7 work with
       either partial length or fixed length with the new style
       messages. */

    if ( !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
      {
        off_t tmpsize;
        int overflow;

	if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
             && !overflow )
          log_info(_("WARNING: `%s' is an empty file\n"), filename );
        /* We can't encode the length of very large files because
           OpenPGP uses only 32 bit for file sizes.  So if the the
           size of a file is larger than 2^32 minus some bytes for
           packet headers, we switch to partial length encoding. */
        if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
          filesize = tmpsize;
        else
          filesize = 0;
      }
    else
      filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */

    if (!opt.no_literal) {
	pt->timestamp = make_timestamp();
	pt->mode = opt.textmode? 't' : 'b';
	pt->len = filesize;
	pt->new_ctb = !pt->len && !RFC1991;
	pt->buf = inp;
	pkt.pkttype = PKT_PLAINTEXT;
	pkt.pkt.plaintext = pt;
	cfx.datalen = filesize && !do_compress ? calc_packet_length( &pkt ) : 0;
    }
    else
      {
        cfx.datalen = filesize && !do_compress ? filesize : 0;
        pkt.pkttype = 0;
        pkt.pkt.generic = NULL;
      }

    /* register the cipher filter */
    if( mode )
	iobuf_push_filter( out, cipher_filter, &cfx );
    /* register the compress filter */
    if( do_compress )
      {
        if (cfx.dek && cfx.dek->use_mdc)
          zfx.new_ctb = 1;
	push_compress_filter(out,&zfx,default_compress_algo());
      }

    /* do the work */
    if (!opt.no_literal) {
	if( (rc = build_packet( out, &pkt )) )
	    log_error("build_packet failed: %s\n", g10_errstr(rc) );
    }
    else {
	/* user requested not to create a literal packet,
	 * so we copy the plain data */
	byte copy_buffer[4096];
	int  bytes_copied;
	while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
	    if (iobuf_write(out, copy_buffer, bytes_copied) == -1) {
		rc = G10ERR_WRITE_FILE;
		log_error("copying input to output failed: %s\n", g10_errstr(rc) );
		break;
	    }
	wipememory(copy_buffer, 4096); /* burn buffer */
    }

    /* finish the stuff */
    iobuf_close(inp);
    if (rc)
	iobuf_cancel(out);
    else {
	iobuf_close(out); /* fixme: check returncode */
        if (mode)
            write_status( STATUS_END_ENCRYPTION );
    }
    if (pt)
	pt->buf = NULL;
    free_packet(&pkt);
    xfree(cfx.dek);
    xfree(s2k);
    return rc;
}