Coverage Report

Created: 2022-08-24 06:30

/src/libressl/crypto/asn1/bio_ndef.c
Line
Count
Source (jump to first uncovered line)
1
/* $OpenBSD: bio_ndef.c,v 1.11 2021/12/25 13:17:48 jsing Exp $ */
2
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3
 * project.
4
 */
5
/* ====================================================================
6
 * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 *
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 *
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in
17
 *    the documentation and/or other materials provided with the
18
 *    distribution.
19
 *
20
 * 3. All advertising materials mentioning features or use of this
21
 *    software must display the following acknowledgment:
22
 *    "This product includes software developed by the OpenSSL Project
23
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24
 *
25
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26
 *    endorse or promote products derived from this software without
27
 *    prior written permission. For written permission, please contact
28
 *    licensing@OpenSSL.org.
29
 *
30
 * 5. Products derived from this software may not be called "OpenSSL"
31
 *    nor may "OpenSSL" appear in their names without prior written
32
 *    permission of the OpenSSL Project.
33
 *
34
 * 6. Redistributions of any form whatsoever must retain the following
35
 *    acknowledgment:
36
 *    "This product includes software developed by the OpenSSL Project
37
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38
 *
39
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50
 * OF THE POSSIBILITY OF SUCH DAMAGE.
51
 * ====================================================================
52
 *
53
 */
54
55
#include <openssl/asn1.h>
56
#include <openssl/asn1t.h>
57
#include <openssl/bio.h>
58
#include <openssl/err.h>
59
60
#include <stdio.h>
61
62
/* Experimental NDEF ASN1 BIO support routines */
63
64
/* The usage is quite simple, initialize an ASN1 structure,
65
 * get a BIO from it then any data written through the BIO
66
 * will end up translated to approptiate format on the fly.
67
 * The data is streamed out and does *not* need to be
68
 * all held in memory at once.
69
 *
70
 * When the BIO is flushed the output is finalized and any
71
 * signatures etc written out.
72
 *
73
 * The BIO is a 'proper' BIO and can handle non blocking I/O
74
 * correctly.
75
 *
76
 * The usage is simple. The implementation is *not*...
77
 */
78
79
/* BIO support data stored in the ASN1 BIO ex_arg */
80
81
typedef struct ndef_aux_st {
82
  /* ASN1 structure this BIO refers to */
83
  ASN1_VALUE *val;
84
  const ASN1_ITEM *it;
85
  /* Top of the BIO chain */
86
  BIO *ndef_bio;
87
  /* Output BIO */
88
  BIO *out;
89
  /* Boundary where content is inserted */
90
  unsigned char **boundary;
91
  /* DER buffer start */
92
  unsigned char *derbuf;
93
} NDEF_SUPPORT;
94
95
static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
96
static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
97
static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
98
static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
99
100
BIO *
101
BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
102
0
{
103
0
  NDEF_SUPPORT *ndef_aux = NULL;
104
0
  BIO *asn_bio = NULL;
105
0
  const ASN1_AUX *aux = it->funcs;
106
0
  ASN1_STREAM_ARG sarg;
107
108
0
  if (!aux || !aux->asn1_cb) {
109
0
    ASN1error(ASN1_R_STREAMING_NOT_SUPPORTED);
110
0
    return NULL;
111
0
  }
112
0
  ndef_aux = malloc(sizeof(NDEF_SUPPORT));
113
0
  asn_bio = BIO_new(BIO_f_asn1());
114
115
  /* ASN1 bio needs to be next to output BIO */
116
117
0
  out = BIO_push(asn_bio, out);
118
119
0
  if (!ndef_aux || !asn_bio || !out)
120
0
    goto err;
121
122
0
  BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
123
0
  BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
124
125
  /* Now let callback prepend any digest, cipher etc BIOs
126
   * ASN1 structure needs.
127
   */
128
129
0
  sarg.out = out;
130
0
  sarg.ndef_bio = NULL;
131
0
  sarg.boundary = NULL;
132
133
0
  if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
134
0
    goto err;
135
136
0
  ndef_aux->val = val;
137
0
  ndef_aux->it = it;
138
0
  ndef_aux->ndef_bio = sarg.ndef_bio;
139
0
  ndef_aux->boundary = sarg.boundary;
140
0
  ndef_aux->out = out;
141
142
0
  BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
143
144
0
  return sarg.ndef_bio;
145
146
0
 err:
147
0
  BIO_free(asn_bio);
148
0
  free(ndef_aux);
149
0
  return NULL;
150
0
}
151
152
static int
153
ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
154
0
{
155
0
  NDEF_SUPPORT *ndef_aux;
156
0
  unsigned char *p;
157
0
  int derlen;
158
159
0
  if (!parg)
160
0
    return 0;
161
162
0
  ndef_aux = *(NDEF_SUPPORT **)parg;
163
164
0
  derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
165
0
  p = malloc(derlen);
166
0
  ndef_aux->derbuf = p;
167
0
  *pbuf = p;
168
0
  derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
169
170
0
  if (!*ndef_aux->boundary)
171
0
    return 0;
172
173
0
  *plen = *ndef_aux->boundary - *pbuf;
174
175
0
  return 1;
176
0
}
177
178
static int
179
ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
180
0
{
181
0
  NDEF_SUPPORT *ndef_aux;
182
183
0
  if (!parg)
184
0
    return 0;
185
186
0
  ndef_aux = *(NDEF_SUPPORT **)parg;
187
188
0
  free(ndef_aux->derbuf);
189
190
0
  ndef_aux->derbuf = NULL;
191
0
  *pbuf = NULL;
192
0
  *plen = 0;
193
0
  return 1;
194
0
}
195
196
static int
197
ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
198
0
{
199
0
  NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
200
0
  if (!ndef_prefix_free(b, pbuf, plen, parg))
201
0
    return 0;
202
0
  free(*pndef_aux);
203
0
  *pndef_aux = NULL;
204
0
  return 1;
205
0
}
206
207
static int
208
ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
209
0
{
210
0
  NDEF_SUPPORT *ndef_aux;
211
0
  unsigned char *p;
212
0
  int derlen;
213
0
  const ASN1_AUX *aux;
214
0
  ASN1_STREAM_ARG sarg;
215
216
0
  if (!parg)
217
0
    return 0;
218
219
0
  ndef_aux = *(NDEF_SUPPORT **)parg;
220
221
0
  aux = ndef_aux->it->funcs;
222
223
  /* Finalize structures */
224
0
  sarg.ndef_bio = ndef_aux->ndef_bio;
225
0
  sarg.out = ndef_aux->out;
226
0
  sarg.boundary = ndef_aux->boundary;
227
0
  if (aux->asn1_cb(ASN1_OP_STREAM_POST,
228
0
      &ndef_aux->val, ndef_aux->it, &sarg) <= 0)
229
0
    return 0;
230
231
0
  derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
232
0
  p = malloc(derlen);
233
0
  ndef_aux->derbuf = p;
234
0
  *pbuf = p;
235
0
  derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
236
237
0
  if (!*ndef_aux->boundary)
238
0
    return 0;
239
0
  *pbuf = *ndef_aux->boundary;
240
0
  *plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
241
242
0
  return 1;
243
0
}