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; }
static crypto_error_t crypto_pad(bytestring_t *dst, const bytestring_t *ctx,const bytestring_t *src) { unsigned char e; bytestring_copy(dst,src); bytestring_get_element(&e,ctx,1); switch (((unsigned)e)<<8) { case CRYPTO_PAD_OPT_80_ZERO: if ((bytestring_get_size(dst)&0x7)==0) break; case CRYPTO_PAD_ISO9797_P2: bytestring_pushback(dst,0x80); bytestring_pad_right(dst,8,0); break; case CRYPTO_PAD_ZERO: bytestring_pad_right(dst,8,0); break; default: bytestring_clear(dst); return CRYPTO_ERROR_UNKNOWN_PADDING_METHOD; } return CRYPTO_OK; }
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); }
crypto_error_t crypto_create_context(bytestring_t *ctx, crypto_alg_t alg_type, const bytestring_t *key_bin) { DES_key_schedule ks; bytestring_clear(ctx); bytestring_pushback(ctx,ALG_TYPE(alg_type)); bytestring_pushback(ctx,PAD_TYPE(alg_type)>>8); switch (ALG_TYPE(alg_type)) { case CRYPTO_ALG_DES_ECB: case CRYPTO_ALG_DES_CBC: if (key_bin==NULL || bytestring_get_size(key_bin)!=8 || key_bin->width!=8) return CRYPTO_ERROR_BAD_KEY_FORMAT; DES_set_key_unchecked((const_DES_cblock *)key_bin->data,&ks); bytestring_append_data(ctx,DES_KS_SIZE,(unsigned char *)&ks); break; case CRYPTO_ALG_DES2_EDE_ECB: case CRYPTO_ALG_DES2_EDE_CBC: case CRYPTO_ALG_ISO9797_M3: if (key_bin==NULL || bytestring_get_size(key_bin)!=16 || key_bin->width!=8) return CRYPTO_ERROR_BAD_KEY_FORMAT; DES_set_key_unchecked((const_DES_cblock *)key_bin->data,&ks); bytestring_append_data(ctx,DES_KS_SIZE,(unsigned char *)&ks); DES_set_key_unchecked((const_DES_cblock *)(key_bin->data+8),&ks); bytestring_append_data(ctx,DES_KS_SIZE,(unsigned char *)&ks); break; case CRYPTO_ALG_SHA1: /* nothing else to do */ break; default: return CRYPTO_ERROR_UNKNOWN_KEY_TYPE; } return CRYPTO_OK; }
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; }