Example #1
0
// Duplicates a bytestring
bytestring *bytestring_dup(const bytestring *bs)
{
  bytestring *dup = bytestring_new(bs->length);
  bytestring_set_bytes(dup, bs->data, bs->length);

  return dup;
}
Example #2
0
cardreader_t* cardreader_new(const char *card_reader_name)
{
  cardreader_t* reader = (cardreader_t *)malloc(sizeof(cardreader_t));
  memset(reader,0,sizeof(cardreader_t));

  if (card_reader_name==NULL || strcmp(card_reader_name,"none")==0)
  {
    reader->name=strdup("(none)");
    if (null_initialize(reader)==0) return NULL;
  }
  else if (strncmp(card_reader_name,"pcsc://",7)==0)
  {
    reader->name=strdup(card_reader_name);
    if (pcsc_initialize(reader)==0) return NULL;
  }
  else if (strncmp(card_reader_name,"replay://",9)==0)
  {
    reader->name=strdup(card_reader_name);
    if (replay_initialize(reader)==0) return NULL;
  }
  else 
  {
    free(reader);
    log_printf(LOG_ERROR,"Unknown reader type : %s",card_reader_name);
    return NULL;
  }
 
  reader->atr=bytestring_new(8);
  reader->cardlog=cardreplay_new();
  return reader;
}
Example #3
0
bytestring *bytestring_new_from_string(const char *str)
{
  size_t len = strlen(str);
  bytestring *bs = bytestring_new(len);
  bytestring_set_bytes(bs, (const uint8_t *)str, len);

  return bs;
}
Example #4
0
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;
}
Example #5
0
// 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;
}
Example #6
0
int main()
{
    bytestring_t *key = bytestring_new_from_string("0123456789ABCDEFh");
    bytestring_t *ctx = bytestring_new(8);
    bytestring_t *src = bytestring_new_from_string("5468652071756663h");
    bytestring_t *dst = bytestring_new(8);
    bytestring_t *clr = bytestring_new(8);

    if (crypto_create_key(ctx,0,key)==CRYPTO_OK)
    {
        fprintf(stderr,"Create key succeeded\n");
    }
    else
    {
        fprintf(stderr,"Create key failed\n");
        return -3;
    }

    if (crypto_encrypt(dst,ctx,src,NULL)==CRYPTO_OK)
    {
        fprintf(stderr,"Crypto: %s\n",bytestring_to_alloc_string(dst));
    }
    else
        fprintf(stderr,"Crypto failed\n");

    if (crypto_decrypt(clr,ctx,dst,NULL)==CRYPTO_OK)
    {
        if (bytestring_is_equal(clr,src))
            fprintf(stderr,"Decrypted clear text matches initial text\n");
        else
            fprintf(stderr,"Crypto: %s\n",bytestring_to_alloc_string(clr));
    }
    else
        fprintf(stderr,"Crypto failed\n");

    return 0;
}
Example #7
0
// Record an error
void frameparser_set_error(frameparser *fp, char *fmt, ...)
{
  fp->state = FP_STATE_ERROR;

  // Bail out if there is already an error. We only want to record the first one.
  if (fp->error)
    return;

  va_list args;

  va_start(args, fmt);
  fp->error = bytestring_append_vprintf(bytestring_new(0), fmt, args);
  va_end(args);

  return;
}
Example #8
0
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;
}
Example #9
0
bytestring_t* bytestring_new_from_hex(const char *hex)
{
  bytestring_t *dat=bytestring_new();
  unsigned hex_len=strlen(hex);
  unsigned c;
  size_t i=0;

  bytestring_reserve(dat,hex_len/2);
  
  while (i<hex_len)
  {
    if (is_blank(hex[i]))
    {
      i++;
      continue;
    }
    c=(hex_nibble(hex[i])<<4) | hex_nibble(hex[i+1]);
    if (c>255)
      return dat;
    bytestring_pushback(dat,(unsigned char)c);
    i+=2;
  }
  return dat;
}
/*
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;
}
Example #11
0
bytestring_t* bytestring_duplicate(const bytestring_t *bs)
{
  bytestring_t* res=bytestring_new();
  bytestring_assign_data(res,bs->len,bs->data);
  return res;
}
Example #12
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;
}
Example #13
0
// Parses a header line. Returns true iff progress was made.
bool frameparser_parse_header(frameparser *fp, buffer *b)
{
  log_printf(LOG_LEVEL_DEBUG, "frameparser_parse_header\n");
  // Valid input in this state is either:
  // 1. CR/LF or LF alone, denoting the end of headers
  // 2. A key name, followed by a colon, followed by a value name, terminated with CR/LF or LF

  // 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_HEADER_LINE_LEN)
      frameparser_set_error(fp, "Line length limit exceeded waiting for header");

    return false;  // No progress
  }
  else if (lfpos == 0)  // LF alone
  {
    buffer_consume(b, 1);
    frameparser_parse_headers_complete(fp);
    return true;
  }
  else if ((lfpos == 1) && (buffer_get_byte(b, 0) == '\x0D'))  // CR/LF alone
  {
    buffer_consume(b, 2);
    frameparser_parse_headers_complete(fp);
    return true;
  }

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

  // Find the colon delimiter
  int colonpos = buffer_find_byte_within(b, ':', 0, len);
  if (colonpos < 0)  // No colon?
  {
    frameparser_set_error(fp, "Expected colon delimiter on header line");
    return false;
  }
  else if (colonpos == 0)  // Starts with colon?
  {
    frameparser_set_error(fp, "Header name has zero length");
    return false;
  }

  // Extract the key
  bytestring *key = bytestring_new(colonpos);
  buffer_append_bytestring(b, key, 0, colonpos);

  // Extract the value
  bytestring *val = bytestring_new(len - colonpos - 1);
  buffer_append_bytestring(b, val, colonpos + 1, len - colonpos - 1);

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

  // Unescape the key and value if needed
  frame_command cmd = frame_get_command(fp->cur_frame);
  if ((cmd != CMD_CONNECT) && (cmd != CMD_CONNECTED))
  {
    key = unescape_header_bytestring(key);
    val = unescape_header_bytestring(val);
  }

  bytestring_dump(key);
  bytestring_dump(val);

  headerbundle *hb = frame_get_headerbundle(fp->cur_frame);
  headerbundle_append_header(hb, key, val);  // The bundle takes ownership of key and val

  return true;
}