Coverage Report

Created: 2025-10-10 06:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/cwa-dnie.c
Line
Count
Source
1
/**
2
 * cwa-dnie.c: DNIe data provider for CWA SM handling.
3
 *
4
 * Copyright (C) 2010 Juan Antonio Martinez <jonsito@terra.es>
5
 *
6
 * This work is derived from many sources at OpenSC Project site,
7
 * (see references) and the information made public by Spanish
8
 * Direccion General de la Policia y de la Guardia Civil
9
 *
10
 * This library is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU Lesser General Public
12
 * License as published by the Free Software Foundation; either
13
 * version 2.1 of the License, or (at your option) any later version.
14
 *
15
 * This library is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public
21
 * License along with this library; if not, write to the Free Software
22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
 */
24
25
#define __SM_DNIE_C__
26
#ifdef HAVE_CONFIG_H
27
#include "config.h"
28
#endif
29
30
#if defined(ENABLE_OPENSSL) && defined(ENABLE_SM) /* empty file without openssl or sm */
31
32
#include <stdlib.h>
33
#include <string.h>
34
35
#include "opensc.h"
36
#include "cardctl.h"
37
#include "internal.h"
38
#include "cwa14890.h"
39
40
#include "cwa-dnie.h"
41
42
#include <openssl/ossl_typ.h>
43
#include <openssl/bn.h>
44
#include <openssl/x509.h>
45
#include <openssl/evp.h>
46
#include <openssl/rsa.h>
47
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
48
# include <openssl/core_names.h>
49
# include <openssl/param_build.h>
50
#endif
51
52
#define MAX_RESP_BUFFER_SIZE 2048
53
54
/********************* Keys and certificates as published by DGP ********/
55
56
/**
57
 * Public Key modulus for the ROOT CA for DNIe (pk-RCAicc->n)
58
 */
59
static u8 icc_root_ca_modulus_0[] = {
60
  0xEA, 0xDE, 0xDA, 0x45, 0x53, 0x32, 0x94, 0x50, 0x39, 0xDA, 0xA4, 0x04,
61
  0xC8, 0xEB, 0xC4, 0xD3, 0xB7, 0xF5, 0xDC, 0x86, 0x92, 0x83, 0xCD, 0xEA,
62
  0x2F, 0x10, 0x1E, 0x2A, 0xB5, 0x4F, 0xB0, 0xD0, 0xB0, 0x3D, 0x8F, 0x03,
63
  0x0D, 0xAF, 0x24, 0x58, 0x02, 0x82, 0x88, 0xF5, 0x4C, 0xE5, 0x52, 0xF8,
64
  0xFA, 0x57, 0xAB, 0x2F, 0xB1, 0x03, 0xB1, 0x12, 0x42, 0x7E, 0x11, 0x13,
65
  0x1D, 0x1D, 0x27, 0xE1, 0x0A, 0x5B, 0x50, 0x0E, 0xAA, 0xE5, 0xD9, 0x40,
66
  0x30, 0x1E, 0x30, 0xEB, 0x26, 0xC3, 0xE9, 0x06, 0x6B, 0x25, 0x71, 0x56,
67
  0xED, 0x63, 0x9D, 0x70, 0xCC, 0xC0, 0x90, 0xB8, 0x63, 0xAF, 0xBB, 0x3B,
68
  0xFE, 0xD8, 0xC1, 0x7B, 0xE7, 0x67, 0x30, 0x34, 0xB9, 0x82, 0x3E, 0x97,
69
  0x7E, 0xD6, 0x57, 0x25, 0x29, 0x27, 0xF9, 0x57, 0x5B, 0x9F, 0xFF, 0x66,
70
  0x91, 0xDB, 0x64, 0xF8, 0x0B, 0x5E, 0x92, 0xCD
71
};
72
73
static u8 icc_root_ca_modulus_1[] = {
74
        0xb9, 0x72, 0x34, 0x5e, 0x35, 0xbc, 0xdd, 0x12, 0xdc, 0x2c, 0x8e, 0x85,
75
        0xf6, 0x22, 0x97, 0x97, 0x9f, 0x12, 0x2b, 0xb7, 0xc9, 0xc3, 0xed, 0x13,
76
        0xa0, 0xc4, 0xeb, 0x59, 0x34, 0xe7, 0x0c, 0xd6, 0xd0, 0x0c, 0x54, 0x06,
77
        0x18, 0x38, 0x6e, 0x42, 0xf2, 0xba, 0x00, 0x89, 0xc0, 0xdd, 0x80, 0x0e,
78
        0xba, 0x78, 0x3b, 0xdc, 0x9d, 0x93, 0xd9, 0xfb, 0xfc, 0x3c, 0x16, 0x9f,
79
        0x9a, 0xf6, 0x4e, 0x80, 0x10, 0x0f, 0xc6, 0x87, 0xcc, 0xa5, 0x62, 0xe7,
80
        0xfc, 0x84, 0xd1, 0x12, 0x92, 0xc2, 0x40, 0x4c, 0x59, 0xb8, 0xa8, 0x60,
81
        0xd3, 0x9e, 0x2d, 0x66, 0x54, 0x7d, 0xc7, 0xb2, 0xd4, 0x8c, 0xa7, 0x89,
82
        0x81, 0x4f, 0x43, 0x06, 0x26, 0x34, 0xe3, 0xe0, 0xc0, 0xd6, 0xbf, 0x5f,
83
        0x54, 0xba, 0x1d, 0x9c, 0x46, 0x64, 0x45, 0x83, 0x1d, 0xcd, 0xea, 0xb0,
84
        0x87, 0x08, 0xf3, 0xf6, 0x22, 0x0e, 0x07, 0x75
85
};
86
87
/**
88
 * Exponente de la clave publica de la Root CA del DNI electronico (pk-RCAicc->e)
89
 */
90
static u8 icc_root_ca_public_exponent[] = {
91
  0x01, 0x00, 0x01
92
};
93
94
/**
95
 * Terminal (IFD) key modulus for SM channel creation (dnieRealParam->sk-IFD-AUT->n)
96
 */
97
static u8 ifd_modulus_0[] = {
98
  0xdb, 0x2c, 0xb4, 0x1e, 0x11, 0x2b, 0xac, 0xfa, 0x2b, 0xd7, 0xc3, 0xd3,
99
  0xd7, 0x96, 0x7e, 0x84, 0xfb, 0x94, 0x34, 0xfc, 0x26, 0x1f, 0x9d, 0x09,
100
  0x0a, 0x89, 0x83, 0x94, 0x7d, 0xaf, 0x84, 0x88, 0xd3, 0xdf, 0x8f, 0xbd,
101
  0xcc, 0x1f, 0x92, 0x49, 0x35, 0x85, 0xe1, 0x34, 0xa1, 0xb4, 0x2d, 0xe5,
102
  0x19, 0xf4, 0x63, 0x24, 0x4d, 0x7e, 0xd3, 0x84, 0xe2, 0x6d, 0x51, 0x6c,
103
  0xc7, 0xa4, 0xff, 0x78, 0x95, 0xb1, 0x99, 0x21, 0x40, 0x04, 0x3a, 0xac,
104
  0xad, 0xfc, 0x12, 0xe8, 0x56, 0xb2, 0x02, 0x34, 0x6a, 0xf8, 0x22, 0x6b,
105
  0x1a, 0x88, 0x21, 0x37, 0xdc, 0x3c, 0x5a, 0x57, 0xf0, 0xd2, 0x81, 0x5c,
106
  0x1f, 0xcd, 0x4b, 0xb4, 0x6f, 0xa9, 0x15, 0x7f, 0xdf, 0xfd, 0x79, 0xec,
107
  0x3a, 0x10, 0xa8, 0x24, 0xcc, 0xc1, 0xeb, 0x3c, 0xe0, 0xb6, 0xb4, 0x39,
108
  0x6a, 0xe2, 0x36, 0x59, 0x00, 0x16, 0xba, 0x69
109
};
110
111
static u8 ifd_modulus_1[] = {
112
        0xbd, 0xef, 0xdb, 0x84, 0xec, 0xe6, 0x98, 0xb8, 0x28, 0x7f, 0x7f, 0xe6,
113
        0x29, 0x6d, 0x80, 0x72, 0x98, 0x3a, 0x1b, 0x3d, 0x3b, 0x9f, 0x57, 0xad,
114
        0x98, 0x4f, 0xba, 0x78, 0x58, 0x1f, 0xff, 0x52, 0xe9, 0x3d, 0x89, 0x6b,
115
        0xf5, 0x62, 0x25, 0xe9, 0xf8, 0x2e, 0x96, 0x95, 0x14, 0x00, 0x69, 0x98,
116
        0x2e, 0x5b, 0x5b, 0xce, 0x37, 0xad, 0x73, 0x16, 0x45, 0x02, 0xd8, 0xac,
117
        0xbd, 0x60, 0x5f, 0x69, 0x12, 0x4a, 0x3c, 0xf5, 0xaf, 0xe4, 0xb0, 0x18,
118
        0x60, 0x2d, 0xd4, 0xba, 0x04, 0xdb, 0xc9, 0x85, 0x88, 0x45, 0xe6, 0xa9,
119
        0xc4, 0x05, 0x5b, 0xc5, 0xbf, 0xa0, 0xed, 0xdb, 0x86, 0x67, 0x89, 0xf0,
120
        0xec, 0x6a, 0x80, 0xfc, 0xe5, 0x3c, 0x66, 0x08, 0xdf, 0xdc, 0x9b, 0x9f,
121
        0xe2, 0xed, 0x56, 0x75, 0x2c, 0xc6, 0x05, 0x51, 0x3b, 0xa3, 0xf1, 0x75,
122
        0x9c, 0xdd, 0x95, 0x22, 0x75, 0x3f, 0x18, 0xd7
123
};
124
125
/**
126
 * Terminal (IFD) key modulus for SM channel creation for PIN channel DNIe 3.0 (dnie30RealParamPIN->sk-IFD-AUT->n)
127
 */
128
static u8 ifd_pin_modulus_0[] = {
129
  0xF4, 0x27, 0x97, 0x8D, 0xA1, 0x59, 0xBA, 0x02, 0x79, 0x30, 0x8A, 0x6C,
130
  0x6A, 0x89, 0x50, 0x5A, 0xDA, 0x5A, 0x67, 0xC3, 0xDA, 0x26, 0x79, 0xEA,
131
  0xF4, 0xA1, 0xB0, 0x11, 0x9E, 0xDD, 0x4D, 0xF4, 0x6E, 0x78, 0x04, 0x24,
132
  0x71, 0xA9, 0xD1, 0x30, 0x1D, 0x3F, 0xB2, 0x8F, 0x38, 0xC5, 0x7D, 0x08,
133
  0x89, 0xF7, 0x31, 0xDB, 0x8E, 0xDD, 0xBC, 0x13, 0x67, 0xC1, 0x34, 0xE1,
134
  0xE9, 0x47, 0x78, 0x6B, 0x8E, 0xC8, 0xE4, 0xB9, 0xCA, 0x6A, 0xA7, 0xC2,
135
  0x4C, 0x86, 0x91, 0xC7, 0xBE, 0x2F, 0xD8, 0xC1, 0x23, 0x66, 0x0E, 0x98,
136
  0x65, 0xE1, 0x4F, 0x19, 0xDF, 0xFB, 0xB7, 0xFF, 0x38, 0x08, 0xC9, 0xF2,
137
  0x04, 0xE7, 0x97, 0xD0, 0x6D, 0xD8, 0x33, 0x3A, 0xC5, 0x83, 0x86, 0xEE,
138
  0x4E, 0xB6, 0x1E, 0x20, 0xEC, 0xA7, 0xEF, 0x38, 0xD5, 0xB0, 0x5E, 0xB1,
139
  0x15, 0x96, 0x6A, 0x5A, 0x89, 0xAD, 0x58, 0xA5
140
};
141
142
static u8 ifd_pin_modulus_1[] = {
143
        0xdf, 0x03, 0x93, 0x0d, 0x4f, 0x1d, 0x97, 0x15, 0xeb, 0xb0, 0x0f, 0xbd,
144
        0xae, 0x48, 0xaf, 0x9c, 0x9d, 0xbf, 0xd6, 0x99, 0xca, 0xb0, 0xbd, 0xbe,
145
        0x5c, 0xdb, 0x01, 0x34, 0x00, 0x0e, 0x46, 0x2e, 0x71, 0x3a, 0xe9, 0x7a,
146
        0x2f, 0x7e, 0x20, 0xaf, 0xbf, 0x84, 0xd3, 0xce, 0x73, 0x4f, 0xe2, 0x15,
147
        0x75, 0x7a, 0xaf, 0xa1, 0xe8, 0x9e, 0x64, 0x57, 0xea, 0xe2, 0xe8, 0x08,
148
        0x11, 0x03, 0x73, 0xe2, 0x56, 0x56, 0x34, 0x94, 0xfb, 0x5d, 0x10, 0x4f,
149
        0x0d, 0xcc, 0x88, 0x8d, 0x47, 0x96, 0x54, 0x3f, 0x03, 0x25, 0x4f, 0x4e,
150
        0x2c, 0xdf, 0x98, 0xb1, 0xe1, 0x26, 0x11, 0xe3, 0x98, 0x1f, 0x53, 0x33,
151
        0xdf, 0x98, 0xc8, 0x86, 0x01, 0x93, 0x75, 0x84, 0x0f, 0xac, 0x61, 0xdb,
152
        0x8f, 0x1b, 0xa3, 0xb5, 0x43, 0xdc, 0xea, 0x3d, 0x05, 0x9e, 0x6a, 0x41,
153
        0x4f, 0x6d, 0xd2, 0x9f, 0xc7, 0xc9, 0x9d, 0x8b
154
};
155
156
/**
157
 * Terminal (IFD) public exponent for SM channel creation
158
 */
159
static u8 ifd_public_exponent[] = {
160
  0x01, 0x00, 0x01
161
};
162
163
/**
164
 * Terminal (IFD) public exponent for SM channel creation for PIN channel DNIe 3.0
165
 */
166
static u8 ifd_pin_public_exponent[] = {
167
  0x01, 0x00, 0x01
168
};
169
170
/**
171
 * Terminal (IFD) private exponent for SM channel establishment (dnieRealParam->sk-IFD-AUT->d)
172
 */
173
static u8 ifd_private_exponent_0[] = {
174
  0x18, 0xb4, 0x4a, 0x3d, 0x15, 0x5c, 0x61, 0xeb, 0xf4, 0xe3, 0x26, 0x1c,
175
  0x8b, 0xb1, 0x57, 0xe3, 0x6f, 0x63, 0xfe, 0x30, 0xe9, 0xaf, 0x28, 0x89,
176
  0x2b, 0x59, 0xe2, 0xad, 0xeb, 0x18, 0xcc, 0x8c, 0x8b, 0xad, 0x28, 0x4b,
177
  0x91, 0x65, 0x81, 0x9c, 0xa4, 0xde, 0xc9, 0x4a, 0xa0, 0x6b, 0x69, 0xbc,
178
  0xe8, 0x17, 0x06, 0xd1, 0xc1, 0xb6, 0x68, 0xeb, 0x12, 0x86, 0x95, 0xe5,
179
  0xf7, 0xfe, 0xde, 0x18, 0xa9, 0x08, 0xa3, 0x01, 0x1a, 0x64, 0x6a, 0x48,
180
  0x1d, 0x3e, 0xa7, 0x1d, 0x8a, 0x38, 0x7d, 0x47, 0x46, 0x09, 0xbd, 0x57,
181
  0xa8, 0x82, 0xb1, 0x82, 0xe0, 0x47, 0xde, 0x80, 0xe0, 0x4b, 0x42, 0x21,
182
  0x41, 0x6b, 0xd3, 0x9d, 0xfa, 0x1f, 0xac, 0x03, 0x00, 0x64, 0x19, 0x62,
183
  0xad, 0xb1, 0x09, 0xe2, 0x8c, 0xaf, 0x50, 0x06, 0x1b, 0x68, 0xc9, 0xca,
184
  0xbd, 0x9b, 0x00, 0x31, 0x3c, 0x0f, 0x46, 0xed
185
};
186
187
static u8 ifd_private_exponent_1[] = {
188
        0xa0, 0x51, 0x55, 0x93, 0xd4, 0x36, 0x2b, 0x8f, 0xbd, 0xb7, 0x28, 0xa8,
189
        0x88, 0x2d, 0x42, 0x2e, 0xf7, 0xa8, 0x8c, 0x17, 0x5a, 0x3c, 0xfb, 0xcf,
190
        0xad, 0xf1, 0x15, 0xee, 0xc0, 0x4b, 0x79, 0xc2, 0x6c, 0xd6, 0xa1, 0x28,
191
        0xbb, 0xbd, 0x35, 0x4d, 0x50, 0x4b, 0x5a, 0x94, 0xc8, 0x86, 0x34, 0x9a,
192
        0xdb, 0xfe, 0x06, 0xf6, 0x7f, 0xee, 0x6a, 0x66, 0xd0, 0xa7, 0x3f, 0x66,
193
        0x46, 0x8e, 0x92, 0xd8, 0x73, 0xb6, 0x8e, 0xe2, 0xcb, 0x47, 0xb1, 0xa1,
194
        0x5a, 0x2a, 0xa7, 0xd8, 0xc6, 0xce, 0x8f, 0x3f, 0x14, 0x93, 0x0d, 0x56,
195
        0xb6, 0x32, 0x7f, 0x56, 0xcb, 0x21, 0x54, 0x69, 0xa5, 0x7a, 0x1e, 0xe0,
196
        0x18, 0x8f, 0xd6, 0xd2, 0x6d, 0x83, 0xa3, 0x80, 0xa6, 0xab, 0xd3, 0xa8,
197
        0x9f, 0x1b, 0x63, 0xc4, 0x99, 0x81, 0x90, 0x46, 0x53, 0x69, 0x35, 0xad,
198
        0xb2, 0xdb, 0x3c, 0x17, 0xcc, 0xbd, 0xaa, 0x51
199
};
200
201
/**
202
 * Terminal (IFD) private exponent for SM channel establishment for PIN channel DNIe 3.0 (dnie30RealParamDataPIN->sk-IFD-AUT->d)
203
 */
204
static u8 ifd_pin_private_exponent_0[] = {
205
  0xD2, 0x7A, 0x03, 0x23, 0x7C, 0x72, 0x2E, 0x71, 0x8D, 0x69, 0xF4, 0x1A,
206
  0xEC, 0x68, 0xBD, 0x95, 0xE4, 0xE0, 0xC4, 0xCD, 0x49, 0x15, 0x9C, 0x4A,
207
  0x99, 0x63, 0x7D, 0xB6, 0x62, 0xFE, 0xA3, 0x02, 0x51, 0xED, 0x32, 0x9C,
208
  0xFC, 0x43, 0x89, 0xEB, 0x71, 0x7B, 0x85, 0x02, 0x04, 0xCD, 0xF3, 0x30,
209
  0xD6, 0x46, 0xFC, 0x7B, 0x2B, 0x19, 0x29, 0xD6, 0x8C, 0xBE, 0x39, 0x49,
210
  0x7B, 0x62, 0x3A, 0x82, 0xC7, 0x64, 0x1A, 0xC3, 0x48, 0x79, 0x57, 0x3D,
211
  0xEA, 0x0D, 0xAB, 0xC7, 0xCA, 0x30, 0x9A, 0xE4, 0xB3, 0xED, 0xDA, 0xFA,
212
  0xEE, 0x55, 0xD5, 0x42, 0xF7, 0x80, 0x23, 0x03, 0x51, 0xE7, 0x5E, 0x7F,
213
  0x32, 0xDC, 0x65, 0x2E, 0xF1, 0xED, 0x47, 0xA5, 0x1C, 0x18, 0xD9, 0xDF,
214
  0x9F, 0xF4, 0x8D, 0x87, 0x8D, 0xB6, 0x22, 0xEA, 0x6E, 0x93, 0x70, 0xE9,
215
  0xC6, 0x3B, 0x35, 0x8B, 0x7C, 0x11, 0x5A, 0xA1
216
};
217
218
static u8 ifd_pin_private_exponent_1[] = {
219
        0x86, 0x6f, 0x0f, 0x2c, 0x0c, 0xaf, 0x17, 0xae, 0x7d, 0x1e, 0xea, 0xbe,
220
        0x3a, 0xdb, 0x52, 0x11, 0x24, 0xfe, 0xc9, 0x8c, 0x77, 0xa4, 0xc7, 0x1c,
221
        0x83, 0xb8, 0xf9, 0x26, 0xb1, 0x89, 0xe9, 0x40, 0x81, 0xbd, 0x33, 0x95,
222
        0x16, 0x1f, 0xff, 0xf0, 0x31, 0x91, 0x0e, 0x64, 0xfb, 0x1a, 0x02, 0x7d,
223
        0x51, 0x0e, 0x1d, 0xe5, 0x89, 0xe6, 0x41, 0x32, 0xc6, 0x42, 0xf6, 0x00,
224
        0x36, 0xd1, 0x4f, 0xfe, 0xd5, 0xd0, 0xce, 0x1f, 0x45, 0xe7, 0x11, 0x6f,
225
        0x13, 0xc4, 0xe6, 0x38, 0x8e, 0x25, 0xdd, 0x43, 0x83, 0x57, 0x78, 0x05,
226
        0x85, 0x73, 0xdc, 0x29, 0xad, 0x6a, 0x37, 0x32, 0x71, 0x6d, 0x08, 0x11,
227
        0x24, 0xb7, 0x52, 0x51, 0x40, 0xb1, 0xdd, 0xab, 0xe2, 0x51, 0xa4, 0x98,
228
        0x0c, 0xc5, 0xc0, 0x3a, 0x86, 0xa8, 0x2d, 0x17, 0x4f, 0xb7, 0xa8, 0x1d,
229
        0x24, 0x8d, 0x7c, 0xaa, 0x2b, 0x3d, 0x61, 0xd1
230
};
231
232
/**
233
 *  Intermediate CA certificate in CVC format (Card verifiable certificate) (c-CV-CA-CS-AUT)
234
 */
235
static u8 C_CV_CA_CS_AUT_cert_0[] = {
236
  0x7f, 0x21, 0x81, 0xce, 0x5f, 0x37, 0x81, 0x80, 0x3c, 0xba, 0xdc, 0x36,
237
  0x84, 0xbe, 0xf3, 0x20, 0x41, 0xad, 0x15, 0x50, 0x89, 0x25, 0x8d, 0xfd,
238
  0x20, 0xc6, 0x91, 0x15, 0xd7, 0x2f, 0x9c, 0x38, 0xaa, 0x99, 0xad, 0x6c,
239
  0x1a, 0xed, 0xfa, 0xb2, 0xbf, 0xac, 0x90, 0x92, 0xfc, 0x70, 0xcc, 0xc0,
240
  0x0c, 0xaf, 0x48, 0x2a, 0x4b, 0xe3, 0x1a, 0xfd, 0xbd, 0x3c, 0xbc, 0x8c,
241
  0x83, 0x82, 0xcf, 0x06, 0xbc, 0x07, 0x19, 0xba, 0xab, 0xb5, 0x6b, 0x6e,
242
  0xc8, 0x07, 0x60, 0xa4, 0xa9, 0x3f, 0xa2, 0xd7, 0xc3, 0x47, 0xf3, 0x44,
243
  0x27, 0xf9, 0xff, 0x5c, 0x8d, 0xe6, 0xd6, 0x5d, 0xac, 0x95, 0xf2, 0xf1,
244
  0x9d, 0xac, 0x00, 0x53, 0xdf, 0x11, 0xa5, 0x07, 0xfb, 0x62, 0x5e, 0xeb,
245
  0x8d, 0xa4, 0xc0, 0x29, 0x9e, 0x4a, 0x21, 0x12, 0xab, 0x70, 0x47, 0x58,
246
  0x8b, 0x8d, 0x6d, 0xa7, 0x59, 0x22, 0x14, 0xf2, 0xdb, 0xa1, 0x40, 0xc7,
247
  0xd1, 0x22, 0x57, 0x9b, 0x5f, 0x38, 0x3d, 0x22, 0x53, 0xc8, 0xb9, 0xcb,
248
  0x5b, 0xc3, 0x54, 0x3a, 0x55, 0x66, 0x0b, 0xda, 0x80, 0x94, 0x6a, 0xfb,
249
  0x05, 0x25, 0xe8, 0xe5, 0x58, 0x6b, 0x4e, 0x63, 0xe8, 0x92, 0x41, 0x49,
250
  0x78, 0x36, 0xd8, 0xd3, 0xab, 0x08, 0x8c, 0xd4, 0x4c, 0x21, 0x4d, 0x6a,
251
  0xc8, 0x56, 0xe2, 0xa0, 0x07, 0xf4, 0x4f, 0x83, 0x74, 0x33, 0x37, 0x37,
252
  0x1a, 0xdd, 0x8e, 0x03, 0x00, 0x01, 0x00, 0x01, 0x42, 0x08, 0x65, 0x73,
253
  0x52, 0x44, 0x49, 0x60, 0x00, 0x06
254
};
255
256
static u8 C_CV_CA_CS_AUT_cert_1[] = {
257
        0x7f, 0x21, 0x81, 0xce, 0x5f, 0x37, 0x81, 0x80, 0x7a, 0xa0, 0x6c, 0x96,
258
        0x5e, 0x8f, 0xb2, 0x19, 0x61, 0xcf, 0xd4, 0x49, 0xd0, 0x9b, 0x9d, 0xaf,
259
        0x03, 0x04, 0x73, 0x01, 0x15, 0x69, 0x70, 0xb7, 0x73, 0xf1, 0x9c, 0x40,
260
        0xf1, 0x27, 0xd3, 0x38, 0xe3, 0xc1, 0x35, 0xeb, 0x21, 0x20, 0x56, 0x6d,
261
        0xc6, 0xf9, 0xf7, 0x45, 0xff, 0xb8, 0xf8, 0xe2, 0xb6, 0x1e, 0xe8, 0x16,
262
        0x6f, 0xfd, 0x06, 0xd2, 0x8c, 0xb4, 0x8c, 0x15, 0x2a, 0x1f, 0xa4, 0xf7,
263
        0xe9, 0xf6, 0x09, 0xd7, 0x52, 0x76, 0x33, 0x1c, 0xb7, 0x00, 0xb8, 0x4e,
264
        0x36, 0xac, 0x8a, 0x0a, 0x77, 0x74, 0x46, 0x8c, 0x3c, 0xf3, 0xd1, 0x47,
265
        0xa4, 0x9c, 0x97, 0x6e, 0x17, 0xab, 0x02, 0xda, 0x03, 0xea, 0x4a, 0xc1,
266
        0x51, 0x77, 0x7e, 0xdf, 0xbc, 0x35, 0xc2, 0x7d, 0x56, 0xfb, 0xa6, 0x85,
267
        0x75, 0x6e, 0xd6, 0x52, 0x85, 0x1d, 0xfd, 0xe7, 0x01, 0xbf, 0x87, 0x49,
268
        0x92, 0xdd, 0x4d, 0xe8, 0x5f, 0x38, 0x3d, 0x33, 0xe3, 0xd5, 0x2a, 0x4b,
269
        0x09, 0x40, 0xe3, 0x90, 0xcd, 0x1a, 0x64, 0x1f, 0xea, 0x2e, 0x9c, 0xdd,
270
        0x79, 0xd3, 0x87, 0x2d, 0xd6, 0xc5, 0x08, 0xd5, 0xef, 0x23, 0x9c, 0xb0,
271
        0x7e, 0xb5, 0x55, 0x68, 0xce, 0x18, 0x8b, 0x65, 0x13, 0xac, 0xb8, 0x84,
272
        0x14, 0xc9, 0xad, 0xf7, 0xa6, 0x4e, 0x2c, 0xc0, 0xb3, 0x14, 0xd1, 0x27,
273
        0x54, 0xae, 0xee, 0x67, 0x00, 0x01, 0x00, 0x01, 0x42, 0x08, 0x65, 0x73,
274
        0x52, 0x44, 0x49, 0x62, 0x00, 0x18
275
};
276
277
/**
278
 * Terminal (IFD) certificate in CVC format (PK.IFD.AUT) (dnieRealParamData->c-CV-IFD-AUT)
279
 */
280
static u8 C_CV_IFDUser_AUT_cert_0[] = {
281
  0x7f, 0x21, 0x81, 0xcd, 0x5f, 0x37, 0x81, 0x80, 0x82, 0x5b, 0x69, 0xc6,
282
  0x45, 0x1e, 0x5f, 0x51, 0x70, 0x74, 0x38, 0x5f, 0x2f, 0x17, 0xd6, 0x4d,
283
  0xfe, 0x2e, 0x68, 0x56, 0x75, 0x67, 0x09, 0x4b, 0x57, 0xf3, 0xc5, 0x78,
284
  0xe8, 0x30, 0xe4, 0x25, 0x57, 0x2d, 0xe8, 0x28, 0xfa, 0xf4, 0xde, 0x1b,
285
  0x01, 0xc3, 0x94, 0xe3, 0x45, 0xc2, 0xfb, 0x06, 0x29, 0xa3, 0x93, 0x49,
286
  0x2f, 0x94, 0xf5, 0x70, 0xb0, 0x0b, 0x1d, 0x67, 0x77, 0x29, 0xf7, 0x55,
287
  0xd1, 0x07, 0x02, 0x2b, 0xb0, 0xa1, 0x16, 0xe1, 0xd7, 0xd7, 0x65, 0x9d,
288
  0xb5, 0xc4, 0xac, 0x0d, 0xde, 0xab, 0x07, 0xff, 0x04, 0x5f, 0x37, 0xb5,
289
  0xda, 0xf1, 0x73, 0x2b, 0x54, 0xea, 0xb2, 0x38, 0xa2, 0xce, 0x17, 0xc9,
290
  0x79, 0x41, 0x87, 0x75, 0x9c, 0xea, 0x9f, 0x92, 0xa1, 0x78, 0x05, 0xa2,
291
  0x7c, 0x10, 0x15, 0xec, 0x56, 0xcc, 0x7e, 0x47, 0x1a, 0x48, 0x8e, 0x6f,
292
  0x1b, 0x91, 0xf7, 0xaa, 0x5f, 0x38, 0x3c, 0xad, 0xfc, 0x12, 0xe8, 0x56,
293
  0xb2, 0x02, 0x34, 0x6a, 0xf8, 0x22, 0x6b, 0x1a, 0x88, 0x21, 0x37, 0xdc,
294
  0x3c, 0x5a, 0x57, 0xf0, 0xd2, 0x81, 0x5c, 0x1f, 0xcd, 0x4b, 0xb4, 0x6f,
295
  0xa9, 0x15, 0x7f, 0xdf, 0xfd, 0x79, 0xec, 0x3a, 0x10, 0xa8, 0x24, 0xcc,
296
  0xc1, 0xeb, 0x3c, 0xe0, 0xb6, 0xb4, 0x39, 0x6a, 0xe2, 0x36, 0x59, 0x00,
297
  0x16, 0xba, 0x69, 0x00, 0x01, 0x00, 0x01, 0x42, 0x08, 0x65, 0x73, 0x53,
298
  0x44, 0x49, 0x60, 0x00, 0x06
299
};
300
301
static u8 C_CV_IFDUser_AUT_cert_1[] = {
302
        0x7f, 0x21, 0x81, 0xcd, 0x5f, 0x37, 0x81, 0x80, 0x5d, 0xa9, 0x4b, 0x6b,
303
        0x4e, 0xb8, 0x61, 0xec, 0xa6, 0x36, 0xd2, 0x67, 0x39, 0x74, 0x71, 0x1f,
304
        0x55, 0x63, 0x0f, 0x5b, 0x89, 0x03, 0x8c, 0x57, 0xd0, 0xbb, 0xbb, 0xc1,
305
        0xd2, 0xc6, 0x8c, 0xc3, 0xeb, 0x56, 0xd5, 0x30, 0x38, 0x00, 0xf5, 0xa9,
306
        0xf5, 0xe2, 0x96, 0x7f, 0xdf, 0x28, 0x91, 0x7b, 0xaf, 0xc8, 0x87, 0x63,
307
        0xb8, 0xec, 0x2c, 0x0e, 0xbe, 0x7a, 0xcb, 0x0b, 0xa4, 0xaf, 0xbf, 0xe6,
308
        0x6d, 0xb2, 0xa1, 0xed, 0xa1, 0x3e, 0x45, 0x64, 0xf7, 0x8e, 0x65, 0x58,
309
        0x6e, 0x51, 0x01, 0x76, 0xf1, 0x1c, 0x4c, 0x99, 0x36, 0x4a, 0xaf, 0x18,
310
        0x97, 0xd1, 0x1b, 0xf9, 0x8e, 0x9d, 0x1d, 0x0a, 0x12, 0xd0, 0x6a, 0xab,
311
        0x75, 0x76, 0x4a, 0xa8, 0xdc, 0x85, 0x8d, 0xf0, 0xf0, 0x03, 0xeb, 0x8b,
312
        0x4b, 0x3b, 0x56, 0xf5, 0xf9, 0x5f, 0xa6, 0x37, 0x53, 0x75, 0x19, 0xe4,
313
        0xc6, 0x55, 0x10, 0xf7, 0x5f, 0x38, 0x3c, 0x60, 0x2d, 0xd4, 0xba, 0x04,
314
        0xdb, 0xc9, 0x85, 0x88, 0x45, 0xe6, 0xa9, 0xc4, 0x05, 0x5b, 0xc5, 0xbf,
315
        0xa0, 0xed, 0xdb, 0x86, 0x67, 0x89, 0xf0, 0xec, 0x6a, 0x80, 0xfc, 0xe5,
316
        0x3c, 0x66, 0x08, 0xdf, 0xdc, 0x9b, 0x9f, 0xe2, 0xed, 0x56, 0x75, 0x2c,
317
        0xc6, 0x05, 0x51, 0x3b, 0xa3, 0xf1, 0x75, 0x9c, 0xdd, 0x95, 0x22, 0x75,
318
        0x3f, 0x18, 0xd7, 0x00, 0x01, 0x00, 0x01, 0x42, 0x08, 0x65, 0x73, 0x53,
319
        0x44, 0x49, 0x62, 0x00, 0x18
320
};
321
322
/**
323
 * Terminal (IFD) certificate in CVC format (PK.IFD.AUT) for the PIN channel in DNIe 3.0 (dnie30RealParamDataPIN->c-CV-IFD-AUT)
324
 */
325
static u8 C_CV_IFDUser_AUT_pin_cert_0[] = {
326
  0x7f, 0x21, 0x81, 0xcd, 0x5f, 0x37, 0x81, 0x80, 0x69, 0xc4, 0xe4, 0x94,
327
  0xf0, 0x08, 0xe2, 0x42, 0x14, 0xb1, 0xc1, 0x31, 0xb6, 0x1f, 0xce, 0x9c,
328
  0x15, 0xfa, 0x3c, 0xb0, 0x61, 0xdd, 0x6f, 0x02, 0xd8, 0xa2, 0xcd, 0x30,
329
  0xd7, 0x2f, 0xb6, 0xdf, 0x89, 0x9a, 0xf1, 0x5b, 0x71, 0x78, 0x21, 0xbf,
330
  0xb1, 0xaf, 0x7d, 0x75, 0x85, 0x01, 0x6d, 0x8c, 0x36, 0xaf, 0x4a, 0xc2,
331
  0xa0, 0xb0, 0xc5, 0x2a, 0xd6, 0x5b, 0x69, 0x25, 0x67, 0x31, 0xc3, 0x4d,
332
  0x59, 0x02, 0x0e, 0x87, 0xab, 0x73, 0xa2, 0x30, 0xfa, 0x69, 0xee, 0x82,
333
  0xb3, 0x3a, 0x31, 0xdf, 0x04, 0x0c, 0xe9, 0x0f, 0x0a, 0xfc, 0x3a, 0x11,
334
  0x1d, 0x35, 0xda, 0x95, 0x66, 0xa8, 0xcd, 0xab, 0xea, 0x0e, 0x3f, 0x75,
335
  0x94, 0xc4, 0x40, 0xd3, 0x74, 0x50, 0x7a, 0x94, 0x35, 0x57, 0x59, 0xb3,
336
  0x9e, 0xc5, 0xe5, 0xfc, 0xb8, 0x03, 0x8d, 0x79, 0x3d, 0x5f, 0x9b, 0xa8,
337
  0xb5, 0xb1, 0x0b, 0x70, 0x5f, 0x38, 0x3c, 0x4c, 0x86, 0x91, 0xc7, 0xbe,
338
  0x2f, 0xd8, 0xc1, 0x23, 0x66, 0x0e, 0x98, 0x65, 0xe1, 0x4f, 0x19, 0xdf,
339
  0xfb, 0xb7, 0xff, 0x38, 0x08, 0xc9, 0xf2, 0x04, 0xe7, 0x97, 0xd0, 0x6d,
340
  0xd8, 0x33, 0x3a, 0xc5, 0x83, 0x86, 0xee, 0x4e, 0xb6, 0x1e, 0x20, 0xec,
341
  0xa7, 0xef, 0x38, 0xd5, 0xb0, 0x5e, 0xb1, 0x15, 0x96, 0x6a, 0x5a, 0x89,
342
  0xad, 0x58, 0xa5, 0x00, 0x01, 0x00, 0x01, 0x42, 0x08, 0x65, 0x73, 0x53,
343
  0x44, 0x49, 0x60, 0x00, 0x06
344
};
345
346
static u8 C_CV_IFDUser_AUT_pin_cert_1[] = {
347
        0x7f, 0x21, 0x81, 0xcd, 0x5f, 0x37, 0x81, 0x80, 0x0a, 0x3d, 0xb4, 0xd1,
348
        0x57, 0x98, 0xf2, 0x34, 0xf6, 0x31, 0xfd, 0x94, 0xc9, 0x1d, 0x2a, 0x63,
349
        0x63, 0xd0, 0xe1, 0x8e, 0x1b, 0x56, 0xda, 0xbd, 0xe6, 0x22, 0xbc, 0x20,
350
        0x1f, 0xd7, 0xc7, 0xff, 0x59, 0xff, 0x66, 0xda, 0x6e, 0x43, 0x4f, 0xe2,
351
        0xf7, 0xf4, 0x6e, 0x42, 0xe4, 0xa6, 0x06, 0xea, 0x82, 0x39, 0xac, 0x1a,
352
        0xc3, 0x0c, 0x7d, 0xad, 0xe2, 0x29, 0x65, 0xdf, 0x60, 0x6d, 0x11, 0x5e,
353
        0x04, 0xc8, 0xef, 0xfc, 0x77, 0x2b, 0x8f, 0x5d, 0x48, 0x77, 0x3e, 0x34,
354
        0x95, 0x5f, 0x33, 0xf4, 0x64, 0xed, 0x85, 0xcc, 0x0e, 0xb1, 0xbc, 0x57,
355
        0x2a, 0xfa, 0xba, 0x47, 0x25, 0xfb, 0xf5, 0xbd, 0xcf, 0x1d, 0x8c, 0x38,
356
        0xc9, 0xfe, 0x9c, 0xd8, 0x53, 0x6f, 0x34, 0x0b, 0xce, 0x14, 0x1d, 0xf5,
357
        0x18, 0x7f, 0xa2, 0xe2, 0x37, 0x2d, 0x73, 0xbc, 0x7f, 0x89, 0x48, 0x35,
358
        0x0c, 0xba, 0xde, 0xf2, 0x5f, 0x38, 0x3c, 0x0d, 0xcc, 0x88, 0x8d, 0x47,
359
        0x96, 0x54, 0x3f, 0x03, 0x25, 0x4f, 0x4e, 0x2c, 0xdf, 0x98, 0xb1, 0xe1,
360
        0x26, 0x11, 0xe3, 0x98, 0x1f, 0x53, 0x33, 0xdf, 0x98, 0xc8, 0x86, 0x01,
361
        0x93, 0x75, 0x84, 0x0f, 0xac, 0x61, 0xdb, 0x8f, 0x1b, 0xa3, 0xb5, 0x43,
362
        0xdc, 0xea, 0x3d, 0x05, 0x9e, 0x6a, 0x41, 0x4f, 0x6d, 0xd2, 0x9f, 0xc7,
363
        0xc9, 0x9d, 0x8b, 0x00, 0x01, 0x00, 0x01, 0x42, 0x08, 0x65, 0x73, 0x53,
364
        0x44, 0x49, 0x62, 0x00, 0x18
365
};
366
367
/**
368
 * Root CA card key reference (pk-RCA-AUT-keyRef)
369
 */
370
static u8 root_ca_keyref[] = { 0x02, 0x0f };
371
372
373
/**
374
 * ICC card private key reference (sk-ICC-AUT-keyRef)
375
 */
376
static u8 icc_priv_keyref[] = { 0x02, 0x1f };
377
378
/**
379
 * Intermediate CA card key reference (ifd-keyRef)
380
 */
381
static u8 cvc_intca_keyref_0[] = { 0x65, 0x73, 0x53, 0x44, 0x49, 0x60, 0x00, 0x06 };
382
static u8 cvc_intca_keyref_1[] = { 0x65, 0x73, 0x53, 0x44, 0x49, 0x62, 0x00, 0x18 };
383
384
/**
385
 * In memory key reference for selecting IFD sent certificate (dnieRealParamData->pk-IFD-AUT-keyRef)
386
 */
387
static u8 cvc_ifd_keyref_0[] = { 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
388
static u8 cvc_ifd_keyref_1[] = { 0x00, 0x00, 0x00, 0x00, 0xd0, 0x02, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x02 };
389
390
/**
391
 * In memory key reference for selecting IFD sent certificate in PIN channel DNIe 3.0 (dnie30RealParamDataPIN->pk-IFD-AUT-keyRef)
392
 */
393
static u8 cvc_ifd_keyref_pin_0[] = { 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
394
static u8 cvc_ifd_keyref_pin_1[] = { 0x00, 0x00, 0x00, 0x00, 0xd0, 0x02, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x04 };
395
396
/**
397
 * Serial number for IFD Terminal application (dnieRealParamData->sn-IFD)
398
 */
399
static u8 sn_ifd_0[] = { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
400
static u8 sn_ifd_1[] = { 0xd0, 0x02, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x02 };
401
402
/**
403
 * Serial number for IFD Terminal application in PIN channel DNIe 3.0 (dnie30RealParamDataPIN->sn-IFD)
404
 */
405
static u8 sn_ifd_pin_0[] = { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
406
static u8 sn_ifd_pin_1[] = { 0xd0, 0x02, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x04 };
407
408
0
#define AC_RAIZ_COMPONENTES_OLD_IDX 0
409
#define AC_RAIZ_COMPONENTES_ISSUER "/C=ES/O=DIRECCION GENERAL DE LA POLICIA/OU=DNIE/OU=AC RAIZ COMPONENTES/CN=000000006573524449600006"
410
0
#define AC_RAIZ_COMPONENTES_2_NEW_IDX 1
411
#define AC_RAIZ_COMPONENTES_2_ISSUER "/C=ES/O=DIRECCION GENERAL DE LA POLICIA/OU=DNIE/organizationIdentifier=VATES-S2816015H/OU=AC RAIZ COMPONENTES 2/CN=000000006573524449620018"
412
0
#define AC_RAIZ_COMPONENTES_2_ISSUER_OU "/OU=AC RAIZ COMPONENTES 2/"
413
414
/**
415
 * The DNIe secure channel uses some static configuration.
416
 * Since DNIe 'BMP100001' it seems that the old values were
417
 * replaced by new certs and keys. So an array of configuration
418
 * values is going to be added that will be set to the card
419
 * private data. For the moment the issuer of the icc intermediate
420
 * CA cert will be used to assign one or the other array element.
421
 */
422
static dnie_channel_data_t channel_data[] = {
423
    {  /* AC_RAIZ_COMPONENTES_OLD_IDX: Channel data configuration for DNIe before BMP100001 */
424
        .icc_root_ca = {
425
            .modulus = { icc_root_ca_modulus_0, sizeof(icc_root_ca_modulus_0) },
426
            .exponent = { icc_root_ca_public_exponent, sizeof(icc_root_ca_public_exponent) }
427
        },
428
        .ifd = {
429
            .modulus = { ifd_modulus_0, sizeof(ifd_modulus_0) },
430
            .exponent = { ifd_public_exponent, sizeof(ifd_public_exponent) },
431
            .private = { ifd_private_exponent_0, sizeof(ifd_private_exponent_0) }
432
        },
433
        .ifd_pin = {
434
            .modulus = { .value = ifd_pin_modulus_0, sizeof(ifd_pin_modulus_0) },
435
            .exponent = { .value = ifd_pin_public_exponent, sizeof(ifd_pin_public_exponent) },
436
            .private = { .value = ifd_pin_private_exponent_0, sizeof(ifd_pin_private_exponent_0) }
437
        },
438
        .C_CV_CA_CS_AUT_cert = { .value = C_CV_CA_CS_AUT_cert_0, sizeof(C_CV_CA_CS_AUT_cert_0) },
439
        .C_CV_IFDUser_AUT_cert = { .value = C_CV_IFDUser_AUT_cert_0, sizeof(C_CV_IFDUser_AUT_cert_0) },
440
        .C_CV_IFDUser_AUT_pin_cert = { .value = C_CV_IFDUser_AUT_pin_cert_0, sizeof(C_CV_IFDUser_AUT_pin_cert_0) },
441
        .root_ca_keyref = { root_ca_keyref, sizeof(root_ca_keyref) },
442
        .icc_priv_keyref = { icc_priv_keyref, sizeof(icc_priv_keyref) },
443
        .cvc_intca_keyref = { cvc_intca_keyref_0, sizeof(cvc_intca_keyref_0) },
444
        .cvc_ifd_keyref = { cvc_ifd_keyref_0, sizeof(cvc_ifd_keyref_0) },
445
        .cvc_ifd_keyref_pin = { cvc_ifd_keyref_pin_0, sizeof(cvc_ifd_keyref_pin_0) },
446
        .sn_ifd = { sn_ifd_0, sizeof(sn_ifd_0) },
447
        .sn_ifd_pin = { sn_ifd_pin_0, sizeof(sn_ifd_pin_0) }
448
    },
449
    { /* AC_RAIZ_COMPONENTES_2_NEW_IDX: Channel data configuration for DNIe BMP100001 and newer */
450
        .icc_root_ca = {
451
            .modulus = { icc_root_ca_modulus_1, sizeof(icc_root_ca_modulus_1) },
452
            .exponent = { icc_root_ca_public_exponent, sizeof(icc_root_ca_public_exponent) }
453
        },
454
        .ifd = {
455
            .modulus = { ifd_modulus_1, sizeof(ifd_modulus_1) },
456
            .exponent = { ifd_public_exponent, sizeof(ifd_public_exponent) },
457
            .private = { ifd_private_exponent_1, sizeof(ifd_private_exponent_1) }
458
        },
459
        .ifd_pin = {
460
            .modulus = { .value = ifd_pin_modulus_1, sizeof(ifd_pin_modulus_1) },
461
            .exponent = { .value = ifd_pin_public_exponent, sizeof(ifd_pin_public_exponent) },
462
            .private = { .value = ifd_pin_private_exponent_1, sizeof(ifd_pin_private_exponent_1) }
463
        },
464
        .C_CV_CA_CS_AUT_cert = { .value = C_CV_CA_CS_AUT_cert_1, sizeof(C_CV_CA_CS_AUT_cert_1) },
465
        .C_CV_IFDUser_AUT_cert = { .value = C_CV_IFDUser_AUT_cert_1, sizeof(C_CV_IFDUser_AUT_cert_1) },
466
        .C_CV_IFDUser_AUT_pin_cert = { .value = C_CV_IFDUser_AUT_pin_cert_1, sizeof(C_CV_IFDUser_AUT_pin_cert_1) },
467
        .root_ca_keyref = { root_ca_keyref, sizeof(root_ca_keyref) },
468
        .icc_priv_keyref = { icc_priv_keyref, sizeof(icc_priv_keyref) },
469
        .cvc_intca_keyref = { cvc_intca_keyref_1, sizeof(cvc_intca_keyref_1) },
470
        .cvc_ifd_keyref = { cvc_ifd_keyref_1, sizeof(cvc_ifd_keyref_1) },
471
        .cvc_ifd_keyref_pin = { cvc_ifd_keyref_pin_1, sizeof(cvc_ifd_keyref_pin_1) },
472
        .sn_ifd = { sn_ifd_1, sizeof(sn_ifd_1) },
473
        .sn_ifd_pin = { sn_ifd_pin_1, sizeof(sn_ifd_pin_1) }
474
    }
475
};
476
477
/************ internal functions **********************************/
478
479
/**
480
 * Select a file from card, process fci and read data.
481
 *
482
 * This is done by mean of iso_select_file() and iso_read_binary()
483
 *
484
 * @param card pointer to sc_card data
485
 * @param path pathfile
486
 * @param file pointer to resulting file descriptor
487
 * @param buffer pointer to buffer where to store file contents
488
 * @param length length of buffer data
489
 * @return SC_SUCCESS if ok; else error code
490
 */
491
int dnie_read_file(sc_card_t * card,
492
       const sc_path_t * path,
493
       sc_file_t ** file, u8 ** buffer, size_t * length)
494
0
{
495
0
  u8 *data = NULL;
496
0
  char *msg = NULL;
497
0
  int res = SC_SUCCESS;
498
0
  size_t fsize = 0; /* file size */
499
0
  sc_context_t *ctx = NULL;
500
501
0
  if (!card || !card->ctx)
502
0
    return SC_ERROR_INVALID_ARGUMENTS;
503
0
  ctx = card->ctx;
504
0
  LOG_FUNC_CALLED(card->ctx);
505
0
  if (!buffer || !length || !path) /* check received arguments */
506
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
507
  /* select file by mean of iso7816 ops */
508
0
  res = card->ops->select_file(card, path, file);
509
0
  if (res != SC_SUCCESS || !file || !(*file)) {
510
0
    msg = "select_file failed";
511
0
    goto dnie_read_file_err;
512
0
  }
513
  /* iso's select file calls if needed process_fci, so arriving here
514
   * we have file structure filled.
515
   */
516
0
  if ((*file)->type == SC_FILE_TYPE_DF) {
517
    /* just a DF, no need to read_binary() */
518
0
    *buffer = NULL;
519
0
    *length = 0;
520
0
    res = SC_SUCCESS;
521
0
    msg = "File is a DF: no need to read_binary()";
522
0
    goto dnie_read_file_end;
523
0
  }
524
0
  fsize = (*file)->size;
525
  /* reserve enough space to read data from card */
526
0
  if (fsize <= 0) {
527
0
    res = SC_ERROR_FILE_TOO_SMALL;
528
0
    msg = "provided buffer size is too small";
529
0
    goto dnie_read_file_err;
530
0
  }
531
0
  data = calloc(fsize, sizeof(u8));
532
0
  if (data == NULL) {
533
0
    res = SC_ERROR_OUT_OF_MEMORY;
534
0
    msg = "cannot reserve requested buffer size";
535
0
    goto dnie_read_file_err;
536
0
  }
537
  /* call sc_read_binary() to retrieve data */
538
0
  sc_log(ctx, "read_binary(): expected '%"SC_FORMAT_LEN_SIZE_T"u' bytes",
539
0
         fsize);
540
0
  res = sc_read_binary(card, 0, data, fsize, 0L);
541
0
  if (res < 0) {   /* read_binary returns number of bytes read */
542
0
    res = SC_ERROR_CARD_CMD_FAILED;
543
0
    msg = "read_binary() failed";
544
0
    goto dnie_read_file_err;
545
0
  }
546
0
  *buffer = data;
547
0
  *length = res;
548
  /* arriving here means success */
549
0
  res = SC_SUCCESS;
550
0
  goto dnie_read_file_end;
551
0
 dnie_read_file_err:
552
0
  if (data)
553
0
    free(data);
554
0
  if (file) {
555
0
    sc_file_free(*file);
556
0
    *file = NULL;
557
0
  }
558
0
 dnie_read_file_end:
559
0
  if (msg)
560
0
    sc_log(ctx, "%s", msg);
561
0
  LOG_FUNC_RETURN(ctx, res);
562
0
}
563
564
/**
565
 * Read SM required certificates from card.
566
 *
567
 * This function uses received path to read a certificate file from
568
 * card.
569
 * No validation is done except that received data is effectively a certificate
570
 * @param card Pointer to card driver structure
571
 * @param certpat path to requested certificate
572
 * @param cert where to store resulting data
573
 * @return SC_SUCCESS if ok, else error code
574
 */
575
static int dnie_read_certificate(sc_card_t * card, char *certpath, X509 ** cert)
576
0
{
577
0
  sc_file_t *file = NULL;
578
0
  sc_path_t path;
579
0
  u8 *buffer = NULL, *buffer2 = NULL;
580
0
  char *msg = NULL;
581
0
  size_t bufferlen = 0;
582
0
  int res = SC_SUCCESS;
583
584
0
  LOG_FUNC_CALLED(card->ctx);
585
0
  sc_format_path(certpath, &path);
586
0
  res = dnie_read_file(card, &path, &file, &buffer, &bufferlen);
587
0
  if (res != SC_SUCCESS) {
588
0
    msg = "Cannot get intermediate CA cert";
589
0
    goto read_cert_end;
590
0
  }
591
0
  buffer2 = buffer;
592
0
  *cert = d2i_X509(NULL, (const unsigned char **)&buffer2, bufferlen);
593
0
  if (*cert == NULL) { /* received data is not a certificate */
594
0
    sc_log_openssl(card->ctx);
595
0
    res = SC_ERROR_OBJECT_NOT_VALID;
596
0
    msg = "Read data is not a certificate";
597
0
    goto read_cert_end;
598
0
  }
599
0
  res = SC_SUCCESS;
600
601
0
 read_cert_end:
602
0
  if (buffer) {
603
0
    free(buffer);
604
0
    buffer = NULL;
605
0
    bufferlen = 0;
606
0
  }
607
0
  sc_file_free(file);
608
0
  file = NULL;
609
0
  if (msg)
610
0
    sc_log(card->ctx, "%s", msg);
611
0
  LOG_FUNC_RETURN(card->ctx, res);
612
0
}
613
614
/**
615
 * Method that sets the configuration channel data to use.
616
 * The configuration data is already set to the card private data.
617
 * Just created in case this will be modified.
618
 *
619
 * @param card Pointer to card driver structure
620
 * @param data The data for the channel will be assigned here
621
 * @return SC_SUCCESS if ok; else error code
622
 */
623
0
static int dnie_get_channel_data(sc_card_t * card, dnie_channel_data_t ** data) {
624
0
  dnie_private_data_t *priv_data = GET_DNIE_PRIV_DATA(card);
625
0
  LOG_FUNC_CALLED(card->ctx);
626
0
  if (!priv_data->channel_data) {
627
0
    sc_log(card->ctx, "Data channel configuration was not initialized");
628
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
629
0
  }
630
0
  *data = priv_data->channel_data;
631
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
632
0
}
633
634
/**
635
 * Method to assign into the private data the secure channel
636
 * configuration to use. Right now the icc_intermediate_ca_cert
637
 * issuer is used. If it is the new one the new data is assigned
638
 * else the old data is set.
639
 *
640
 * @param card Pointer to card driver structure
641
 * @param icc_intermediate_ca_cert Pointer to the X509 icc intermediate CA certificate
642
 * @return SC_SUCCESS if ok; else error code
643
 */
644
0
static int dnie_set_channel_data(sc_card_t * card, X509 * icc_intermediate_ca_cert) {
645
0
  char *buf = NULL;
646
0
  dnie_private_data_t *priv_data = GET_DNIE_PRIV_DATA(card);
647
0
  LOG_FUNC_CALLED(card->ctx);
648
649
0
  X509_NAME *issuer = X509_get_issuer_name(icc_intermediate_ca_cert);
650
0
  if (issuer) {
651
0
    buf = X509_NAME_oneline(issuer, buf, 0);
652
0
    if (!buf) {
653
0
      sc_log_openssl(card->ctx);
654
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
655
0
    }
656
0
    sc_log(card->ctx, "icc_intermediate_ca_cert issuer %s", buf);
657
0
  }
658
659
0
  if (buf && strstr(buf, AC_RAIZ_COMPONENTES_2_ISSUER_OU)) {
660
0
    sc_log(card->ctx, "assigning new data channel configuration");
661
0
    priv_data->channel_data = &channel_data[AC_RAIZ_COMPONENTES_2_NEW_IDX];
662
0
  } else {
663
0
    sc_log(card->ctx, "assigning old data channel configuration");
664
0
    priv_data->channel_data = &channel_data[AC_RAIZ_COMPONENTES_OLD_IDX];
665
0
  }
666
0
  if (buf) {
667
0
    OPENSSL_free(buf);
668
0
  }
669
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
670
0
}
671
672
/************ implementation of cwa provider methods **************/
673
674
/**
675
 * Retrieve Root CA public key.
676
 *
677
 * Just returns (as local SM authentication) static data
678
 * @param card Pointer to card driver structure
679
 * @param root_ca_key pointer to resulting returned key
680
 * @return SC_SUCCESS if ok; else error code
681
 */
682
static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key)
683
0
{
684
0
  int res = SC_SUCCESS;
685
0
  BIGNUM *root_ca_rsa_n = NULL, *root_ca_rsa_e = NULL;
686
0
  dnie_channel_data_t *data;
687
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
688
0
  RSA *root_ca_rsa = NULL;
689
0
  root_ca_rsa = RSA_new();
690
0
  *root_ca_key = EVP_PKEY_new();
691
0
  if (!root_ca_rsa || !*root_ca_key) {
692
0
    if (root_ca_rsa)
693
0
      RSA_free(root_ca_rsa);
694
0
    if (*root_ca_key)
695
0
      EVP_PKEY_free(*root_ca_key);
696
#else
697
  EVP_PKEY_CTX *ctx = NULL;
698
  OSSL_PARAM_BLD *bld = NULL;
699
  OSSL_PARAM *params = NULL;
700
701
  ctx = EVP_PKEY_CTX_new_from_name(card->ctx->ossl3ctx->libctx, "RSA", NULL);
702
  if (!ctx) {
703
#endif
704
0
    sc_log_openssl(card->ctx);
705
0
    sc_log(card->ctx, "Cannot create data for root CA public key");
706
0
    return SC_ERROR_OUT_OF_MEMORY;
707
0
  }
708
709
0
  LOG_FUNC_CALLED(card->ctx);
710
711
  /* obtain the data channel info for the card */
712
0
  res = dnie_get_channel_data(card, &data);
713
0
  if (res < 0) {
714
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
715
0
    RSA_free(root_ca_rsa);
716
0
    EVP_PKEY_free(*root_ca_key);
717
#else
718
    EVP_PKEY_CTX_free(ctx);
719
#endif
720
0
  }
721
0
  LOG_TEST_RET(card->ctx, res, "Error getting the card channel data");
722
723
  /* compose root_ca_public key with data provided by Dnie Manual */
724
0
  root_ca_rsa_n = BN_bin2bn(data->icc_root_ca.modulus.value, (int)data->icc_root_ca.modulus.len, NULL);
725
0
  root_ca_rsa_e = BN_bin2bn(data->icc_root_ca.exponent.value, (int)data->icc_root_ca.exponent.len, NULL);
726
727
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
728
0
  if (RSA_set0_key(root_ca_rsa, root_ca_rsa_n, root_ca_rsa_e, NULL) != 1) {
729
0
    sc_log_openssl(card->ctx);
730
0
    BN_free(root_ca_rsa_n);
731
0
    BN_free(root_ca_rsa_e);
732
0
    EVP_PKEY_free(*root_ca_key);
733
0
    RSA_free(root_ca_rsa);
734
0
    sc_log(card->ctx, "Cannot set RSA values for CA public key");
735
0
    return SC_ERROR_INTERNAL;
736
0
  }
737
0
  res = EVP_PKEY_assign_RSA(*root_ca_key, root_ca_rsa);
738
0
  if (!res) {
739
0
    sc_log_openssl(card->ctx);
740
0
    RSA_free(root_ca_rsa);
741
#else
742
  if (!(bld = OSSL_PARAM_BLD_new()) ||
743
    OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N, root_ca_rsa_n) != 1 ||
744
    OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E, root_ca_rsa_e) != 1 ||
745
    !(params = OSSL_PARAM_BLD_to_param(bld))) {
746
    sc_log_openssl(card->ctx);
747
    OSSL_PARAM_BLD_free(bld);
748
    OSSL_PARAM_free(params);
749
    EVP_PKEY_CTX_free(ctx);
750
    sc_log(card->ctx, "Cannot set RSA values for CA public key");
751
    return SC_ERROR_INTERNAL;
752
  }
753
  OSSL_PARAM_BLD_free(bld);
754
755
  if (EVP_PKEY_fromdata_init(ctx) != 1 ||
756
    EVP_PKEY_fromdata(ctx, root_ca_key, EVP_PKEY_PUBLIC_KEY, params) != 1) {
757
    sc_log_openssl(card->ctx);
758
    EVP_PKEY_CTX_free(ctx);
759
    OSSL_PARAM_free(params);
760
#endif
761
0
    BN_free(root_ca_rsa_n);
762
0
    BN_free(root_ca_rsa_e);
763
0
    EVP_PKEY_free(*root_ca_key);
764
0
    sc_log(card->ctx, "Cannot compose root CA public key");
765
0
    return SC_ERROR_INTERNAL;
766
0
  }
767
768
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
769
  EVP_PKEY_CTX_free(ctx);
770
  OSSL_PARAM_free(params);
771
  BN_free(root_ca_rsa_n);
772
  BN_free(root_ca_rsa_e);
773
#endif
774
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
775
0
}
776
777
/**
778
 * Retrieve IFD (application) CVC intermediate CA certificate and length.
779
 *
780
 * Returns a byte array with the intermediate CA certificate
781
 * (in CardVerifiable Certificate format) to be sent to the
782
 * card in External Authentication process
783
 * As this is local provider, just points to provided static data,
784
 * and always return success
785
 *
786
 * @param card Pointer to card driver Certificate
787
 * @param cert Where to store resulting byte array
788
 * @param length len of returned byte array
789
 * @return SC_SUCCESS if ok; else error code
790
 */
791
static int dnie_get_cvc_ca_cert(sc_card_t * card, u8 ** cert, size_t * length)
792
0
{
793
0
  int res;
794
0
  dnie_channel_data_t *data;
795
0
  LOG_FUNC_CALLED(card->ctx);
796
797
  /* obtain the data channel info for the card */
798
0
  res = dnie_get_channel_data(card, &data);
799
0
  LOG_TEST_RET(card->ctx, res, "Error getting the card channel data");
800
801
0
  *cert = data->C_CV_CA_CS_AUT_cert.value;
802
0
  *length = data->C_CV_CA_CS_AUT_cert.len;
803
0
  LOG_FUNC_RETURN(card->ctx, res);
804
0
}
805
806
/**
807
 * Retrieve IFD (application) CVC certificate and length.
808
 *
809
 * Returns a byte array with the application's certificate
810
 * (in CardVerifiable Certificate format) to be sent to the
811
 * card in External Authentication process
812
 * As this is local provider, just points to provided static data,
813
 * and always return success
814
 *
815
 * @param card Pointer to card driver Certificate
816
 * @param cert Where to store resulting byte array
817
 * @param length len of returned byte array
818
 * @return SC_SUCCESS if ok; else error code
819
 */
820
static int dnie_get_cvc_ifd_cert(sc_card_t * card, u8 ** cert, size_t * length)
821
0
{
822
0
  int res;
823
0
  dnie_channel_data_t *data;
824
0
  LOG_FUNC_CALLED(card->ctx);
825
826
  /* obtain the data channel info for the card */
827
0
  res = dnie_get_channel_data(card, &data);
828
0
  LOG_TEST_RET(card->ctx, res, "Error getting the card channel data");
829
830
0
  *cert = data->C_CV_IFDUser_AUT_cert.value;
831
0
  *length = data->C_CV_IFDUser_AUT_cert.len;
832
0
  LOG_FUNC_RETURN(card->ctx, res);
833
0
}
834
835
/**
836
 * Retrieve IFD (application) CVC certificate and length for
837
 * the PIN channel.
838
 *
839
 * Returns a byte array with the application's certificate
840
 * (in CardVerifiable Certificate format) to be sent to the
841
 * card in External Authentication process
842
 * As this is local provider, just points to provided static data,
843
 * and always return success
844
 *
845
 * @param card Pointer to card driver Certificate
846
 * @param cert Where to store resulting byte array
847
 * @param length len of returned byte array
848
 * @return SC_SUCCESS if ok; else error code
849
 */
850
static int dnie_get_cvc_ifd_cert_pin(sc_card_t * card, u8 ** cert, size_t * length)
851
0
{
852
0
  int res;
853
0
  dnie_channel_data_t *data;
854
0
  LOG_FUNC_CALLED(card->ctx);
855
856
  /* obtain the data channel info for the card */
857
0
  res = dnie_get_channel_data(card, &data);
858
0
  LOG_TEST_RET(card->ctx, res, "Error getting the card channel data");
859
860
0
  *cert = data->C_CV_IFDUser_AUT_pin_cert.value;
861
0
  *length = data->C_CV_IFDUser_AUT_pin_cert.len;
862
0
  LOG_FUNC_RETURN(card->ctx, res);
863
0
}
864
865
/**
866
 * Get IFD (Terminal) private key data passing the three
867
 * arguments (modulus, public and private exponent).
868
 *
869
 * @param card pointer to card driver structure
870
 * @param ifd_privkey where to store IFD private key
871
 * @param modulus the byte array used as the modulus of the key
872
 * @param modulus_len the length of the modulus
873
 * @param public_exponent the byte array for the public exponent
874
 * @param public_exponent_len the length of the public exponent
875
 * @param private_exponent the byte array for the private exponent
876
 * @param private_exponent_len the length of the private exponent
877
 * @return SC_SUCCESS if ok; else error code
878
 */
879
static int dnie_get_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey,
880
                            u8 * modulus, int modulus_len,
881
                            u8 * public_exponent, size_t public_exponent_len,
882
                            u8 * private_exponent, size_t private_exponent_len)
883
0
{
884
0
  BIGNUM *ifd_rsa_n = NULL, *ifd_rsa_e = NULL, *ifd_rsa_d = NULL;
885
886
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
887
0
  int res = SC_ERROR_INTERNAL;
888
0
  RSA *ifd_rsa = NULL;
889
890
0
  LOG_FUNC_CALLED(card->ctx);
891
0
  ifd_rsa = RSA_new();
892
0
  *ifd_privkey = EVP_PKEY_new();
893
894
0
  if (!ifd_rsa || !*ifd_privkey) {
895
0
    if (ifd_rsa)
896
0
      RSA_free(ifd_rsa);
897
0
    if (*ifd_privkey)
898
0
      EVP_PKEY_free(*ifd_privkey);
899
#else
900
  OSSL_PARAM_BLD *bld = NULL;
901
  OSSL_PARAM *params = NULL;
902
  EVP_PKEY_CTX *ctx = NULL;
903
904
  LOG_FUNC_CALLED(card->ctx);
905
  ctx = EVP_PKEY_CTX_new_from_name(card->ctx->ossl3ctx->libctx, "RSA", NULL);
906
907
  if (!ctx) {
908
#endif
909
0
    sc_log_openssl(card->ctx);
910
0
    sc_log(card->ctx, "Cannot create data for IFD private key");
911
0
    return SC_ERROR_OUT_OF_MEMORY;
912
0
  }
913
914
  /* compose ifd_private key with data provided in Annex 3 of DNIe Manual */
915
0
  ifd_rsa_n = BN_bin2bn(modulus, modulus_len, NULL);
916
0
  ifd_rsa_e = BN_bin2bn(public_exponent, (int)public_exponent_len, NULL);
917
0
  ifd_rsa_d = BN_bin2bn(private_exponent, (int)private_exponent_len, NULL);
918
919
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
920
0
  if (RSA_set0_key(ifd_rsa, ifd_rsa_n, ifd_rsa_e, ifd_rsa_d) != 1) {
921
0
    sc_log_openssl(card->ctx);
922
0
    BN_free(ifd_rsa_n);
923
0
    BN_free(ifd_rsa_e);
924
0
    BN_free(ifd_rsa_d);
925
0
    RSA_free(ifd_rsa);
926
0
    EVP_PKEY_free(*ifd_privkey);
927
0
    sc_log(card->ctx, "Cannot set RSA values for IFD private key");
928
0
    return SC_ERROR_INTERNAL;
929
0
  }
930
931
0
  res = EVP_PKEY_assign_RSA(*ifd_privkey, ifd_rsa);
932
0
  if (!res) {
933
0
    RSA_free(ifd_rsa);
934
0
    sc_log_openssl(card->ctx);
935
#else
936
  if (!(bld = OSSL_PARAM_BLD_new()) ||
937
    OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N, ifd_rsa_n) != 1 ||
938
    OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E, ifd_rsa_e) != 1 ||
939
    OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_D, ifd_rsa_d) != 1 ||
940
    !(params = OSSL_PARAM_BLD_to_param(bld))) {
941
    sc_log_openssl(card->ctx);
942
    OSSL_PARAM_BLD_free(bld);
943
    OSSL_PARAM_free(params);
944
    EVP_PKEY_CTX_free(ctx);
945
    BN_free(ifd_rsa_n);
946
    BN_free(ifd_rsa_e);
947
    BN_free(ifd_rsa_d);
948
    sc_log(card->ctx, "Cannot set RSA values for CA public key");
949
    return SC_ERROR_INTERNAL;
950
  }
951
  OSSL_PARAM_BLD_free(bld);
952
953
  if (EVP_PKEY_fromdata_init(ctx) != 1 ||
954
    EVP_PKEY_fromdata(ctx, ifd_privkey, EVP_PKEY_KEYPAIR, params) != 1) {
955
    sc_log_openssl(card->ctx);
956
    EVP_PKEY_CTX_free(ctx);
957
#endif
958
0
    BN_free(ifd_rsa_n);
959
0
    BN_free(ifd_rsa_e);
960
0
    BN_free(ifd_rsa_d);
961
0
    if (*ifd_privkey)
962
0
      EVP_PKEY_free(*ifd_privkey); /* implies ifd_rsa free() */
963
0
    sc_log(card->ctx, "Cannot compose IFD private key");
964
0
    return SC_ERROR_INTERNAL;
965
0
  }
966
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
967
  OSSL_PARAM_free(params);
968
  EVP_PKEY_CTX_free(ctx);
969
  BN_free(ifd_rsa_n);
970
  BN_free(ifd_rsa_e);
971
  BN_free(ifd_rsa_d);
972
#endif
973
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
974
0
}
975
976
/**
977
 * Get IFD (Terminal) private key data
978
 *
979
 * As this is a local (in memory) provider, just get data specified in
980
 * DNIe's manual and compose an OpenSSL private key structure
981
 *
982
 * @param card pointer to card driver structure
983
 * @param ifd_privkey where to store IFD private key
984
 * @return SC_SUCCESS if ok; else error code
985
 */
986
static int dnie_get_ifd_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey)
987
0
{
988
0
  int res;
989
0
  dnie_channel_data_t *data;
990
991
  /* obtain the data channel info for the card */
992
0
  res = dnie_get_channel_data(card, &data);
993
0
  LOG_TEST_RET(card->ctx, res, "Error getting the card channel data");
994
995
0
  return dnie_get_privkey(card, ifd_privkey, data->ifd.modulus.value, (int)data->ifd.modulus.len,
996
0
        data->ifd.exponent.value, data->ifd.exponent.len,
997
0
        data->ifd.private.value, data->ifd.private.len);
998
0
}
999
1000
/**
1001
 * Get IFD (Terminal) private key data for the PIN channel DNIe 3.0
1002
 *
1003
 * As this is a local (in memory) provider, just get data specified in
1004
 * DNIe's manual and compose an OpenSSL private key structure
1005
 *
1006
 * @param card pointer to card driver structure
1007
 * @param ifd_privkey where to store IFD private key
1008
 * @return SC_SUCCESS if ok; else error code
1009
 */
1010
static int dnie_get_ifd_privkey_pin(sc_card_t * card, EVP_PKEY ** ifd_privkey)
1011
0
{
1012
0
  int res;
1013
0
  dnie_channel_data_t *data;
1014
1015
  /* obtain the data channel info for the card */
1016
0
  res = dnie_get_channel_data(card, &data);
1017
0
  LOG_TEST_RET(card->ctx, res, "Error getting the card channel data");
1018
1019
0
  return dnie_get_privkey(card, ifd_privkey, data->ifd_pin.modulus.value, (int)data->ifd_pin.modulus.len,
1020
0
        data->ifd_pin.exponent.value, data->ifd_pin.exponent.len,
1021
0
        data->ifd_pin.private.value, data->ifd_pin.private.len);
1022
0
}
1023
1024
/**
1025
 * Get ICC intermediate CA Certificate from card.
1026
 *
1027
 * @param card Pointer to card driver structure
1028
 * @param cert where to store resulting certificate
1029
 * @return SC_SUCCESS if ok; else error code
1030
 */
1031
static int dnie_get_icc_intermediate_ca_cert(sc_card_t * card, X509 ** cert)
1032
0
{
1033
0
  dnie_private_data_t *priv_data = GET_DNIE_PRIV_DATA(card);
1034
1035
0
  int res = dnie_read_certificate(card, "3F006020", cert);
1036
0
  if (res == SC_SUCCESS && !priv_data->channel_data) {
1037
    /* initialize the secure channel data using the issuer cert */
1038
0
    res = dnie_set_channel_data(card, *cert);
1039
0
  }
1040
0
  return res;
1041
0
}
1042
1043
/**
1044
 * Get ICC (card) certificate.
1045
 *
1046
 * @param card Pointer to card driver structure
1047
 * @param cert where to store resulting certificate
1048
 * @return SC_SUCCESS if ok; else error code
1049
 */
1050
static int dnie_get_icc_cert(sc_card_t * card, X509 ** cert)
1051
0
{
1052
0
  return dnie_read_certificate(card, "3F00601F", cert);
1053
0
}
1054
1055
/**
1056
 * Retrieve key reference for Root CA to validate CVC intermediate CA certs.
1057
 *
1058
 * This is required in the process of On card external authenticate
1059
 * @param card Pointer to card driver structure
1060
 * @param buf where to store resulting key reference
1061
 * @param len where to store buffer length
1062
 * @return SC_SUCCESS if ok; else error code
1063
 */
1064
static int dnie_get_root_ca_pubkey_ref(sc_card_t * card, u8 ** buf,
1065
               size_t * len)
1066
0
{
1067
0
  int res;
1068
0
  dnie_channel_data_t *data;
1069
1070
  /* obtain the data channel info for the card */
1071
0
  res = dnie_get_channel_data(card, &data);
1072
0
  LOG_TEST_RET(card->ctx, res, "Error getting the card channel data");
1073
1074
0
  *buf = data->root_ca_keyref.value;
1075
0
  *len = data->root_ca_keyref.len;
1076
0
  return res;
1077
0
}
1078
1079
/**
1080
 * Retrieve public key reference for intermediate CA to validate IFD cert.
1081
 *
1082
 * This is required in the process of On card external authenticate
1083
 * As this driver is for local SM authentication SC_SUCCESS is always returned
1084
 *
1085
 * @param card Pointer to card driver structure
1086
 * @param buf where to store resulting key reference
1087
 * @param len where to store buffer length
1088
 * @return SC_SUCCESS if ok; else error code
1089
 */
1090
static int dnie_get_intermediate_ca_pubkey_ref(sc_card_t * card, u8 ** buf,
1091
                 size_t * len)
1092
0
{
1093
0
  int res;
1094
0
  dnie_channel_data_t *data;
1095
1096
  /* obtain the data channel info for the card */
1097
0
  res = dnie_get_channel_data(card, &data);
1098
0
  LOG_TEST_RET(card->ctx, res, "Error getting the card channel data");
1099
1100
0
  *buf = data->cvc_intca_keyref.value;
1101
0
  *len = data->cvc_intca_keyref.len;
1102
0
  return res;
1103
0
}
1104
1105
/**
1106
 *  Retrieve public key reference for IFD certificate.
1107
 *
1108
 * This tells the card with in memory key reference is to be used
1109
 * when CVC cert is sent for external auth procedure
1110
 * As this driver is for local SM authentication SC_SUCCESS is always returned
1111
 *
1112
 * @param card pointer to card driver structure
1113
 * @param buf where to store data to be sent
1114
 * @param len where to store data length
1115
 * @return SC_SUCCESS if ok; else error code
1116
 */
1117
static int dnie_get_ifd_pubkey_ref(sc_card_t * card, u8 ** buf, size_t * len)
1118
0
{
1119
0
  int res;
1120
0
  dnie_channel_data_t *data;
1121
1122
  /* obtain the data channel info for the card */
1123
0
  res = dnie_get_channel_data(card, &data);
1124
0
  LOG_TEST_RET(card->ctx, res, "Error getting the card channel data");
1125
1126
0
  *buf = data->cvc_ifd_keyref.value;
1127
0
  *len = data->cvc_ifd_keyref.len;
1128
0
  return res;
1129
0
}
1130
1131
/**
1132
 *  Retrieve public key reference for IFD certificate for the PIN channel.
1133
 *
1134
 * This tells the card with in memory key reference is to be used
1135
 * when CVC cert is sent for external auth procedure
1136
 * As this driver is for local SM authentication SC_SUCCESS is always returned
1137
 *
1138
 * @param card pointer to card driver structure
1139
 * @param buf where to store data to be sent
1140
 * @param len where to store data length
1141
 * @return SC_SUCCESS if ok; else error code
1142
 */
1143
static int dnie_get_ifd_pubkey_ref_pin(sc_card_t * card, u8 ** buf, size_t * len)
1144
0
{
1145
0
  int res;
1146
0
  dnie_channel_data_t *data;
1147
0
  LOG_FUNC_CALLED(card->ctx);
1148
1149
  /* obtain the data channel info for the card */
1150
0
  res = dnie_get_channel_data(card, &data);
1151
0
  LOG_TEST_RET(card->ctx, res, "Error getting the card channel data");
1152
1153
0
  *buf = data->cvc_ifd_keyref_pin.value;
1154
0
  *len = data->cvc_ifd_keyref_pin.len;
1155
0
  return res;
1156
0
}
1157
1158
/**
1159
 * Retrieve key reference for ICC privkey.
1160
 *
1161
 * In local SM establishment, just retrieve key reference from static
1162
 * data tables and just return success
1163
 *
1164
 * @param card pointer to card driver structure
1165
 * @param buf where to store data
1166
 * @param len where to store data length
1167
 * @return SC_SUCCESS if ok; else error
1168
 */
1169
static int dnie_get_icc_privkey_ref(sc_card_t * card, u8 ** buf, size_t * len)
1170
0
{
1171
0
  int res;
1172
0
  dnie_channel_data_t *data;
1173
1174
  /* obtain the data channel info for the card */
1175
0
  res = dnie_get_channel_data(card, &data);
1176
0
  LOG_TEST_RET(card->ctx, res, "Error getting the card channel data");
1177
1178
0
  *buf = data->icc_priv_keyref.value;
1179
0
  *len = data->icc_priv_keyref.len;
1180
0
  return res;
1181
0
}
1182
1183
/**
1184
 * Retrieve SN.IFD (8 bytes left padded with zeroes if required).
1185
 *
1186
 * In DNIe local SM procedure, just read it from static data and
1187
 * return SC_SUCCESS
1188
 *
1189
 * @param card pointer to card structure
1190
 * @param buf where to store result (8 bytes)
1191
 * @return SC_SUCCESS if ok; else error
1192
 */
1193
static int dnie_get_sn_ifd(sc_card_t * card)
1194
0
{
1195
0
  int res;
1196
0
  dnie_channel_data_t *data;
1197
0
  struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
1198
1199
  /* obtain the data channel info for the card */
1200
0
  res = dnie_get_channel_data(card, &data);
1201
0
  LOG_TEST_RET(card->ctx, res, "Error getting the card channel data");
1202
1203
0
  memcpy(sm->ifd.sn, data->sn_ifd.value, data->sn_ifd.len);
1204
0
  return res;
1205
0
}
1206
1207
/**
1208
 * Retrieve SN.IFD (8 bytes left padded with zeroes if required)
1209
 * for the PIN channel DNIe 3.0.
1210
 *
1211
 * In DNIe local SM procedure, just read it from static data and
1212
 * return SC_SUCCESS
1213
 *
1214
 * @param card pointer to card structure
1215
 * @return SC_SUCCESS if ok; else error
1216
 */
1217
static int dnie_get_sn_ifd_pin(sc_card_t * card)
1218
0
{
1219
0
  int res;
1220
0
  dnie_channel_data_t *data;
1221
0
  struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
1222
1223
  /* obtain the data channel info for the card */
1224
0
  res = dnie_get_channel_data(card, &data);
1225
0
  LOG_TEST_RET(card->ctx, res, "Error getting the card channel data");
1226
1227
0
  memcpy(sm->ifd.sn, data->sn_ifd_pin.value, data->sn_ifd_pin.len);
1228
0
  return res;
1229
0
}
1230
1231
/* Retrieve SN.ICC (8 bytes left padded with zeroes if needed).
1232
 *
1233
 * As DNIe reads serial number at startup, no need to read again
1234
 * Just retrieve it from cache and return success
1235
 *
1236
 * @param card pointer to card structure
1237
 * @return SC_SUCCESS if ok; else error
1238
 */
1239
static int dnie_get_sn_icc(sc_card_t * card)
1240
0
{
1241
0
  int res=SC_SUCCESS;
1242
0
  sc_serial_number_t serial;
1243
0
  struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
1244
1245
0
  res = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial);
1246
0
  LOG_TEST_RET(card->ctx, res, "Error in getting serial number");
1247
  /* copy into sn_icc buffer.Remember that dnie sn has 7 bytes length */
1248
0
  memset(sm->icc.sn, 0, sizeof(sm->icc.sn));
1249
0
  memcpy(&sm->icc.sn[1], serial.value, 7);
1250
0
  return SC_SUCCESS;
1251
0
}
1252
1253
/**
1254
 * CWA-14890 SM stablisment pre-operations.
1255
 *
1256
 * DNIe needs to get icc serial number at the begin of the sm creation
1257
 * (to avoid breaking key references) so get it an store into serialnr
1258
 * cache here.
1259
 *
1260
 * In this way if get_sn_icc is called(), we make sure that no APDU
1261
 * command is to be sent to card, just retrieve it from cache
1262
 *
1263
 * @param card pointer to card driver structure
1264
 * @param provider pointer to SM data provider for DNIe
1265
 * @return SC_SUCCESS if OK. else error code
1266
 */
1267
static int dnie_create_pre_ops(sc_card_t * card, cwa_provider_t * provider)
1268
0
{
1269
0
  sc_serial_number_t serial;
1270
1271
  /* make sure that this cwa provider is used with a working DNIe card */
1272
0
  if (card->type != SC_CARD_TYPE_DNIE_USER)
1273
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD);
1274
1275
  /* ensure that Card Serial Number is properly cached */
1276
0
  return sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial);
1277
0
}
1278
1279
/**
1280
 * Main entry point for DNIe CWA14890 SM data provider.
1281
 *
1282
 * Return a pointer to DNIe data provider with proper function pointers
1283
 *
1284
 * @param card pointer to card driver data structure
1285
 * @return cwa14890 DNIe data provider if success, null on error
1286
 */
1287
cwa_provider_t *dnie_get_cwa_provider(sc_card_t * card)
1288
35
{
1289
1290
35
  cwa_provider_t *res = cwa_get_default_provider(card);
1291
35
  if (!res)
1292
0
    return NULL;
1293
1294
  /* set up proper data */
1295
1296
  /* pre and post operations */
1297
35
  res->cwa_create_pre_ops = dnie_create_pre_ops;
1298
1299
  /* Get ICC intermediate CA  path */
1300
35
  res->cwa_get_icc_intermediate_ca_cert = dnie_get_icc_intermediate_ca_cert;
1301
  /* Get ICC certificate path */
1302
35
  res->cwa_get_icc_cert = dnie_get_icc_cert;
1303
1304
  /* Obtain RSA public key from RootCA */
1305
35
  res->cwa_get_root_ca_pubkey = dnie_get_root_ca_pubkey;
1306
  /* Obtain RSA IFD private key */
1307
35
  res->cwa_get_ifd_privkey = dnie_get_ifd_privkey;
1308
1309
  /* Retrieve CVC intermediate CA certificate and length */
1310
35
  res->cwa_get_cvc_ca_cert = dnie_get_cvc_ca_cert;
1311
  /* Retrieve CVC IFD certificate and length */
1312
35
  res->cwa_get_cvc_ifd_cert = dnie_get_cvc_ifd_cert;
1313
1314
  /* Get public key references for Root CA to validate intermediate CA cert */
1315
35
  res->cwa_get_root_ca_pubkey_ref = dnie_get_root_ca_pubkey_ref;
1316
1317
  /* Get public key reference for IFD intermediate CA certificate */
1318
35
  res->cwa_get_intermediate_ca_pubkey_ref = dnie_get_intermediate_ca_pubkey_ref;
1319
1320
  /* Get public key reference for IFD CVC certificate */
1321
35
  res->cwa_get_ifd_pubkey_ref = dnie_get_ifd_pubkey_ref;
1322
1323
  /* Get ICC private key reference */
1324
35
  res->cwa_get_icc_privkey_ref = dnie_get_icc_privkey_ref;
1325
1326
  /* Get IFD Serial Number */
1327
35
  res->cwa_get_sn_ifd = dnie_get_sn_ifd;
1328
1329
  /* Get ICC Serial Number */
1330
35
  res->cwa_get_sn_icc = dnie_get_sn_icc;
1331
1332
35
  return res;
1333
35
}
1334
1335
/**
1336
 * Changes the provider to use the common secure (DNIe 2.0)
1337
 * channel.
1338
 *
1339
 * @param card the card to change the cwa provider for
1340
 */
1341
void dnie_change_cwa_provider_to_secure(sc_card_t * card)
1342
0
{
1343
0
  cwa_provider_t * res = GET_DNIE_PRIV_DATA(card)->cwa_provider;
1344
1345
  /* redefine different IFD data for secure channel */
1346
0
  res->cwa_get_cvc_ifd_cert = dnie_get_cvc_ifd_cert;
1347
0
  res->cwa_get_ifd_privkey = dnie_get_ifd_privkey;
1348
0
  res->cwa_get_ifd_pubkey_ref = dnie_get_ifd_pubkey_ref;
1349
0
  res->cwa_get_sn_ifd = dnie_get_sn_ifd;
1350
0
}
1351
1352
/**
1353
 * Changes the provider to use the new PIN (DNIe 3.0)
1354
 * channel.
1355
 *
1356
 * @param card the card to change the cwa provider for
1357
 */
1358
void dnie_change_cwa_provider_to_pin(sc_card_t * card)
1359
0
{
1360
0
  cwa_provider_t * res = GET_DNIE_PRIV_DATA(card)->cwa_provider;
1361
1362
  /* redefine different IFD data for PIN channel */
1363
0
  res->cwa_get_cvc_ifd_cert = dnie_get_cvc_ifd_cert_pin;
1364
0
  res->cwa_get_ifd_privkey = dnie_get_ifd_privkey_pin;
1365
0
  res->cwa_get_ifd_pubkey_ref = dnie_get_ifd_pubkey_ref_pin;
1366
0
  res->cwa_get_sn_ifd = dnie_get_sn_ifd_pin;
1367
0
}
1368
1369
void dnie_format_apdu(sc_card_t *card, sc_apdu_t *apdu,
1370
      int cse, int ins, int p1, int p2, size_t le, size_t lc,
1371
      unsigned char * resp, size_t resplen,
1372
      const unsigned char * data, size_t datalen)
1373
46
{
1374
46
  sc_format_apdu(card, apdu, cse, ins, p1, p2);
1375
46
  apdu->le = le;
1376
46
  apdu->lc = lc;
1377
46
  if (resp != NULL) {
1378
46
    apdu->resp = resp;
1379
46
    apdu->resplen = resplen;
1380
46
  }
1381
46
  if (data != NULL) {
1382
46
    apdu->data = data;
1383
46
    apdu->datalen = datalen;
1384
46
  }
1385
46
}
1386
1387
#endif        /* HAVE_OPENSSL */
1388
/* _ end of cwa-dnie.c - */