crypto_error_t crypto_mac(bytestring_t *dst,
                          const bytestring_t *ctx,
                          const bytestring_t *src)
{
    unsigned u,v;
    unsigned char tmp[8];
    unsigned char clr[8];
    unsigned char alg;
    crypto_error_t retval;
    bytestring_t *padded_src;
    DES_key_schedule key_schedule;
    DES_key_schedule key_schedule2;

    bytestring_get_element(&alg,ctx,0);

    if (alg==CRYPTO_ALG_ISO9797_M3)
    {
        padded_src = bytestring_new(8);
        retval = crypto_pad(padded_src,ctx,src);
        if (retval!=CRYPTO_OK)
        {
            bytestring_free(padded_src);
            return retval;
        }
        memset(tmp,0,8);

        memcpy(&key_schedule,ctx->data+KS_HEADER_SIZE,DES_KS_SIZE);
        memcpy(&key_schedule2,ctx->data+KS_HEADER_SIZE+DES_KS_SIZE,DES_KS_SIZE);

        for (u=0; u<bytestring_get_size(padded_src)/8; u++)
        {
            for (v=0; v<8; v++) clr[v]=padded_src->data[u*8+v]^tmp[v];
            DES_ecb_encrypt((const_DES_cblock *)clr,
                            (DES_cblock *)tmp,
                            &key_schedule,
                            DES_ENCRYPT);
        }
        memcpy(clr,tmp,8);
        DES_ecb_encrypt((const_DES_cblock *)clr,
                        (DES_cblock *)tmp,
                        &key_schedule2,
                        DES_DECRYPT);
        memcpy(clr,tmp,8);
        DES_ecb_encrypt((const_DES_cblock *)clr,
                        (DES_cblock *)tmp,
                        &key_schedule,
                        DES_ENCRYPT);
        bytestring_assign_data(dst,8,tmp);
        bytestring_free(padded_src);
    }
    else
        return CRYPTO_ERROR_UNKNOWN_ALGORITHM;
    return CRYPTO_OK;
}
static gboolean internal_load_image(CustomCellRendererFlexi *cr, const char *src, const char *mime_type)
{
    GdkPixbufLoader *loader;
    bytestring_t *bs = bytestring_new_from_string(src);
    GError *err = NULL;

    if (bs==NULL)
    {
        internal_render_error(cr,"No image data.");
        return FALSE;
    }

    if (bs->width!=8)
    {
        internal_render_error(cr,"Image data must be octets.");
        bytestring_free(bs);
        return FALSE;
    }

    loader = gdk_pixbuf_loader_new_with_mime_type(mime_type,&err);

    if (!loader)
        goto internal_load_image_fail;

    if (gdk_pixbuf_loader_write(loader,bs->data,bs->len,&err)==FALSE)
        goto internal_load_image_fail;
    
    err=NULL;

    if (gdk_pixbuf_loader_close(loader,&err)==FALSE)
        goto internal_load_image_fail;

    cr->rendered_type  = RENDER_PIXBUF;
    cr->rendered_value = (GdkPixbuf*) gdk_pixbuf_loader_get_pixbuf(loader);

    g_object_ref(cr->rendered_value);

    g_object_unref(loader);

    bytestring_free(bs);
    return TRUE;

internal_load_image_fail:
    if (err!=NULL)
    {
        internal_render_error(cr,err->message);
        g_error_free(err);
    }
    if (bs) bytestring_free(bs);
    return FALSE;
}
void headerbundle_free(headerbundle *hb)
{
  // Free header contents
  for (int i = 0; i < hb->count; i++)
  {
    bytestring_free(hb->headers[i].key);
    bytestring_free(hb->headers[i].val);
  }

  // Free array of header structs
  xfree(hb->headers);

  // Free root struct
  xfree(hb);
}
Beispiel #4
0
void queue_free(queue *q)
{
  bytestring_free(q->name);
  storage_free(q->storage);

  xfree(q);
}
Beispiel #5
0
void cardreader_free(cardreader_t *reader)
{
  reader->finalize(reader);
  bytestring_free(reader->atr);
  cardreplay_free(reader->cardlog);
  free(reader->name);
  free(reader);
}
// Parses a frame's command. Returns true iff progress was made.
bool frameparser_parse_command(frameparser *fp, buffer *b)
{
  log_printf(LOG_LEVEL_DEBUG, "frameparser_parse_command\n");
  // Valid input in this state is a string followed by CR/LF or LF, which matches a known frame command

  // Try to find LF line terminator
  int lfpos = buffer_find_byte(b, '\x0A');
  if (lfpos < 0)  // No LF yet?
  {
    if (buffer_get_length(b) > LIMIT_FRAME_CMD_LINE_LEN)
      frameparser_set_error(fp, "Line length limit exceeded waiting for command");

    return false;  // No progress
  }
  else if (lfpos == 0)
    abort();  // Should never happen in this state

  // Figure out number of bytes in command string
  int len = lfpos;
  if (buffer_get_byte(b, len - 1) == '\x0D')
    len--;

  // Extract the command into a new bytestring
  bytestring *bs = bytestring_new(len);
  buffer_append_bytestring(b, bs, 0, len);
  bytestring_dump(bs);

  // Consume the current line
  buffer_consume(b, lfpos + 1);

  // Find the command code for this command
  frame_command cmd = frame_command_code(bytestring_get_bytes(bs), bytestring_get_length(bs));

  // Clean up the bytestring
  bytestring_free(bs);

  // Make sure command is valid
  if (cmd == CMD_NONE)
  {
    frameparser_set_error(fp, "Unknown command");
    return false;
  }

  // Set up a new frame structure to hold parsed data
  if (!fp->cur_frame)
    fp->cur_frame = frame_new();

  // Store parsed data
  frame_set_command(fp->cur_frame, cmd);

  // Got a valid command, so headers should be next
  fp->state = FP_STATE_HEADER;
  return true;
}
void frameparser_free(frameparser *fp)
{
  if (fp->cur_frame)
    xfree(fp->cur_frame);

  if (fp->fin_frame)
    xfree(fp->fin_frame);

  if (fp->error)
    bytestring_free(fp->error);

  xfree(fp);
}
crypto_error_t crypto_encrypt(bytestring_t *dst,
                              const bytestring_t *ctx,
                              const bytestring_t *src,
                              const bytestring_t *iv)
{
    unsigned pad_type;
    bytestring_t *padded_src;
    crypto_error_t retval;

    bytestring_get_element((unsigned char *)&pad_type,ctx,1);

    if (pad_type==0 && (bytestring_get_size(src)&0x7)==0)
        return crypto_cipher(dst,ctx,src,iv,DES_ENCRYPT);

    padded_src=bytestring_new(8);
    retval = crypto_pad(padded_src,ctx,src);
    if (retval==CRYPTO_OK)
    {
        retval = crypto_cipher(dst,ctx,padded_src,iv,DES_ENCRYPT);
    }
    bytestring_free(padded_src);
    return retval;
}
/*
static void update_dump(update_t *update, FILE* out)
{
    update_item_t *item = update->items;

    fprintf(out,"Update version %s\n",update->update_version);
    while (item)
    {
        update_item_dump(item,out);
        item = item->next;
    }
}
*/
static int update_load(update_t *update, const char *data, unsigned data_len)
{
    char *ptr = (char *)data;
    unsigned ptr_len = data_len;
    char *data_end;
    char *value;
    update_item_t *item = NULL;
    bytestring_t *signature;
    bytestring_t *source;
    int signature_verified;

#define fail_update(m) { log_printf(LOG_ERROR,"Failed to parse update information: %s",m); \
                         goto update_new_fail; }


    if ((value = tokenizer_get_record(&ptr,&ptr_len))==NULL) fail_update("Missing header");
    if (strcmp(value,"header")!=0) fail_update("Incorrect header");
    g_free(value);
    
    if ((value = tokenizer_get_field("version",&ptr,&ptr_len))==NULL) fail_update("missing version");
    update->update_version = value; /* don't free value */

    data_end = ptr;
    while ((value = tokenizer_get_record(&ptr,&ptr_len))!=NULL)
    {
        if (strcmp(value,"update")!=0) break;
        g_free(value);

        item = update_item_new();

        if ((value = tokenizer_get_field("file",&ptr,&ptr_len))==NULL) 
            fail_update("missing file name");
        item->file = value;

        if ((value = tokenizer_get_field("url",&ptr,&ptr_len))==NULL) 
            fail_update("missing url");
        item->url = value;

        if ((value = tokenizer_get_field("required_version",&ptr,&ptr_len))==NULL) 
            fail_update("missing required version");
        item->required_version = value;

        if ((value = tokenizer_get_field("digest",&ptr,&ptr_len))==NULL) 
            fail_update("missing digest");
        bytestring_assign_digit_string(&item->digest,value);
        g_free(value);

        if (bytestring_get_size(&item->digest)!=SHA256_DIGEST_LENGTH) 
            fail_update("incorrect digest length");

        if ((value = tokenizer_get_field("message",&ptr,&ptr_len))==NULL)
            fail_update("missing message");
        item->message = value;

        update->item_count++;
        item->next = update->items;
        update->items = item;
        item = NULL;
        data_end = ptr;
    }
    if (value==NULL) 
        fail_update("missing section");
    if (strcmp(value,"authentication")!=0) 
        fail_update("missing authentication");
    g_free(value);

    if ((value = tokenizer_get_field("signature",&ptr,&ptr_len))==NULL) 
        fail_update("missing signature");

    signature = bytestring_new(8);
    bytestring_assign_digit_string(signature,value);
    g_free(value);

    log_printf(LOG_DEBUG,"Verifying %d bit signature on update information (%d bytes), representing %d files.",
               bytestring_get_size(signature)*8,data_end-data,update->item_count);


    source =  bytestring_new(8);
    bytestring_assign_data(source,data_end-data,(const unsigned char *)data);

    if (verify_signature(source,signature)==0)
    {
        log_printf(LOG_ERROR,"Signature verification failed on update information.");
        signature_verified = 0;
        update_clear(update);
    }
    else
    {
        log_printf(LOG_INFO,"Signature verification succeeded on update information.");
        signature_verified = 1;
    }

    bytestring_free(signature);
    bytestring_free(source);
  
    return signature_verified;

update_new_fail:
    if (value) g_free(value);
    if (update) update_clear(update);
    if (item) update_item_free(item);
    return 0;
}
Beispiel #10
0
// Unescapes a bytestring according to the rules used for headers:
//  "\r" => CR, "\n" => LF, "\c" => ":", "\\" => "\"
// If the input bytestring is well-formed, it is consumed and a new bytestring
//  is returned. If the input bytestring is malformed, it is not consumed and
//  NULL is returned.
static bytestring *unescape_header_bytestring(bytestring *in)
{
  bytestring *out = NULL;
  bool success = true;
  size_t inlen = bytestring_get_length(in);
  int pos = 0;

  // Handle trivial case of zero-length input
  if (inlen == 0)
    return in;

  while (pos < inlen)
  {
    // Find next backslash
    int bspos = bytestring_find_byte(in, '\\', pos);
    if (bspos == -1)
    {
      // No backslash, can take the rest of the input verbatim
      if (!out)
        return in;  // No transforms needed, so just return the input string

      // Create output string, if needed
      if (!out)
        out = bytestring_new(bytestring_get_length(in));

      // Grab rest of input string
      size_t count = inlen - pos;
      bytestring_append_bytestring(out, in, pos, count);
      pos += count;
    }
    else
    {
      // There was a backslash, so we'll need to do some transforming

      // Create output string, if needed
      if (!out)
        out = bytestring_new(bytestring_get_length(in));

      // Grab all characters before the backslash, if any
      if (bspos > 0)
      {
        // Copy everything before the backslash
        size_t count = bspos - pos;
        bytestring_append_bytestring(out, in, pos, count);
        pos += count;
      }

      // Process the character following the backslash
      if (bytestring_get_length(in) == (bspos + 1))
      {
        success = false;  // There is no following character
        break;
      }
      else
      {
        uint8_t c = bytestring_get_bytes(in)[bspos + 1];
        if (c == '\\')
          bytestring_append_byte(out, '\\');
        else if (c == 'r')
          bytestring_append_byte(out, '\x0D');  // CR
        else if (c == 'n')
          bytestring_append_byte(out, '\x0A');  // LF
        else if (c == 'c')
          bytestring_append_byte(out, ':');
        else
        {
          success = false;  // Invalid escape sequence
          break;
        }

        pos += 2;
      }
    }
  }

  // Handle errors
  if (!success)
  {
    if (out)
      bytestring_free(out);
    return NULL;
  }

  // All done
  bytestring_free(in);
  return out;
}