2 * libopenemv - a library to work with EMV family of smart cards
3 * Copyright (C) 2015 Dmitry Eremin-Solenikov
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
20 #include "emv_pki_priv.h"
27 struct emv_pk
*emv_pki_make_ca(const struct crypto_pk
*cp
,
28 const unsigned char *rid
, unsigned char index
,
29 unsigned int expire
, enum crypto_algo_hash hash_algo
)
31 size_t modlen
, explen
;
32 unsigned char *mod
, *exp
;
37 mod
= crypto_pk_get_parameter(cp
, 0, &modlen
);
38 exp
= crypto_pk_get_parameter(cp
, 1, &explen
);
40 if (!mod
|| !modlen
|| !exp
|| !explen
) {
47 struct emv_pk
*pk
= emv_pk_new(modlen
, explen
);
48 memcpy(pk
->rid
, rid
, 5);
51 pk
->pk_algo
= crypto_pk_get_algo(cp
);
52 pk
->hash_algo
= hash_algo
;
53 memcpy(pk
->modulus
, mod
, modlen
);
54 memcpy(pk
->exp
, exp
, explen
);
59 struct crypto_hash
*ch
= crypto_hash_open(pk
->hash_algo
);
65 crypto_hash_write(ch
, pk
->rid
, sizeof(pk
->rid
));
66 crypto_hash_write(ch
, &pk
->index
, 1);
67 crypto_hash_write(ch
, pk
->modulus
, pk
->mlen
);
68 crypto_hash_write(ch
, pk
->exp
, pk
->elen
);
70 unsigned char *h
= crypto_hash_read(ch
);
72 crypto_hash_close(ch
);
78 memcpy(pk
->hash
, h
, crypto_hash_get_size(ch
));
79 crypto_hash_close(ch
);
84 static struct tlvdb
*emv_pki_sign_message(const struct crypto_pk
*cp
,
85 tlv_tag_t cert_tag
, tlv_tag_t rem_tag
,
86 const unsigned char *msg
, size_t msg_len
,
87 ... /* A list of tlv pointers, end with NULL */
90 size_t tmp_len
= (crypto_pk_get_nbits(cp
) + 7) / 8;
91 unsigned char *tmp
= malloc(tmp_len
);
96 struct crypto_hash
*ch
= crypto_hash_open(HASH_SHA_1
);
104 tmp
[tmp_len
- 1] = 0xbc;
106 const unsigned char *rem
;
108 size_t hash_len
= crypto_hash_get_size(ch
);
109 size_t part_len
= tmp_len
- 2 - hash_len
;
110 if (part_len
< msg_len
) {
111 memcpy(tmp
+ 1, msg
, part_len
);
112 rem
= msg
+ part_len
;
113 rem_len
= msg_len
- part_len
;
115 memcpy(tmp
+ 1, msg
, msg_len
);
116 memset(tmp
+ 1 + msg_len
, 0xbb, part_len
- msg_len
);
120 crypto_hash_write(ch
, tmp
+ 1, part_len
);
121 crypto_hash_write(ch
, rem
, rem_len
);
124 va_start(vl
, msg_len
);
126 const struct tlv
*add_tlv
= va_arg(vl
, const struct tlv
*);
130 crypto_hash_write(ch
, add_tlv
->value
, add_tlv
->len
);
134 unsigned char *h
= crypto_hash_read(ch
);
136 crypto_hash_close(ch
);
142 memcpy(tmp
+ 1 + part_len
, h
, hash_len
);
143 crypto_hash_close(ch
);
146 unsigned char *cert
= crypto_pk_decrypt(cp
, tmp
, tmp_len
, &cert_len
);
152 struct tlvdb
*db
= tlvdb_fixed(cert_tag
, cert_len
, cert
);
158 struct tlvdb
*rdb
= tlvdb_fixed(rem_tag
, rem_len
, rem
);
170 static struct tlvdb
*emv_pki_sign_key(const struct crypto_pk
*cp
,
172 unsigned char msgtype
,
177 const struct tlv
*add_tlv
181 unsigned char *msg
= malloc(1 + pan_len
+ 2 + 3 + 1 + 1 + 1 + 1 + ipk
->mlen
);
186 msg
[pos
++] = msgtype
;
187 memcpy(msg
+ pos
, ipk
->pan
, pan_len
); pos
+= pan_len
;
188 msg
[pos
++] = (ipk
->expire
>> 8) & 0xff;
189 msg
[pos
++] = (ipk
->expire
>> 16) & 0xff;
190 memcpy(msg
+ pos
, ipk
->serial
, 3); pos
+= 3;
191 msg
[pos
++] = ipk
->hash_algo
;
192 msg
[pos
++] = ipk
->pk_algo
;
193 msg
[pos
++] = ipk
->mlen
;
194 msg
[pos
++] = ipk
->elen
;
195 memcpy(msg
+ pos
, ipk
->modulus
, ipk
->mlen
);
198 struct tlvdb
*exp_db
= tlvdb_fixed(exp_tag
, ipk
->elen
, ipk
->exp
);
205 struct tlvdb
*db
= emv_pki_sign_message(cp
,
208 tlvdb_get(exp_db
, exp_tag
, NULL
),
215 tlvdb_add(db
, exp_db
);
220 struct tlvdb
*emv_pki_sign_issuer_cert(const struct crypto_pk
*cp
, struct emv_pk
*issuer_pk
)
222 return emv_pki_sign_key(cp
, issuer_pk
, 2, 4, 0x90, 0x9f32, 0x92, NULL
);
225 struct tlvdb
*emv_pki_sign_icc_cert(const struct crypto_pk
*cp
, struct emv_pk
*icc_pk
, const struct tlv
*sda_tlv
)
227 return emv_pki_sign_key(cp
, icc_pk
, 4, 10, 0x9f46, 0x9f47, 0x9f48, sda_tlv
);
230 struct tlvdb
*emv_pki_sign_icc_pe_cert(const struct crypto_pk
*cp
, struct emv_pk
*icc_pe_pk
)
232 return emv_pki_sign_key(cp
, icc_pe_pk
, 4, 10, 0x9f2d, 0x9f2e, 0x9f2f, NULL
);
235 struct tlvdb
*emv_pki_sign_dac(const struct crypto_pk
*cp
, const struct tlv
*dac_tlv
, const struct tlv
*sda_tlv
)
238 unsigned char *msg
= malloc(1+1+dac_tlv
->len
);
244 msg
[pos
++] = HASH_SHA_1
;
245 memcpy(msg
+pos
, dac_tlv
->value
, dac_tlv
->len
);
248 struct tlvdb
*db
= emv_pki_sign_message(cp
,
259 struct tlvdb
*emv_pki_sign_idn(const struct crypto_pk
*cp
, const struct tlv
*idn_tlv
, const struct tlv
*dyn_tlv
)
262 unsigned char *msg
= malloc(1+1+1+1+idn_tlv
->len
);
268 msg
[pos
++] = HASH_SHA_1
;
269 msg
[pos
++] = idn_tlv
->len
+ 1;
270 msg
[pos
++] = idn_tlv
->len
;
271 memcpy(msg
+pos
, idn_tlv
->value
, idn_tlv
->len
);
274 struct tlvdb
*db
= emv_pki_sign_message(cp
,