Coverage Report

Created: 2025-11-13 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/pkcs15-data.c
Line
Count
Source
1
/*
2
 * pkcs15-data.c: PKCS #15 data object functions
3
 *
4
 * Copyright (C) 2002  Danny De Cock <daniel.decock@postbox.be>
5
 *
6
 * This source file was inspired by pkcs15-cert.c.
7
 * 
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 */
22
23
#ifdef HAVE_CONFIG_H
24
#include "config.h"
25
#endif
26
27
#include <stdlib.h>
28
#include <string.h>
29
#include <stdio.h>
30
#include <sys/stat.h>
31
#ifdef HAVE_UNISTD_H
32
#include <unistd.h>
33
#endif
34
35
#include "internal.h"
36
#include "asn1.h"
37
#include "pkcs15.h"
38
#include "common/compat_strnlen.h"
39
40
41
int
42
sc_pkcs15_read_data_object(struct sc_pkcs15_card *p15card,
43
    const struct sc_pkcs15_data_info *info,
44
    int private_obj,
45
    struct sc_pkcs15_data **data_object_out)
46
197
{
47
197
  struct sc_context *ctx = p15card->card->ctx;
48
197
  struct sc_pkcs15_data *data_object;
49
197
  struct sc_pkcs15_der der;
50
197
  int r;
51
52
197
  LOG_FUNC_CALLED(ctx);
53
197
  if (!info || !data_object_out)
54
197
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
55
56
197
  if (!info->data.value)   {
57
197
    r = sc_pkcs15_read_file(p15card, &info->path, (unsigned char **) &info->data.value, (size_t *) &info->data.len, private_obj);
58
197
    LOG_TEST_RET(ctx, r, "Cannot get DATA object data");
59
197
  }
60
61
159
  r = sc_der_copy(&der, &info->data);
62
159
  LOG_TEST_RET(ctx, r, "Cannot allocate memory for der value");
63
64
159
  data_object = calloc(1, sizeof(struct sc_pkcs15_data));
65
159
  if (!data_object)   {
66
0
    free(der.value);
67
0
    LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot allocate memory for data object");
68
0
  }
69
70
159
  data_object->data = der.value;
71
159
  data_object->data_len = der.len;
72
159
  *data_object_out = data_object;
73
74
159
  LOG_FUNC_RETURN(ctx,SC_SUCCESS);
75
159
}
76
77
78
static const struct sc_asn1_entry c_asn1_data[] = {
79
  { "data", SC_ASN1_PKCS15_OBJECT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
80
  { NULL, 0, 0, 0, NULL, NULL }
81
};
82
static const struct sc_asn1_entry c_asn1_com_data_attr[] = {
83
  { "appName", SC_ASN1_UTF8STRING, SC_ASN1_TAG_UTF8STRING, SC_ASN1_OPTIONAL, NULL, NULL },
84
  { "appOID", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, SC_ASN1_OPTIONAL, NULL, NULL },
85
  { NULL, 0, 0, 0, NULL, NULL }
86
};
87
static const struct sc_asn1_entry c_asn1_type_data_attr[] = {
88
  { "path", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
89
  { NULL, 0, 0, 0, NULL, NULL }
90
};
91
92
int sc_pkcs15_decode_dodf_entry(struct sc_pkcs15_card *p15card,
93
             struct sc_pkcs15_object *obj,
94
             const u8 ** buf, size_t *buflen)
95
4.01k
{
96
4.01k
        sc_context_t *ctx = p15card->card->ctx;
97
4.01k
  struct sc_pkcs15_data_info info;
98
4.01k
  struct sc_asn1_entry  asn1_com_data_attr[3],
99
4.01k
        asn1_type_data_attr[2],
100
4.01k
        asn1_data[2];
101
4.01k
  struct sc_asn1_pkcs15_object data_obj = { obj, asn1_com_data_attr, NULL,
102
4.01k
               asn1_type_data_attr };
103
4.01k
  size_t label_len = sizeof(info.app_label) - 1;
104
4.01k
  int r;
105
106
4.01k
  memset(info.app_label, 0, sizeof(info.app_label));
107
108
4.01k
  sc_copy_asn1_entry(c_asn1_com_data_attr, asn1_com_data_attr);
109
4.01k
  sc_copy_asn1_entry(c_asn1_type_data_attr, asn1_type_data_attr);
110
4.01k
  sc_copy_asn1_entry(c_asn1_data, asn1_data);
111
112
4.01k
  sc_format_asn1_entry(asn1_com_data_attr + 0, &info.app_label, &label_len, 0);
113
4.01k
  sc_format_asn1_entry(asn1_com_data_attr + 1, &info.app_oid, NULL, 0);
114
4.01k
  sc_format_asn1_entry(asn1_type_data_attr + 0, &info.path, NULL, 0);
115
4.01k
  sc_format_asn1_entry(asn1_data + 0, &data_obj, NULL, 0);
116
117
  /* Fill in defaults */
118
4.01k
  memset(&info, 0, sizeof(info));
119
4.01k
  sc_init_oid(&info.app_oid);
120
121
4.01k
  r = sc_asn1_decode(ctx, asn1_data, *buf, *buflen, buf, buflen);
122
4.01k
  if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
123
992
    return r;
124
3.02k
  LOG_TEST_RET(ctx, r, "ASN.1 decoding failed");
125
126
9
  if (!p15card->app || !p15card->app->ddo.aid.len) {
127
8
    if (!p15card->file_app) {
128
6
      return SC_ERROR_INTERNAL;
129
6
    }
130
2
    r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path);
131
2
    if (r < 0)
132
1
      return r;
133
2
  }
134
1
  else   {
135
1
    info.path.aid = p15card->app->ddo.aid;
136
1
  }
137
138
2
  obj->type = SC_PKCS15_TYPE_DATA_OBJECT;
139
2
  obj->data = malloc(sizeof(info));
140
2
  if (obj->data == NULL)
141
2
    LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
142
2
  memcpy(obj->data, &info, sizeof(info));
143
144
2
  return SC_SUCCESS;
145
2
}
146
147
int sc_pkcs15_encode_dodf_entry(sc_context_t *ctx,
148
             const struct sc_pkcs15_object *obj,
149
             u8 **buf, size_t *bufsize)
150
0
{
151
0
  struct sc_asn1_entry  asn1_com_data_attr[4],
152
0
        asn1_type_data_attr[2],
153
0
        asn1_data[2];
154
0
  struct sc_pkcs15_data_info *info;
155
0
  struct sc_asn1_pkcs15_object data_obj = { (struct sc_pkcs15_object *) obj,
156
0
              asn1_com_data_attr, NULL,
157
0
              asn1_type_data_attr };
158
0
  size_t label_len;
159
160
0
  info = (struct sc_pkcs15_data_info *) obj->data;
161
0
  label_len = strnlen(info->app_label, sizeof info->app_label);
162
163
0
  sc_copy_asn1_entry(c_asn1_com_data_attr, asn1_com_data_attr);
164
0
  sc_copy_asn1_entry(c_asn1_type_data_attr, asn1_type_data_attr);
165
0
  sc_copy_asn1_entry(c_asn1_data, asn1_data);
166
167
0
  if (label_len)
168
0
    sc_format_asn1_entry(asn1_com_data_attr + 0, &info->app_label, &label_len, 1);
169
170
0
  if (sc_valid_oid(&info->app_oid))
171
0
    sc_format_asn1_entry(asn1_com_data_attr + 1, &info->app_oid, NULL, 1);
172
173
0
  sc_format_asn1_entry(asn1_type_data_attr + 0, &info->path, NULL, 1);
174
0
  sc_format_asn1_entry(asn1_data + 0, &data_obj, NULL, 1);
175
176
0
  return sc_asn1_encode(ctx, asn1_data, buf, bufsize);
177
0
}
178
179
void sc_pkcs15_free_data_object(struct sc_pkcs15_data *data_object)
180
159
{
181
159
  if (data_object == NULL)
182
0
    return;
183
184
159
  free(data_object->data);
185
159
  free(data_object);
186
159
}
187
188
void sc_pkcs15_free_data_info(struct sc_pkcs15_data_info *info)
189
19.8k
{
190
19.8k
  if (info && info->data.value && info->data.len)
191
0
    free(info->data.value);
192
193
19.8k
  free(info);
194
19.8k
}