Home | History | Annotate | Line # | Download | only in src
      1 /*
      2  * Copyright (c) 2018 Yubico AB. All rights reserved.
      3  * Use of this source code is governed by a BSD-style
      4  * license that can be found in the LICENSE file.
      5  * SPDX-License-Identifier: BSD-2-Clause
      6  */
      7 
      8 #include "fido.h"
      9 
     10 iso7816_apdu_t *
     11 iso7816_new(uint8_t cla, uint8_t ins, uint8_t p1, uint16_t payload_len)
     12 {
     13 	iso7816_apdu_t *apdu;
     14 	size_t alloc_len;
     15 
     16 	alloc_len = sizeof(iso7816_apdu_t) + payload_len + 2; /* le1 le2 */
     17 	if ((apdu = calloc(1, alloc_len)) == NULL)
     18 		return NULL;
     19 	apdu->alloc_len = alloc_len;
     20 	apdu->payload_len = payload_len;
     21 	apdu->payload_ptr = apdu->payload;
     22 	apdu->header.cla = cla;
     23 	apdu->header.ins = ins;
     24 	apdu->header.p1 = p1;
     25 	apdu->header.lc2 = (uint8_t)((payload_len >> 8) & 0xff);
     26 	apdu->header.lc3 = (uint8_t)(payload_len & 0xff);
     27 
     28 	return apdu;
     29 }
     30 
     31 void
     32 iso7816_free(iso7816_apdu_t **apdu_p)
     33 {
     34 	iso7816_apdu_t *apdu;
     35 
     36 	if (apdu_p == NULL || (apdu = *apdu_p) == NULL)
     37 		return;
     38 	freezero(apdu, apdu->alloc_len);
     39 	*apdu_p = NULL;
     40 }
     41 
     42 int
     43 iso7816_add(iso7816_apdu_t *apdu, const void *buf, size_t cnt)
     44 {
     45 	if (cnt > apdu->payload_len || cnt > UINT16_MAX)
     46 		return -1;
     47 	memcpy(apdu->payload_ptr, buf, cnt);
     48 	apdu->payload_ptr += cnt;
     49 	apdu->payload_len = (uint16_t)(apdu->payload_len - cnt);
     50 
     51 	return 0;
     52 }
     53 
     54 const unsigned char *
     55 iso7816_ptr(const iso7816_apdu_t *apdu)
     56 {
     57 	return (const unsigned char *)&apdu->header;
     58 }
     59 
     60 size_t
     61 iso7816_len(const iso7816_apdu_t *apdu)
     62 {
     63 	return apdu->alloc_len - offsetof(iso7816_apdu_t, header) -
     64 	    (sizeof(iso7816_apdu_t) - offsetof(iso7816_apdu_t, payload));
     65 }
     66