Coverage Report

Created: 2025-11-13 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/pkcs15init/pkcs15-isoApplet.c
Line
Count
Source
1
/*
2
 * pkcs15-init driver for JavaCards with IsoApplet installed.
3
 *
4
 * Copyright (C) 2014 Philip Wendland <wendlandphilip@gmail.com>
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20
21
#include "config.h"
22
23
#include <sys/types.h>
24
#include <stdlib.h>
25
#include <string.h>
26
#include <assert.h>
27
#include <stdarg.h>
28
29
#include "../libopensc/log.h"
30
#include "../libopensc/internal.h"
31
#include "../libopensc/opensc.h"
32
#include "../libopensc/cardctl.h"
33
#include "../libopensc/asn1.h"
34
#include "pkcs15-init.h"
35
#include "profile.h"
36
37
0
#define ISOAPPLET_KEY_ID_MIN 0
38
0
#define ISOAPPLET_KEY_ID_MAX 15
39
40
/* Curve parameters of a curve specified by the OID. */
41
struct ec_curve
42
{
43
  const struct sc_lv_data oid; /* Object ID in hex, including structural information */
44
  const struct sc_lv_data prime;
45
  const struct sc_lv_data coefficientA;
46
  const struct sc_lv_data coefficientB;
47
  const struct sc_lv_data basePointG;
48
  const struct sc_lv_data order;
49
  const struct sc_lv_data coFactor;
50
};
51
52
/* OpenSC only works with named curves, but we need the
53
 * explicit parameters for ECC key generation or import. */
54
static const struct ec_curve curves[] =
55
{
56
  {
57
    /* brainpoolP192r1 */
58
    { (unsigned char *) "\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x03", 11},
59
    { (unsigned char *) "\xC3\x02\xF4\x1D\x93\x2A\x36\xCD\xA7\xA3\x46\x30\x93\xD1\x8D\xB7\x8F\xCE\x47\x6D\xE1\xA8\x62\x97", 24},
60
    { (unsigned char *) "\x6A\x91\x17\x40\x76\xB1\xE0\xE1\x9C\x39\xC0\x31\xFE\x86\x85\xC1\xCA\xE0\x40\xE5\xC6\x9A\x28\xEF", 24},
61
    { (unsigned char *) "\x46\x9A\x28\xEF\x7C\x28\xCC\xA3\xDC\x72\x1D\x04\x4F\x44\x96\xBC\xCA\x7E\xF4\x14\x6F\xBF\x25\xC9", 24},
62
    { (unsigned char *) "\x04\xC0\xA0\x64\x7E\xAA\xB6\xA4\x87\x53\xB0\x33\xC5\x6C\xB0\xF0\x90\x0A\x2F\x5C\x48\x53\x37\x5F\xD6\x14\xB6\x90\x86\x6A\xBD\x5B\xB8\x8B\x5F\x48\x28\xC1\x49\x00\x02\xE6\x77\x3F\xA2\xFA\x29\x9B\x8F", 49},
63
    { (unsigned char *) "\xC3\x02\xF4\x1D\x93\x2A\x36\xCD\xA7\xA3\x46\x2F\x9E\x9E\x91\x6B\x5B\xE8\xF1\x02\x9A\xC4\xAC\xC1", 24},
64
    { (unsigned char *) "\x00\x01", 2}
65
  },
66
67
  {
68
    /* brainpoolP224r1 */
69
    { (unsigned char *) "\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x05", 11},
70
    { (unsigned char *) "\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A\x18\x30\x25\x75\xD1\xD7\x87\xB0\x9F\x07\x57\x97\xDA\x89\xF5\x7E\xC8\xC0\xFF", 28},
71
    { (unsigned char *) "\x68\xA5\xE6\x2C\xA9\xCE\x6C\x1C\x29\x98\x03\xA6\xC1\x53\x0B\x51\x4E\x18\x2A\xD8\xB0\x04\x2A\x59\xCA\xD2\x9F\x43", 28},
72
    { (unsigned char *) "\x25\x80\xF6\x3C\xCF\xE4\x41\x38\x87\x07\x13\xB1\xA9\x23\x69\xE3\x3E\x21\x35\xD2\x66\xDB\xB3\x72\x38\x6C\x40\x0B", 28},
73
    { (unsigned char *) "\x04\x0D\x90\x29\xAD\x2C\x7E\x5C\xF4\x34\x08\x23\xB2\xA8\x7D\xC6\x8C\x9E\x4C\xE3\x17\x4C\x1E\x6E\xFD\xEE\x12\xC0\x7D\x58\xAA\x56\xF7\x72\xC0\x72\x6F\x24\xC6\xB8\x9E\x4E\xCD\xAC\x24\x35\x4B\x9E\x99\xCA\xA3\xF6\xD3\x76\x14\x02\xCD", 57},
74
    { (unsigned char *) "\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A\x18\x30\x25\x75\xD0\xFB\x98\xD1\x16\xBC\x4B\x6D\xDE\xBC\xA3\xA5\xA7\x93\x9F", 28},
75
    { (unsigned char *) "\x00\x01", 2}
76
  },
77
78
  {
79
    /* brainpoolP256r1 */
80
    { (unsigned char *) "\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x07", 11},
81
    { (unsigned char *) "\xA9\xFB\x57\xDB\xA1\xEE\xA9\xBC\x3E\x66\x0A\x90\x9D\x83\x8D\x72\x6E\x3B\xF6\x23\xD5\x26\x20\x28\x20\x13\x48\x1D\x1F\x6E\x53\x77", 32},
82
    { (unsigned char *) "\x7D\x5A\x09\x75\xFC\x2C\x30\x57\xEE\xF6\x75\x30\x41\x7A\xFF\xE7\xFB\x80\x55\xC1\x26\xDC\x5C\x6C\xE9\x4A\x4B\x44\xF3\x30\xB5\xD9", 32},
83
    { (unsigned char *) "\x26\xDC\x5C\x6C\xE9\x4A\x4B\x44\xF3\x30\xB5\xD9\xBB\xD7\x7C\xBF\x95\x84\x16\x29\x5C\xF7\xE1\xCE\x6B\xCC\xDC\x18\xFF\x8C\x07\xB6", 32},
84
    { (unsigned char *) "\x04\x8B\xD2\xAE\xB9\xCB\x7E\x57\xCB\x2C\x4B\x48\x2F\xFC\x81\xB7\xAF\xB9\xDE\x27\xE1\xE3\xBD\x23\xC2\x3A\x44\x53\xBD\x9A\xCE\x32\x62\x54\x7E\xF8\x35\xC3\xDA\xC4\xFD\x97\xF8\x46\x1A\x14\x61\x1D\xC9\xC2\x77\x45\x13\x2D\xED\x8E\x54\x5C\x1D\x54\xC7\x2F\x04\x69\x97", 65},
85
    { (unsigned char *) "\xA9\xFB\x57\xDB\xA1\xEE\xA9\xBC\x3E\x66\x0A\x90\x9D\x83\x8D\x71\x8C\x39\x7A\xA3\xB5\x61\xA6\xF7\x90\x1E\x0E\x82\x97\x48\x56\xA7", 32},
86
    { (unsigned char *) "\x00\x01", 2}
87
  },
88
89
  {
90
    /* brainpoolP320r1 */
91
    { (unsigned char *) "\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x09", 11},
92
    { (unsigned char *) "\xD3\x5E\x47\x20\x36\xBC\x4F\xB7\xE1\x3C\x78\x5E\xD2\x01\xE0\x65\xF9\x8F\xCF\xA6\xF6\xF4\x0D\xEF\x4F\x92\xB9\xEC\x78\x93\xEC\x28\xFC\xD4\x12\xB1\xF1\xB3\x2E\x27", 40},
93
    { (unsigned char *) "\x3E\xE3\x0B\x56\x8F\xBA\xB0\xF8\x83\xCC\xEB\xD4\x6D\x3F\x3B\xB8\xA2\xA7\x35\x13\xF5\xEB\x79\xDA\x66\x19\x0E\xB0\x85\xFF\xA9\xF4\x92\xF3\x75\xA9\x7D\x86\x0E\xB4", 40},
94
    { (unsigned char *) "\x52\x08\x83\x94\x9D\xFD\xBC\x42\xD3\xAD\x19\x86\x40\x68\x8A\x6F\xE1\x3F\x41\x34\x95\x54\xB4\x9A\xCC\x31\xDC\xCD\x88\x45\x39\x81\x6F\x5E\xB4\xAC\x8F\xB1\xF1\xA6", 40},
95
    { (unsigned char *) "\x04\x43\xBD\x7E\x9A\xFB\x53\xD8\xB8\x52\x89\xBC\xC4\x8E\xE5\xBF\xE6\xF2\x01\x37\xD1\x0A\x08\x7E\xB6\xE7\x87\x1E\x2A\x10\xA5\x99\xC7\x10\xAF\x8D\x0D\x39\xE2\x06\x11\x14\xFD\xD0\x55\x45\xEC\x1C\xC8\xAB\x40\x93\x24\x7F\x77\x27\x5E\x07\x43\xFF\xED\x11\x71\x82\xEA\xA9\xC7\x78\x77\xAA\xAC\x6A\xC7\xD3\x52\x45\xD1\x69\x2E\x8E\xE1", 81},
96
    { (unsigned char *) "\xD3\x5E\x47\x20\x36\xBC\x4F\xB7\xE1\x3C\x78\x5E\xD2\x01\xE0\x65\xF9\x8F\xCF\xA5\xB6\x8F\x12\xA3\x2D\x48\x2E\xC7\xEE\x86\x58\xE9\x86\x91\x55\x5B\x44\xC5\x93\x11", 40},
97
    { (unsigned char *) "\x00\x01", 2}
98
  },
99
100
  {
101
    /* prime192v1, secp192r1, ansiX9p192r1 */
102
    { (unsigned char *) "\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x01", 10},
103
    { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 24},
104
    { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC", 24},
105
    { (unsigned char *) "\x64\x21\x05\x19\xE5\x9C\x80\xE7\x0F\xA7\xE9\xAB\x72\x24\x30\x49\xFE\xB8\xDE\xEC\xC1\x46\xB9\xB1", 24},
106
    { (unsigned char *) "\x04\x18\x8D\xA8\x0E\xB0\x30\x90\xF6\x7C\xBF\x20\xEB\x43\xA1\x88\x00\xF4\xFF\x0A\xFD\x82\xFF\x10\x12\x07\x19\x2B\x95\xFF\xC8\xDA\x78\x63\x10\x11\xED\x6B\x24\xCD\xD5\x73\xF9\x77\xA1\x1E\x79\x48\x11", 49},
107
    { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x99\xDE\xF8\x36\x14\x6B\xC9\xB1\xB4\xD2\x28\x31", 24},
108
    { (unsigned char *) "\x00\x01", 2}
109
  },
110
111
  {
112
    /* prime224v1, nistp224 */
113
    { (unsigned char *) "\x06\x05\x2b\x81\x04\x00\x21", 7},
114
    { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 28},
115
    { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE", 28},
116
    { (unsigned char *) "\xB4\x05\x0A\x85\x0C\x04\xB3\xAB\xF5\x41\x32\x56\x50\x44\xB0\xB7\xD7\xBF\xD8\xBA\x27\x0B\x39\x43\x23\x55\xFF\xB4", 28},
117
    { (unsigned char *) "\x04\xB7\x0E\x0C\xBD\x6B\xB4\xBF\x7F\x32\x13\x90\xB9\x4A\x03\xC1\xD3\x56\xC2\x11\x22\x34\x32\x80\xD6\x11\x5C\x1D\x21\xBD\x37\x63\x88\xB5\xF7\x23\xFB\x4C\x22\xDF\xE6\xCD\x43\x75\xA0\x5A\x07\x47\x64\x44\xD5\x81\x99\x85\x00\x7E\x34", 57},
118
    { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\xA2\xE0\xB8\xF0\x3E\x13\xDD\x29\x45\x5C\x5C\x2A\x3D", 28},
119
    { (unsigned char *) "\x00\x01", 2}
120
  },
121
122
  {
123
    /* prime256v1, secp256r1, ansiX9p256r1 */
124
    { (unsigned char *) "\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x07", 10},
125
    { (unsigned char *) "\xFF\xFF\xFF\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 32},
126
    { (unsigned char *) "\xFF\xFF\xFF\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC", 32},
127
    { (unsigned char *) "\x5A\xC6\x35\xD8\xAA\x3A\x93\xE7\xB3\xEB\xBD\x55\x76\x98\x86\xBC\x65\x1D\x06\xB0\xCC\x53\xB0\xF6\x3B\xCE\x3C\x3E\x27\xD2\x60\x4B", 32},
128
    { (unsigned char *) "\x04\x6B\x17\xD1\xF2\xE1\x2C\x42\x47\xF8\xBC\xE6\xE5\x63\xA4\x40\xF2\x77\x03\x7D\x81\x2D\xEB\x33\xA0\xF4\xA1\x39\x45\xD8\x98\xC2\x96\x4F\xE3\x42\xE2\xFE\x1A\x7F\x9B\x8E\xE7\xEB\x4A\x7C\x0F\x9E\x16\x2B\xCE\x33\x57\x6B\x31\x5E\xCE\xCB\xB6\x40\x68\x37\xBF\x51\xF5", 65},
129
    { (unsigned char *) "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xBC\xE6\xFA\xAD\xA7\x17\x9E\x84\xF3\xB9\xCA\xC2\xFC\x63\x25\x51", 32},
130
    { (unsigned char *) "\x00\x01", 2}
131
  },
132
133
  {
134
    /* prime384v1, secp384r1, ansiX9p384r1 */
135
    { (unsigned char *) "\x06\x05\x2B\x81\x04\x00\x22", 7},
136
    { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF", 48},
137
    { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFC", 48},
138
    { (unsigned char *) "\xB3\x31\x2F\xA7\xE2\x3E\xE7\xE4\x98\x8E\x05\x6B\xE3\xF8\x2D\x19\x18\x1D\x9C\x6E\xFE\x81\x41\x12\x03\x14\x08\x8F\x50\x13\x87\x5A\xC6\x56\x39\x8D\x8A\x2E\xD1\x9D\x2A\x85\xC8\xED\xD3\xEC\x2A\xEF", 48},
139
    { (unsigned char *) "\x04\xAA\x87\xCA\x22\xBE\x8B\x05\x37\x8E\xB1\xC7\x1E\xF3\x20\xAD\x74\x6E\x1D\x3B\x62\x8B\xA7\x9B\x98\x59\xF7\x41\xE0\x82\x54\x2A\x38\x55\x02\xF2\x5D\xBF\x55\x29\x6C\x3A\x54\x5E\x38\x72\x76\x0A\xB7\x36\x17\xDE\x4A\x96\x26\x2C\x6F\x5D\x9E\x98\xBF\x92\x92\xDC\x29\xF8\xF4\x1D\xBD\x28\x9A\x14\x7C\xE9\xDA\x31\x13\xB5\xF0\xB8\xC0\x0A\x60\xB1\xCE\x1D\x7E\x81\x9D\x7A\x43\x1D\x7C\x90\xEA\x0E\x5F", 97},
140
    { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC7\x63\x4D\x81\xF4\x37\x2D\xDF\x58\x1A\x0D\xB2\x48\xB0\xA7\x7A\xEC\xEC\x19\x6A\xCC\xC5\x29\x73", 48},
141
    { (unsigned char *) "\x00\x01", 2}
142
  },
143
144
  {
145
    /* secp192k1 */
146
    { (unsigned char *) "\x06\x05\x2B\x81\x04\x00\x1F", 7},
147
    { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xEE\x37", 24},
148
    { (unsigned char *) "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 24},
149
    { (unsigned char *) "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03", 24},
150
    { (unsigned char *) "\x04\xDB\x4F\xF1\x0E\xC0\x57\xE9\xAE\x26\xB0\x7D\x02\x80\xB7\xF4\x34\x1D\xA5\xD1\xB1\xEA\xE0\x6C\x7D\x9B\x2F\x2F\x6D\x9C\x56\x28\xA7\x84\x41\x63\xD0\x15\xBE\x86\x34\x40\x82\xAA\x88\xD9\x5E\x2F\x9D", 49},
151
    { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\x26\xF2\xFC\x17\x0F\x69\x46\x6A\x74\xDE\xFD\x8D", 24},
152
    { (unsigned char *) "\x00\x01", 2}
153
  },
154
155
  {
156
    /* secp256k1 */
157
    { (unsigned char *) "\x06\x05\x2B\x81\x04\x00\x0A", 7},
158
    { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFC\x2F", 32},
159
    { (unsigned char *) "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32},
160
    { (unsigned char *) "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07", 32},
161
    { (unsigned char *) "\x04\x79\xBE\x66\x7E\xF9\xDC\xBB\xAC\x55\xA0\x62\x95\xCE\x87\x0B\x07\x02\x9B\xFC\xDB\x2D\xCE\x28\xD9\x59\xF2\x81\x5B\x16\xF8\x17\x98\x48\x3A\xDA\x77\x26\xA3\xC4\x65\x5D\xA4\xFB\xFC\x0E\x11\x08\xA8\xFD\x17\xB4\x48\xA6\x85\x54\x19\x9C\x47\xD0\x8F\xFB\x10\xD4\xB8", 65},
162
    { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xBA\xAE\xDC\xE6\xAF\x48\xA0\x3B\xBF\xD2\x5E\x8C\xD0\x36\x41\x41", 32},
163
    { (unsigned char *) "\x00\x01", 2}
164
  },
165
166
  {
167
    { NULL, 0},
168
    { NULL, 0},
169
    { NULL, 0},
170
    { NULL, 0},
171
    { NULL, 0},
172
    { NULL, 0},
173
    { NULL, 0}
174
  }
175
};
176
177
178
/*
179
 * Create DF, using default pkcs15init functions.
180
 */
181
static int
182
isoApplet_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df)
183
0
{
184
0
  sc_card_t *card = p15card->card;
185
0
  int r = SC_SUCCESS;
186
187
0
  LOG_FUNC_CALLED(card->ctx);
188
189
0
  if(!profile || !df || !p15card->card->ctx)
190
0
  {
191
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
192
0
  }
193
0
  r = sc_pkcs15init_create_file(profile, p15card, df);
194
0
  LOG_FUNC_RETURN(card->ctx, r);
195
0
}
196
197
/*
198
 * Select a PIN reference.
199
 *
200
 * Basically (as I understand it) the caller passes an auth_info object and the
201
 * auth_info->attrs.pin.reference is supposed to be set accordingly and return.
202
 *
203
 * The IsoApplet only supports a PIN and a PUK at the moment.
204
 * The reference for the PIN is 1, for the PUK 2.
205
 */
206
static int
207
isoApplet_select_pin_reference(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
208
                               sc_pkcs15_auth_info_t *auth_info)
209
0
{
210
0
  sc_card_t *card = p15card->card;
211
0
  int preferred;
212
0
  int current;
213
214
0
  LOG_FUNC_CALLED(card->ctx);
215
216
0
  if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
217
0
  {
218
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_VALID);
219
0
  }
220
221
0
  current = auth_info->attrs.pin.reference;
222
0
  if (current < 0)
223
0
  {
224
0
    current = 0;
225
0
  }
226
227
0
  if(current > 2)
228
0
  {
229
    /* Only two PINs supported: User PIN and PUK. */
230
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_TOO_MANY_OBJECTS);
231
0
  }
232
0
  else
233
0
  {
234
0
    if(auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN)
235
0
    {
236
      /* PUK */
237
0
      preferred = 2;
238
0
    }
239
0
    else
240
0
    {
241
      /* PIN */
242
0
      preferred = 1;
243
0
    }
244
0
  }
245
246
0
  auth_info->attrs.pin.reference = preferred;
247
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
248
0
}
249
250
/*
251
 * Create a PIN and store it on the card using CHANGE REFERENCE DATA for PIN transmission.
252
 * First, the PUK is transmitted, then the PIN. Now, the IsoApplet is in the
253
 * "STATE_OPERATIONAL_ACTIVATED" lifecycle state.
254
 */
255
static int
256
isoApplet_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df,
257
                     sc_pkcs15_object_t *pin_obj,
258
                     const u8 *pin, size_t pin_len,
259
                     const u8 *puk, size_t puk_len)
260
0
{
261
0
  sc_card_t *card = p15card->card;
262
0
  sc_pkcs15_auth_info_t *auth_info = (sc_pkcs15_auth_info_t *) pin_obj->data;
263
0
  struct sc_pkcs15_pin_attributes *pin_attrs = &auth_info->attrs.pin;
264
0
  int r;
265
266
0
  LOG_FUNC_CALLED(card->ctx);
267
268
0
  if(!pin || !pin_len || !df)
269
0
  {
270
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
271
0
  }
272
273
0
  if(pin_attrs->reference != 1 && pin_attrs->reference != 2)
274
0
  {
275
    /* Reject PIN reference. */
276
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_PIN_REFERENCE);
277
0
  }
278
279
  /* If we have a PUK, set it first. */
280
0
  if(puk && puk_len)
281
0
  {
282
    /* The PUK has a incremented reference, i.e. pins are odd, puks are equal (+1). */
283
0
    r = sc_change_reference_data(p15card->card, SC_AC_CHV,
284
0
                                 pin_attrs->reference+1,
285
0
                                 NULL, 0,
286
0
                                 puk, puk_len, NULL);
287
0
    if(r < 0)
288
0
    {
289
0
      LOG_FUNC_RETURN(card->ctx, r);
290
0
    }
291
0
  }
292
293
  /* Store PIN: (use CHANGE REFERENCE DATA). */
294
0
  r = sc_change_reference_data(p15card->card, SC_AC_CHV,
295
0
                               pin_attrs->reference,
296
0
                               NULL, 0,
297
0
                               pin, pin_len, NULL);
298
0
  LOG_TEST_RET(card->ctx, r, "Failed to set PIN");
299
300
0
  sc_pkcs15_pincache_add(p15card, pin_obj, pin, pin_len);
301
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
302
0
}
303
304
/*
305
 * @brief Get the curve parameters associated with the curve specified by an OID.
306
 *
307
 * @param[in]  oid       The DER encoded OID of the curve.
308
 * @param[in]  oid_len   The length of oid.
309
 * @param[out] curve_out The ec_curve containing the set of parameters.
310
 *
311
 * @returns SC_SUCCESS: If the curve was found.
312
 *      SC_ERROR_INVALID_ARGUMENTS: If named_curve was null or the curve
313
 *                    was not found
314
 */
315
static int
316
isoApplet_get_curve(u8 *oid, size_t oid_len, const struct ec_curve **curve_out)
317
0
{
318
0
  int i;
319
320
0
  if(!oid)
321
0
    return SC_ERROR_INVALID_ARGUMENTS;
322
323
  /* Search the curve parameters. */
324
0
  for (i = 0; curves[i].oid.value; i++)
325
0
  {
326
0
    if (oid_len == curves[i].oid.len && memcmp(oid, curves[i].oid.value, curves[i].oid.len) == 0)
327
0
    {
328
0
      *curve_out = &curves[i];
329
0
      return SC_SUCCESS;
330
0
    }
331
0
  }
332
333
0
  return SC_ERROR_INVALID_ARGUMENTS;
334
0
}
335
336
337
/*
338
 * @brief Generate a RSA private key on the card.
339
 *
340
 * A MANAGE SECURITY ENVIRONMENT apdu must have been sent before.
341
 * This function uses card_ctl to access the card-isoApplet driver.
342
 *
343
 * @param[in] key_info
344
 * @param[in] card
345
 * @param[in] pubkey The public key of the generated key pair
346
 *                   returned by the card.
347
 *
348
 * @return  SC_ERROR_INVALID_ARGUMENTS: Invalid key length.
349
 *          SC_ERROR_OUT_OF_MEMORY
350
 */
351
static int
352
isoApplet_generate_key_rsa(sc_pkcs15_prkey_info_t *key_info, sc_card_t *card,
353
                           sc_pkcs15_pubkey_t *pubkey)
354
0
{
355
0
  int rv;
356
0
  size_t keybits;
357
0
  struct sc_cardctl_isoApplet_genkey args;
358
359
0
  LOG_FUNC_CALLED(card->ctx);
360
361
0
  memset(&args, 0, sizeof(args));
362
363
  /* Check key size: */
364
0
  keybits = key_info->modulus_length;
365
0
  if (keybits != 2048 && keybits != 4096)
366
0
  {
367
0
    rv = SC_ERROR_INVALID_ARGUMENTS;
368
0
    sc_log(card->ctx, "%s: RSA private key length is unsupported, correct length is 2048 or 4096", sc_strerror(rv));
369
0
    goto err;
370
0
  }
371
372
  /* Generate the key.
373
   * Note: key size is not explicitly passed to the card.
374
   * Its derived from the algorithm reference. */
375
0
  args.algorithm_ref = keybits == 2048 ? SC_ISOAPPLET_ALG_REF_RSA_GEN_2048 : SC_ISOAPPLET_ALG_REF_RSA_GEN_4096;
376
0
  args.priv_key_ref = key_info->key_reference;
377
378
0
  args.pubkey.rsa.modulus.len = keybits / 8;
379
0
  args.pubkey.rsa.modulus.value = malloc(args.pubkey.rsa.modulus.len);
380
0
  if (!args.pubkey.rsa.modulus.value)
381
0
  {
382
0
    rv = SC_ERROR_OUT_OF_MEMORY;
383
0
    sc_log(card->ctx, "%s: Unable to allocate public key buffer.", sc_strerror(rv));
384
0
    goto err;
385
0
  }
386
387
0
  args.pubkey.rsa.exponent.len = 3;
388
0
  args.pubkey.rsa.exponent.value = malloc(args.pubkey.rsa.exponent.len);
389
0
  if(!args.pubkey.rsa.exponent.value)
390
0
  {
391
0
    rv = SC_ERROR_OUT_OF_MEMORY;
392
0
    sc_log(card->ctx, "%s: Unable to allocate public key exponent buffer.", sc_strerror(rv));
393
0
    goto err;
394
0
  }
395
396
0
  rv = sc_card_ctl(card, SC_CARDCTL_ISOAPPLET_GENERATE_KEY, &args);
397
0
  if (rv < 0)
398
0
  {
399
0
    sc_log(card->ctx, "%s: Error in card_ctl", sc_strerror(rv));
400
0
    goto err;
401
0
  }
402
403
  /* extract the public key */
404
0
  pubkey->algorithm = SC_ALGORITHM_RSA;
405
0
  pubkey->u.rsa.modulus.len = args.pubkey.rsa.modulus.len;
406
0
  pubkey->u.rsa.modulus.data  = args.pubkey.rsa.modulus.value;
407
0
  pubkey->u.rsa.exponent.len  = args.pubkey.rsa.exponent.len;
408
0
  pubkey->u.rsa.exponent.data = args.pubkey.rsa.exponent.value;
409
0
  rv = SC_SUCCESS;
410
0
  LOG_FUNC_RETURN(card->ctx, rv);
411
0
err:
412
0
  if (args.pubkey.rsa.modulus.value)
413
0
  {
414
0
    free(args.pubkey.rsa.modulus.value);
415
0
    pubkey->u.rsa.modulus.data = NULL;
416
0
    pubkey->u.rsa.modulus.len = 0;
417
0
  }
418
0
  if (args.pubkey.rsa.exponent.value)
419
0
  {
420
0
    free(args.pubkey.rsa.exponent.value);
421
0
    pubkey->u.rsa.exponent.data = NULL;
422
0
    pubkey->u.rsa.exponent.len = 0;
423
0
  }
424
0
  LOG_FUNC_RETURN(card->ctx, rv);
425
0
}
426
427
/*
428
 * @brief Generate a EC private key on the card.
429
 *
430
 * A MANAGE SECURITY ENVIRONMENT apdu must have been sent before.
431
 * This function uses card_ctl to access the card-isoApplet driver.
432
 *
433
 * @param[in]     key_info
434
 * @param[in]     card
435
 * @param[in/out] pubkey The public key of the generated key pair
436
 *             returned by the card.
437
 *
438
 * @return SC_ERROR_INVALID_ARGUMENTS: Invalid key length or curve.
439
 *         SC_ERROR_OUT_OF_MEMORY
440
 *         SC_ERROR_INCOMPATIBLE_KEY: The data returned by the card
441
 *                                    was unexpected and can not be
442
 *                                    handled.
443
 */
444
static int
445
isoApplet_generate_key_ec(const sc_pkcs15_prkey_info_t *key_info, sc_card_t *card,
446
                          sc_pkcs15_pubkey_t *pubkey)
447
0
{
448
0
  int r;
449
0
  const struct ec_curve *curve = NULL;
450
0
  struct sc_ec_parameters *alg_id_params = NULL;
451
0
  sc_cardctl_isoApplet_genkey_t args;
452
0
  const struct sc_ec_parameters *info_ecp =
453
0
      (struct sc_ec_parameters *) key_info->params.data;
454
455
0
  LOG_FUNC_CALLED(card->ctx);
456
457
0
  memset(&args, 0, sizeof(args));
458
459
  /* Check key size: */
460
0
  if(key_info->field_length == 0)
461
0
  {
462
0
    sc_log(card->ctx, "Unknown field length.");
463
0
    r = SC_ERROR_INVALID_ARGUMENTS;
464
0
    goto out;
465
0
  }
466
467
0
  r = isoApplet_get_curve(info_ecp->der.value, info_ecp->der.len, &curve);
468
0
  if(r < 0)
469
0
  {
470
0
    sc_log(card->ctx, "EC key generation failed: Unsupported curve: [%s].", info_ecp->named_curve);
471
0
    goto out;
472
0
  }
473
474
  /* Generate the key.
475
   * Note: The field size is not explicitly passed to the card.
476
   *       As we only support FP curves, the field length can be calculated from any parameter. */
477
0
  args.pubkey.ec.params.prime.value     = curve->prime.value;
478
0
  args.pubkey.ec.params.prime.len       = curve->prime.len;
479
0
  args.pubkey.ec.params.coefficientA.value  = curve->coefficientA.value;
480
0
  args.pubkey.ec.params.coefficientA.len    = curve->coefficientA.len;
481
0
  args.pubkey.ec.params.coefficientB.value  = curve->coefficientB.value;
482
0
  args.pubkey.ec.params.coefficientB.len    = curve->coefficientB.len;
483
0
  args.pubkey.ec.params.basePointG.value    = curve->basePointG.value;
484
0
  args.pubkey.ec.params.basePointG.len    = curve->basePointG.len;
485
0
  args.pubkey.ec.params.order.value       = curve->order.value;
486
0
  args.pubkey.ec.params.order.len       = curve->order.len;
487
0
  args.pubkey.ec.params.coFactor.value    = curve->coFactor.value;
488
0
  args.pubkey.ec.params.coFactor.len      = curve->coFactor.len;
489
  /* The length of the public key point will be:
490
   * Uncompressed tag + 2 * field length in bytes. */
491
0
  args.pubkey.ec.ecPointQ.len = 1 + BYTES4BITS(key_info->field_length) * 2;
492
0
  args.pubkey.ec.ecPointQ.value = malloc(args.pubkey.ec.ecPointQ.len);
493
0
  if(!args.pubkey.ec.ecPointQ.value)
494
0
  {
495
0
    r = SC_ERROR_OUT_OF_MEMORY;
496
0
    goto out;
497
0
  }
498
499
0
  args.algorithm_ref = SC_ISOAPPLET_ALG_REF_EC_GEN;
500
0
  args.priv_key_ref = key_info->key_reference;
501
502
  /* On-card key generation */
503
0
  r = sc_card_ctl(card, SC_CARDCTL_ISOAPPLET_GENERATE_KEY, &args);
504
0
  if (r < 0)
505
0
  {
506
0
    sc_log(card->ctx, "%s: Error in card_ctl.", sc_strerror(r));
507
0
    goto out;
508
0
  }
509
510
  /* Extract and compose the public key. */
511
0
  pubkey->algorithm = SC_ALGORITHM_EC;
512
513
  /* der-encoded parameters */
514
0
  alg_id_params = calloc(1, sizeof(*alg_id_params));
515
0
  if(!alg_id_params)
516
0
  {
517
0
    r = SC_ERROR_OUT_OF_MEMORY;
518
0
    goto out;
519
0
  }
520
0
  alg_id_params->der.len = curve->oid.len;
521
0
  alg_id_params->der.value = malloc(alg_id_params->der.len);
522
0
  if(!alg_id_params->der.value)
523
0
  {
524
0
    r = SC_ERROR_OUT_OF_MEMORY;
525
0
    goto out;
526
0
  }
527
0
  memcpy(alg_id_params->der.value, curve->oid.value, curve->oid.len);
528
0
  alg_id_params->type = 1; /* named curve */
529
530
0
  pubkey->alg_id = malloc(sizeof(*pubkey->alg_id));
531
0
  if(!pubkey->alg_id)
532
0
  {
533
0
    r = SC_ERROR_OUT_OF_MEMORY;
534
0
    goto out;
535
0
  }
536
0
  pubkey->alg_id->algorithm = SC_ALGORITHM_EC;
537
0
  sc_init_oid(&pubkey->alg_id->oid);
538
0
  pubkey->alg_id->params = alg_id_params;
539
540
  /* Extract ecpointQ */
541
0
  pubkey->u.ec.ecpointQ.len = args.pubkey.ec.ecPointQ.len;
542
0
  pubkey->u.ec.ecpointQ.value = malloc(pubkey->u.ec.ecpointQ.len);
543
0
  if(!pubkey->u.ec.ecpointQ.value)
544
0
  {
545
0
    r = SC_ERROR_OUT_OF_MEMORY;
546
0
    goto out;
547
0
  }
548
0
  memcpy(pubkey->u.ec.ecpointQ.value, args.pubkey.ec.ecPointQ.value, args.pubkey.ec.ecPointQ.len);
549
550
  /* The OID is also written to the pubkey->u.ec.params */
551
0
  free(pubkey->u.ec.params.der.value);
552
0
  pubkey->u.ec.params.der.value = malloc(alg_id_params->der.len);
553
0
  if(!pubkey->u.ec.params.der.value)
554
0
  {
555
0
    r = SC_ERROR_OUT_OF_MEMORY;
556
0
    goto out;
557
0
  }
558
0
  memcpy(pubkey->u.ec.params.der.value, alg_id_params->der.value, alg_id_params->der.len);
559
0
  pubkey->u.ec.params.der.len = alg_id_params->der.len;
560
0
  r = sc_pkcs15_fix_ec_parameters(card->ctx, &pubkey->u.ec.params);
561
0
out:
562
0
  if(args.pubkey.ec.ecPointQ.value)
563
0
  {
564
0
    free(args.pubkey.ec.ecPointQ.value);
565
0
    args.pubkey.ec.ecPointQ.value = NULL;
566
0
  }
567
0
  if(r < 0 && pubkey)
568
0
  {
569
0
    if(pubkey->alg_id)
570
0
    {
571
0
      free(pubkey->alg_id);
572
0
      pubkey->alg_id = NULL;
573
0
    }
574
0
    if(pubkey->u.ec.params.der.value)
575
0
    {
576
0
      free(pubkey->u.ec.params.der.value);
577
0
      pubkey->u.ec.params.der.value = NULL;
578
0
      pubkey->u.ec.params.der.len = 0;
579
0
    }
580
0
    if(pubkey->u.ec.params.named_curve)
581
0
    {
582
0
      free(pubkey->u.ec.params.named_curve);
583
0
      pubkey->u.ec.params.named_curve = NULL;
584
0
    }
585
0
    if(pubkey->u.ec.ecpointQ.value)
586
0
    {
587
0
      free(pubkey->u.ec.ecpointQ.value);
588
0
      pubkey->u.ec.ecpointQ.value = NULL;
589
0
      pubkey->u.ec.ecpointQ.len = 0;
590
0
    }
591
0
    memset(pubkey, 0, sizeof(sc_pkcs15_pubkey_t));
592
0
  }
593
0
  if(r < 0 && alg_id_params)
594
0
  {
595
0
    if(alg_id_params->der.value)
596
0
    {
597
0
      free(alg_id_params->der.value);
598
0
      alg_id_params->der.value = NULL;
599
0
    }
600
0
    free(alg_id_params);
601
0
    pubkey->alg_id->params = NULL;
602
0
  }
603
0
  LOG_FUNC_RETURN(card->ctx, r);
604
0
}
605
606
static int
607
isoApplet_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
608
                       sc_pkcs15_object_t *obj,
609
                       sc_pkcs15_pubkey_t *pubkey)
610
0
{
611
0
  int r;
612
0
  sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
613
0
  sc_file_t *privKeyFile=NULL;
614
0
  sc_card_t *card = p15card->card;
615
616
0
  LOG_FUNC_CALLED(card->ctx);
617
618
  /* Authentication stuff. */
619
0
  r = sc_profile_get_file_by_path(profile, &key_info->path, &privKeyFile);
620
0
  if(r < 0 || !privKeyFile)
621
0
  {
622
0
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED);
623
0
  }
624
0
  r = sc_pkcs15init_authenticate(profile, p15card, privKeyFile, SC_AC_OP_CREATE_EF);
625
0
  if(r < 0)
626
0
  {
627
0
    sc_file_free(privKeyFile);
628
0
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED);
629
0
  }
630
0
  sc_file_free(privKeyFile);
631
632
  /* Generate the key. */
633
0
  switch(obj->type)
634
0
  {
635
0
  case SC_PKCS15_TYPE_PRKEY_RSA:
636
0
    r = isoApplet_generate_key_rsa(key_info, card, pubkey);
637
0
    break;
638
639
0
  case SC_PKCS15_TYPE_PRKEY_EC:
640
0
    r = isoApplet_generate_key_ec(key_info, card, pubkey);
641
0
    break;
642
643
0
  default:
644
0
    r = SC_ERROR_NOT_SUPPORTED;
645
0
    sc_log(card->ctx, "%s: Key generation failed: Unknown/unsupported key type.", strerror(r));
646
0
  }
647
648
0
  LOG_FUNC_RETURN(card->ctx, r);
649
0
}
650
651
652
/*
653
 * Create a new key file. This is a no-op, because private keys are stored as key objects on the javacard.
654
 */
655
static int
656
isoApplet_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *obj)
657
0
{
658
0
  sc_card_t *card = p15card->card;
659
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
660
0
}
661
662
/*
663
 * Select a key reference.
664
 */
665
static int
666
isoApplet_select_key_reference(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
667
                               sc_pkcs15_prkey_info_t *key_info)
668
0
{
669
0
  int rv = SC_SUCCESS;
670
0
  sc_card_t *card = p15card->card;
671
672
0
  LOG_FUNC_CALLED(card->ctx);
673
674
0
  if(key_info->key_reference < ISOAPPLET_KEY_ID_MIN)
675
0
  {
676
0
    key_info->key_reference = ISOAPPLET_KEY_ID_MIN;
677
0
    rv = SC_SUCCESS;
678
0
  }
679
0
  if(key_info->key_reference > ISOAPPLET_KEY_ID_MAX)
680
0
  {
681
0
    rv = SC_ERROR_TOO_MANY_OBJECTS;
682
0
  }
683
0
  LOG_FUNC_RETURN(card->ctx, rv);
684
0
}
685
686
/*
687
 * Store a usable private key on the card.
688
 */
689
static int
690
isoApplet_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *object,
691
                    sc_pkcs15_prkey_t *key)
692
0
{
693
0
  sc_card_t *card = p15card->card;
694
0
  sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) object->data;
695
0
  sc_file_t *privKeyFile=NULL;
696
0
  sc_cardctl_isoApplet_import_key_t args;
697
0
  int r;
698
699
0
  LOG_FUNC_CALLED(card->ctx);
700
701
  /* Authentication stuff. */
702
0
  r = sc_profile_get_file_by_path(profile, &key_info->path, &privKeyFile);
703
0
  if(r < 0 || !privKeyFile)
704
0
  {
705
0
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED);
706
0
  }
707
0
  r = sc_pkcs15init_authenticate(profile, p15card, privKeyFile, SC_AC_OP_CREATE_EF);
708
0
  if(r < 0)
709
0
  {
710
0
    sc_file_free(privKeyFile);
711
0
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED);
712
0
  }
713
0
  sc_file_free(privKeyFile);
714
715
  /* Key import. */
716
0
  switch(object->type)
717
0
  {
718
0
  case SC_PKCS15_TYPE_PRKEY_RSA:
719
0
    args.algorithm_ref = SC_ISOAPPLET_ALG_REF_RSA_GEN_2048;
720
0
    if(!key->u.rsa.p.data
721
0
            ||!key->u.rsa.q.data
722
0
            ||!key->u.rsa.iqmp.data
723
0
            ||!key->u.rsa.dmp1.data
724
0
            ||!key->u.rsa.dmq1.data)
725
0
    {
726
0
      LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Only CRT RSA keys may be imported.");
727
0
    }
728
0
    args.privkey.rsa.p.value    = key->u.rsa.p.data;
729
0
    args.privkey.rsa.p.len      = key->u.rsa.p.len;
730
0
    args.privkey.rsa.q.value    = key->u.rsa.q.data;
731
0
    args.privkey.rsa.q.len      = key->u.rsa.q.len;
732
0
    args.privkey.rsa.iqmp.value = key->u.rsa.iqmp.data;
733
0
    args.privkey.rsa.iqmp.len   = key->u.rsa.iqmp.len;
734
0
    args.privkey.rsa.dmp1.value = key->u.rsa.dmp1.data;
735
0
    args.privkey.rsa.dmp1.len   = key->u.rsa.dmp1.len;
736
0
    args.privkey.rsa.dmq1.value = key->u.rsa.dmq1.data;
737
0
    args.privkey.rsa.dmq1.len   = key->u.rsa.dmq1.len;
738
0
    break;
739
740
0
  case SC_PKCS15_TYPE_PRKEY_EC:
741
0
  {
742
0
    const struct ec_curve *curve = NULL;
743
744
0
    args.algorithm_ref = SC_ISOAPPLET_ALG_REF_EC_GEN;
745
0
    if(key->u.ec.params.der.len == 0 || key->u.ec.params.der.value == NULL) {
746
0
      r = sc_pkcs15_fix_ec_parameters(card->ctx, &key->u.ec.params);
747
0
      LOG_TEST_RET(card->ctx, r, "EC key storing failed: Unknown curve.");
748
0
    }
749
0
    r = isoApplet_get_curve(key->u.ec.params.der.value, key->u.ec.params.der.len, &curve);
750
0
    LOG_TEST_RET(card->ctx, r, "EC key generation failed: Unsupported curve");
751
0
    args.privkey.ec.params.prime.value        = curve->prime.value;
752
0
    args.privkey.ec.params.prime.len          = curve->prime.len;
753
0
    args.privkey.ec.params.coefficientA.value = curve->coefficientA.value;
754
0
    args.privkey.ec.params.coefficientA.len   = curve->coefficientA.len;
755
0
    args.privkey.ec.params.coefficientB.value = curve->coefficientB.value;
756
0
    args.privkey.ec.params.coefficientB.len   = curve->coefficientB.len;
757
0
    args.privkey.ec.params.basePointG.value   = curve->basePointG.value;
758
0
    args.privkey.ec.params.basePointG.len     = curve->basePointG.len;
759
0
    args.privkey.ec.params.order.value        = curve->order.value;
760
0
    args.privkey.ec.params.order.len          = curve->order.len;
761
0
    args.privkey.ec.params.coFactor.value     = curve->coFactor.value;
762
0
    args.privkey.ec.params.coFactor.len       = curve->coFactor.len;
763
0
    args.privkey.ec.privateD.value            = key->u.ec.privateD.data;
764
0
    args.privkey.ec.privateD.len              = key->u.ec.privateD.len;
765
0
  }
766
0
  break;
767
768
0
  default:
769
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
770
0
  }
771
0
  args.priv_key_ref = key_info->key_reference;
772
773
0
  r = sc_card_ctl(card, SC_CARDCTL_ISOAPPLET_IMPORT_KEY, &args);
774
0
  if (r < 0)
775
0
  {
776
0
    sc_log(card->ctx, "%s: Error in card_ctl", sc_strerror(r));
777
0
    LOG_FUNC_RETURN(card->ctx, r);
778
0
  }
779
780
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
781
0
}
782
783
static struct sc_pkcs15init_operations sc_pkcs15init_isoApplet_operations =
784
{
785
  NULL,                           /* erase_card */
786
  NULL,                           /* init_card */
787
  isoApplet_create_dir,           /* create_dir */
788
  NULL,                           /* create_domain */
789
  isoApplet_select_pin_reference, /* pin_reference*/
790
  isoApplet_create_pin,           /* create_pin */
791
  isoApplet_select_key_reference, /* key_reference */
792
  isoApplet_create_key,           /* create_key */
793
  isoApplet_store_key,            /* store_key */
794
  isoApplet_generate_key,         /* generate_key */
795
  NULL, NULL,                     /* encode private/public key */
796
  NULL,                           /* finalize */
797
  NULL,                           /* delete_object */
798
  NULL, NULL, NULL, NULL, NULL,   /* pkcs15init emulation */
799
  NULL,                           /* sanity_check*/
800
};
801
802
struct
803
sc_pkcs15init_operations *sc_pkcs15init_get_isoApplet_ops(void)
804
0
{
805
0
  return &sc_pkcs15init_isoApplet_operations;
806
0
}