コード例 #1
0
static const bytestring_t* pcsc_last_atr(cardreader_t* cr)
{
    pcsc_data_t* pcsc = cr->extra_data;
    DWORD state;
    DWORD protocol;
    BYTE pbAtr[MAX_ATR_SIZE];
    DWORD atrlen=MAX_ATR_SIZE;
    char readername[MAX_READERNAME];
    DWORD readernamelen=MAX_READERNAME;
    /*char *tmp;*/

    pcsc->status = SCardStatus(pcsc->hcard,
                               readername,&readernamelen,
                               &state,
                               &protocol,
                               pbAtr,&atrlen);

    if (pcsc->status==SCARD_S_SUCCESS)
    {
        bytestring_assign_data(cr->atr,atrlen,pbAtr);
        /*tmp = bytestring_to_format("%D",cr->atr);
        log_printf(LOG_INFO,"ATR is %i bytes: %s",atrlen,tmp);
        free(tmp);*/
    }
    else
    {
        bytestring_clear(cr->atr);
        log_printf(LOG_ERROR,"Failed to query card status: %s (error 0x%08x).",
                   pcsc_stringify_error(pcsc->status),
                   pcsc->status );
    }
    return cr->atr;
}
コード例 #2
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;
}
コード例 #3
0
ファイル: bytestring.c プロジェクト: pterjan/cardpeek-navigo
int bytestring_substr(const bytestring_t *src,
		      unsigned pos, unsigned len,
		      bytestring_t* dst)
{
  if (pos>src->len)
  {
    bytestring_clear(dst);
    return 1;
  }
  if (len==BYTESTRING_NPOS || pos+len>src->len)
    len = src->len-pos;
  return bytestring_assign_data(dst,len,src->data+pos);
}
コード例 #4
0
/*
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;
}
コード例 #5
0
ファイル: bytestring.c プロジェクト: pterjan/cardpeek-navigo
int bytestring_copy(bytestring_t *bs,
                    const bytestring_t *src)
{
  return bytestring_assign_data(bs,src->len,src->data);
}
コード例 #6
0
ファイル: bytestring.c プロジェクト: pterjan/cardpeek-navigo
bytestring_t* bytestring_duplicate(const bytestring_t *bs)
{
  bytestring_t* res=bytestring_new();
  bytestring_assign_data(res,bs->len,bs->data);
  return res;
}
コード例 #7
0
static unsigned short pcsc_transmit(cardreader_t* cr,
                                    const bytestring_t* command,
                                    bytestring_t* result)
{
    pcsc_data_t* pcsc = cr->extra_data;
    BYTE REC_DAT[MAX_PCSC_READ_LENGTH];
    DWORD REC_LEN=MAX_PCSC_READ_LENGTH;
    unsigned short SW;

    if (cr->protocol==SCARD_PROTOCOL_T0)
    {
        pcsc->status = SCardTransmit(pcsc->hcard,SCARD_PCI_T0,
                bytestring_get_data(command),
                bytestring_get_size(command),
                SCARD_PCI_NULL,
                REC_DAT,&REC_LEN);
    }
    else if (cr->protocol==SCARD_PROTOCOL_T1)
    {
        pcsc->status = SCardTransmit(pcsc->hcard,SCARD_PCI_T1,
                bytestring_get_data(command),
                bytestring_get_size(command),
                SCARD_PCI_NULL,
                REC_DAT,&REC_LEN);

    }
    else
    {
        log_printf(LOG_ERROR,"Unknown smartcard protocol: %i",cr->protocol);
        return CARDPEEK_ERROR_SW;
    }

    if (pcsc->status!=SCARD_S_SUCCESS)
    {
        log_printf(LOG_ERROR,"Failed to transmit command to card: %s (error 0x%08x).",
                pcsc_stringify_error(pcsc->status),
                pcsc->status );
        return CARDPEEK_ERROR_SW;
    }

    if (REC_LEN>=2)
    {
        bytestring_assign_data(result,REC_LEN-2,REC_DAT);
        SW = (REC_DAT[REC_LEN-2]<<8)|REC_DAT[REC_LEN-1];
    }
    else if (REC_LEN==1)
    {
        bytestring_clear(result);
        SW = REC_DAT[0];
    }
    else
    {
        log_printf(LOG_ERROR,"Transmited %i bytes to the card (%s), but recieved a response of length %i, without any status word included.",
                bytestring_get_size(command),
                pcsc_stringify_protocol(cr->protocol),
                REC_LEN);
        return CARDPEEK_ERROR_SW;
    }

    return SW;
}