1 /* $OpenBSD$ */
2 /*
3  * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include "tls_compat.h"
19 
20 #ifdef USUAL_LIBSSL_FOR_TLS
21 
22 #include <openssl/bn.h>
23 #include <openssl/err.h>
24 #include <openssl/x509v3.h>
25 
26 #include "tls_internal.h"
27 
28 #define TLS_CERT_INTERNAL_FUNCS
29 #include "tls_cert.h"
30 
31 /*
32  * Load cert data from X509 cert.
33  */
34 
35 /* Upper bounds */
36 #define UB_COMMON_NAME				255
37 #define UB_COUNTRY_NAME				255
38 #define UB_STATE_NAME				255
39 #define UB_LOCALITY_NAME			255
40 #define UB_STREET_ADDRESS			255
41 #define UB_ORGANIZATION_NAME			255
42 #define UB_ORGANIZATIONAL_UNIT_NAME		255
43 
44 #define UB_GNAME_DNS				255
45 #define UB_GNAME_EMAIL				255
46 #define UB_GNAME_URI				255
47 
48 /* Convert ASN1_INTEGER to decimal string string */
49 static int
tls_parse_bigint(struct tls * ctx,const ASN1_INTEGER * asn1int,const char ** dst_p)50 tls_parse_bigint(struct tls *ctx, const ASN1_INTEGER *asn1int, const char **dst_p)
51 {
52 	long small;
53 	BIGNUM *big;
54 	char *tmp, buf[64];
55 
56 	*dst_p = NULL;
57 	small = ASN1_INTEGER_get(asn1int);
58 	if (small < 0) {
59 		big = ASN1_INTEGER_to_BN(asn1int, NULL);
60 		if (big) {
61 			tmp = BN_bn2dec(big);
62 			if (tmp)
63 				*dst_p = strdup(tmp);
64 			OPENSSL_free(tmp);
65 		}
66 		BN_free(big);
67 	} else {
68 		snprintf(buf, sizeof buf, "%lu", small);
69 		*dst_p = strdup(buf);
70 	}
71 	if (*dst_p)
72 		return 0;
73 
74 	tls_set_errorx(ctx, "cannot parse serial");
75 	return -1;
76 }
77 
78 /*
79  * Decode all string types used in RFC5280.
80  *
81  * OpenSSL used (before Jun 1 2014 commit) to pick between PrintableString,
82  * T61String, BMPString and UTF8String, depending on data.  This code
83  * tries to match that.
84  *
85  * Disallow any ancient ASN.1 escape sequences.
86  */
87 
88 static int
check_invalid_bytes(struct tls * ctx,const unsigned char * data,unsigned int len,int ascii_only,const char * desc)89 check_invalid_bytes(struct tls *ctx, const unsigned char *data, unsigned int len,
90 		    int ascii_only, const char *desc)
91 {
92 	unsigned int i, c;
93 
94 	/* data is utf8 string, check for crap */
95 	for (i = 0; i < len; i++) {
96 		c = data[i];
97 
98 		if (ascii_only && (c & 0x80) != 0) {
99 			tls_set_errorx(ctx, "invalid %s: contains non-ascii in ascii string", desc);
100 			goto failed;
101 		} else if (c < 0x20) {
102 			/* ascii control chars, including NUL */
103 			if (c != '\t' && c != '\n' && c != '\r') {
104 				tls_set_errorx(ctx, "invalid %s: contains C0 control char", desc);
105 				goto failed;
106 			}
107 		} else if (c == 0xC2 && (i + 1) < len) {
108 			/* C1 control chars in UTF-8: \xc2\x80 - \xc2\x9f */
109 			c = data[i + 1];
110 			if (c >= 0x80 && c <= 0x9F) {
111 				tls_set_errorx(ctx, "invalid %s: contains C1 control char", desc);
112 				goto failed;
113 			}
114 		} else if (c == 0x7F) {
115 			tls_set_errorx(ctx, "invalid %s: contains DEL char", desc);
116 			goto failed;
117 		}
118 	}
119 	return 0;
120  failed:
121 	return -1;
122 }
123 
124 static int
tls_parse_asn1string(struct tls * ctx,ASN1_STRING * a1str,const char ** dst_p,int minchars,int maxchars,const char * desc)125 tls_parse_asn1string(struct tls *ctx, ASN1_STRING *a1str, const char **dst_p, int minchars, int maxchars, const char *desc)
126 {
127 	int format, len, ret = -1;
128 	const unsigned char *data;
129 	ASN1_STRING *a1utf = NULL;
130 	int ascii_only = 0;
131 	char *cstr = NULL;
132 	int mbres, mbconvert = -1;
133 
134 	*dst_p = NULL;
135 
136 	format = ASN1_STRING_type(a1str);
137 	data = ASN1_STRING_get0_data(a1str);
138 	len = ASN1_STRING_length(a1str);
139 	if (len < minchars) {
140 		tls_set_errorx(ctx, "invalid %s: string too short", desc);
141 		goto failed;
142 	}
143 
144 	switch (format) {
145 	case V_ASN1_NUMERICSTRING:
146 	case V_ASN1_VISIBLESTRING:
147 	case V_ASN1_PRINTABLESTRING:
148 	case V_ASN1_IA5STRING:
149 		/* Ascii */
150 		if (len > maxchars) {
151 			tls_set_errorx(ctx, "invalid %s: string too long", desc);
152 			goto failed;
153 		}
154 		ascii_only = 1;
155 		break;
156 	case V_ASN1_T61STRING:
157 		/* Latin1 */
158 		mbconvert = MBSTRING_ASC;
159 		break;
160 	case V_ASN1_BMPSTRING:
161 		/* UCS-2 big-endian */
162 		mbconvert = MBSTRING_BMP;
163 		break;
164 	case V_ASN1_UNIVERSALSTRING:
165 		/* UCS-4 big-endian */
166 		mbconvert = MBSTRING_UNIV;
167 		break;
168 	case V_ASN1_UTF8STRING:
169 		/*
170 		 * UTF-8 - could be used directly if OpenSSL has already
171 		 * validated the data.  ATM be safe and validate here.
172 		 */
173 		mbconvert = MBSTRING_UTF8;
174 		break;
175 	default:
176 		tls_set_errorx(ctx, "invalid %s: unexpected string type", desc);
177 		goto failed;
178 	}
179 
180 	/* Convert to UTF-8 */
181 	if (mbconvert != -1) {
182 		mbres = ASN1_mbstring_ncopy(&a1utf, data, len, mbconvert, B_ASN1_UTF8STRING, minchars, maxchars);
183 		if (mbres < 0) {
184 			tls_set_error_libssl(ctx, "invalid %s", desc);
185 			goto failed;
186 		}
187 		if (mbres != V_ASN1_UTF8STRING) {
188 			tls_set_errorx(ctx, "multibyte conversion failed: expected UTF8 result");
189 			goto failed;
190 		}
191 		data = ASN1_STRING_get0_data(a1utf);
192 		len = ASN1_STRING_length(a1utf);
193 	}
194 
195 	/* must not allow \0 */
196 	if (memchr(data, 0, len) != NULL) {
197 		tls_set_errorx(ctx, "invalid %s: contains NUL", desc);
198 		goto failed;
199 	}
200 
201 	/* no escape codes please */
202 	if (check_invalid_bytes(ctx, data, len, ascii_only, desc) < 0)
203 		goto failed;
204 
205 	/* copy to new string */
206 	cstr = malloc(len + 1);
207 	if (!cstr) {
208 		tls_set_error(ctx, "malloc");
209 		goto failed;
210 	}
211 	memcpy(cstr, data, len);
212 	cstr[len] = 0;
213 	*dst_p = cstr;
214 	ret = len;
215  failed:
216 	ASN1_STRING_free(a1utf);
217 	return ret;
218 }
219 
220 static int
tls_cert_get_dname_string(struct tls * ctx,X509_NAME * name,int nid,const char ** str_p,int minchars,int maxchars,const char * desc)221 tls_cert_get_dname_string(struct tls *ctx, X509_NAME *name, int nid, const char **str_p, int minchars, int maxchars, const char *desc)
222 {
223 	int loc, len;
224 	X509_NAME_ENTRY *ne;
225 	ASN1_STRING *a1str;
226 
227 	*str_p = NULL;
228 
229 	loc = X509_NAME_get_index_by_NID(name, nid, -1);
230 	if (loc < 0)
231 		return 0;
232 	ne = X509_NAME_get_entry(name, loc);
233 	if (!ne)
234 		return 0;
235 	a1str = X509_NAME_ENTRY_get_data(ne);
236 	if (!a1str)
237 		return 0;
238 	len = tls_parse_asn1string(ctx, a1str, str_p, minchars, maxchars, desc);
239 	if (len < 0)
240 		return -1;
241 	return 0;
242 }
243 
244 static int
tls_load_alt_ia5string(struct tls * ctx,ASN1_IA5STRING * ia5str,struct tls_cert * cert,int slot_type,int minchars,int maxchars,const char * desc)245 tls_load_alt_ia5string(struct tls *ctx, ASN1_IA5STRING *ia5str, struct tls_cert *cert, int slot_type, int minchars, int maxchars, const char *desc)
246 {
247 	struct tls_cert_general_name *slot;
248 	const char *data;
249 	int len;
250 
251 	slot = &cert->subject_alt_names[cert->subject_alt_name_count];
252 
253 	len = tls_parse_asn1string(ctx, ia5str, &data, minchars, maxchars, desc);
254 	if (len < 0)
255 		return 0;
256 
257 	/*
258 	 * Per RFC 5280 section 4.2.1.6:
259 	 * " " is a legal domain name, but that
260 	 * dNSName must be rejected.
261 	 */
262 	if (len == 1 && data[0] == ' ') {
263 		tls_set_errorx(ctx, "invalid %s: single space", desc);
264 		return -1;
265 	}
266 
267 	slot->name_value = data;
268 	slot->name_type = slot_type;
269 
270 	cert->subject_alt_name_count++;
271 	return 0;
272 }
273 
274 static int
tls_load_alt_ipaddr(struct tls * ctx,ASN1_OCTET_STRING * bin,struct tls_cert * cert)275 tls_load_alt_ipaddr(struct tls *ctx, ASN1_OCTET_STRING *bin, struct tls_cert *cert)
276 {
277 	struct tls_cert_general_name *slot;
278 	const void *data;
279 	int len;
280 
281 	slot = &cert->subject_alt_names[cert->subject_alt_name_count];
282 	len = ASN1_STRING_length(bin);
283 	data = ASN1_STRING_get0_data(bin);
284 	if (len < 0) {
285 		tls_set_errorx(ctx, "negative length for ipaddress");
286 		return -1;
287 	}
288 
289 	/*
290 	 * Per RFC 5280 section 4.2.1.6:
291 	 * IPv4 must use 4 octets and IPv6 must use 16 octets.
292 	 */
293 	if (len == 4) {
294 		slot->name_type = TLS_CERT_GNAME_IPv4;
295 	} else if (len == 16) {
296 		slot->name_type = TLS_CERT_GNAME_IPv6;
297 	} else {
298 		tls_set_errorx(ctx, "invalid length for ipaddress");
299 		return -1;
300 	}
301 
302 	slot->name_value = malloc(len);
303 	if (slot->name_value == NULL) {
304 		tls_set_error(ctx, "malloc");
305 		return -1;
306 	}
307 
308 	memcpy((void *)slot->name_value, data, len);
309 	cert->subject_alt_name_count++;
310 	return 0;
311 }
312 
313 /* See RFC 5280 section 4.2.1.6 for SubjectAltName details. */
314 static int
tls_cert_get_altnames(struct tls * ctx,struct tls_cert * cert,X509 * x509_cert)315 tls_cert_get_altnames(struct tls *ctx, struct tls_cert *cert, X509 *x509_cert)
316 {
317 	STACK_OF(GENERAL_NAME) *altname_stack = NULL;
318 	GENERAL_NAME *altname;
319 	int count, i;
320 	int rv = -1;
321 
322 	altname_stack = X509_get_ext_d2i(x509_cert, NID_subject_alt_name, NULL, NULL);
323 	if (altname_stack == NULL)
324 		return 0;
325 
326 	count = sk_GENERAL_NAME_num(altname_stack);
327 	if (count == 0) {
328 		rv = 0;
329 		goto out;
330 	}
331 
332 	cert->subject_alt_names = calloc(sizeof (struct tls_cert_general_name), count);
333 	if (cert->subject_alt_names == NULL) {
334 		tls_set_error(ctx, "calloc");
335 		goto out;
336 	}
337 
338 	for (i = 0; i < count; i++) {
339 		altname = sk_GENERAL_NAME_value(altname_stack, i);
340 
341 		if (altname->type == GEN_DNS) {
342 			rv = tls_load_alt_ia5string(ctx, altname->d.dNSName, cert, TLS_CERT_GNAME_DNS, 1, UB_GNAME_DNS, "dns");
343 		} else if (altname->type == GEN_EMAIL) {
344 			rv = tls_load_alt_ia5string(ctx, altname->d.rfc822Name, cert, TLS_CERT_GNAME_EMAIL, 1, UB_GNAME_EMAIL, "email");
345 		} else if (altname->type == GEN_URI) {
346 			rv = tls_load_alt_ia5string(ctx, altname->d.uniformResourceIdentifier, cert, TLS_CERT_GNAME_URI, 1, UB_GNAME_URI, "uri");
347 		} else if (altname->type == GEN_IPADD) {
348 			rv = tls_load_alt_ipaddr(ctx, altname->d.iPAddress, cert);
349 		} else {
350 			/* ignore unknown types */
351 			rv = 0;
352 		}
353 		if (rv < 0)
354 			goto out;
355 	}
356 	rv = 0;
357  out:
358 	sk_GENERAL_NAME_pop_free(altname_stack, GENERAL_NAME_free);
359 	return rv;
360 }
361 
362 static int
tls_get_dname(struct tls * ctx,X509_NAME * name,struct tls_cert_dname * dname)363 tls_get_dname(struct tls *ctx, X509_NAME *name, struct tls_cert_dname *dname)
364 {
365 	int ret;
366 	ret = tls_cert_get_dname_string(ctx, name, NID_commonName, &dname->common_name,
367 					0, UB_COMMON_NAME, "commonName");
368 	if (ret == 0)
369 		ret = tls_cert_get_dname_string(ctx, name, NID_countryName, &dname->country_name,
370 						0, UB_COUNTRY_NAME, "countryName");
371 	if (ret == 0)
372 		ret = tls_cert_get_dname_string(ctx, name, NID_stateOrProvinceName, &dname->state_or_province_name,
373 						0, UB_STATE_NAME, "stateName");
374 	if (ret == 0)
375 		ret = tls_cert_get_dname_string(ctx, name, NID_localityName, &dname->locality_name,
376 						0, UB_LOCALITY_NAME, "localityName");
377 	if (ret == 0)
378 		ret = tls_cert_get_dname_string(ctx, name, NID_streetAddress, &dname->street_address,
379 						0, UB_STREET_ADDRESS, "streetAddress");
380 	if (ret == 0)
381 		ret = tls_cert_get_dname_string(ctx, name, NID_organizationName, &dname->organization_name,
382 						0, UB_ORGANIZATION_NAME, "organizationName");
383 	if (ret == 0)
384 		ret = tls_cert_get_dname_string(ctx, name, NID_organizationalUnitName, &dname->organizational_unit_name,
385 						0, UB_ORGANIZATIONAL_UNIT_NAME, "organizationalUnitName");
386 	return ret;
387 }
388 
389 static int
tls_get_basic_constraints(struct tls * ctx,struct tls_cert * cert,X509 * x509)390 tls_get_basic_constraints(struct tls *ctx, struct tls_cert *cert, X509 *x509)
391 {
392 	BASIC_CONSTRAINTS *bc;
393 	int crit;
394 	int ret = -1;
395 
396 	bc = X509_get_ext_d2i(x509, NID_basic_constraints, &crit, NULL);
397 	if (!bc)
398 		return 0;
399 
400 	cert->ext_set |= TLS_EXT_BASIC;
401 	if (crit)
402 		cert->ext_crit |= TLS_EXT_BASIC;
403 
404 	cert->basic_constraints_ca = bc->ca ? 1 : 0;
405 	if (bc->pathlen) {
406 		cert->basic_constraints_pathlen = ASN1_INTEGER_get(bc->pathlen);
407 		if (cert->basic_constraints_pathlen < 0) {
408 			tls_set_error(ctx, "BasicConstraints has invalid pathlen");
409 			goto failed;
410 		}
411 	} else {
412 		cert->basic_constraints_pathlen = -1;
413 	}
414 	ret = 0;
415 failed:
416 	BASIC_CONSTRAINTS_free(bc);
417 	return ret;
418 }
419 
map_bits(const uint32_t map[][2],uint32_t input)420 static uint32_t map_bits(const uint32_t map[][2], uint32_t input)
421 {
422 	uint32_t i, out = 0;
423 	for (i = 0; map[i][0]; i++) {
424 		if (map[i][0] & input)
425 			out |= map[i][1];
426 	}
427 	return out;
428 }
429 
430 static int
tls_get_key_usage(struct tls * ctx,struct tls_cert * cert,X509 * x509)431 tls_get_key_usage(struct tls *ctx, struct tls_cert *cert, X509 *x509)
432 {
433 	static const uint32_t ku_map[][2] = {
434 		{KU_DIGITAL_SIGNATURE, KU_DIGITAL_SIGNATURE},
435 		{KU_NON_REPUDIATION, KU_NON_REPUDIATION},
436 		{KU_KEY_ENCIPHERMENT, KU_KEY_ENCIPHERMENT},
437 		{KU_DATA_ENCIPHERMENT, KU_DATA_ENCIPHERMENT},
438 		{KU_KEY_AGREEMENT, KU_KEY_AGREEMENT},
439 		{KU_KEY_CERT_SIGN, KU_KEY_CERT_SIGN},
440 		{KU_CRL_SIGN, KU_CRL_SIGN},
441 		{KU_ENCIPHER_ONLY, KU_ENCIPHER_ONLY},
442 		{KU_DECIPHER_ONLY, KU_DECIPHER_ONLY},
443 		{0, 0},
444 	};
445 	ASN1_BIT_STRING *ku;
446 	int crit;
447 
448 	ku = X509_get_ext_d2i(x509, NID_key_usage, &crit, NULL);
449 	if (!ku)
450 		return 0;
451 
452 	cert->ext_set |= TLS_EXT_KEY_USAGE;
453 	if (crit)
454 		cert->ext_crit |= TLS_EXT_KEY_USAGE;
455 	ASN1_BIT_STRING_free(ku);
456 
457 	cert->key_usage_flags = map_bits(ku_map, X509_get_key_usage(x509));
458 	return 0;
459 }
460 
461 static int
tls_get_ext_key_usage(struct tls * ctx,struct tls_cert * cert,X509 * x509)462 tls_get_ext_key_usage(struct tls *ctx, struct tls_cert *cert, X509 *x509)
463 {
464 	static const uint32_t xku_map[][2] = {
465 		{XKU_SSL_SERVER, TLS_XKU_SSL_SERVER},
466 		{XKU_SSL_CLIENT, TLS_XKU_SSL_CLIENT},
467 		{XKU_SMIME, TLS_XKU_SMIME},
468 		{XKU_CODE_SIGN, TLS_XKU_CODE_SIGN},
469 		{XKU_SGC, TLS_XKU_SGC},
470 		{XKU_OCSP_SIGN, TLS_XKU_OCSP_SIGN},
471 		{XKU_TIMESTAMP, TLS_XKU_TIMESTAMP},
472 		{XKU_DVCS, TLS_XKU_DVCS},
473 		{0, 0},
474 	};
475 	EXTENDED_KEY_USAGE *xku;
476 	int crit;
477 
478 	xku = X509_get_ext_d2i(x509, NID_ext_key_usage, &crit, NULL);
479 	if (!xku)
480 		return 0;
481 	sk_ASN1_OBJECT_pop_free(xku, ASN1_OBJECT_free);
482 
483 	cert->ext_set |= TLS_EXT_EXTENDED_KEY_USAGE;
484 	if (crit)
485 		cert->ext_crit |= TLS_EXT_EXTENDED_KEY_USAGE;
486 
487 	cert->extended_key_usage_flags = map_bits(xku_map, X509_get_extended_key_usage(x509));
488 	return 0;
489 }
490 
491 static int
tls_load_extensions(struct tls * ctx,struct tls_cert * cert,X509 * x509)492 tls_load_extensions(struct tls *ctx, struct tls_cert *cert, X509 *x509)
493 {
494 	int ret;
495 
496 	/*
497 	 * Force libssl to fill extension fields under X509 struct.
498 	 * Then libtls does not need to parse raw data.
499 	 */
500 	X509_check_ca(x509);
501 
502 	ret = tls_get_basic_constraints(ctx, cert, x509);
503 	if (ret == 0)
504 		ret = tls_get_key_usage(ctx, cert, x509);
505 	if (ret == 0)
506 		ret = tls_get_ext_key_usage(ctx, cert, x509);
507 	if (ret == 0)
508 		ret = tls_cert_get_altnames(ctx, cert, x509);
509 	return ret;
510 }
511 
512 static void *
tls_calc_fingerprint(struct tls * ctx,X509 * x509,const char * algo,size_t * outlen)513 tls_calc_fingerprint(struct tls *ctx, X509 *x509, const char *algo, size_t *outlen)
514 {
515 	const EVP_MD *md;
516 	void *res;
517 	int ret;
518 	unsigned int tmplen, mdlen;
519 
520 	if (outlen)
521 		*outlen = 0;
522 
523 	if (strcasecmp(algo, "sha1") == 0) {
524 		md = EVP_sha1();
525 	} else if (strcasecmp(algo, "sha256") == 0) {
526 		md = EVP_sha256();
527 	} else {
528 		tls_set_errorx(ctx, "invalid fingerprint algorithm");
529 		return NULL;
530 	}
531 
532 	mdlen = EVP_MD_size(md);
533 	res = malloc(mdlen);
534 	if (!res) {
535 		tls_set_error(ctx, "malloc");
536 		return NULL;
537 	}
538 
539 	ret = X509_digest(x509, md, res, &tmplen);
540 	if (ret != 1 || tmplen != mdlen) {
541 		free(res);
542 		tls_set_errorx(ctx, "X509_digest failed");
543 		return NULL;
544 	}
545 
546 	if (outlen)
547 		*outlen = mdlen;
548 
549 	return res;
550 }
551 
552 static void
check_verify_error(struct tls * ctx,struct tls_cert * cert)553 check_verify_error(struct tls *ctx, struct tls_cert *cert)
554 {
555 	long vres = SSL_get_verify_result(ctx->ssl_conn);
556 	if (vres == X509_V_OK) {
557 		cert->successful_verify = 1;
558 	} else {
559 		cert->successful_verify = 0;
560 	}
561 }
562 
563 int
tls_parse_cert(struct tls * ctx,struct tls_cert ** cert_p,const char * fingerprint_algo,X509 * x509)564 tls_parse_cert(struct tls *ctx, struct tls_cert **cert_p, const char *fingerprint_algo, X509 *x509)
565 {
566 	struct tls_cert *cert = NULL;
567 	X509_NAME *subject, *issuer;
568 	int ret = -1;
569 	long version;
570 
571 	*cert_p = NULL;
572 
573 	version = X509_get_version(x509);
574 	if (version < 0) {
575 		tls_set_errorx(ctx, "invalid version");
576 		return -1;
577 	}
578 
579 	subject = X509_get_subject_name(x509);
580 	if (!subject) {
581 		tls_set_errorx(ctx, "cert does not have subject");
582 		return -1;
583 	}
584 
585 	issuer = X509_get_issuer_name(x509);
586 	if (!issuer) {
587 		tls_set_errorx(ctx, "cert does not have issuer");
588 		return -1;
589 	}
590 
591 	cert = calloc(sizeof *cert, 1);
592 	if (!cert) {
593 		tls_set_error(ctx, "calloc");
594 		goto failed;
595 	}
596 	cert->version = version;
597 
598 	if (fingerprint_algo) {
599 		cert->fingerprint = tls_calc_fingerprint(ctx, x509, fingerprint_algo, &cert->fingerprint_size);
600 		if (!cert->fingerprint)
601 			goto failed;
602 	}
603 
604 	ret = tls_get_dname(ctx, subject, &cert->subject);
605 	if (ret == 0)
606 		ret = tls_get_dname(ctx, issuer, &cert->issuer);
607 	if (ret == 0)
608 		ret = tls_asn1_parse_time(ctx, X509_get_notBefore(x509), &cert->not_before);
609 	if (ret == 0)
610 		ret = tls_asn1_parse_time(ctx, X509_get_notAfter(x509), &cert->not_after);
611 	if (ret == 0)
612 		ret = tls_parse_bigint(ctx, X509_get_serialNumber(x509), &cert->serial);
613 	if (ret == 0)
614 		ret = tls_load_extensions(ctx, cert, x509);
615 	if (ret == 0) {
616 		*cert_p = cert;
617 		return 0;
618 	}
619  failed:
620 	tls_cert_free(cert);
621 	return ret;
622 }
623 
624 int
tls_get_peer_cert(struct tls * ctx,struct tls_cert ** cert_p,const char * fingerprint_algo)625 tls_get_peer_cert(struct tls *ctx, struct tls_cert **cert_p, const char *fingerprint_algo)
626 {
627 	X509 *peer = ctx->ssl_peer_cert;
628 	int res;
629 
630 	*cert_p = NULL;
631 
632 	if (!peer) {
633 		tls_set_errorx(ctx, "peer does not have cert");
634 		return TLS_NO_CERT;
635 	}
636 
637 	ERR_clear_error();
638 	res = tls_parse_cert(ctx, cert_p, fingerprint_algo, peer);
639 	if (res == 0)
640 		check_verify_error(ctx, *cert_p);
641 	ERR_clear_error();
642 	return res;
643 }
644 
645 static void
tls_cert_free_dname(struct tls_cert_dname * dname)646 tls_cert_free_dname(struct tls_cert_dname *dname)
647 {
648 	free((void*)dname->common_name);
649 	free((void*)dname->country_name);
650 	free((void*)dname->state_or_province_name);
651 	free((void*)dname->locality_name);
652 	free((void*)dname->street_address);
653 	free((void*)dname->organization_name);
654 	free((void*)dname->organizational_unit_name);
655 }
656 
657 void
tls_cert_free(struct tls_cert * cert)658 tls_cert_free(struct tls_cert *cert)
659 {
660 	int i;
661 	if (!cert)
662 		return;
663 
664 	tls_cert_free_dname(&cert->issuer);
665 	tls_cert_free_dname(&cert->subject);
666 
667 	if (cert->subject_alt_name_count) {
668 		for (i = 0; i < cert->subject_alt_name_count; i++)
669 			free((void*)cert->subject_alt_names[i].name_value);
670 	}
671 	free(cert->subject_alt_names);
672 
673 	free((void*)cert->serial);
674 	free((void*)cert->fingerprint);
675 	free(cert);
676 }
677 
678 #endif /* USUAL_LIBSSL_FOR_TLS */
679