1 #define _POSIX_C_SOURCE 200809L
15 static const unsigned char *find_mem(const char *needle, size_t nlen,
16 const unsigned char *haystack, size_t hlen,
19 const unsigned char *res = 0;
21 /* can't be found if it's longer */
26 /* empty string at beginning */
32 for (i=0; i<hlen; i++) {
33 if (nlen + i > hlen) {
34 /* can't match any more */
37 /* check for first byte */
38 if (needle[0] == haystack[i]) {
39 if (memcmp(needle, haystack+i, nlen) == 0) {
53 /* fills in a struct pem_loc with offsets from in to the start
54 * of a pem, and one past the end, and the length of the pem data
56 static const unsigned char *next_pem(const unsigned char *in, size_t len, struct pem_loc *pem) {
58 const unsigned char *next;
60 next = find_mem("BEGIN CERT", 10, in, len, &i);
65 while (i<len && in[i] != '\n') {
74 /* look for terminating line */
75 next = find_mem("END CERT", 8, in+pem->start, len, &i);
82 /* find prev newline */
83 while (in[i] != '\n') {
86 pem->len = i - pem->start;
89 /* skip over the terminating line */
90 while (pem->end < len && in[pem->end] != '\n') {
94 fprintf(stderr, "found cert:\n");
95 write(2, in+pem->start, pem->len);
96 write(2, in+pem->start+pem->len, pem->end-pem->start-pem->len+1);
99 return in + pem->start;
103 unsigned char *uudecode(const unsigned char *in, size_t len, size_t *outlen) {
104 size_t need = len/4 * 3 + 1;
109 base64decode((const char *)in, len, out, &need);
117 unsigned char *tls_pem_decode(const unsigned char *data_in,
118 unsigned int input_length, int cert_index,
119 unsigned int *output_len) {
121 size_t alloc_len = input_length / 4 * 3;
122 unsigned char *output = malloc(alloc_len);
126 unsigned int start_at = 0;
127 unsigned int idx = 0;
129 for (i = 0; i < input_length; i++) {
130 if ((data_in[i] == '\n') || (data_in[i] == '\r'))
133 if (data_in[i] != '-') {
134 /* read entire line */
135 while ((i < input_length) && (data_in[i] != '\n'))
140 if (data_in[i] == '-') {
141 unsigned int end_idx = i;
142 /* read until end of line */
143 while ((i < input_length) && (data_in[i] != '\n'))
146 if (cert_index > 0) {
150 base64decode((const char
174 int load_cert_list(struct TLSContext *tls, const unsigned char *buf, size_t
175 bufsize, struct TLSCertificate **certs, int flags) {
176 struct pem_loc loc = { 0 };
177 struct TLSCertificate *cert = 0;
178 const unsigned char *pem = buf;
181 while (bufsize > 0) {
182 if (bufsize <= loc.end) {
187 //fprintf(stderr, "checking %zu bytes at %p\n", remaining, pem);
188 pem = next_pem(pem, bufsize, &loc);
192 cert = asn1_parse(tls, buf+loc.start, loc.len, 0);
196 #ifdef TLS_X509_V1_SUPPORT
197 if (cert->version != 2 && cert->version != 0)
199 if (cert->version != 2)
207 //fprintf(stderr, "found length %zu pem starting at %zu taking %zu bytes\n",
216 int add_to_list(struct TLSCertificate ***list, int *len,
217 struct TLSCertificate *cert) {
220 new = TLS_REALLOC(*list, (*len+1) * sizeof *list);
223 (*list)[(*len)++] = cert;
230 int tls_load_certificates(struct TLSContext *tls,
231 const unsigned char *pem, int size) {
233 return TLS_GENERIC_ERROR;
238 unsigned char *data =
239 tls_pem_decode(pem, size, idx++, &len);
240 if ((!data) || (!len))
242 struct TLSCertificate *cert =
243 asn1_parse(tls, data, len, 0);
245 if ((cert->version == 2)
246 #ifdef TLS_X509_V1_SUPPORT
247 || (cert->version == 0)
251 free(cert->der_bytes);
252 cert->der_bytes = data;
257 ("WARNING - parse error (private key encountered in certificate)\n");
262 add_to_list(&tls->certificates, &tls->certificates_count, cert);
266 ("WARNING - certificate version error (v%d)\n",
267 (int) cert->version);
268 tls_destroy_certificate(cert);
273 return tls->certificates_count;
276 int tls_load_private_key(struct TLSContext *tls,
277 const unsigned char *pem_buffer, int pem_size) {
279 return TLS_GENERIC_ERROR;
284 unsigned char *data =
285 tls_pem_decode(pem_buffer, pem_size, idx++, &len);
286 if ((!data) || (!len))
288 struct TLSCertificate *cert =
289 asn1_parse(tls, data, len, -1);
291 if (!cert->der_len) {
292 free(cert->der_bytes);
293 cert->der_bytes = data;
298 if ((cert) && (cert->priv) && (cert->priv_len)) {
299 #ifdef TLS_ECDSA_SUPPORTED
300 if (cert->ec_algorithm) {
302 ("Loaded ECC private key\n");
303 if (tls->ec_private_key)
304 tls_destroy_certificate
305 (tls->ec_private_key);
306 tls->ec_private_key = cert;
312 ("Loaded private key\n");
313 if (tls->private_key)
314 tls_destroy_certificate
316 tls->private_key = cert;
320 tls_destroy_certificate(cert);
327 int tls_load_root_certificates(struct TLSContext *tls,
328 const unsigned char *pem_buffer,
337 unsigned char *data =
338 tls_pem_decode(pem_buffer, pem_size, idx++, &len);
342 struct TLSCertificate *cert = asn1_parse(NULL, data, len, 0);
344 if (cert->version == 2) {
347 ("WARNING - parse error (private key encountered in certificate)\n");
352 add_to_list(&tls->root_certificates,
355 DEBUG_PRINT("Loaded certificate: %d\n",
359 ("WARNING - certificate version error (v%d)\n",
360 (int) cert->version);
361 tls_destroy_certificate(cert);
366 return tls->root_count;