2 * Copyright (c) 2005 - 2006 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 _hx509_map_file_os(const char *fn
, heim_octet_string
*os
)
43 ret
= rk_undumpdata(fn
, &data
, &length
);
52 _hx509_unmap_file_os(heim_octet_string
*os
)
58 _hx509_write_file(const char *fn
, const void *data
, size_t length
)
60 rk_dumpdata(fn
, data
, length
);
69 print_pem_stamp(FILE *f
, const char *type
, const char *str
)
71 fprintf(f
, "-----%s %s-----\n", type
, str
);
75 hx509_pem_write(hx509_context context
, const char *type
,
76 hx509_pem_header
*headers
, FILE *f
,
77 const void *data
, size_t size
)
83 #define ENCODE_LINE_LENGTH 54
85 print_pem_stamp(f
, "BEGIN", type
);
88 fprintf(f
, "%s: %s\n%s",
89 headers
->header
, headers
->value
,
90 headers
->next
? "" : "\n");
91 headers
= headers
->next
;
98 if (length
> ENCODE_LINE_LENGTH
)
99 length
= ENCODE_LINE_LENGTH
;
101 l
= base64_encode(p
, length
, &line
);
103 hx509_set_error_string(context
, 0, ENOMEM
,
104 "malloc - out of memory");
108 fprintf(f
, "%s\n", line
);
113 print_pem_stamp(f
, "END", type
);
123 hx509_pem_add_header(hx509_pem_header
**headers
,
124 const char *header
, const char *value
)
128 h
= calloc(1, sizeof(*h
));
131 h
->header
= strdup(header
);
132 if (h
->header
== NULL
) {
136 h
->value
= strdup(value
);
137 if (h
->value
== NULL
) {
150 hx509_pem_free_header(hx509_pem_header
*headers
)
155 headers
= headers
->next
;
167 hx509_pem_find_header(const hx509_pem_header
*h
, const char *header
)
170 if (strcmp(header
, h
->header
) == 0)
183 hx509_pem_read(hx509_context context
,
185 hx509_pem_read_func func
,
188 hx509_pem_header
*headers
= NULL
;
193 int ret
= HX509_PARSING_KEY_FAILED
;
195 enum { BEFORE
, SEARCHHEADER
, INHEADER
, INDATA
, DONE
} where
;
199 while (fgets(buf
, sizeof(buf
), f
) != NULL
) {
203 i
= strcspn(buf
, "\n");
204 if (buf
[i
] == '\n') {
209 if (buf
[i
] == '\r') {
217 if (strncmp("-----BEGIN ", buf
, 11) == 0) {
218 type
= strdup(buf
+ 11);
221 p
= strchr(type
, '-');
224 where
= SEARCHHEADER
;
228 p
= strchr(buf
, ':');
235 if (buf
[0] == '\0') {
239 p
= strchr(buf
, ':');
242 while (isspace((int)*p
))
244 ret
= hx509_pem_add_header(&headers
, buf
, p
);
252 if (strncmp("-----END ", buf
, 9) == 0) {
258 i
= base64_decode(buf
, p
);
264 data
= erealloc(data
, len
+ i
);
265 memcpy(((char *)data
) + len
, p
, i
);
274 ret
= (*func
)(context
, type
, headers
, data
, len
, ctx
);
282 hx509_pem_free_header(headers
);
289 if (where
!= BEFORE
) {
290 hx509_set_error_string(context
, 0, HX509_PARSING_KEY_FAILED
,
291 "File ends before end of PEM end tag");
292 ret
= HX509_PARSING_KEY_FAILED
;
299 hx509_pem_free_header(headers
);