Coverage Report

Created: 2026-05-30 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/pkcs15-sc-hsm.c
Line
Count
Source
1
/*
2
 * pkcs15-sc-hsm.c : Initialize PKCS#15 emulation
3
 *
4
 * Copyright (C) 2012 Andreas Schwier, CardContact, Minden, Germany
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
#ifdef HAVE_CONFIG_H
22
#include "config.h"
23
#endif
24
25
#include <stdlib.h>
26
#include <string.h>
27
#include <stdio.h>
28
29
#include "internal.h"
30
#include "pkcs15.h"
31
#include "asn1.h"
32
#include "common/compat_strlcpy.h"
33
#include "common/compat_strnlen.h"
34
35
#include "card-sc-hsm.h"
36
37
38
extern struct sc_aid sc_hsm_aid;
39
40
41
void sc_hsm_set_serialnr(sc_card_t *card, char *serial);
42
43
// clang-format off
44
static struct ec_curve curves[] = {
45
    {
46
        { (unsigned char *) "\x2A\x86\x48\xCE\x3D\x03\x01\x01", 8}, // secp192r1 aka prime192r1
47
        { (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},
48
        { (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},
49
        { (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},
50
        { (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},
51
        { (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},
52
        { (unsigned char *) "\x01", 1}
53
    },
54
    {
55
        { (unsigned char *) "\x2A\x86\x48\xCE\x3D\x03\x01\x07", 8}, // secp256r1 aka prime256r1
56
        { (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},
57
        { (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},
58
        { (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},
59
        { (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},
60
        { (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},
61
        { (unsigned char *) "\x01", 1}
62
    },
63
    {
64
        { (unsigned char *) "\x2B\x81\x04\x00\x22", 5}, // secp384r1
65
        { (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},
66
        { (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},
67
        { (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},
68
        { (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},
69
        { (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},
70
        { (unsigned char *) "\x01", 1}
71
    },
72
    {
73
        { (unsigned char *) "\x2B\x81\x04\x00\x23", 5}, // secp521r1
74
        { (unsigned char *) "\x01\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\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\xFF\xFF\xFF", 66},
75
        { (unsigned char *) "\x01\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\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\xFF\xFF\xFC", 66},
76
        { (unsigned char *) "\x00\x51\x95\x3E\xB9\x61\x8E\x1C\x9A\x1F\x92\x9A\x21\xA0\xB6\x85\x40\xEE\xA2\xDA\x72\x5B\x99\xB3\x15\xF3\xB8\xB4\x89\x91\x8E\xF1\x09\xE1\x56\x19\x39\x51\xEC\x7E\x93\x7B\x16\x52\xC0\xBD\x3B\xB1\xBF\x07\x35\x73\xDF\x88\x3D\x2C\x34\xF1\xEF\x45\x1F\xD4\x6B\x50\x3F\x00", 66},
77
        { (unsigned char *) "\x04\x00\xC6\x85\x8E\x06\xB7\x04\x04\xE9\xCD\x9E\x3E\xCB\x66\x23\x95\xB4\x42\x9C\x64\x81\x39\x05\x3F\xB5\x21\xF8\x28\xAF\x60\x6B\x4D\x3D\xBA\xA1\x4B\x5E\x77\xEF\xE7\x59\x28\xFE\x1D\xC1\x27\xA2\xFF\xA8\xDE\x33\x48\xB3\xC1\x85\x6A\x42\x9B\xF9\x7E\x7E\x31\xC2\xE5\xBD\x66\x01\x18\x39\x29\x6A\x78\x9A\x3B\xC0\x04\x5C\x8A\x5F\xB4\x2C\x7D\x1B\xD9\x98\xF5\x44\x49\x57\x9B\x44\x68\x17\xAF\xBD\x17\x27\x3E\x66\x2C\x97\xEE\x72\x99\x5E\xF4\x26\x40\xC5\x50\xB9\x01\x3F\xAD\x07\x61\x35\x3C\x70\x86\xA2\x72\xC2\x40\x88\xBE\x94\x76\x9F\xD1\x66\x50", 133},
78
        { (unsigned char *) "\x01\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\xFF\xFA\x51\x86\x87\x83\xBF\x2F\x96\x6B\x7F\xCC\x01\x48\xF7\x09\xA5\xD0\x3B\xB5\xC9\xB8\x89\x9C\x47\xAE\xBB\x6F\xB7\x1E\x91\x38\x64\x09", 66},
79
        { (unsigned char *) "\x01", 1}
80
    },
81
    {
82
        { (unsigned char *) "\x2B\x24\x03\x03\x02\x08\x01\x01\x03", 9}, // brainpoolP192r1
83
        { (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},
84
        { (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},
85
        { (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},
86
        { (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},
87
        { (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},
88
        { (unsigned char *) "\x01", 1}
89
    },
90
    {
91
        { (unsigned char *) "\x2B\x24\x03\x03\x02\x08\x01\x01\x05", 9}, // brainpoolP224r1
92
        { (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},
93
        { (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},
94
        { (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},
95
        { (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},
96
        { (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},
97
        { (unsigned char *) "\x01", 1}
98
    },
99
    {
100
        { (unsigned char *) "\x2B\x24\x03\x03\x02\x08\x01\x01\x07", 9}, // brainpoolP256r1
101
        { (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},
102
        { (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},
103
        { (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},
104
        { (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},
105
        { (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},
106
        { (unsigned char *) "\x01", 1}
107
    },
108
    {
109
        { (unsigned char *) "\x2B\x24\x03\x03\x02\x08\x01\x01\x09", 9}, // brainpoolP320r1
110
        { (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},
111
        { (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},
112
        { (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},
113
        { (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},
114
        { (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},
115
        { (unsigned char *) "\x01", 1}
116
    },
117
    {
118
        { (unsigned char *) "\x2B\x24\x03\x03\x02\x08\x01\x01\x0B", 9}, // brainpoolP384r1
119
        { (unsigned char *) "\x8C\xB9\x1E\x82\xA3\x38\x6D\x28\x0F\x5D\x6F\x7E\x50\xE6\x41\xDF\x15\x2F\x71\x09\xED\x54\x56\xB4\x12\xB1\xDA\x19\x7F\xB7\x11\x23\xAC\xD3\xA7\x29\x90\x1D\x1A\x71\x87\x47\x00\x13\x31\x07\xEC\x53", 48},
120
        { (unsigned char *) "\x7B\xC3\x82\xC6\x3D\x8C\x15\x0C\x3C\x72\x08\x0A\xCE\x05\xAF\xA0\xC2\xBE\xA2\x8E\x4F\xB2\x27\x87\x13\x91\x65\xEF\xBA\x91\xF9\x0F\x8A\xA5\x81\x4A\x50\x3A\xD4\xEB\x04\xA8\xC7\xDD\x22\xCE\x28\x26", 48},
121
        { (unsigned char *) "\x04\xA8\xC7\xDD\x22\xCE\x28\x26\x8B\x39\xB5\x54\x16\xF0\x44\x7C\x2F\xB7\x7D\xE1\x07\xDC\xD2\xA6\x2E\x88\x0E\xA5\x3E\xEB\x62\xD5\x7C\xB4\x39\x02\x95\xDB\xC9\x94\x3A\xB7\x86\x96\xFA\x50\x4C\x11", 48},
122
        { (unsigned char *) "\x04\x1D\x1C\x64\xF0\x68\xCF\x45\xFF\xA2\xA6\x3A\x81\xB7\xC1\x3F\x6B\x88\x47\xA3\xE7\x7E\xF1\x4F\xE3\xDB\x7F\xCA\xFE\x0C\xBD\x10\xE8\xE8\x26\xE0\x34\x36\xD6\x46\xAA\xEF\x87\xB2\xE2\x47\xD4\xAF\x1E\x8A\xBE\x1D\x75\x20\xF9\xC2\xA4\x5C\xB1\xEB\x8E\x95\xCF\xD5\x52\x62\xB7\x0B\x29\xFE\xEC\x58\x64\xE1\x9C\x05\x4F\xF9\x91\x29\x28\x0E\x46\x46\x21\x77\x91\x81\x11\x42\x82\x03\x41\x26\x3C\x53\x15", 97},
123
        { (unsigned char *) "\x8C\xB9\x1E\x82\xA3\x38\x6D\x28\x0F\x5D\x6F\x7E\x50\xE6\x41\xDF\x15\x2F\x71\x09\xED\x54\x56\xB3\x1F\x16\x6E\x6C\xAC\x04\x25\xA7\xCF\x3A\xB6\xAF\x6B\x7F\xC3\x10\x3B\x88\x32\x02\xE9\x04\x65\x65", 48},
124
        { (unsigned char *) "\x01", 1}
125
    },
126
    {
127
        { (unsigned char *) "\x2B\x24\x03\x03\x02\x08\x01\x01\x0D", 9}, // brainpoolP512r1
128
        { (unsigned char *) "\xAA\xDD\x9D\xB8\xDB\xE9\xC4\x8B\x3F\xD4\xE6\xAE\x33\xC9\xFC\x07\xCB\x30\x8D\xB3\xB3\xC9\xD2\x0E\xD6\x63\x9C\xCA\x70\x33\x08\x71\x7D\x4D\x9B\x00\x9B\xC6\x68\x42\xAE\xCD\xA1\x2A\xE6\xA3\x80\xE6\x28\x81\xFF\x2F\x2D\x82\xC6\x85\x28\xAA\x60\x56\x58\x3A\x48\xF3", 64},
129
        { (unsigned char *) "\x78\x30\xA3\x31\x8B\x60\x3B\x89\xE2\x32\x71\x45\xAC\x23\x4C\xC5\x94\xCB\xDD\x8D\x3D\xF9\x16\x10\xA8\x34\x41\xCA\xEA\x98\x63\xBC\x2D\xED\x5D\x5A\xA8\x25\x3A\xA1\x0A\x2E\xF1\xC9\x8B\x9A\xC8\xB5\x7F\x11\x17\xA7\x2B\xF2\xC7\xB9\xE7\xC1\xAC\x4D\x77\xFC\x94\xCA", 64},
130
        { (unsigned char *) "\x3D\xF9\x16\x10\xA8\x34\x41\xCA\xEA\x98\x63\xBC\x2D\xED\x5D\x5A\xA8\x25\x3A\xA1\x0A\x2E\xF1\xC9\x8B\x9A\xC8\xB5\x7F\x11\x17\xA7\x2B\xF2\xC7\xB9\xE7\xC1\xAC\x4D\x77\xFC\x94\xCA\xDC\x08\x3E\x67\x98\x40\x50\xB7\x5E\xBA\xE5\xDD\x28\x09\xBD\x63\x80\x16\xF7\x23", 64},
131
        { (unsigned char *) "\x04\x81\xAE\xE4\xBD\xD8\x2E\xD9\x64\x5A\x21\x32\x2E\x9C\x4C\x6A\x93\x85\xED\x9F\x70\xB5\xD9\x16\xC1\xB4\x3B\x62\xEE\xF4\xD0\x09\x8E\xFF\x3B\x1F\x78\xE2\xD0\xD4\x8D\x50\xD1\x68\x7B\x93\xB9\x7D\x5F\x7C\x6D\x50\x47\x40\x6A\x5E\x68\x8B\x35\x22\x09\xBC\xB9\xF8\x22\x7D\xDE\x38\x5D\x56\x63\x32\xEC\xC0\xEA\xBF\xA9\xCF\x78\x22\xFD\xF2\x09\xF7\x00\x24\xA5\x7B\x1A\xA0\x00\xC5\x5B\x88\x1F\x81\x11\xB2\xDC\xDE\x49\x4A\x5F\x48\x5E\x5B\xCA\x4B\xD8\x8A\x27\x63\xAE\xD1\xCA\x2B\x2F\xA8\xF0\x54\x06\x78\xCD\x1E\x0F\x3A\xD8\x08\x92", 129},
132
        { (unsigned char *) "\xAA\xDD\x9D\xB8\xDB\xE9\xC4\x8B\x3F\xD4\xE6\xAE\x33\xC9\xFC\x07\xCB\x30\x8D\xB3\xB3\xC9\xD2\x0E\xD6\x63\x9C\xCA\x70\x33\x08\x70\x55\x3E\x5C\x41\x4C\xA9\x26\x19\x41\x86\x61\x19\x7F\xAC\x10\x47\x1D\xB1\xD3\x81\x08\x5D\xDA\xDD\xB5\x87\x96\x82\x9C\xA9\x00\x69", 64},
133
        { (unsigned char *) "\x01", 1}
134
    },
135
    {
136
        { (unsigned char *) "\x2B\x24\x03\x03\x02\x08\x01\x01\x04", 9}, // brainpoolP192t1
137
        { (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},
138
        { (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\x94", 24},
139
        { (unsigned char *) "\x13\xD5\x6F\xFA\xEC\x78\x68\x1E\x68\xF9\xDE\xB4\x3B\x35\xBE\xC2\xFB\x68\x54\x2E\x27\x89\x7B\x79", 24},
140
        { (unsigned char *) "\x04\x3A\xE9\xE5\x8C\x82\xF6\x3C\x30\x28\x2E\x1F\xE7\xBB\xF4\x3F\xA7\x2C\x44\x6A\xF6\xF4\x61\x81\x29\x09\x7E\x2C\x56\x67\xC2\x22\x3A\x90\x2A\xB5\xCA\x44\x9D\x00\x84\xB7\xE5\xB3\xDE\x7C\xCC\x01\xC9", 49},
141
        { (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},
142
        { (unsigned char *) "\x01", 1}
143
    },
144
    {
145
        { (unsigned char *) "\x2B\x24\x03\x03\x02\x08\x01\x01\x06", 9}, // brainpoolP224t1
146
        { (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},
147
        { (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\xFC", 28},
148
        { (unsigned char *) "\x4B\x33\x7D\x93\x41\x04\xCD\x7B\xEF\x27\x1B\xF6\x0C\xED\x1E\xD2\x0D\xA1\x4C\x08\xB3\xBB\x64\xF1\x8A\x60\x88\x8D", 28},
149
        { (unsigned char *) "\x04\x6A\xB1\xE3\x44\xCE\x25\xFF\x38\x96\x42\x4E\x7F\xFE\x14\x76\x2E\xCB\x49\xF8\x92\x8A\xC0\xC7\x60\x29\xB4\xD5\x80\x03\x74\xE9\xF5\x14\x3E\x56\x8C\xD2\x3F\x3F\x4D\x7C\x0D\x4B\x1E\x41\xC8\xCC\x0D\x1C\x6A\xBD\x5F\x1A\x46\xDB\x4C", 57},
150
        { (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},
151
        { (unsigned char *) "\x01", 1}
152
    },
153
    {
154
        { (unsigned char *) "\x2B\x24\x03\x03\x02\x08\x01\x01\x08", 9}, // brainpoolP256t1
155
        { (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},
156
        { (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\x74", 32},
157
        { (unsigned char *) "\x66\x2C\x61\xC4\x30\xD8\x4E\xA4\xFE\x66\xA7\x73\x3D\x0B\x76\xB7\xBF\x93\xEB\xC4\xAF\x2F\x49\x25\x6A\xE5\x81\x01\xFE\xE9\x2B\x04", 32},
158
        { (unsigned char *) "\x04\xA3\xE8\xEB\x3C\xC1\xCF\xE7\xB7\x73\x22\x13\xB2\x3A\x65\x61\x49\xAF\xA1\x42\xC4\x7A\xAF\xBC\x2B\x79\xA1\x91\x56\x2E\x13\x05\xF4\x2D\x99\x6C\x82\x34\x39\xC5\x6D\x7F\x7B\x22\xE1\x46\x44\x41\x7E\x69\xBC\xB6\xDE\x39\xD0\x27\x00\x1D\xAB\xE8\xF3\x5B\x25\xC9\xBE", 65},
159
        { (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},
160
        { (unsigned char *) "\x01", 1}
161
    },
162
    {
163
        { (unsigned char *) "\x2B\x24\x03\x03\x02\x08\x01\x01\x0A", 9}, // brainpoolP320t1
164
        { (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},
165
        { (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\x24", 40},
166
        { (unsigned char *) "\xA7\xF5\x61\xE0\x38\xEB\x1E\xD5\x60\xB3\xD1\x47\xDB\x78\x20\x13\x06\x4C\x19\xF2\x7E\xD2\x7C\x67\x80\xAA\xF7\x7F\xB8\xA5\x47\xCE\xB5\xB4\xFE\xF4\x22\x34\x03\x53", 40},
167
        { (unsigned char *) "\x04\x92\x5B\xE9\xFB\x01\xAF\xC6\xFB\x4D\x3E\x7D\x49\x90\x01\x0F\x81\x34\x08\xAB\x10\x6C\x4F\x09\xCB\x7E\xE0\x78\x68\xCC\x13\x6F\xFF\x33\x57\xF6\x24\xA2\x1B\xED\x52\x63\xBA\x3A\x7A\x27\x48\x3E\xBF\x66\x71\xDB\xEF\x7A\xBB\x30\xEB\xEE\x08\x4E\x58\xA0\xB0\x77\xAD\x42\xA5\xA0\x98\x9D\x1E\xE7\x1B\x1B\x9B\xC0\x45\x5F\xB0\xD2\xC3", 81},
168
        { (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},
169
        { (unsigned char *) "\x01", 1}
170
    },
171
    {
172
        { (unsigned char *) "\x2B\x24\x03\x03\x02\x08\x01\x01\x0C", 9}, // brainpoolP384t1
173
        { (unsigned char *) "\x8C\xB9\x1E\x82\xA3\x38\x6D\x28\x0F\x5D\x6F\x7E\x50\xE6\x41\xDF\x15\x2F\x71\x09\xED\x54\x56\xB4\x12\xB1\xDA\x19\x7F\xB7\x11\x23\xAC\xD3\xA7\x29\x90\x1D\x1A\x71\x87\x47\x00\x13\x31\x07\xEC\x53", 48},
174
        { (unsigned char *) "\x8C\xB9\x1E\x82\xA3\x38\x6D\x28\x0F\x5D\x6F\x7E\x50\xE6\x41\xDF\x15\x2F\x71\x09\xED\x54\x56\xB4\x12\xB1\xDA\x19\x7F\xB7\x11\x23\xAC\xD3\xA7\x29\x90\x1D\x1A\x71\x87\x47\x00\x13\x31\x07\xEC\x50", 48},
175
        { (unsigned char *) "\x7F\x51\x9E\xAD\xA7\xBD\xA8\x1B\xD8\x26\xDB\xA6\x47\x91\x0F\x8C\x4B\x93\x46\xED\x8C\xCD\xC6\x4E\x4B\x1A\xBD\x11\x75\x6D\xCE\x1D\x20\x74\xAA\x26\x3B\x88\x80\x5C\xED\x70\x35\x5A\x33\xB4\x71\xEE", 48},
176
        { (unsigned char *) "\x04\x18\xDE\x98\xB0\x2D\xB9\xA3\x06\xF2\xAF\xCD\x72\x35\xF7\x2A\x81\x9B\x80\xAB\x12\xEB\xD6\x53\x17\x24\x76\xFE\xCD\x46\x2A\xAB\xFF\xC4\xFF\x19\x1B\x94\x6A\x5F\x54\xD8\xD0\xAA\x2F\x41\x88\x08\xCC\x25\xAB\x05\x69\x62\xD3\x06\x51\xA1\x14\xAF\xD2\x75\x5A\xD3\x36\x74\x7F\x93\x47\x5B\x7A\x1F\xCA\x3B\x88\xF2\xB6\xA2\x08\xCC\xFE\x46\x94\x08\x58\x4D\xC2\xB2\x91\x26\x75\xBF\x5B\x9E\x58\x29\x28", 97},
177
        { (unsigned char *) "\x8C\xB9\x1E\x82\xA3\x38\x6D\x28\x0F\x5D\x6F\x7E\x50\xE6\x41\xDF\x15\x2F\x71\x09\xED\x54\x56\xB3\x1F\x16\x6E\x6C\xAC\x04\x25\xA7\xCF\x3A\xB6\xAF\x6B\x7F\xC3\x10\x3B\x88\x32\x02\xE9\x04\x65\x65", 48},
178
        { (unsigned char *) "\x01", 1}
179
    },
180
    {
181
        { (unsigned char *) "\x2B\x24\x03\x03\x02\x08\x01\x01\x0E", 9}, // brainpoolP512t1
182
        { (unsigned char *) "\xAA\xDD\x9D\xB8\xDB\xE9\xC4\x8B\x3F\xD4\xE6\xAE\x33\xC9\xFC\x07\xCB\x30\x8D\xB3\xB3\xC9\xD2\x0E\xD6\x63\x9C\xCA\x70\x33\x08\x71\x7D\x4D\x9B\x00\x9B\xC6\x68\x42\xAE\xCD\xA1\x2A\xE6\xA3\x80\xE6\x28\x81\xFF\x2F\x2D\x82\xC6\x85\x28\xAA\x60\x56\x58\x3A\x48\xF3", 64},
183
        { (unsigned char *) "\xAA\xDD\x9D\xB8\xDB\xE9\xC4\x8B\x3F\xD4\xE6\xAE\x33\xC9\xFC\x07\xCB\x30\x8D\xB3\xB3\xC9\xD2\x0E\xD6\x63\x9C\xCA\x70\x33\x08\x71\x7D\x4D\x9B\x00\x9B\xC6\x68\x42\xAE\xCD\xA1\x2A\xE6\xA3\x80\xE6\x28\x81\xFF\x2F\x2D\x82\xC6\x85\x28\xAA\x60\x56\x58\x3A\x48\xF0", 64},
184
        { (unsigned char *) "\x7C\xBB\xBC\xF9\x44\x1C\xFA\xB7\x6E\x18\x90\xE4\x68\x84\xEA\xE3\x21\xF7\x0C\x0B\xCB\x49\x81\x52\x78\x97\x50\x4B\xEC\x3E\x36\xA6\x2B\xCD\xFA\x23\x04\x97\x65\x40\xF6\x45\x00\x85\xF2\xDA\xE1\x45\xC2\x25\x53\xB4\x65\x76\x36\x89\x18\x0E\xA2\x57\x18\x67\x42\x3E", 64},
185
        { (unsigned char *) "\x04\x64\x0E\xCE\x5C\x12\x78\x87\x17\xB9\xC1\xBA\x06\xCB\xC2\xA6\xFE\xBA\x85\x84\x24\x58\xC5\x6D\xDE\x9D\xB1\x75\x8D\x39\xC0\x31\x3D\x82\xBA\x51\x73\x5C\xDB\x3E\xA4\x99\xAA\x77\xA7\xD6\x94\x3A\x64\xF7\xA3\xF2\x5F\xE2\x6F\x06\xB5\x1B\xAA\x26\x96\xFA\x90\x35\xDA\x5B\x53\x4B\xD5\x95\xF5\xAF\x0F\xA2\xC8\x92\x37\x6C\x84\xAC\xE1\xBB\x4E\x30\x19\xB7\x16\x34\xC0\x11\x31\x15\x9C\xAE\x03\xCE\xE9\xD9\x93\x21\x84\xBE\xEF\x21\x6B\xD7\x1D\xF2\xDA\xDF\x86\xA6\x27\x30\x6E\xCF\xF9\x6D\xBB\x8B\xAC\xE1\x98\xB6\x1E\x00\xF8\xB3\x32", 129},
186
        { (unsigned char *) "\xAA\xDD\x9D\xB8\xDB\xE9\xC4\x8B\x3F\xD4\xE6\xAE\x33\xC9\xFC\x07\xCB\x30\x8D\xB3\xB3\xC9\xD2\x0E\xD6\x63\x9C\xCA\x70\x33\x08\x70\x55\x3E\x5C\x41\x4C\xA9\x26\x19\x41\x86\x61\x19\x7F\xAC\x10\x47\x1D\xB1\xD3\x81\x08\x5D\xDA\xDD\xB5\x87\x96\x82\x9C\xA9\x00\x69", 64},
187
        { (unsigned char *) "\x01", 1}
188
    },
189
    {
190
        { (unsigned char *) "\x2B\x81\x04\x00\x1F", 5}, // secp192k1
191
        { (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},
192
        { (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},
193
        { (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},
194
        { (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},
195
        { (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},
196
        { (unsigned char *) "\x01", 1}
197
    },
198
    {
199
        { (unsigned char *) "\x2B\x81\x04\x00\x0A", 5}, // secp256k1
200
        { (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},
201
        { (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},
202
        { (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},
203
        { (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},
204
        { (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},
205
        { (unsigned char *) "\x01", 1}
206
    },
207
    {
208
        { NULL, 0},
209
        { NULL, 0},
210
        { NULL, 0},
211
        { NULL, 0},
212
        { NULL, 0},
213
        { NULL, 0},
214
        { NULL, 0}
215
    }
216
};
217
// clang-format on
218
219
118
#define C_ASN1_CVC_PUBKEY_SIZE 10
220
static const struct sc_asn1_entry c_asn1_cvc_pubkey[C_ASN1_CVC_PUBKEY_SIZE] = {
221
  { "publicKeyOID", SC_ASN1_OBJECT, SC_ASN1_UNI | SC_ASN1_OBJECT, 0, NULL, NULL },
222
  { "primeOrModulus", SC_ASN1_OCTET_STRING, SC_ASN1_CTX | 1, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL },
223
  { "coefficientAorExponent", SC_ASN1_OCTET_STRING, SC_ASN1_CTX | 2,  SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL },
224
  { "coefficientB", SC_ASN1_OCTET_STRING, SC_ASN1_CTX | 3, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL },
225
  { "basePointG", SC_ASN1_OCTET_STRING, SC_ASN1_CTX | 4, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL },
226
  { "order", SC_ASN1_OCTET_STRING, SC_ASN1_CTX | 5, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL },
227
  { "publicPoint", SC_ASN1_OCTET_STRING, SC_ASN1_CTX | 6, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL },
228
  { "cofactor", SC_ASN1_OCTET_STRING, SC_ASN1_CTX | 7, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL },
229
  { "modulusSize", SC_ASN1_INTEGER, SC_ASN1_UNI | SC_ASN1_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
230
  { NULL, 0, 0, 0, NULL, NULL }
231
};
232
233
118
#define C_ASN1_CVC_BODY_SIZE 5
234
static const struct sc_asn1_entry c_asn1_cvc_body[C_ASN1_CVC_BODY_SIZE] = {
235
  { "certificateProfileIdentifier", SC_ASN1_INTEGER, SC_ASN1_APP | 0x1F29, 0, NULL, NULL },
236
  { "certificationAuthorityReference", SC_ASN1_PRINTABLESTRING, SC_ASN1_APP | 2, SC_ASN1_OPTIONAL, NULL, NULL },
237
  { "publicKey", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_APP | 0x1F49, 0, NULL, NULL },
238
  { "certificateHolderReference", SC_ASN1_PRINTABLESTRING, SC_ASN1_APP | 0x1F20, 0, NULL, NULL },
239
  { NULL, 0, 0, 0, NULL, NULL }
240
};
241
242
118
#define C_ASN1_CVCERT_SIZE 3
243
static const struct sc_asn1_entry c_asn1_cvcert[C_ASN1_CVCERT_SIZE] = {
244
  { "certificateBody", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_APP | 0x1F4E, 0, NULL, NULL },
245
  { "signature", SC_ASN1_OCTET_STRING, SC_ASN1_APP | 0x1F37, SC_ASN1_ALLOC, NULL, NULL },
246
  { NULL, 0, 0, 0, NULL, NULL }
247
};
248
249
#define C_ASN1_CVC_SIZE 2
250
static const struct sc_asn1_entry c_asn1_cvc[C_ASN1_CVC_SIZE] = {
251
  { "certificate", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_APP | 0x1F21, 0, NULL, NULL },
252
  { NULL, 0, 0, 0, NULL, NULL }
253
};
254
255
118
#define C_ASN1_AUTHREQ_SIZE 4
256
static const struct sc_asn1_entry c_asn1_authreq[C_ASN1_AUTHREQ_SIZE] = {
257
  { "certificate", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_APP | 0x1F21, 0, NULL, NULL },
258
  { "outerCAR", SC_ASN1_PRINTABLESTRING, SC_ASN1_APP | 2, 0, NULL, NULL },
259
  { "signature", SC_ASN1_OCTET_STRING, SC_ASN1_APP | 0x1F37, SC_ASN1_ALLOC, NULL, NULL },
260
  { NULL, 0, 0, 0, NULL, NULL }
261
};
262
263
#define C_ASN1_REQ_SIZE 2
264
static const struct sc_asn1_entry c_asn1_req[C_ASN1_REQ_SIZE] = {
265
  { "authenticatedrequest", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_APP | 7, 0, NULL, NULL },
266
  { NULL, 0, 0, 0, NULL, NULL }
267
};
268
269
struct sc_object_id sc_hsm_public_key_oid = {
270
    {1, 3, 6, 1, 4, 1, 24991, 4, 3, 1, -1}
271
};
272
273
#define C_ASN1_SC_HSM_PKA_NEW_SIZE 5
274
static const struct sc_asn1_entry c_asn1_sc_hsm_pka_new_format[C_ASN1_SC_HSM_PKA_NEW_SIZE] = {
275
  { "oid", SC_ASN1_OBJECT, SC_ASN1_TAG_UNIVERSAL | SC_ASN1_TAG_OBJECT, 0, NULL, NULL },
276
  { "dicaCVC", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_APP | 1, 0, NULL, NULL },
277
  { "deviceCVC", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_APP | 2, 0, NULL, NULL },
278
  { "publicKey", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_APP | 3, 0, NULL, NULL },
279
  { NULL, 0, 0, 0, NULL, NULL }
280
};
281
282
#define C_ASN1_SC_HSM_PKA_OLD_SIZE 4
283
static const struct sc_asn1_entry c_asn1_sc_hsm_pka_old_format[C_ASN1_SC_HSM_PKA_OLD_SIZE] = {
284
  { "publicKey", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_APP | 7, 0, NULL, NULL },
285
  { "deviceCVCert", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_APP | 0x1F21, 0, NULL, NULL },
286
  { "dicaCVCert", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_APP | 0x1F21, 0, NULL, NULL },
287
  { NULL, 0, 0, 0, NULL, NULL }
288
};
289
290
291
static int read_file(sc_pkcs15_card_t * p15card, u8 fid[2],
292
    u8 *efbin, size_t *len, int optional)
293
58
{
294
58
  sc_path_t path;
295
58
  int r;
296
297
58
  sc_path_set(&path, SC_PATH_TYPE_FILE_ID, fid, 2, 0, 0);
298
  /* look this up with our AID */
299
58
  path.aid = sc_hsm_aid;
300
  /* we don't have a pre-known size of the file */
301
58
  path.count = -1;
302
58
  if (!p15card->opts.use_file_cache || !efbin
303
58
      || SC_SUCCESS != sc_pkcs15_read_cached_file(p15card, &path, &efbin, len)) {
304
    /* avoid re-selection of SC-HSM */
305
58
    path.aid.len = 0;
306
58
    r = sc_select_file(p15card->card, &path, NULL);
307
58
    if (r < 0) {
308
20
      sc_log(p15card->card->ctx, "Could not select EF");
309
38
    } else {
310
38
      r = sc_read_binary(p15card->card, 0, efbin, *len, 0);
311
38
    }
312
313
58
    if (r < 0) {
314
29
      sc_log(p15card->card->ctx, "Could not read EF");
315
29
      if (!optional) {
316
0
        return r;
317
0
      }
318
      /* optional files are saved as empty files to avoid card
319
       * transactions. Parsing the file's data will reveal that they were
320
       * missing. */
321
29
      *len = 0;
322
29
    } else {
323
29
      *len = r;
324
29
    }
325
326
58
    if (p15card->opts.use_file_cache) {
327
      /* save this with our AID */
328
0
      path.aid = sc_hsm_aid;
329
0
      sc_pkcs15_cache_file(p15card, &path, efbin, *len);
330
0
    }
331
58
  }
332
333
58
  return SC_SUCCESS;
334
58
}
335
336
static void fixup_cvc_printable_string_lengths(sc_cvc_t *cvc)
337
0
{
338
  /* SC_ASN1_PRINTABLESTRING adds 1 for the null-terminator */
339
0
  if (cvc->chrLen > 0) {
340
0
    cvc->chrLen--;
341
0
  }
342
0
  if (cvc->carLen > 0) {
343
0
    cvc->carLen--;
344
0
  }
345
0
  if (cvc->outerCARLen > 0) {
346
0
    cvc->outerCARLen--;
347
0
  }
348
0
}
349
350
/*
351
 * Sets up asn1_cvcert to point to asn1_cvc_body, asn1_cvc_pubkey, and
352
 * cvc. When sc_asn1_decode is called on asn1_cvcert, it will populate fields
353
 * in cvc.
354
 *
355
 * @param asn1_cvcert: unpopulated array with len matching c_asn1_cvcert
356
 * @param asn1_cvc_cert: unpopulated array with len matching c_asn1_cvc_body
357
 * @param asn1_cvc_pubkey: unpopulated array matching c_asn1_cvc_pubkey
358
 * @param cvc: non NULL cvc struct
359
 */
360
static int sc_pkcs15emu_sc_hsm_format_asn1_cvcert(
361
    struct sc_asn1_entry *asn1_cvcert, size_t asn1_cvcert_len,
362
    struct sc_asn1_entry *asn1_cvc_body, size_t asn1_cvc_body_len,
363
    struct sc_asn1_entry *asn1_cvc_pubkey, size_t asn1_cvc_pubkey_len,
364
    sc_cvc_t *cvc)
365
59
{
366
59
  if ((asn1_cvc_pubkey_len < C_ASN1_CVC_PUBKEY_SIZE) ||
367
59
    (asn1_cvc_body_len < C_ASN1_CVC_BODY_SIZE) ||
368
59
    (asn1_cvcert_len < C_ASN1_CVCERT_SIZE)) {
369
0
    return SC_ERROR_BUFFER_TOO_SMALL;
370
0
  }
371
372
59
  sc_copy_asn1_entry(c_asn1_cvc_pubkey, asn1_cvc_pubkey);
373
59
  sc_copy_asn1_entry(c_asn1_cvc_body, asn1_cvc_body);
374
59
  sc_copy_asn1_entry(c_asn1_cvcert, asn1_cvcert);
375
376
59
  sc_format_asn1_entry(asn1_cvc_pubkey    , &cvc->pukoid, NULL, 0);
377
59
  sc_format_asn1_entry(asn1_cvc_pubkey + 1, &cvc->primeOrModulus, &cvc->primeOrModuluslen, 0);
378
59
  sc_format_asn1_entry(asn1_cvc_pubkey + 2, &cvc->coefficientAorExponent, &cvc->coefficientAorExponentlen, 0);
379
59
  sc_format_asn1_entry(asn1_cvc_pubkey + 3, &cvc->coefficientB, &cvc->coefficientBlen, 0);
380
59
  sc_format_asn1_entry(asn1_cvc_pubkey + 4, &cvc->basePointG, &cvc->basePointGlen, 0);
381
59
  sc_format_asn1_entry(asn1_cvc_pubkey + 5, &cvc->order, &cvc->orderlen, 0);
382
59
  sc_format_asn1_entry(asn1_cvc_pubkey + 6, &cvc->publicPoint, &cvc->publicPointlen, 0);
383
59
  sc_format_asn1_entry(asn1_cvc_pubkey + 7, &cvc->cofactor, &cvc->cofactorlen, 0);
384
59
  sc_format_asn1_entry(asn1_cvc_pubkey + 8, &cvc->modulusSize, NULL, 0);
385
386
59
  sc_format_asn1_entry(asn1_cvc_body    , &cvc->cpi, NULL, 0);
387
59
  cvc->carLen = sizeof(cvc->car);
388
59
  sc_format_asn1_entry(asn1_cvc_body + 1, &cvc->car, &cvc->carLen, 0);
389
59
  sc_format_asn1_entry(asn1_cvc_body + 2, asn1_cvc_pubkey, NULL, 0);
390
59
  cvc->chrLen = sizeof(cvc->chr);
391
59
  sc_format_asn1_entry(asn1_cvc_body + 3, &cvc->chr, &cvc->chrLen, 0);
392
393
59
  sc_format_asn1_entry(asn1_cvcert    , asn1_cvc_body, NULL, 0);
394
59
  sc_format_asn1_entry(asn1_cvcert + 1, &cvc->signature, &cvc->signatureLen, 0);
395
59
  return SC_SUCCESS;
396
59
}
397
398
/*
399
 * Sets up asn1_req to point to asn1_authreq, which points to asn1_cvcert and
400
 * cvc
401
 * When sc_asn1_decode is called on asn1_authreq, it will populate fields
402
 * in cvc and asn1_cvcert
403
 *
404
 * @param asn1_authreq: unpopulated array with len matching c_asn1_req
405
 * @param asn1_authreq: unpopulated array with len matching c_asn1_authreq
406
 * @param asn1_cvcert: already-initialized array matching c_asn1_cvcert
407
 *
408
 */
409
static int sc_pkcs15emu_sc_hsm_format_asn1_req(
410
    struct sc_asn1_entry *asn1_authreq, size_t asn1_authreq_len,
411
    struct sc_asn1_entry *asn1_cvcert,
412
    sc_cvc_t *cvc)
413
59
{
414
59
  if (asn1_authreq_len < C_ASN1_AUTHREQ_SIZE) {
415
0
    return SC_ERROR_BUFFER_TOO_SMALL;
416
0
  }
417
418
59
  sc_copy_asn1_entry(c_asn1_authreq, asn1_authreq);
419
420
59
  sc_format_asn1_entry(asn1_authreq    , asn1_cvcert, NULL, 0);
421
59
  cvc->outerCARLen = sizeof(cvc->outer_car);
422
59
  sc_format_asn1_entry(asn1_authreq + 1, &cvc->outer_car, &cvc->outerCARLen, 0);
423
59
  sc_format_asn1_entry(asn1_authreq + 2, &cvc->outerSignature, &cvc->outerSignatureLen, 0);
424
59
  return SC_SUCCESS;
425
59
}
426
427
/*
428
 * Decode a card verifiable certificate as defined in TR-03110.
429
 */
430
int sc_pkcs15emu_sc_hsm_decode_cvc(sc_pkcs15_card_t * p15card,
431
  const u8 ** buf, size_t *buflen,
432
  sc_cvc_t *cvc)
433
59
{
434
59
  sc_card_t *card = p15card->card;
435
59
  struct sc_asn1_entry asn1_req[C_ASN1_REQ_SIZE];
436
59
  struct sc_asn1_entry asn1_authreq[C_ASN1_AUTHREQ_SIZE];
437
59
  struct sc_asn1_entry asn1_cvc[C_ASN1_CVC_SIZE];
438
59
  struct sc_asn1_entry asn1_cvcert[C_ASN1_CVCERT_SIZE];
439
59
  struct sc_asn1_entry asn1_cvc_body[C_ASN1_CVC_BODY_SIZE];
440
59
  struct sc_asn1_entry asn1_cvc_pubkey[C_ASN1_CVC_PUBKEY_SIZE];
441
59
  unsigned int cla = 0, tag = 0;
442
59
  size_t taglen;
443
59
  const u8 *tbuf;
444
59
  int r;
445
446
59
  memset(cvc, 0, sizeof(*cvc));
447
59
  sc_copy_asn1_entry(c_asn1_req, asn1_req);
448
59
  sc_copy_asn1_entry(c_asn1_cvc, asn1_cvc);
449
450
59
  r = sc_pkcs15emu_sc_hsm_format_asn1_cvcert(
451
59
      asn1_cvcert, C_ASN1_CVCERT_SIZE,
452
59
      asn1_cvc_body, C_ASN1_CVC_BODY_SIZE,
453
59
      asn1_cvc_pubkey, C_ASN1_CVC_PUBKEY_SIZE,
454
59
      cvc);
455
59
  LOG_TEST_RET(card->ctx, r, "sc_asn1_entry array too small");
456
457
59
  sc_format_asn1_entry(asn1_cvc, asn1_cvcert, NULL, 0);
458
459
59
  r = sc_pkcs15emu_sc_hsm_format_asn1_req(
460
59
      asn1_authreq, C_ASN1_AUTHREQ_SIZE,
461
59
      asn1_cvcert, cvc);
462
59
  LOG_TEST_RET(card->ctx, r, "sc_asn1_entry array too small");
463
464
59
  sc_format_asn1_entry(asn1_req, asn1_authreq, NULL, 0);
465
466
/*  sc_asn1_print_tags(*buf, *buflen); */
467
468
59
  tbuf = *buf;
469
59
  r = sc_asn1_read_tag(&tbuf, *buflen, &cla, &tag, &taglen);
470
59
  LOG_TEST_RET(card->ctx, r, "Could not decode card verifiable certificate");
471
472
  /*  Determine if we deal with an authenticated request, plain request or certificate */
473
22
  if ((cla == (SC_ASN1_TAG_APPLICATION|SC_ASN1_TAG_CONSTRUCTED)) && (tag == 7)) {
474
3
    r = sc_asn1_decode(card->ctx, asn1_req, *buf, *buflen, buf, buflen);
475
19
  } else {
476
19
    r = sc_asn1_decode(card->ctx, asn1_cvc, *buf, *buflen, buf, buflen);
477
19
  }
478
479
22
  LOG_TEST_RET(card->ctx, r, "Could not decode card verifiable certificate");
480
481
0
  fixup_cvc_printable_string_lengths(cvc);
482
483
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
484
0
}
485
486
struct sc_asn1_cvc_format {
487
  struct sc_asn1_entry asn1_cvc[C_ASN1_CVC_SIZE];
488
  struct sc_asn1_entry asn1_cvcert[C_ASN1_CVCERT_SIZE];
489
  struct sc_asn1_entry asn1_cvc_body[C_ASN1_CVC_BODY_SIZE];
490
  struct sc_asn1_entry asn1_cvc_pubkey[C_ASN1_CVC_PUBKEY_SIZE];
491
};
492
493
struct sc_asn1_sc_hsm_pka_callback_arg {
494
  sc_context_t *ctx;
495
  struct sc_asn1_entry *next_entry;
496
  sc_cvc_pka_component_t *component;
497
};
498
499
500
struct sc_asn1_sc_hsm_pka_data {
501
  struct sc_asn1_entry asn1_public_key_req[C_ASN1_REQ_SIZE];
502
  struct sc_asn1_entry asn1_public_key_authreq[C_ASN1_AUTHREQ_SIZE];
503
  struct sc_asn1_cvc_format asn1_public_key_cvc;
504
  struct sc_asn1_cvc_format asn1_device_cvc;
505
  struct sc_asn1_cvc_format asn1_dica_cvc;
506
  struct sc_asn1_sc_hsm_pka_callback_arg public_key_req_arg;
507
  struct sc_asn1_sc_hsm_pka_callback_arg device_arg;
508
  struct sc_asn1_sc_hsm_pka_callback_arg dica_arg;
509
};
510
511
struct sc_asn1_sc_hsm_pka_new_format {
512
  struct sc_asn1_entry seq[C_ASN1_SC_HSM_PKA_NEW_SIZE];
513
  struct sc_asn1_sc_hsm_pka_data data;
514
  struct sc_object_id oid;
515
};
516
517
struct sc_asn1_sc_hsm_pka_old_format {
518
  struct sc_asn1_entry seq[C_ASN1_SC_HSM_PKA_OLD_SIZE];
519
  struct sc_asn1_sc_hsm_pka_data data;
520
};
521
522
/*
523
 * Saves the current pointer then continues to decode
524
 */
525
static int sc_asn1_sc_hsm_pka_set_ptr_callback(
526
    sc_context_t *nctx, void *arg, const u8 *obj,
527
    size_t objlen, int depth)
528
0
{
529
0
  struct sc_asn1_sc_hsm_pka_callback_arg *carg = arg;
530
531
0
  carg->component->ptr = obj;
532
0
  carg->component->len = objlen;
533
534
0
  return sc_asn1_decode(carg->ctx, carg->next_entry, obj, objlen, NULL, NULL);
535
0
}
536
537
static int sc_asn1_sc_hsm_pka_data_init(sc_context_t *ctx,
538
  struct sc_asn1_sc_hsm_pka_data *data,
539
  sc_cvc_pka_t *pka)
540
0
{
541
0
  int r;
542
543
0
  data->public_key_req_arg.ctx = ctx;
544
0
  data->device_arg.ctx = ctx;
545
0
  data->dica_arg.ctx = ctx;
546
547
  /* public key info is in an authenticatedrequest (0x67) */
548
0
  r = sc_pkcs15emu_sc_hsm_format_asn1_cvcert(
549
0
      data->asn1_public_key_cvc.asn1_cvcert, C_ASN1_CVCERT_SIZE,
550
0
      data->asn1_public_key_cvc.asn1_cvc_body, C_ASN1_CVC_BODY_SIZE,
551
0
      data->asn1_public_key_cvc.asn1_cvc_pubkey, C_ASN1_CVC_PUBKEY_SIZE,
552
0
      &pka->public_key_req.cvc);
553
0
  LOG_TEST_RET(ctx, r, "sc_asn1_entry too small");
554
555
0
  r = sc_pkcs15emu_sc_hsm_format_asn1_req(
556
0
      data->asn1_public_key_authreq, C_ASN1_AUTHREQ_SIZE,
557
0
      data->asn1_public_key_cvc.asn1_cvcert,
558
0
      &pka->public_key_req.cvc);
559
0
  LOG_TEST_RET(ctx, r, "sc_asn1_entry too small");
560
561
  /*
562
   * insert a callback between req and authreq
563
   * the HSM expects the contents of the 0x67 authenticatedrequest tag (not
564
   * including the 0x67 tag itself)
565
   */
566
0
  sc_copy_asn1_entry(c_asn1_req, data->asn1_public_key_req);
567
0
  data->asn1_public_key_req[0].type = SC_ASN1_CALLBACK;
568
0
  data->public_key_req_arg.component = &pka->public_key_req;
569
0
  data->public_key_req_arg.next_entry = data->asn1_public_key_authreq;
570
0
  sc_format_asn1_entry(data->asn1_public_key_req,
571
0
      sc_asn1_sc_hsm_pka_set_ptr_callback,
572
0
      &data->public_key_req_arg, 0);
573
574
  /* device CVC is a certificate (0x7F21) */
575
0
  r = sc_pkcs15emu_sc_hsm_format_asn1_cvcert(
576
0
      data->asn1_device_cvc.asn1_cvcert, C_ASN1_CVCERT_SIZE,
577
0
      data->asn1_device_cvc.asn1_cvc_body, C_ASN1_CVC_BODY_SIZE,
578
0
      data->asn1_device_cvc.asn1_cvc_pubkey, C_ASN1_CVC_PUBKEY_SIZE,
579
0
      &pka->device.cvc);
580
0
  LOG_TEST_RET(ctx, r, "sc_asn1_entry too small");
581
582
  /*
583
   * insert a callback between asn1_cvc and asn1_cvcert
584
   * the HSM expects the contents of the 0x7F21 CVC tag (not including the
585
   * 0x7F21 tag itself)
586
   */
587
0
  sc_copy_asn1_entry(c_asn1_cvc, data->asn1_device_cvc.asn1_cvc);
588
0
  data->asn1_device_cvc.asn1_cvc[0].type = SC_ASN1_CALLBACK;
589
0
  data->device_arg.component = &pka->device;
590
0
  data->device_arg.next_entry = data->asn1_device_cvc.asn1_cvcert;
591
0
  sc_format_asn1_entry(data->asn1_device_cvc.asn1_cvc,
592
0
      sc_asn1_sc_hsm_pka_set_ptr_callback,
593
0
      &data->device_arg, 0);
594
595
  /* device issuer CA CVC is a certificate (0x7F21) */
596
0
  r = sc_pkcs15emu_sc_hsm_format_asn1_cvcert(
597
0
      data->asn1_dica_cvc.asn1_cvcert, C_ASN1_CVCERT_SIZE,
598
0
      data->asn1_dica_cvc.asn1_cvc_body, C_ASN1_CVC_BODY_SIZE,
599
0
      data->asn1_dica_cvc.asn1_cvc_pubkey, C_ASN1_CVC_PUBKEY_SIZE,
600
0
      &pka->dica.cvc);
601
0
  LOG_TEST_RET(ctx, r, "sc_asn1_entry too small");
602
603
  /*
604
   * insert a callback between asn1_cvc and asn1_cvcert
605
   * the HSM expects the contents of the 0x7F21 CVC tag (not including the
606
   * 0x7F21 tag itself)
607
   */
608
0
  sc_copy_asn1_entry(c_asn1_cvc, data->asn1_dica_cvc.asn1_cvc);
609
0
  data->asn1_dica_cvc.asn1_cvc[0].type = SC_ASN1_CALLBACK;
610
0
  data->dica_arg.component = &pka->dica;
611
0
  data->dica_arg.next_entry = data->asn1_dica_cvc.asn1_cvcert;
612
0
  sc_format_asn1_entry(data->asn1_dica_cvc.asn1_cvc,
613
0
      sc_asn1_sc_hsm_pka_set_ptr_callback,
614
0
      &data->dica_arg, 0);
615
0
  return SC_SUCCESS;
616
0
}
617
618
/*
619
 * For SmartCard HSMs, this is the older format for registering a public key
620
 * for public key authentication.
621
 *
622
 * @param buf: *buf should point to the first tag in the sequence
623
 *
624
 * SEQUENCE (0x30)
625
 *   authenticatedrequest for public key details (0x67)
626
 *   device CVC (0x7F21)
627
 *   device issuer CA CVC (0x7F21)
628
 */
629
static int decode_pka_old_format(sc_pkcs15_card_t *p15card,
630
  const u8 **buf, size_t *buflen,
631
  sc_cvc_pka_t *pka)
632
0
{
633
0
  int r;
634
0
  sc_card_t *card;
635
0
  struct sc_asn1_sc_hsm_pka_old_format *format = NULL;
636
637
0
  card = p15card->card;
638
639
0
  format = calloc(1, sizeof(*format));
640
0
  if (format == NULL) {
641
0
    r = SC_ERROR_OUT_OF_MEMORY;
642
0
    goto err;
643
0
  }
644
645
0
  r = sc_asn1_sc_hsm_pka_data_init(card->ctx, &format->data, pka);
646
0
  LOG_TEST_GOTO_ERR(card->ctx, r, "sc_asn1_entry array too small");
647
648
0
  sc_copy_asn1_entry(c_asn1_sc_hsm_pka_old_format, format->seq);
649
0
  format->seq[0] = format->data.asn1_public_key_req[0];
650
0
  format->seq[1] = format->data.asn1_device_cvc.asn1_cvc[0];
651
0
  format->seq[2] = format->data.asn1_dica_cvc.asn1_cvc[0];
652
653
0
  r = sc_asn1_decode(p15card->card->ctx, format->seq, *buf, *buflen,
654
0
      buf, buflen);
655
0
  LOG_TEST_GOTO_ERR(card->ctx, r,
656
0
    "Could not decode ASN.1 for public key file's old format");
657
658
0
  r = SC_SUCCESS;
659
  /* fall-through */
660
661
0
err:
662
0
  free(format);
663
0
  format = NULL;
664
0
  return r;
665
0
}
666
667
/*
668
 * For SmartCard HSMs, this is the newer format for registering a public key
669
 * for public key authentication.
670
 *
671
 * @param buf: *buf should point to the first tag after the sequence tag
672
 *
673
 * 1.3.6.1.4.1.24991 is the CardContact organization
674
 * The 4.3.1 part is from inspecting their exported public key, but it doesn't
675
 * seem to be publicly registered.
676
 *
677
 * SEQUENCE (0x30)
678
 *   OID (0x6) 1.3.6.1.4.1.24991.4.3.1
679
 *   Application 1 (0x61)
680
 *      device CVC (0x7F21)
681
 *   Application 2 (0x62)
682
 *      device issuer CA CVC (0x7F21)
683
 *   Application 3 (0x63)
684
 *      authenticatedrequest for public key details (0x67)
685
 */
686
static int decode_pka_new_format(sc_pkcs15_card_t *p15card,
687
  const u8 **buf, size_t *buflen,
688
  sc_cvc_pka_t *pka)
689
0
{
690
0
  int r;
691
0
  sc_card_t *card;
692
0
  struct sc_asn1_sc_hsm_pka_new_format *format = NULL;
693
694
0
  card = p15card->card;
695
696
0
  format = calloc(1, sizeof(*format));
697
0
  if (format == NULL) {
698
0
    r = SC_ERROR_OUT_OF_MEMORY;
699
0
    goto err;
700
0
  }
701
702
0
  r = sc_asn1_sc_hsm_pka_data_init(card->ctx, &format->data, pka);
703
0
  LOG_TEST_GOTO_ERR(card->ctx, r, "sc_asn1_entry array too small");
704
705
0
  sc_copy_asn1_entry(c_asn1_sc_hsm_pka_new_format, format->seq);
706
0
  sc_format_asn1_entry(&format->seq[0], &format->oid, NULL, 0);
707
0
  sc_format_asn1_entry(&format->seq[1],
708
0
      format->data.asn1_dica_cvc.asn1_cvc, NULL, 0);
709
0
  sc_format_asn1_entry(&format->seq[2],
710
0
      format->data.asn1_device_cvc.asn1_cvc, NULL, 0);
711
0
  sc_format_asn1_entry(&format->seq[3],
712
0
      format->data.asn1_public_key_req, NULL, 0);
713
714
0
  r = sc_asn1_decode(p15card->card->ctx, format->seq, *buf, *buflen,
715
0
      buf, buflen);
716
0
  LOG_TEST_GOTO_ERR(card->ctx, r,
717
0
    "Could not decode ASN.1 for public key file's new format");
718
719
0
  if (sc_compare_oid(&format->oid, &sc_hsm_public_key_oid) == 0) {
720
    /* sc_dump_oid uses static memory */
721
0
    sc_log(p15card->card->ctx, "OID %s did not match expected value",
722
0
         sc_dump_oid(&format->oid));
723
0
    r = -1;
724
0
    goto err;
725
0
  }
726
727
0
  r = SC_SUCCESS;
728
  /* fall-through */
729
730
0
err:
731
0
  free(format);
732
0
  format = NULL;
733
0
  return r;
734
0
}
735
736
/*
737
 * @param pka: will be overwritten, should be uninitialized or memset to 0
738
 */
739
int sc_pkcs15emu_sc_hsm_decode_pka(sc_pkcs15_card_t *p15card,
740
  const u8 **buf, size_t *buflen,
741
  sc_cvc_pka_t *pka)
742
0
{
743
0
  int r;
744
0
  const u8 *curr;
745
0
  const u8 *peek;
746
0
  unsigned int cla, tag;
747
0
  size_t taglen;
748
0
  size_t currlen;
749
0
  sc_card_t *card;
750
751
0
  memset(pka, 0, sizeof(*pka));
752
753
0
  card = p15card->card;
754
0
  curr = *buf;
755
0
  currlen = *buflen;
756
757
  /* first tag should be sequence */
758
0
  r = sc_asn1_read_tag(&curr, currlen, &cla, &tag, &taglen);
759
0
  LOG_TEST_GOTO_ERR(card->ctx, r,
760
0
      "Could not decode first sequence tag for public key file");
761
0
  currlen = *buflen - (curr - *buf);
762
763
0
  if ((cla != (SC_ASN1_TAG_UNIVERSAL|SC_ASN1_TAG_CONSTRUCTED)) ||
764
0
      (tag != SC_ASN1_TAG_SEQUENCE)) {
765
0
    sc_log(card->ctx,
766
0
         "Expected sequence tag, but got tag %u class 0x%x", tag, cla);
767
0
    r = SC_ERROR_INVALID_ASN1_OBJECT;
768
0
    goto err;
769
0
  }
770
771
  /* next tag is either OID (new format) or 0x67 (old format) */
772
0
  peek = curr;
773
0
  r = sc_asn1_read_tag(&peek, currlen, &cla, &tag, &taglen);
774
0
  LOG_TEST_GOTO_ERR(card->ctx, r,
775
0
      "Could not decode first sequence element tag for public key file");
776
777
0
  if (tag == SC_ASN1_TAG_OBJECT) {
778
    /* OID means it's the new format */
779
0
    r = decode_pka_new_format(p15card, &curr, &currlen, pka);
780
0
    LOG_TEST_GOTO_ERR(card->ctx, r,
781
0
      "Could not decode public key file new format");
782
0
  } else if ((cla == (SC_ASN1_TAG_APPLICATION|SC_ASN1_TAG_CONSTRUCTED)) &&
783
0
        (tag == 7)) {
784
    /*
785
     * if it's authenticatedrequest (Application 7 / 0x67), then attempt
786
     * to parse the old format
787
     */
788
0
    r = decode_pka_old_format(p15card, &curr, &currlen, pka);
789
0
    LOG_TEST_GOTO_ERR(card->ctx, r,
790
0
      "Could not decode authenticatedrequest for public key file");
791
0
  } else {
792
0
    sc_log(card->ctx,
793
0
        "Unexpected tag %u class 0x%x for first element of sequence",
794
0
        tag, cla);
795
0
    r = SC_ERROR_INVALID_ASN1_OBJECT;
796
0
    goto err;
797
0
  }
798
799
0
  fixup_cvc_printable_string_lengths(&pka->public_key_req.cvc);
800
0
  fixup_cvc_printable_string_lengths(&pka->device.cvc);
801
0
  fixup_cvc_printable_string_lengths(&pka->dica.cvc);
802
803
0
  *buf = curr;
804
0
  *buflen = *buflen - (curr - *buf);
805
806
0
  return SC_SUCCESS;
807
808
0
err:
809
0
  sc_pkcs15emu_sc_hsm_free_cvc_pka(pka);
810
0
  return r;
811
0
}
812
813
/*
814
 * Encode a card verifiable certificate as defined in TR-03110.
815
 */
816
int sc_pkcs15emu_sc_hsm_encode_cvc(sc_pkcs15_card_t * p15card,
817
    sc_cvc_t *cvc,
818
    u8 ** buf, size_t *buflen)
819
0
{
820
0
  sc_card_t *card = p15card->card;
821
0
  struct sc_asn1_entry asn1_cvc[C_ASN1_CVC_SIZE];
822
0
  struct sc_asn1_entry asn1_cvcert[C_ASN1_CVCERT_SIZE];
823
0
  struct sc_asn1_entry asn1_cvc_body[C_ASN1_CVC_BODY_SIZE];
824
0
  struct sc_asn1_entry asn1_cvc_pubkey[C_ASN1_CVC_PUBKEY_SIZE];
825
0
  int r;
826
827
0
  sc_copy_asn1_entry(c_asn1_cvc, asn1_cvc);
828
0
  sc_copy_asn1_entry(c_asn1_cvcert, asn1_cvcert);
829
0
  sc_copy_asn1_entry(c_asn1_cvc_body, asn1_cvc_body);
830
0
  sc_copy_asn1_entry(c_asn1_cvc_pubkey, asn1_cvc_pubkey);
831
832
0
  asn1_cvc_pubkey[1].flags = SC_ASN1_OPTIONAL;
833
0
  asn1_cvcert[1].flags = SC_ASN1_OPTIONAL;
834
835
0
  sc_format_asn1_entry(asn1_cvc_pubkey    , &cvc->pukoid, NULL, 1);
836
0
  if (cvc->primeOrModulus && (cvc->primeOrModuluslen > 0)) {
837
0
    sc_format_asn1_entry(asn1_cvc_pubkey + 1, cvc->primeOrModulus, &cvc->primeOrModuluslen, 1);
838
0
  }
839
0
  sc_format_asn1_entry(asn1_cvc_pubkey + 2, cvc->coefficientAorExponent, &cvc->coefficientAorExponentlen, 1);
840
0
  if (cvc->coefficientB && (cvc->coefficientBlen > 0)) {
841
0
    sc_format_asn1_entry(asn1_cvc_pubkey + 3, cvc->coefficientB, &cvc->coefficientBlen, 1);
842
0
    sc_format_asn1_entry(asn1_cvc_pubkey + 4, cvc->basePointG, &cvc->basePointGlen, 1);
843
0
    sc_format_asn1_entry(asn1_cvc_pubkey + 5, cvc->order, &cvc->orderlen, 1);
844
0
    if (cvc->publicPoint && (cvc->publicPointlen > 0)) {
845
0
      sc_format_asn1_entry(asn1_cvc_pubkey + 6, cvc->publicPoint, &cvc->publicPointlen, 1);
846
0
    }
847
0
    sc_format_asn1_entry(asn1_cvc_pubkey + 7, cvc->cofactor, &cvc->cofactorlen, 1);
848
0
  }
849
0
  if (cvc->modulusSize > 0) {
850
0
    sc_format_asn1_entry(asn1_cvc_pubkey + 8, &cvc->modulusSize, NULL, 1);
851
0
  }
852
853
0
  sc_format_asn1_entry(asn1_cvc_body    , &cvc->cpi, NULL, 1);
854
0
  sc_format_asn1_entry(asn1_cvc_body + 1, &cvc->car, &cvc->carLen, 1);
855
0
  sc_format_asn1_entry(asn1_cvc_body + 2, &asn1_cvc_pubkey, NULL, 1);
856
0
  sc_format_asn1_entry(asn1_cvc_body + 3, &cvc->chr, &cvc->chrLen, 1);
857
858
0
  sc_format_asn1_entry(asn1_cvcert    , &asn1_cvc_body, NULL, 1);
859
0
  if (cvc->signature && (cvc->signatureLen > 0)) {
860
0
    sc_format_asn1_entry(asn1_cvcert + 1, cvc->signature, &cvc->signatureLen, 1);
861
0
  }
862
863
0
  sc_format_asn1_entry(asn1_cvc , &asn1_cvcert, NULL, 1);
864
865
0
  r = sc_asn1_encode(card->ctx, asn1_cvc, buf, buflen);
866
0
  LOG_TEST_RET(card->ctx, r, "Could not encode card verifiable certificate");
867
868
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
869
0
}
870
871
872
873
int sc_pkcs15emu_sc_hsm_get_curve(struct ec_curve **curve, u8 *oid, size_t oidlen)
874
0
{
875
0
  int i;
876
877
0
  for (i = 0; curves[i].oid.value; i++) {
878
0
    if ((curves[i].oid.len == oidlen) && !memcmp(curves[i].oid.value, oid, oidlen)) {
879
0
      *curve = &curves[i];
880
0
      return SC_SUCCESS;
881
0
    }
882
0
  }
883
0
  return SC_ERROR_INVALID_DATA;
884
0
}
885
886
887
888
int sc_pkcs15emu_sc_hsm_get_curve_oid(sc_cvc_t *cvc, const struct sc_lv_data **oid)
889
0
{
890
0
  int i;
891
892
0
  for (i = 0; curves[i].oid.value; i++) {
893
0
    if ((curves[i].prime.len == cvc->primeOrModuluslen) &&
894
0
        !memcmp(curves[i].prime.value, cvc->primeOrModulus, cvc->primeOrModuluslen) &&
895
0
        (curves[i].coefficientA.len == cvc->coefficientAorExponentlen) &&
896
0
        !memcmp(curves[i].coefficientA.value,
897
0
            cvc->coefficientAorExponent, cvc->coefficientAorExponentlen)) {
898
0
      *oid = &curves[i].oid;
899
0
      return SC_SUCCESS;
900
0
    }
901
0
  }
902
0
  return SC_ERROR_INVALID_DATA;
903
0
}
904
905
906
907
static int sc_pkcs15emu_sc_hsm_get_rsa_public_key(struct sc_context *ctx, sc_cvc_t *cvc, struct sc_pkcs15_pubkey *pubkey)
908
0
{
909
0
  pubkey->algorithm = SC_ALGORITHM_RSA;
910
911
0
  pubkey->alg_id = (struct sc_algorithm_id *)calloc(1, sizeof(struct sc_algorithm_id));
912
0
  if (!pubkey->alg_id)
913
0
    return SC_ERROR_OUT_OF_MEMORY;
914
915
0
  pubkey->alg_id->algorithm = SC_ALGORITHM_RSA;
916
917
0
  pubkey->u.rsa.modulus.len = cvc->primeOrModuluslen;
918
0
  pubkey->u.rsa.modulus.data  = malloc(pubkey->u.rsa.modulus.len);
919
0
  pubkey->u.rsa.exponent.len  = cvc->coefficientAorExponentlen;
920
0
  pubkey->u.rsa.exponent.data = malloc(pubkey->u.rsa.exponent.len);
921
0
  if (!pubkey->u.rsa.modulus.data || !pubkey->u.rsa.exponent.data) {
922
0
    free(pubkey->u.rsa.modulus.data);
923
0
    free(pubkey->u.rsa.exponent.data);
924
0
    free(pubkey->alg_id);
925
0
    return SC_ERROR_OUT_OF_MEMORY;
926
0
  }
927
928
0
  memcpy(pubkey->u.rsa.exponent.data, cvc->coefficientAorExponent, pubkey->u.rsa.exponent.len);
929
0
  memcpy(pubkey->u.rsa.modulus.data, cvc->primeOrModulus, pubkey->u.rsa.modulus.len);
930
931
0
  return SC_SUCCESS;
932
0
}
933
934
935
936
static int sc_pkcs15emu_sc_hsm_get_ec_public_key(struct sc_context *ctx, sc_cvc_t *cvc, struct sc_pkcs15_pubkey *pubkey)
937
0
{
938
0
  struct sc_ec_parameters *ecp;
939
0
  const struct sc_lv_data *oid;
940
0
  int r;
941
942
0
  pubkey->algorithm = SC_ALGORITHM_EC;
943
944
0
  r = sc_pkcs15emu_sc_hsm_get_curve_oid(cvc, &oid);
945
0
  if (r != SC_SUCCESS)
946
0
    return r;
947
948
0
  ecp = calloc(1, sizeof(struct sc_ec_parameters));
949
0
  if (!ecp)
950
0
    return SC_ERROR_OUT_OF_MEMORY;
951
952
0
  ecp->der.len = oid->len + 2;
953
0
  ecp->der.value = calloc(1, ecp->der.len);
954
0
  if (!ecp->der.value) {
955
0
    free(ecp);
956
0
    return SC_ERROR_OUT_OF_MEMORY;
957
0
  }
958
959
0
  *(ecp->der.value + 0) = 0x06;
960
0
  *(ecp->der.value + 1) = (u8)oid->len;
961
0
  memcpy(ecp->der.value + 2, oid->value, oid->len);
962
0
  ecp->type = 1;    // Named curve
963
964
0
  pubkey->alg_id = (struct sc_algorithm_id *)calloc(1, sizeof(struct sc_algorithm_id));
965
0
  if (!pubkey->alg_id) {
966
0
    free(ecp->der.value);
967
0
    free(ecp);
968
0
    return SC_ERROR_OUT_OF_MEMORY;
969
0
  }
970
971
0
  pubkey->alg_id->algorithm = SC_ALGORITHM_EC;
972
0
  pubkey->alg_id->params = ecp;
973
974
0
  pubkey->u.ec.ecpointQ.value = malloc(cvc->publicPointlen);
975
0
  if (!pubkey->u.ec.ecpointQ.value) {
976
0
    free(pubkey->alg_id);
977
0
    free(ecp->der.value);
978
0
    free(ecp);
979
0
    return SC_ERROR_OUT_OF_MEMORY;
980
0
  }
981
0
  memcpy(pubkey->u.ec.ecpointQ.value, cvc->publicPoint, cvc->publicPointlen);
982
0
  pubkey->u.ec.ecpointQ.len = cvc->publicPointlen;
983
984
0
  pubkey->u.ec.params.der.value = malloc(ecp->der.len);
985
0
  if (!pubkey->u.ec.params.der.value) {
986
0
    free(pubkey->u.ec.ecpointQ.value);
987
0
    free(pubkey->alg_id);
988
0
    free(ecp->der.value);
989
0
    free(ecp);
990
0
    return SC_ERROR_OUT_OF_MEMORY;
991
0
  }
992
0
  memcpy(pubkey->u.ec.params.der.value, ecp->der.value, ecp->der.len);
993
0
  pubkey->u.ec.params.der.len = ecp->der.len;
994
995
  /* FIXME: check return value? */
996
0
  sc_pkcs15_fix_ec_parameters(ctx, &pubkey->u.ec.params);
997
998
0
  return SC_SUCCESS;
999
0
}
1000
1001
1002
1003
int sc_pkcs15emu_sc_hsm_get_public_key(struct sc_context *ctx, sc_cvc_t *cvc, struct sc_pkcs15_pubkey *pubkey)
1004
0
{
1005
0
  if (cvc->publicPoint && cvc->publicPointlen) {
1006
0
    return sc_pkcs15emu_sc_hsm_get_ec_public_key(ctx, cvc, pubkey);
1007
0
  } else {
1008
0
    return sc_pkcs15emu_sc_hsm_get_rsa_public_key(ctx, cvc, pubkey);
1009
0
  }
1010
0
}
1011
1012
1013
1014
void sc_pkcs15emu_sc_hsm_free_cvc(sc_cvc_t *cvc)
1015
6
{
1016
6
  if (cvc->outerSignature) {
1017
0
    free(cvc->outerSignature);
1018
0
    cvc->outerSignature = NULL;
1019
0
  }
1020
6
  if (cvc->signature) {
1021
0
    free(cvc->signature);
1022
0
    cvc->signature = NULL;
1023
0
  }
1024
6
  if (cvc->primeOrModulus) {
1025
0
    free(cvc->primeOrModulus);
1026
0
    cvc->primeOrModulus = NULL;
1027
0
  }
1028
6
  if (cvc->coefficientAorExponent) {
1029
0
    free(cvc->coefficientAorExponent);
1030
0
    cvc->coefficientAorExponent = NULL;
1031
0
  }
1032
6
  if (cvc->coefficientB) {
1033
0
    free(cvc->coefficientB);
1034
0
    cvc->coefficientB = NULL;
1035
0
  }
1036
6
  if (cvc->basePointG) {
1037
0
    free(cvc->basePointG);
1038
0
    cvc->basePointG = NULL;
1039
0
  }
1040
6
  if (cvc->order) {
1041
0
    free(cvc->order);
1042
0
    cvc->order = NULL;
1043
0
  }
1044
6
  if (cvc->publicPoint) {
1045
0
    free(cvc->publicPoint);
1046
0
    cvc->publicPoint = NULL;
1047
0
  }
1048
6
  if (cvc->cofactor) {
1049
0
    free(cvc->cofactor);
1050
0
    cvc->cofactor = NULL;
1051
0
  }
1052
6
}
1053
1054
void sc_pkcs15emu_sc_hsm_free_cvc_pka(sc_cvc_pka_t *pka)
1055
0
{
1056
0
  sc_pkcs15emu_sc_hsm_free_cvc(&pka->public_key_req.cvc);
1057
0
  sc_pkcs15emu_sc_hsm_free_cvc(&pka->device.cvc);
1058
0
  sc_pkcs15emu_sc_hsm_free_cvc(&pka->dica.cvc);
1059
0
  memset(pka, 0, sizeof(*pka));
1060
0
}
1061
1062
static int sc_pkcs15emu_sc_hsm_add_pubkey(sc_pkcs15_card_t *p15card, u8 *efbin, size_t len, sc_pkcs15_prkey_info_t *key_info, char *label)
1063
0
{
1064
0
  struct sc_context *ctx = p15card->card->ctx;
1065
0
  sc_card_t *card = p15card->card;
1066
0
  sc_pkcs15_pubkey_info_t pubkey_info;
1067
0
  sc_pkcs15_object_t pubkey_obj;
1068
0
  struct sc_pkcs15_pubkey pubkey;
1069
0
  sc_cvc_t cvc;
1070
0
  u8 *cvcpo;
1071
0
  int r;
1072
1073
0
  cvcpo = efbin;
1074
1075
0
  memset(&cvc, 0, sizeof(cvc));
1076
0
  r = sc_pkcs15emu_sc_hsm_decode_cvc(p15card, (const u8 **)&cvcpo, &len, &cvc);
1077
0
  LOG_TEST_RET(ctx, r, "Could decode certificate signing request");
1078
1079
0
  memset(&pubkey, 0, sizeof(pubkey));
1080
0
  r = sc_pkcs15emu_sc_hsm_get_public_key(ctx, &cvc, &pubkey);
1081
0
  LOG_TEST_RET(card->ctx, r, "Could not extract public key");
1082
1083
0
  memset(&pubkey_info, 0, sizeof(pubkey_info));
1084
0
  memset(&pubkey_obj, 0, sizeof(pubkey_obj));
1085
1086
0
  r = sc_pkcs15_encode_pubkey(ctx, &pubkey, &pubkey_obj.content.value, &pubkey_obj.content.len);
1087
0
  if (r != SC_SUCCESS) {
1088
0
    sc_pkcs15_erase_pubkey(&pubkey);
1089
0
    LOG_TEST_RET(ctx, r, "Could not encode public key");
1090
0
  }
1091
0
  r = sc_pkcs15_encode_pubkey(ctx, &pubkey, &pubkey_info.direct.raw.value, &pubkey_info.direct.raw.len);
1092
0
  if (r != SC_SUCCESS) {
1093
0
    sc_pkcs15_erase_pubkey(&pubkey);
1094
0
    LOG_TEST_RET(ctx, r, "Could not encode public key");
1095
0
  }
1096
0
  r = sc_pkcs15_encode_pubkey_as_spki(ctx, &pubkey, &pubkey_info.direct.spki.value, &pubkey_info.direct.spki.len);
1097
0
  if (r != SC_SUCCESS) {
1098
0
    sc_pkcs15_erase_pubkey(&pubkey);
1099
0
    LOG_TEST_RET(ctx, r, "Could not encode public key");
1100
0
  }
1101
1102
0
  pubkey_info.id = key_info->id;
1103
0
  strlcpy(pubkey_obj.label, label, sizeof(pubkey_obj.label));
1104
1105
0
  if (pubkey.algorithm == SC_ALGORITHM_RSA) {
1106
0
    pubkey_info.modulus_length = pubkey.u.rsa.modulus.len << 3;
1107
0
    pubkey_info.usage = SC_PKCS15_PRKEY_USAGE_ENCRYPT|SC_PKCS15_PRKEY_USAGE_VERIFY|SC_PKCS15_PRKEY_USAGE_WRAP;
1108
0
    r = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info);
1109
0
  } else {
1110
    /* TODO fix if support of non multiple of 8 curves are added */
1111
0
    pubkey_info.field_length = cvc.primeOrModuluslen << 3;
1112
0
    pubkey_info.usage = SC_PKCS15_PRKEY_USAGE_VERIFY|SC_PKCS15_PRKEY_USAGE_DERIVE;
1113
0
    r = sc_pkcs15emu_add_ec_pubkey(p15card, &pubkey_obj, &pubkey_info);
1114
0
  }
1115
0
  if (r < 0)
1116
0
    free(pubkey_info.direct.spki.value);
1117
0
  LOG_TEST_RET(ctx, r, "Could not add public key");
1118
1119
0
  sc_pkcs15emu_sc_hsm_free_cvc(&cvc);
1120
0
  sc_pkcs15_erase_pubkey(&pubkey);
1121
1122
0
  return SC_SUCCESS;
1123
0
}
1124
1125
1126
1127
/*
1128
 * Add a key and the key description in PKCS#15 format to the framework
1129
 */
1130
0
static int sc_pkcs15emu_sc_hsm_add_prkd(sc_pkcs15_card_t * p15card, u8 keyid) {
1131
1132
0
  sc_card_t *card = p15card->card;
1133
0
  sc_pkcs15_cert_info_t cert_info;
1134
0
  sc_pkcs15_object_t cert_obj;
1135
0
  struct sc_pkcs15_object prkd;
1136
0
  sc_pkcs15_prkey_info_t *key_info;
1137
0
  u8 fid[2];
1138
  /* enough to hold a complete certificate */
1139
0
  u8 efbin[4096];
1140
0
  u8 *ptr;
1141
0
  size_t len;
1142
0
  int r;
1143
1144
0
  if (keyid == 0) {
1145
    // Device authentication key does not have PKCS#15 meta data
1146
0
    return SC_SUCCESS;
1147
0
  }
1148
1149
0
  fid[0] = PRKD_PREFIX;
1150
0
  fid[1] = keyid;
1151
1152
  /* Try to select a related EF containing the PKCS#15 description of the key */
1153
0
  len = sizeof efbin;
1154
0
  r = read_file(p15card, fid, efbin, &len, 1);
1155
0
  LOG_TEST_RET(card->ctx, r, "Skipping optional EF.PRKD");
1156
1157
0
  ptr = efbin;
1158
1159
0
  memset(&prkd, 0, sizeof(prkd));
1160
0
  r = sc_pkcs15_decode_prkdf_entry(p15card, &prkd, (const u8 **)&ptr, &len);
1161
0
  LOG_TEST_RET(card->ctx, r, "Skipping optional EF.PRKD");
1162
1163
  /* All keys require user PIN authentication */
1164
0
  prkd.auth_id.len = 1;
1165
0
  prkd.auth_id.value[0] = 1;
1166
1167
  /*
1168
   * Set private key flag as all keys are private anyway
1169
   */
1170
0
  prkd.flags |= SC_PKCS15_CO_FLAG_PRIVATE;
1171
1172
0
  key_info = (sc_pkcs15_prkey_info_t *)prkd.data;
1173
0
  key_info->key_reference = keyid;
1174
0
  key_info->path.aid.len = 0;
1175
1176
0
  if (prkd.type == SC_PKCS15_TYPE_PRKEY_RSA) {
1177
0
    r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkd, key_info);
1178
0
  } else {
1179
0
    if (key_info->field_length == 528) {
1180
      // Fix a bug for secp521 key generated with OpenSCDP
1181
0
      key_info->field_length = 521;
1182
0
    }
1183
0
    r = sc_pkcs15emu_add_ec_prkey(p15card, &prkd, key_info);
1184
0
  }
1185
1186
0
  LOG_TEST_RET(card->ctx, r, "Could not add private key to framework");
1187
1188
  /* Check if we also have a certificate for the private key */
1189
0
  fid[0] = EE_CERTIFICATE_PREFIX;
1190
1191
0
  len = sizeof efbin;
1192
0
  r = read_file(p15card, fid, efbin, &len, 0);
1193
0
  LOG_TEST_RET(card->ctx, r, "Could not read EF");
1194
1195
0
  if (efbin[0] == 0x67) {   /* Decode CSR and create public key object */
1196
0
    sc_pkcs15emu_sc_hsm_add_pubkey(p15card, efbin, len, key_info, prkd.label);
1197
0
    free(key_info);
1198
0
    return SC_SUCCESS;   /* Ignore any errors */
1199
0
  }
1200
1201
0
  if (efbin[0] != 0x30) {
1202
0
    free(key_info);
1203
0
    return SC_SUCCESS;
1204
0
  }
1205
1206
0
  memset(&cert_info, 0, sizeof(cert_info));
1207
0
  memset(&cert_obj, 0, sizeof(cert_obj));
1208
1209
0
  cert_info.id = key_info->id;
1210
0
  sc_path_set(&cert_info.path, SC_PATH_TYPE_FILE_ID, fid, 2, 0, 0);
1211
0
  cert_info.path.count = -1;
1212
0
  if (p15card->opts.use_file_cache) {
1213
    /* look this up with our AID, which should already be cached from the
1214
     * call to `read_file`. This may have the side effect that OpenSC's
1215
     * caching layer re-selects our applet *if the cached file cannot be
1216
     * found/used* and we may loose the authentication status. We assume
1217
     * that caching works perfectly without this side effect. */
1218
0
    cert_info.path.aid = sc_hsm_aid;
1219
0
  }
1220
1221
0
  strlcpy(cert_obj.label, prkd.label, sizeof(cert_obj.label));
1222
0
  r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
1223
1224
0
  free(key_info);
1225
1226
0
  LOG_TEST_RET(card->ctx, r, "Could not add certificate");
1227
1228
0
  return SC_SUCCESS;
1229
0
}
1230
1231
1232
1233
/*
1234
 * Add a data object and description in PKCS#15 format to the framework
1235
 */
1236
0
static int sc_pkcs15emu_sc_hsm_add_dcod(sc_pkcs15_card_t * p15card, u8 id) {
1237
1238
0
  sc_card_t *card = p15card->card;
1239
0
  sc_pkcs15_data_info_t *data_info;
1240
0
  sc_pkcs15_object_t data_obj;
1241
0
  u8 fid[2];
1242
0
  u8 efbin[512];
1243
0
  const u8 *ptr;
1244
0
  size_t len;
1245
0
  int r;
1246
1247
0
  fid[0] = DCOD_PREFIX;
1248
0
  fid[1] = id;
1249
1250
  /* Try to select a related EF containing the PKCS#15 description of the data */
1251
0
  len = sizeof efbin;
1252
0
  r = read_file(p15card, fid, efbin, &len, 1);
1253
0
  LOG_TEST_RET(card->ctx, r, "Skipping optional EF.DCOD");
1254
1255
0
  ptr = efbin;
1256
1257
0
  memset(&data_obj, 0, sizeof(data_obj));
1258
0
  r = sc_pkcs15_decode_dodf_entry(p15card, &data_obj, &ptr, &len);
1259
0
  LOG_TEST_RET(card->ctx, r, "Could not decode optional EF.DCOD");
1260
1261
0
  data_info = (sc_pkcs15_data_info_t *)data_obj.data;
1262
1263
0
  r = sc_pkcs15emu_add_data_object(p15card, &data_obj, data_info);
1264
1265
0
  LOG_TEST_RET(card->ctx, r, "Could not add data object to framework");
1266
1267
0
  return SC_SUCCESS;
1268
0
}
1269
1270
1271
1272
/*
1273
 * Add a unrelated certificate object and description in PKCS#15 format to the framework
1274
 */
1275
0
static int sc_pkcs15emu_sc_hsm_add_cd(sc_pkcs15_card_t * p15card, u8 id) {
1276
1277
0
  sc_card_t *card = p15card->card;
1278
0
  sc_pkcs15_cert_info_t *cert_info;
1279
0
  sc_pkcs15_object_t obj;
1280
0
  u8 fid[2];
1281
0
  u8 efbin[512];
1282
0
  const u8 *ptr;
1283
0
  size_t len;
1284
0
  int r;
1285
1286
0
  fid[0] = CD_PREFIX;
1287
0
  fid[1] = id;
1288
1289
  /* Try to select a related EF containing the PKCS#15 description of the data */
1290
0
  len = sizeof efbin;
1291
0
  r = read_file(p15card, fid, efbin, &len, 1);
1292
0
  LOG_TEST_RET(card->ctx, r, "Skipping optional EF.CDF");
1293
1294
0
  ptr = efbin;
1295
1296
0
  memset(&obj, 0, sizeof(obj));
1297
0
  r = sc_pkcs15_decode_cdf_entry(p15card, &obj, &ptr, &len);
1298
0
  if (obj.data == NULL && r >= SC_SUCCESS)
1299
0
    r = SC_ERROR_OBJECT_NOT_FOUND;
1300
0
  LOG_TEST_RET(card->ctx, r, "Skipping optional EF.CDF");
1301
1302
0
  cert_info = (sc_pkcs15_cert_info_t *)obj.data;
1303
1304
0
  r = sc_pkcs15emu_add_x509_cert(p15card, &obj, cert_info);
1305
1306
0
  LOG_TEST_RET(card->ctx, r, "Could not add data object to framework");
1307
1308
0
  return SC_SUCCESS;
1309
0
}
1310
1311
1312
1313
static int sc_pkcs15emu_sc_hsm_read_tokeninfo (sc_pkcs15_card_t * p15card)
1314
0
{
1315
0
  sc_card_t *card = p15card->card;
1316
0
  int r;
1317
0
  u8 efbin[512];
1318
0
  size_t len;
1319
1320
0
  LOG_FUNC_CALLED(card->ctx);
1321
1322
  /* Read token info */
1323
0
  len = sizeof efbin;
1324
0
  r = read_file(p15card, (u8 *) "\x2F\x03", efbin, &len, 1);
1325
0
  LOG_TEST_RET(card->ctx, r, "Skipping optional EF.TokenInfo");
1326
1327
0
  r = sc_pkcs15_parse_tokeninfo(card->ctx, p15card->tokeninfo, efbin, len);
1328
0
  LOG_TEST_RET(card->ctx, r, "Skipping optional EF.TokenInfo");
1329
1330
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1331
0
}
1332
1333
1334
1335
/*
1336
 * Initialize PKCS#15 emulation with user PIN, private keys, certificate and data objects
1337
 *
1338
 */
1339
static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card)
1340
105
{
1341
105
  sc_card_t *card = p15card->card;
1342
105
  sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
1343
105
  sc_file_t *file = NULL;
1344
105
  sc_path_t path;
1345
105
  u8 filelist[MAX_EXT_APDU_LENGTH];
1346
105
  int filelistlength;
1347
105
  int r, i;
1348
105
  sc_cvc_t devcert;
1349
105
  struct sc_app_info *appinfo;
1350
105
  struct sc_pkcs15_auth_info pin_info;
1351
105
  struct sc_pkcs15_object pin_obj;
1352
105
  struct sc_pin_cmd_data pindata;
1353
105
  u8 efbin[1024];
1354
105
  u8 *ptr;
1355
105
  size_t len;
1356
1357
105
  LOG_FUNC_CALLED(card->ctx);
1358
1359
105
  appinfo = calloc(1, sizeof(struct sc_app_info));
1360
1361
105
  if (appinfo == NULL) {
1362
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
1363
0
  }
1364
1365
105
  appinfo->aid = sc_hsm_aid;
1366
1367
105
  appinfo->ddo.aid = sc_hsm_aid;
1368
105
  p15card->app = appinfo;
1369
1370
105
  sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
1371
105
  r = sc_select_file(card, &path, &file);
1372
105
  LOG_TEST_RET(card->ctx, r, "Could not select SmartCard-HSM application");
1373
1374
58
  p15card->card->version.hw_major = 24; /* JCOP 2.4.1r3 */
1375
58
  p15card->card->version.hw_minor = 13;
1376
58
  if (file && file->prop_attr && file->prop_attr_len >= 2) {
1377
4
    p15card->card->version.fw_major = file->prop_attr[file->prop_attr_len - 2];
1378
4
    p15card->card->version.fw_minor = file->prop_attr[file->prop_attr_len - 1];
1379
4
  }
1380
1381
58
  sc_file_free(file);
1382
1383
  /* Read device certificate to determine serial number */
1384
58
  if (priv->EF_C_DevAut && priv->EF_C_DevAut_len) {
1385
0
    ptr = priv->EF_C_DevAut;
1386
0
    len = priv->EF_C_DevAut_len;
1387
58
  } else {
1388
58
    len = sizeof efbin;
1389
58
    r = read_file(p15card, (u8 *) "\x2F\x02", efbin, &len, 1);
1390
58
    LOG_TEST_RET(card->ctx, r, "Skipping optional EF.C_DevAut");
1391
1392
58
    if (len > 0) {
1393
      /* save EF_C_DevAut for further use */
1394
25
      ptr = realloc(priv->EF_C_DevAut, len);
1395
25
      if (ptr) {
1396
25
        memcpy(ptr, efbin, len);
1397
25
        priv->EF_C_DevAut = ptr;
1398
25
        priv->EF_C_DevAut_len = len;
1399
25
      }
1400
25
    }
1401
1402
58
    ptr = efbin;
1403
58
  }
1404
1405
58
  memset(&devcert, 0 ,sizeof(devcert));
1406
58
  r = sc_pkcs15emu_sc_hsm_decode_cvc(p15card, (const u8 **)&ptr, &len, &devcert);
1407
58
  LOG_TEST_RET(card->ctx, r, "Could not decode EF.C_DevAut");
1408
1409
0
  sc_pkcs15emu_sc_hsm_read_tokeninfo(p15card);
1410
1411
0
  if (p15card->tokeninfo->label == NULL) {
1412
0
    if (p15card->card->type == SC_CARD_TYPE_SC_HSM_GOID
1413
0
        || p15card->card->type == SC_CARD_TYPE_SC_HSM_SOC) {
1414
0
      p15card->tokeninfo->label = strdup("GoID");
1415
0
    } else {
1416
0
      p15card->tokeninfo->label = strdup("SmartCard-HSM");
1417
0
    }
1418
0
    if (p15card->tokeninfo->label == NULL)
1419
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
1420
0
  }
1421
1422
0
  if ((p15card->tokeninfo->manufacturer_id != NULL) && !strcmp("(unknown)", p15card->tokeninfo->manufacturer_id)) {
1423
0
    free(p15card->tokeninfo->manufacturer_id);
1424
0
    p15card->tokeninfo->manufacturer_id = NULL;
1425
0
  }
1426
1427
0
  if (p15card->tokeninfo->manufacturer_id == NULL) {
1428
0
    if (p15card->card->type == SC_CARD_TYPE_SC_HSM_GOID
1429
0
        || p15card->card->type == SC_CARD_TYPE_SC_HSM_SOC) {
1430
0
      p15card->tokeninfo->manufacturer_id = strdup("Bundesdruckerei GmbH");
1431
0
    } else {
1432
0
      p15card->tokeninfo->manufacturer_id = strdup("www.CardContact.de");
1433
0
    }
1434
0
    if (p15card->tokeninfo->manufacturer_id == NULL) {
1435
0
      sc_pkcs15_card_clear(p15card);
1436
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
1437
0
    }
1438
0
  }
1439
1440
0
  appinfo->label = strdup(p15card->tokeninfo->label);
1441
0
  if (appinfo->label == NULL) {
1442
0
    sc_pkcs15_card_clear(p15card);
1443
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
1444
0
  }
1445
1446
0
  len = strnlen(devcert.chr, sizeof devcert.chr);   /* Strip last 5 digit sequence number from CHR */
1447
0
  if (len < 8)
1448
0
    return SC_ERROR_INTERNAL;
1449
0
  len -= 5;
1450
1451
0
  free(p15card->tokeninfo->serial_number);
1452
0
  p15card->tokeninfo->serial_number = calloc(1, len + 1);
1453
0
  if (p15card->tokeninfo->serial_number == NULL) {
1454
0
    sc_pkcs15_card_clear(p15card);
1455
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
1456
0
  }
1457
1458
0
  memcpy(p15card->tokeninfo->serial_number, devcert.chr, len);
1459
0
  *(p15card->tokeninfo->serial_number + len) = 0;
1460
1461
0
  sc_hsm_set_serialnr(card, p15card->tokeninfo->serial_number);
1462
1463
0
  sc_pkcs15emu_sc_hsm_free_cvc(&devcert);
1464
1465
0
  memset(&pin_info, 0, sizeof(pin_info));
1466
0
  memset(&pin_obj, 0, sizeof(pin_obj));
1467
1468
0
  pin_info.auth_id.len = 1;
1469
0
  pin_info.auth_id.value[0] = 1;
1470
0
  pin_info.path.aid = sc_hsm_aid;
1471
0
  pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
1472
0
  pin_info.auth_method = SC_AC_CHV;
1473
0
  pin_info.attrs.pin.reference = 0x81;
1474
0
  pin_info.attrs.pin.flags = SC_PKCS15_PIN_FLAG_LOCAL|SC_PKCS15_PIN_FLAG_INITIALIZED|SC_PKCS15_PIN_FLAG_EXCHANGE_REF_DATA;
1475
0
  pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC;
1476
0
  pin_info.attrs.pin.min_length = 6;
1477
0
  pin_info.attrs.pin.stored_length = 0;
1478
0
  pin_info.attrs.pin.max_length = 15;
1479
0
  pin_info.attrs.pin.pad_char = '\0';
1480
0
  pin_info.tries_left = 3;
1481
0
  pin_info.max_tries = 3;
1482
1483
0
  pin_obj.auth_id.len = 1;
1484
0
  pin_obj.auth_id.value[0] = 2;
1485
0
  strlcpy(pin_obj.label, "UserPIN", sizeof(pin_obj.label));
1486
0
  pin_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE|SC_PKCS15_CO_FLAG_MODIFIABLE;
1487
1488
0
  pin_obj.data = &pin_info;
1489
1490
0
  r = sc_pkcs15_get_pin_info(p15card, &pin_obj);
1491
1492
0
  if (r != SC_ERROR_DATA_OBJECT_NOT_FOUND) {
1493
0
    if (r < 0) {
1494
0
      sc_pkcs15_card_clear(p15card);
1495
0
      LOG_FUNC_RETURN(card->ctx, r);
1496
0
    }
1497
1498
0
    r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info);
1499
0
    if (r < 0) {
1500
0
      sc_pkcs15_card_clear(p15card);
1501
0
      LOG_FUNC_RETURN(card->ctx, r);
1502
0
    }
1503
0
  }
1504
1505
0
  memset(&pin_info, 0, sizeof(pin_info));
1506
0
  memset(&pin_obj, 0, sizeof(pin_obj));
1507
1508
0
  pin_info.auth_id.len = 1;
1509
0
  pin_info.auth_id.value[0] = 2;
1510
0
  pin_info.path.aid = sc_hsm_aid;
1511
0
  pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
1512
0
  pin_info.auth_method = SC_AC_CHV;
1513
0
  pin_info.attrs.pin.reference = 0x88;
1514
0
  pin_info.attrs.pin.flags = SC_PKCS15_PIN_FLAG_LOCAL|SC_PKCS15_PIN_FLAG_UNBLOCK_DISABLED|SC_PKCS15_PIN_FLAG_SO_PIN;
1515
0
  pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_BCD;
1516
0
  pin_info.attrs.pin.min_length = 16;
1517
0
  pin_info.attrs.pin.stored_length = 0;
1518
0
  pin_info.attrs.pin.max_length = 16;
1519
0
  pin_info.attrs.pin.pad_char = '\0';
1520
0
  pin_info.tries_left = 15;
1521
0
  pin_info.max_tries = 15;
1522
1523
0
  strlcpy(pin_obj.label, "SOPIN", sizeof(pin_obj.label));
1524
0
  pin_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE;
1525
1526
0
  pin_obj.data = &pin_info;
1527
1528
0
  r = sc_pkcs15_get_pin_info(p15card, &pin_obj);
1529
1530
0
  if (r != SC_ERROR_DATA_OBJECT_NOT_FOUND) {
1531
0
    pin_info.attrs.pin.flags |= SC_PKCS15_PIN_FLAG_INITIALIZED;
1532
0
  } else {
1533
0
    r = SC_SUCCESS;
1534
0
  }
1535
1536
0
  if (r < 0) {
1537
0
    sc_pkcs15_card_clear(p15card);
1538
0
    LOG_FUNC_RETURN(card->ctx, r);
1539
0
  }
1540
1541
0
  r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info);
1542
0
  if (r < 0) {
1543
0
    sc_pkcs15_card_clear(p15card);
1544
0
    LOG_FUNC_RETURN(card->ctx, r);
1545
0
  }
1546
1547
1548
0
  if (card->type == SC_CARD_TYPE_SC_HSM_SOC
1549
0
      || card->type == SC_CARD_TYPE_SC_HSM_GOID) {
1550
    /* SC-HSM of this type always has a PIN-Pad */
1551
0
    r = SC_SUCCESS;
1552
0
  } else {
1553
0
    memset(&pindata, 0, sizeof(pindata));
1554
0
    pindata.cmd = SC_PIN_CMD_GET_INFO;
1555
0
    pindata.pin_type = SC_AC_CHV;
1556
0
    pindata.pin_reference = 0x85;
1557
1558
0
    r = sc_pin_cmd(card, &pindata, NULL);
1559
0
  }
1560
0
  if (r == SC_ERROR_DATA_OBJECT_NOT_FOUND) {
1561
0
    memset(&pindata, 0, sizeof(pindata));
1562
0
    pindata.cmd = SC_PIN_CMD_GET_INFO;
1563
0
    pindata.pin_type = SC_AC_CHV;
1564
0
    pindata.pin_reference = 0x86;
1565
1566
0
    r = sc_pin_cmd(card, &pindata, NULL);
1567
0
  }
1568
1569
0
  if ((r != SC_ERROR_DATA_OBJECT_NOT_FOUND) && (r != SC_ERROR_INCORRECT_PARAMETERS) && (r != SC_ERROR_REF_DATA_NOT_USABLE))
1570
0
    card->caps |= SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH;
1571
1572
1573
0
  filelistlength = sc_list_files(card, filelist, sizeof(filelist));
1574
0
  if (filelistlength < 0)
1575
0
    sc_pkcs15_card_clear(p15card);
1576
0
  LOG_TEST_RET(card->ctx, filelistlength, "Could not enumerate file and key identifier");
1577
1578
0
  for (i = 0; i < filelistlength; i += 2) {
1579
0
    switch(filelist[i]) {
1580
0
    case KEY_PREFIX:
1581
0
      r = sc_pkcs15emu_sc_hsm_add_prkd(p15card, filelist[i + 1]);
1582
0
      break;
1583
0
    case DCOD_PREFIX:
1584
0
      r = sc_pkcs15emu_sc_hsm_add_dcod(p15card, filelist[i + 1]);
1585
0
      break;
1586
0
    case CD_PREFIX:
1587
0
      r = sc_pkcs15emu_sc_hsm_add_cd(p15card, filelist[i + 1]);
1588
0
      break;
1589
0
    }
1590
0
    if (r != SC_SUCCESS) {
1591
0
      sc_log(card->ctx, "Error %d adding elements to framework", r);
1592
0
    }
1593
0
  }
1594
1595
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1596
0
}
1597
1598
1599
1600
int sc_pkcs15emu_sc_hsm_init_ex(sc_pkcs15_card_t *p15card,
1601
        struct sc_aid *aid)
1602
8.70k
{
1603
8.70k
  if (p15card->card->type != SC_CARD_TYPE_SC_HSM
1604
8.70k
      && p15card->card->type != SC_CARD_TYPE_SC_HSM_SOC
1605
8.70k
      && p15card->card->type != SC_CARD_TYPE_SC_HSM_GOID) {
1606
8.59k
    return SC_ERROR_WRONG_CARD;
1607
8.59k
  }
1608
105
  return sc_pkcs15emu_sc_hsm_init(p15card);
1609
8.70k
}