1 /* $NetBSD: file.c,v 1.1.1.2 2014/04/24 12:45:41 pettai Exp $ */
4 * Copyright (c) 2005 - 2006 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 _hx509_map_file_os(const char *fn
, heim_octet_string
*os
)
45 ret
= rk_undumpdata(fn
, &data
, &length
);
54 _hx509_unmap_file_os(heim_octet_string
*os
)
60 _hx509_write_file(const char *fn
, const void *data
, size_t length
)
62 rk_dumpdata(fn
, data
, length
);
71 print_pem_stamp(FILE *f
, const char *type
, const char *str
)
73 fprintf(f
, "-----%s %s-----\n", type
, str
);
77 hx509_pem_write(hx509_context context
, const char *type
,
78 hx509_pem_header
*headers
, FILE *f
,
79 const void *data
, size_t size
)
85 #define ENCODE_LINE_LENGTH 54
87 print_pem_stamp(f
, "BEGIN", type
);
90 fprintf(f
, "%s: %s\n%s",
91 headers
->header
, headers
->value
,
92 headers
->next
? "" : "\n");
93 headers
= headers
->next
;
100 if (length
> ENCODE_LINE_LENGTH
)
101 length
= ENCODE_LINE_LENGTH
;
103 l
= base64_encode(p
, length
, &line
);
105 hx509_set_error_string(context
, 0, ENOMEM
,
106 "malloc - out of memory");
110 fprintf(f
, "%s\n", line
);
115 print_pem_stamp(f
, "END", type
);
125 hx509_pem_add_header(hx509_pem_header
**headers
,
126 const char *header
, const char *value
)
130 h
= calloc(1, sizeof(*h
));
133 h
->header
= strdup(header
);
134 if (h
->header
== NULL
) {
138 h
->value
= strdup(value
);
139 if (h
->value
== NULL
) {
152 hx509_pem_free_header(hx509_pem_header
*headers
)
157 headers
= headers
->next
;
169 hx509_pem_find_header(const hx509_pem_header
*h
, const char *header
)
172 if (strcmp(header
, h
->header
) == 0)
185 hx509_pem_read(hx509_context context
,
187 hx509_pem_read_func func
,
190 hx509_pem_header
*headers
= NULL
;
195 int ret
= HX509_PARSING_KEY_FAILED
;
197 enum { BEFORE
, SEARCHHEADER
, INHEADER
, INDATA
, DONE
} where
;
201 while (fgets(buf
, sizeof(buf
), f
) != NULL
) {
205 i
= strcspn(buf
, "\n");
206 if (buf
[i
] == '\n') {
211 if (buf
[i
] == '\r') {
219 if (strncmp("-----BEGIN ", buf
, 11) == 0) {
220 type
= strdup(buf
+ 11);
223 p
= strchr(type
, '-');
226 where
= SEARCHHEADER
;
230 p
= strchr(buf
, ':');
237 if (buf
[0] == '\0') {
241 p
= strchr(buf
, ':');
244 while (isspace((int)*p
))
246 ret
= hx509_pem_add_header(&headers
, buf
, p
);
254 if (strncmp("-----END ", buf
, 9) == 0) {
260 i
= base64_decode(buf
, p
);
266 data
= erealloc(data
, len
+ i
);
267 memcpy(((char *)data
) + len
, p
, i
);
276 ret
= (*func
)(context
, type
, headers
, data
, len
, ctx
);
284 hx509_pem_free_header(headers
);
291 if (where
!= BEFORE
) {
292 hx509_set_error_string(context
, 0, HX509_PARSING_KEY_FAILED
,
293 "File ends before end of PEM end tag");
294 ret
= HX509_PARSING_KEY_FAILED
;
301 hx509_pem_free_header(headers
);