GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/asn1/bio_ndef.c Lines: 0 74 0.0 %
Date: 2017-11-07 Branches: 0 22 0.0 %

Line Branch Exec Source
1
/* $OpenBSD: bio_ndef.c,v 1.10 2017/01/29 17:49:22 beck 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
{
103
	NDEF_SUPPORT *ndef_aux = NULL;
104
	BIO *asn_bio = NULL;
105
	const ASN1_AUX *aux = it->funcs;
106
	ASN1_STREAM_ARG sarg;
107
108
	if (!aux || !aux->asn1_cb) {
109
		ASN1error(ASN1_R_STREAMING_NOT_SUPPORTED);
110
		return NULL;
111
	}
112
	ndef_aux = malloc(sizeof(NDEF_SUPPORT));
113
	asn_bio = BIO_new(BIO_f_asn1());
114
115
	/* ASN1 bio needs to be next to output BIO */
116
117
	out = BIO_push(asn_bio, out);
118
119
	if (!ndef_aux || !asn_bio || !out)
120
		goto err;
121
122
	BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
123
	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
	sarg.out = out;
130
	sarg.ndef_bio = NULL;
131
	sarg.boundary = NULL;
132
133
	if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
134
		goto err;
135
136
	ndef_aux->val = val;
137
	ndef_aux->it = it;
138
	ndef_aux->ndef_bio = sarg.ndef_bio;
139
	ndef_aux->boundary = sarg.boundary;
140
	ndef_aux->out = out;
141
142
	BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
143
144
	return sarg.ndef_bio;
145
146
err:
147
	BIO_free(asn_bio);
148
	free(ndef_aux);
149
	return NULL;
150
}
151
152
static int
153
ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
154
{
155
	NDEF_SUPPORT *ndef_aux;
156
	unsigned char *p;
157
	int derlen;
158
159
	if (!parg)
160
		return 0;
161
162
	ndef_aux = *(NDEF_SUPPORT **)parg;
163
164
	derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
165
	p = malloc(derlen);
166
	ndef_aux->derbuf = p;
167
	*pbuf = p;
168
	derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
169
170
	if (!*ndef_aux->boundary)
171
		return 0;
172
173
	*plen = *ndef_aux->boundary - *pbuf;
174
175
	return 1;
176
}
177
178
static int
179
ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
180
{
181
	NDEF_SUPPORT *ndef_aux;
182
183
	if (!parg)
184
		return 0;
185
186
	ndef_aux = *(NDEF_SUPPORT **)parg;
187
188
	free(ndef_aux->derbuf);
189
190
	ndef_aux->derbuf = NULL;
191
	*pbuf = NULL;
192
	*plen = 0;
193
	return 1;
194
}
195
196
static int
197
ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
198
{
199
	NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
200
	if (!ndef_prefix_free(b, pbuf, plen, parg))
201
		return 0;
202
	free(*pndef_aux);
203
	*pndef_aux = NULL;
204
	return 1;
205
}
206
207
static int
208
ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
209
{
210
	NDEF_SUPPORT *ndef_aux;
211
	unsigned char *p;
212
	int derlen;
213
	const ASN1_AUX *aux;
214
	ASN1_STREAM_ARG sarg;
215
216
	if (!parg)
217
		return 0;
218
219
	ndef_aux = *(NDEF_SUPPORT **)parg;
220
221
	aux = ndef_aux->it->funcs;
222
223
	/* Finalize structures */
224
	sarg.ndef_bio = ndef_aux->ndef_bio;
225
	sarg.out = ndef_aux->out;
226
	sarg.boundary = ndef_aux->boundary;
227
	if (aux->asn1_cb(ASN1_OP_STREAM_POST,
228
	    &ndef_aux->val, ndef_aux->it, &sarg) <= 0)
229
		return 0;
230
231
	derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
232
	p = malloc(derlen);
233
	ndef_aux->derbuf = p;
234
	*pbuf = p;
235
	derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
236
237
	if (!*ndef_aux->boundary)
238
		return 0;
239
	*pbuf = *ndef_aux->boundary;
240
	*plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
241
242
	return 1;
243
}