Branch data Line data Source code
1 : : /*
2 : : * defines the entry point for the Global Plarform Applet emulation. Only used
3 : : * by vcard_emul_type.c
4 : : *
5 : : * Copyright 2018 Red Hat, Inc.
6 : : *
7 : : * Author: Jakub Jelen <jjelen@redhat.com>
8 : : *
9 : : * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
10 : : * See the COPYING file in the top-level directory.
11 : : */
12 : :
13 : : #include <glib.h>
14 : :
15 : : #include <string.h>
16 : : #include <stdio.h>
17 : : #include <stdbool.h>
18 : :
19 : : #include "gp.h"
20 : : #include "vcard.h"
21 : : #include "vcard_emul.h"
22 : : #include "card_7816.h"
23 : :
24 : : static unsigned char gp_container_aid[] = {
25 : : 0xa0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00 };
26 : :
27 : : /* CPLC (card production life cycle) data
28 : : * from: https://sourceforge.net/p/globalplatform/wiki/GPShell/
29 : : */
30 : : static unsigned char cplp_data[] = {
31 : : 0x9F, 0x7F, 0x2A, /* Tag, length */
32 : : 0x00, 0x05, /* IC Fabricator */
33 : : 0x00, 0x45, /* IC Type */
34 : : 0xD0, 0x01, /* Operating System ID */
35 : : 0x40, 0x21, /* Operating System release date 21. 1. 2014 */
36 : : 0x01, 0x01, /* Operating System release level */
37 : : 0x07, 0x4F, /* IC Fabrication Date ??? */
38 : : /* The following 6 bytes are filled by unique hash from certificates */
39 : : 0x00, 0x00, 0x00, 0x00, /* IC Serial Number */
40 : : 0x00, 0x00, /* IC Batch Identifier */
41 : : 0x47, 0x92, /* IC Module Fabricator */
42 : : 0x72, 0x05, /* IC Module Packaging Date 205th day of 2017 */
43 : : 0x16, 0x73, /* ICC Manufacturer */
44 : : 0x72, 0x05, /* IC Embedding Date 205th day of 2017 */
45 : : 0x16, 0x74, /* IC Pre-Personalizer */
46 : : 0x72, 0x05, /* IC Pre-Perso. Equipment Date 205th day of 2017 */
47 : : 0x00, 0x00, 0x0A, 0x40, /* IC Pre-Perso. Equipment ID */
48 : : 0x00, 0x00, /* IC Personalizer */
49 : : 0x00, 0x00, /* IC Personalization Date */
50 : : 0x00, 0x09, 0x29, 0xBB, /* IC Perso. Equipment ID */
51 : : };
52 : :
53 : : /* Card Recognition Data returned for Get Data Instruction */
54 : : static unsigned char card_recognition_data[] = {
55 : : 0x66, 0x31, /* Card Data tag, length */
56 : : 0x73, 0x2F, /* OID for Card Recognition Data */
57 : : 0x06, 0x07, 0x2A, 0x86, 0x48, 0x86, 0xFC, 0x6B, 0x01,
58 : : 0x60, 0x0C, /* OID for Card Management Type and Version */
59 : : 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86, 0xFC, 0x6B, 0x02, 0x02, 0x02, 0x01,
60 : : 0x63, 0x09, /* OID for Card Identification Scheme */
61 : : 0x06, 0x07, 0x2A, 0x86, 0x48, 0x86, 0xFC, 0x6B, 0x03,
62 : : 0x64, 0x0B, /* OID for Secure Channel Protocol of the Issuer Security Domain and its implementation options */
63 : : 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xFC, 0x6B, 0x04, 0x03, 0x10,
64 : : };
65 : :
66 : : static VCardStatus
67 : 8 : gp_applet_container_process_apdu(VCard *card, VCardAPDU *apdu,
68 : : VCardResponse **response)
69 : : {
70 : : VCardStatus ret = VCARD_FAIL;
71 : : unsigned int tag;
72 : :
73 [ + + ]: 8 : switch (apdu->a_ins) {
74 : 3 : case GP_GET_DATA:
75 : : /* GET DATA instruction for tags:
76 : : * P1|P2: 00 66 (len = 4E):
77 : : * P1|P2: 9F 7F (len = 2D):
78 : : */
79 : 3 : tag = (apdu->a_p1 & 0xff) << 8 | (apdu->a_p2 & 0xff);
80 [ + - ]: 3 : if (tag == 0x9f7f) {
81 : 3 : int len = 0;
82 : 3 : unsigned char *serial = vcard_get_serial(card, &len);
83 : : /* Some of the fields should not be static and should identify
84 : : * unique card (usually for caching and speedup in drivers).
85 : : * One of these fields we can use is IC Serial (4B)
86 : : * and IC Batch (2B). We could use more, but this should ge good
87 : : * enough for distinguishing few cards */
88 [ + - ]: 3 : if (len > 0) {
89 : 3 : memcpy(cplp_data + 15, serial, 6);
90 : : }
91 : :
92 : 3 : *response = vcard_response_new(card, cplp_data,
93 : : sizeof(cplp_data), apdu->a_Le, VCARD7816_STATUS_SUCCESS);
94 : : ret = VCARD_DONE;
95 : : break;
96 [ # # ]: 0 : } else if (tag == 0x0066) {
97 : 0 : *response = vcard_response_new(card, card_recognition_data,
98 : : sizeof(card_recognition_data), apdu->a_Le, VCARD7816_STATUS_SUCCESS);
99 : : ret = VCARD_DONE;
100 : 0 : break;
101 : : }
102 : 0 : *response = vcard_make_response(VCARD7816_STATUS_ERROR_DATA_NOT_FOUND);
103 : : ret = VCARD_DONE;
104 : 0 : break;
105 : :
106 : : default:
107 : : /* Let the ISO 7816 code to handle other APDUs */
108 : : ret = VCARD_NEXT;
109 : : break;
110 : : }
111 : 8 : return ret;
112 : : }
113 : :
114 : :
115 : : /*
116 : : * Initialize the gp applet. This is the only public function in this file. All
117 : : * the rest are connected through function pointers.
118 : : */
119 : : VCardStatus
120 : 5 : gp_card_init(G_GNUC_UNUSED VReader *reader, VCard *card)
121 : : {
122 : : VCardApplet *applet;
123 : :
124 : : /* create Card Manager container */
125 : 5 : applet = vcard_new_applet(gp_applet_container_process_apdu,
126 : : NULL, gp_container_aid,
127 : : sizeof(gp_container_aid));
128 [ - + ]: 5 : if (applet == NULL) {
129 : 0 : goto failure;
130 : : }
131 : 5 : vcard_add_applet(card, applet);
132 : :
133 : 5 : return VCARD_DONE;
134 : :
135 : : failure:
136 : 0 : return VCARD_FAIL;
137 : : }
138 : :
139 : : /* vim: set ts=4 sw=4 tw=0 noet expandtab: */
|