/src/opensc/src/libopensc/pkcs15-dtrust.c
Line | Count | Source |
1 | | /* |
2 | | * PKCS15 emulation layer for D-Trust card. |
3 | | * |
4 | | * Copyright (C) 2024, Mario Haustein <mario.haustein@hrz.tu-chemnitz.de> |
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 <string.h> |
22 | | |
23 | | #ifdef HAVE_CONFIG_H |
24 | | #include "config.h" |
25 | | #endif |
26 | | |
27 | | #include "internal.h" |
28 | | #include "pkcs15.h" |
29 | | |
30 | | static int |
31 | | _dtrust_parse_df(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df) |
32 | 0 | { |
33 | 0 | struct sc_context *ctx = p15card->card->ctx; |
34 | 0 | struct sc_pkcs15_object *pkobjs[32]; |
35 | 0 | struct sc_pkcs15_prkey_info *prkey_info; |
36 | 0 | int rv, i, count; |
37 | |
|
38 | 0 | LOG_FUNC_CALLED(ctx); |
39 | |
|
40 | 0 | if (!df) |
41 | 0 | LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); |
42 | | |
43 | 0 | if (df->enumerated) |
44 | 0 | LOG_FUNC_RETURN(ctx, SC_SUCCESS); |
45 | | |
46 | 0 | rv = sc_pkcs15_parse_df(p15card, df); |
47 | 0 | LOG_TEST_RET(ctx, rv, "DF parse error"); |
48 | | |
49 | 0 | if (df->type != SC_PKCS15_PRKDF) |
50 | 0 | LOG_FUNC_RETURN(ctx, SC_SUCCESS); |
51 | | |
52 | 0 | rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, pkobjs, sizeof(pkobjs) / sizeof(pkobjs[0])); |
53 | 0 | LOG_TEST_RET(ctx, rv, "Cannot get PRKEY objects list"); |
54 | | |
55 | 0 | count = rv; |
56 | 0 | for (i = 0; i < count; i++) { |
57 | 0 | prkey_info = (struct sc_pkcs15_prkey_info *)pkobjs[i]->data; |
58 | |
|
59 | 0 | switch (p15card->card->type) { |
60 | | /* Cards with EC keys, don't encode the curve size in the |
61 | | * private key directory file. We need to set the field_length |
62 | | * element after parsing the private key directory file. */ |
63 | 0 | case SC_CARD_TYPE_DTRUST_V4_1_MULTI: |
64 | 0 | case SC_CARD_TYPE_DTRUST_V4_1_M100: |
65 | 0 | case SC_CARD_TYPE_DTRUST_V4_4_MULTI: |
66 | 0 | prkey_info->field_length = 256; |
67 | 0 | break; |
68 | | |
69 | 0 | case SC_CARD_TYPE_DTRUST_V5_1_MULTI: |
70 | 0 | case SC_CARD_TYPE_DTRUST_V5_1_M100: |
71 | 0 | case SC_CARD_TYPE_DTRUST_V5_4_MULTI: |
72 | 0 | prkey_info->field_length = 384; |
73 | 0 | break; |
74 | 0 | } |
75 | 0 | } |
76 | | |
77 | 0 | LOG_FUNC_RETURN(ctx, SC_SUCCESS); |
78 | 0 | } |
79 | | |
80 | | static int |
81 | | dtrust_pkcs15emu_detect_card(sc_pkcs15_card_t *p15card) |
82 | 8.31k | { |
83 | 8.31k | if (p15card->card->type < SC_CARD_TYPE_DTRUST_V4_1_STD) |
84 | 8.31k | return SC_ERROR_WRONG_CARD; |
85 | | |
86 | 0 | if (p15card->card->type > SC_CARD_TYPE_DTRUST_V5_4_MULTI) |
87 | 0 | return SC_ERROR_WRONG_CARD; |
88 | | |
89 | 0 | return SC_SUCCESS; |
90 | 0 | } |
91 | | |
92 | | static int |
93 | | sc_pkcs15emu_dtrust_init(struct sc_pkcs15_card *p15card, struct sc_aid *aid) |
94 | 0 | { |
95 | 0 | struct sc_context *ctx = p15card->card->ctx; |
96 | 0 | int rv; |
97 | |
|
98 | 0 | LOG_FUNC_CALLED(ctx); |
99 | |
|
100 | 0 | rv = sc_pkcs15_bind_internal(p15card, aid); |
101 | |
|
102 | 0 | p15card->ops.parse_df = _dtrust_parse_df; |
103 | |
|
104 | 0 | #if defined(ENABLE_SM) && defined(ENABLE_OPENPACE) |
105 | 0 | struct sc_pkcs15_search_key sk; |
106 | 0 | struct sc_pkcs15_object *objs[8]; |
107 | 0 | int i, len; |
108 | |
|
109 | 0 | memset(&sk, 0, sizeof(sk)); |
110 | 0 | sk.class_mask = SC_PKCS15_SEARCH_CLASS_AUTH; |
111 | 0 | len = sc_pkcs15_search_objects(p15card, &sk, (struct sc_pkcs15_object **)&objs, sizeof(objs) / sizeof(struct sc_pkcs15_object *)); |
112 | 0 | for (i = 0; i < len; i++) { |
113 | 0 | if (!strcmp(objs[i]->label, "CAN")) { |
114 | | /* Mark "Card CAN" as NOT a PIN object, so that it doesn't get it's own PKCS#11 slot */ |
115 | 0 | objs[i]->type &= ~SC_PKCS15_TYPE_AUTH_PIN; |
116 | 0 | } |
117 | 0 | } |
118 | 0 | #endif |
119 | |
|
120 | 0 | LOG_FUNC_RETURN(ctx, rv); |
121 | 0 | } |
122 | | |
123 | | int |
124 | | sc_pkcs15emu_dtrust_init_ex(struct sc_pkcs15_card *p15card, struct sc_aid *aid) |
125 | 8.31k | { |
126 | 8.31k | if (dtrust_pkcs15emu_detect_card(p15card)) |
127 | 8.31k | return SC_ERROR_WRONG_CARD; |
128 | | |
129 | 0 | return sc_pkcs15emu_dtrust_init(p15card, aid); |
130 | 8.31k | } |