00001
00002
00003
00004
00005
00006
00007 #include <ccid.h>
00008 #include <list.h>
00009 #include <emv.h>
00010 #include <ber.h>
00011 #include "emv-internal.h"
00012
00013 #include <ctype.h>
00014
00015 uint8_t _emv_sw1(emv_t e)
00016 {
00017 return xfr_rx_sw1(e->e_xfr);
00018 }
00019
00020 uint8_t _emv_sw2(emv_t e)
00021 {
00022 return xfr_rx_sw2(e->e_xfr);
00023 }
00024
00025 int _emsa_pss_decode(const uint8_t *msg, size_t msg_len,
00026 const uint8_t *em, size_t em_len)
00027 {
00028 uint8_t md[SHA_DIGEST_LENGTH];
00029 size_t mdb_len;
00030
00031
00032 SHA1(msg, msg_len, md);
00033
00034
00035
00036 if ( em[em_len - 1] != 0xbc ) {
00037 printf("emsa-pss: bad trailer\n");
00038 return 0;
00039 }
00040
00041 mdb_len = em_len - sizeof(md) - 1;
00042
00043 if ( memcmp(em + mdb_len, md, SHA_DIGEST_LENGTH) )
00044 return 0;
00045
00046 return 1;
00047 }
00048
00049 #if 0
00050 static int tag_cmp(const struct dol_tag *tag, const uint8_t *idb, size_t len)
00051 {
00052 if ( tag->tag_len < len )
00053 return 1;
00054 if ( tag->tag_len > len )
00055 return -1;
00056 return memcmp(idb, tag->tag, len);
00057 }
00058
00059 static const struct dol_tag *find_tag(const struct dol_tag *tags,
00060 unsigned int num_tags,
00061 const uint8_t *idb,
00062 size_t tag_len)
00063 {
00064 while ( num_tags ) {
00065 unsigned int i;
00066 int cmp;
00067
00068 i = num_tags / 2U;
00069 cmp = tag_cmp(tags + i, idb, tag_len);
00070 if ( cmp < 0 ) {
00071 num_tags = i;
00072 }else if ( cmp > 0 ) {
00073 tags = tags + (i + 1U);
00074 num_tags = num_tags - (i + 1U);
00075 }else
00076 return tags + i;
00077 }
00078
00079 return NULL;
00080 }
00081 #endif
00082
00083 static uint8_t *construct_dol(emv_dol_cb_t cbfn, const uint8_t *ptr, size_t len,
00084 size_t *ret_len, void *priv)
00085 {
00086 const uint8_t *tmp, *end;
00087 uint8_t *dol, *dtmp;
00088 size_t sz;
00089
00090 end = ptr + len;
00091
00092 for(sz = 0, tmp = ptr; tmp < end; tmp++) {
00093 size_t tag_len;
00094
00095 tag_len = ber_tag_len(tmp, end);
00096 if ( tag_len == 0 )
00097 return NULL;
00098
00099 tmp += tag_len;
00100 sz += *tmp;
00101 }
00102
00103 dol = dtmp = malloc(sz);
00104 if ( NULL == dol )
00105 return NULL;
00106
00107 for(tmp = ptr; tmp < end; tmp++) {
00108
00109 size_t tag_len;
00110 uint16_t tag;
00111
00112 tag_len = ber_tag_len(tmp, end);
00113 switch(tag_len) {
00114 case 1:
00115 tag = tmp[0];
00116 break;
00117 case 2:
00118 tag = (tmp[0] << 8) | tmp[1];
00119 break;
00120 default:
00121 free(dol);
00122 return NULL;
00123 }
00124
00125 tmp += tag_len;
00126 #if 0
00127 tag = find_tag(tags, num_tags, tmp, tag_len);
00128
00129 if ( NULL == tag || NULL == tag->op ||
00130 !(*tag->op)(dtmp, *tmp, priv) ) {
00131 if ( NULL == tag ) {
00132 size_t i;
00133 printf("Unknown tag in DOL: ");
00134 for (i = 0; i < tag_len; i++)
00135 printf("%.2x", tmp[i - tag_len]);
00136 printf("\n");
00137 }
00138 memset(dtmp, 0, *tmp);
00139 }
00140 #else
00141 if ( NULL == cbfn || !(*cbfn)(tag, dtmp, *tmp, priv) )
00142 memset(dtmp, 0, *tmp);
00143 #endif
00144 dtmp += *tmp;
00145 }
00146
00147 *ret_len = sz;
00148 return dol;
00149 }
00150
00151 uint8_t *emv_construct_dol(emv_dol_cb_t cbfn, const uint8_t *ptr, size_t len,
00152 size_t *ret_len, void *priv)
00153 {
00154 return construct_dol(cbfn, ptr, len, ret_len, priv);
00155 }
00156
00157 uint8_t *_emv_construct_dol(emv_dol_cb_t cbfn, const uint8_t *ptr, size_t len,
00158 size_t *ret_len, void *priv)
00159 {
00160 return construct_dol(cbfn, ptr, len, ret_len, priv);
00161 }
00162
00163 int _emv_pin2pb(const char *pin, emv_pb_t pb)
00164 {
00165 unsigned int i;
00166
00167 size_t plen;
00168 plen = strlen(pin);
00169 if ( plen < 4 || plen > 12 )
00170 return 0;
00171
00172 memset(pb, 0xff, EMV_PIN_BLOCK_LEN);
00173
00174 pb[0] = 0x20 | (plen & 0xf);
00175 for(i = 0; pin[i]; i++) {
00176 if ( !isdigit(pin[i]) )
00177 return 0;
00178 if ( i & 0x1 ) {
00179 pb[1 + (i >> 1)] = (pb[1 + (i >> 1)] & 0xf0) |
00180 ((pin[i] - '0') & 0xf);
00181 }else{
00182 pb[1 + (i >> 1)] = ((pin[i] - '0') << 4) | 0xf;
00183 }
00184 }
00185
00186 return 1;
00187 }
00188
00189 const uint8_t *emv_generate_ac(emv_t e, uint8_t ref,
00190 const uint8_t *tx, uint8_t len,
00191 size_t *rlen)
00192 {
00193 if ( !_emv_generate_ac(e, ref, tx, len) )
00194 return NULL;
00195 return xfr_rx_data(e->e_xfr, rlen);
00196 }
00197
00198 static void do_emv_fini(emv_t e)
00199 {
00200 if ( e ) {
00201 RSA_free(e->e_ca_pk);
00202 RSA_free(e->e_iss_pk);
00203
00204 _emv_free_applist(e);
00205
00206 free(e->e_app);
00207
00208 mpool_free(e->e_data);
00209 gang_free(e->e_files);
00210
00211 free(e->e_afl);
00212
00213 if ( e->e_xfr )
00214 xfr_free(e->e_xfr);
00215
00216 free(e);
00217 }
00218 }
00219
00220 emv_app_t emv_current_app(emv_t e)
00221 {
00222 return e->e_app;
00223 }
00224
00225 emv_t emv_init(chipcard_t cc)
00226 {
00227 struct _emv *e;
00228
00229 if ( chipcard_status(cc) != CHIPCARD_ACTIVE )
00230 return NULL;
00231
00232 e = calloc(1, sizeof(*e));
00233 if ( e ) {
00234 e->e_dev = cc;
00235 INIT_LIST_HEAD(&e->e_apps);
00236
00237 e->e_xfr = xfr_alloc(1024, 1204);
00238 if ( NULL == e->e_xfr )
00239 goto err;
00240
00241 e->e_data = mpool_new(sizeof(struct _emv_data), 0);
00242 if ( NULL == e->e_data )
00243 goto err;
00244
00245 e->e_files = gang_new(0, 0);
00246 if ( NULL == e->e_files )
00247 goto err_free_data;
00248 }
00249
00250 return e;
00251
00252
00253
00254 err_free_data:
00255 mpool_free(e->e_data);
00256 err:
00257 do_emv_fini(e);
00258 return NULL;
00259 }
00260
00261 void emv_fini(emv_t e)
00262 {
00263 do_emv_fini(e);
00264 }