Coverage Report

Created: 2025-10-13 07:02

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
0
{
47
0
  struct sc_context *ctx = p15card->card->ctx;
48
0
  struct sc_pkcs15_data *data_object;
49
0
  struct sc_pkcs15_der der;
50
0
  int r;
51
52
0
  LOG_FUNC_CALLED(ctx);
53
0
  if (!info || !data_object_out)
54
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
55
56
0
  if (!info->data.value)   {
57
0
    r = sc_pkcs15_read_file(p15card, &info->path, (unsigned char **) &info->data.value, (size_t *) &info->data.len, private_obj);
58
0
    LOG_TEST_RET(ctx, r, "Cannot get DATA object data");
59
0
  }
60
61
0
  r = sc_der_copy(&der, &info->data);
62
0
  LOG_TEST_RET(ctx, r, "Cannot allocate memory for der value");
63
64
0
  data_object = calloc(1, sizeof(struct sc_pkcs15_data));
65
0
  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
0
  data_object->data = der.value;
71
0
  data_object->data_len = der.len;
72
0
  *data_object_out = data_object;
73
74
0
  LOG_FUNC_RETURN(ctx,SC_SUCCESS);
75
0
}
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
0
{
96
0
        sc_context_t *ctx = p15card->card->ctx;
97
0
  struct sc_pkcs15_data_info info;
98
0
  struct sc_asn1_entry  asn1_com_data_attr[3],
99
0
        asn1_type_data_attr[2],
100
0
        asn1_data[2];
101
0
  struct sc_asn1_pkcs15_object data_obj = { obj, asn1_com_data_attr, NULL,
102
0
               asn1_type_data_attr };
103
0
  size_t label_len = sizeof(info.app_label) - 1;
104
0
  int r;
105
106
0
  memset(info.app_label, 0, sizeof(info.app_label));
107
108
0
  sc_copy_asn1_entry(c_asn1_com_data_attr, asn1_com_data_attr);
109
0
  sc_copy_asn1_entry(c_asn1_type_data_attr, asn1_type_data_attr);
110
0
  sc_copy_asn1_entry(c_asn1_data, asn1_data);
111
112
0
  sc_format_asn1_entry(asn1_com_data_attr + 0, &info.app_label, &label_len, 0);
113
0
  sc_format_asn1_entry(asn1_com_data_attr + 1, &info.app_oid, NULL, 0);
114
0
  sc_format_asn1_entry(asn1_type_data_attr + 0, &info.path, NULL, 0);
115
0
  sc_format_asn1_entry(asn1_data + 0, &data_obj, NULL, 0);
116
117
  /* Fill in defaults */
118
0
  memset(&info, 0, sizeof(info));
119
0
  sc_init_oid(&info.app_oid);
120
121
0
  r = sc_asn1_decode(ctx, asn1_data, *buf, *buflen, buf, buflen);
122
0
  if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
123
0
    return r;
124
0
  LOG_TEST_RET(ctx, r, "ASN.1 decoding failed");
125
126
0
  if (!p15card->app || !p15card->app->ddo.aid.len) {
127
0
    if (!p15card->file_app) {
128
0
      return SC_ERROR_INTERNAL;
129
0
    }
130
0
    r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path);
131
0
    if (r < 0)
132
0
      return r;
133
0
  }
134
0
  else   {
135
0
    info.path.aid = p15card->app->ddo.aid;
136
0
  }
137
138
0
  obj->type = SC_PKCS15_TYPE_DATA_OBJECT;
139
0
  obj->data = malloc(sizeof(info));
140
0
  if (obj->data == NULL)
141
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
142
0
  memcpy(obj->data, &info, sizeof(info));
143
144
0
  return SC_SUCCESS;
145
0
}
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
0
{
181
0
  if (data_object == NULL)
182
0
    return;
183
184
0
  free(data_object->data);
185
0
  free(data_object);
186
0
}
187
188
void sc_pkcs15_free_data_info(struct sc_pkcs15_data_info *info)
189
0
{
190
0
  if (info && info->data.value && info->data.len)
191
0
    free(info->data.value);
192
193
0
  free(info);
194
0
}