1/*++
2/* NAME
3/*	tls_verify 3
4/* SUMMARY
5/*	peer name and peer certificate verification
6/* SYNOPSIS
7/*	#define TLS_INTERNAL
8/*	#include <tls.h>
9/*
10/*	int	tls_verify_certificate_callback(ok, ctx)
11/*	int	ok;
12/*	X509_STORE_CTX *ctx;
13/*
14/*	int     tls_log_verify_error(TLScontext)
15/*	TLS_SESS_STATE *TLScontext;
16/*
17/*	char *tls_peer_CN(peercert, TLScontext)
18/*	X509   *peercert;
19/*	TLS_SESS_STATE *TLScontext;
20/*
21/*	char *tls_issuer_CN(peercert, TLScontext)
22/*	X509   *peercert;
23/*	TLS_SESS_STATE *TLScontext;
24/*
25/*	const char *tls_dns_name(gn, TLScontext)
26/*	const GENERAL_NAME *gn;
27/*	TLS_SESS_STATE *TLScontext;
28/* DESCRIPTION
29/*	tls_verify_certificate_callback() is called several times (directly
30/*	or indirectly) from crypto/x509/x509_vfy.c. It collects errors
31/*	and trust information at each element of the trust chain.
32/*	The last call at depth 0 sets the verification status based
33/*	on the cumulative winner (lowest depth) of errors vs. trust.
34/*	We always return 1 (continue the handshake) and handle trust
35/*	and peer-name verification problems at the application level.
36/*
37/*	tls_log_verify_error() (called only when we care about the
38/*	peer certificate, that is not when opportunistic) logs the
39/*	reason why the certificate failed to be verified.
40/*
41/*	tls_peer_CN() returns the text CommonName for the peer
42/*	certificate subject, or an empty string if no CommonName was
43/*	found. The result is allocated with mymalloc() and must be
44/*	freed by the caller; it contains UTF-8 without non-printable
45/*	ASCII characters.
46/*
47/*	tls_issuer_CN() returns the text CommonName for the peer
48/*	certificate issuer, or an empty string if no CommonName was
49/*	found. The result is allocated with mymalloc() and must be
50/*	freed by the caller; it contains UTF-8 without non-printable
51/*	ASCII characters.
52/*
53/*	tls_dns_name() returns the string value of a GENERAL_NAME
54/*	from a DNS subjectAltName extension. If non-printable characters
55/*	are found, a null string is returned instead. Further sanity
56/*	checks may be added if the need arises.
57/*
58/*	Arguments:
59/* .IP ok
60/*	Result of prior verification: non-zero means success.  In
61/*	order to reduce the noise level, some tests or error reports
62/*	are disabled when verification failed because of some
63/*	earlier problem.
64/* .IP ctx
65/*	SSL application context. This links to the Postfix TLScontext
66/*	with enforcement and logging options.
67/* .IP gn
68/*	An OpenSSL GENERAL_NAME structure holding a DNS subjectAltName
69/*	to be decoded and checked for validity.
70/* .IP peercert
71/*	Server or client X.509 certificate.
72/* .IP TLScontext
73/*	Server or client context for warning messages.
74/* DIAGNOSTICS
75/*	tls_peer_CN(), tls_issuer_CN() and tls_dns_name() log a warning
76/*	when 1) the requested information is not available in the specified
77/*	certificate, 2) the result exceeds a fixed limit, 3) the result
78/*	contains NUL characters or the result contains non-printable or
79/*	non-ASCII characters.
80/* LICENSE
81/* .ad
82/* .fi
83/*	This software is free. You can do with it whatever you want.
84/*	The original author kindly requests that you acknowledge
85/*	the use of his software.
86/* AUTHOR(S)
87/*	Originally written by:
88/*	Lutz Jaenicke
89/*	BTU Cottbus
90/*	Allgemeine Elektrotechnik
91/*	Universitaetsplatz 3-4
92/*	D-03044 Cottbus, Germany
93/*
94/*	Updated by:
95/*	Wietse Venema
96/*	IBM T.J. Watson Research
97/*	P.O. Box 704
98/*	Yorktown Heights, NY 10598, USA
99/*
100/*	Victor Duchovni
101/*	Morgan Stanley
102/*--*/
103
104/* System library. */
105
106#include <sys_defs.h>
107#include <ctype.h>
108
109#ifdef USE_TLS
110#include <string.h>
111
112/* Utility library. */
113
114#include <msg.h>
115#include <mymalloc.h>
116#include <stringops.h>
117
118/* TLS library. */
119
120#define TLS_INTERNAL
121#include <tls.h>
122
123/* update_error_state - safely stash away error state */
124
125static void update_error_state(TLS_SESS_STATE *TLScontext, int depth,
126			               X509 *errorcert, int errorcode)
127{
128    /* No news is good news */
129    if (TLScontext->errordepth >= 0 && TLScontext->errordepth <= depth)
130	return;
131
132    /*
133     * The certificate pointer is stable during the verification callback,
134     * but may be freed after the callback returns.  Since we delay error
135     * reporting till later, we bump the refcount so we can rely on it still
136     * being there until later.
137     */
138    if (TLScontext->errorcert != 0)
139	X509_free(TLScontext->errorcert);
140    if (errorcert != 0)
141	CRYPTO_add(&errorcert->references, 1, CRYPTO_LOCK_X509);
142    TLScontext->errorcert = errorcert;
143    TLScontext->errorcode = errorcode;
144    TLScontext->errordepth = depth;
145}
146
147/* tls_verify_certificate_callback - verify peer certificate info */
148
149int     tls_verify_certificate_callback(int ok, X509_STORE_CTX *ctx)
150{
151    char    buf[CCERT_BUFSIZ];
152    X509   *cert;
153    int     err;
154    int     depth;
155    int     max_depth;
156    SSL    *con;
157    TLS_SESS_STATE *TLScontext;
158
159    /* May be NULL as of OpenSSL 1.0, thanks for the API change! */
160    cert = X509_STORE_CTX_get_current_cert(ctx);
161    err = X509_STORE_CTX_get_error(ctx);
162    con = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
163    TLScontext = SSL_get_ex_data(con, TLScontext_index);
164    depth = X509_STORE_CTX_get_error_depth(ctx);
165
166    /* Don't log the internal root CA unless there's an unexpected error. */
167    if (ok && TLScontext->tadepth > 0 && depth > TLScontext->tadepth)
168	return (1);
169
170    /*
171     * Certificate chain depth limit violations are mis-reported by the
172     * OpenSSL library, from SSL_CTX_set_verify(3):
173     *
174     * The certificate verification depth set with SSL[_CTX]_verify_depth()
175     * stops the verification at a certain depth. The error message produced
176     * will be that of an incomplete certificate chain and not
177     * X509_V_ERR_CERT_CHAIN_TOO_LONG as may be expected.
178     *
179     * We set a limit that is one higher than the user requested limit. If this
180     * higher limit is reached, we raise an error even a trusted root CA is
181     * present at this depth. This disambiguates trust chain truncation from
182     * an incomplete trust chain.
183     */
184    max_depth = SSL_get_verify_depth(con) - 1;
185
186    /*
187     * We never terminate the SSL handshake in the verification callback,
188     * rather we allow the TLS handshake to continue, but mark the session as
189     * unverified. The application is responsible for closing any sessions
190     * with unverified credentials.
191     */
192    if (max_depth >= 0 && depth > max_depth) {
193	X509_STORE_CTX_set_error(ctx, err = X509_V_ERR_CERT_CHAIN_TOO_LONG);
194	ok = 0;
195    }
196    if (ok == 0)
197	update_error_state(TLScontext, depth, cert, err);
198
199    if (TLScontext->log_mask & TLS_LOG_VERBOSE) {
200	if (cert)
201	    X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
202	else
203	    strcpy(buf, "<unknown>");
204	msg_info("%s: depth=%d verify=%d subject=%s",
205		 TLScontext->namaddr, depth, ok, printable(buf, '?'));
206    }
207    return (1);
208}
209
210/* tls_log_verify_error - Report final verification error status */
211
212void    tls_log_verify_error(TLS_SESS_STATE *TLScontext)
213{
214    char    buf[CCERT_BUFSIZ];
215    int     err = TLScontext->errorcode;
216    X509   *cert = TLScontext->errorcert;
217    int     depth = TLScontext->errordepth;
218
219#define PURPOSE ((depth>0) ? "CA": TLScontext->am_server ? "client": "server")
220
221    if (err == X509_V_OK)
222	return;
223
224    /*
225     * Specific causes for verification failure.
226     */
227    switch (err) {
228    case X509_V_ERR_CERT_UNTRUSTED:
229
230	/*
231	 * We expect the error cert to be the leaf, but it is likely
232	 * sufficient to omit it from the log, even less user confusion.
233	 */
234	msg_info("certificate verification failed for %s: "
235		 "not trusted by local or TLSA policy", TLScontext->namaddr);
236	break;
237    case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
238	msg_info("certificate verification failed for %s: "
239		 "self-signed certificate", TLScontext->namaddr);
240	break;
241    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
242    case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
243
244	/*
245	 * There is no difference between issuing cert not provided and
246	 * provided, but not found in CAfile/CApath. Either way, we don't
247	 * trust it.
248	 */
249	if (cert)
250	    X509_NAME_oneline(X509_get_issuer_name(cert), buf, sizeof(buf));
251	else
252	    strcpy(buf, "<unknown>");
253	msg_info("certificate verification failed for %s: untrusted issuer %s",
254		 TLScontext->namaddr, printable(buf, '?'));
255	break;
256    case X509_V_ERR_CERT_NOT_YET_VALID:
257    case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
258	msg_info("%s certificate verification failed for %s: certificate not"
259		 " yet valid", PURPOSE, TLScontext->namaddr);
260	break;
261    case X509_V_ERR_CERT_HAS_EXPIRED:
262    case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
263	msg_info("%s certificate verification failed for %s: certificate has"
264		 " expired", PURPOSE, TLScontext->namaddr);
265	break;
266    case X509_V_ERR_INVALID_PURPOSE:
267	msg_info("certificate verification failed for %s: not designated for "
268		 "use as a %s certificate", TLScontext->namaddr, PURPOSE);
269	break;
270    case X509_V_ERR_CERT_CHAIN_TOO_LONG:
271	msg_info("certificate verification failed for %s: "
272		 "certificate chain longer than limit(%d)",
273		 TLScontext->namaddr, depth - 1);
274	break;
275    default:
276	msg_info("%s certificate verification failed for %s: num=%d:%s",
277		 PURPOSE, TLScontext->namaddr, err,
278		 X509_verify_cert_error_string(err));
279	break;
280    }
281}
282
283#ifndef DONT_GRIPE
284#define DONT_GRIPE 0
285#define DO_GRIPE 1
286#endif
287
288/* tls_text_name - extract certificate property value by name */
289
290static char *tls_text_name(X509_NAME *name, int nid, const char *label,
291			        const TLS_SESS_STATE *TLScontext, int gripe)
292{
293    const char *myname = "tls_text_name";
294    int     pos;
295    X509_NAME_ENTRY *entry;
296    ASN1_STRING *entry_str;
297    int     asn1_type;
298    int     utf8_length;
299    unsigned char *utf8_value;
300    int     ch;
301    unsigned char *cp;
302
303    if (name == 0 || (pos = X509_NAME_get_index_by_NID(name, nid, -1)) < 0) {
304	if (gripe != DONT_GRIPE) {
305	    msg_warn("%s: %s: peer certificate has no %s",
306		     myname, TLScontext->namaddr, label);
307	    tls_print_errors();
308	}
309	return (0);
310    }
311#if 0
312
313    /*
314     * If the match is required unambiguous, insist that that no other values
315     * be present.
316     */
317    if (X509_NAME_get_index_by_NID(name, nid, pos) >= 0) {
318	msg_warn("%s: %s: multiple %ss in peer certificate",
319		 myname, TLScontext->namaddr, label);
320	return (0);
321    }
322#endif
323
324    if ((entry = X509_NAME_get_entry(name, pos)) == 0) {
325	/* This should not happen */
326	msg_warn("%s: %s: error reading peer certificate %s entry",
327		 myname, TLScontext->namaddr, label);
328	tls_print_errors();
329	return (0);
330    }
331    if ((entry_str = X509_NAME_ENTRY_get_data(entry)) == 0) {
332	/* This should not happen */
333	msg_warn("%s: %s: error reading peer certificate %s data",
334		 myname, TLScontext->namaddr, label);
335	tls_print_errors();
336	return (0);
337    }
338
339    /*
340     * XXX Convert everything into UTF-8. This is a super-set of ASCII, so we
341     * don't have to bother with separate code paths for ASCII-like content.
342     * If the payload is ASCII then we won't waste lots of CPU cycles
343     * converting it into UTF-8. It's up to OpenSSL to do something
344     * reasonable when converting ASCII formats that contain non-ASCII
345     * content.
346     *
347     * XXX Don't bother optimizing the string length error check. It is not
348     * worth the complexity.
349     */
350    asn1_type = ASN1_STRING_type(entry_str);
351    if ((utf8_length = ASN1_STRING_to_UTF8(&utf8_value, entry_str)) < 0) {
352	msg_warn("%s: %s: error decoding peer %s of ASN.1 type=%d",
353		 myname, TLScontext->namaddr, label, asn1_type);
354	tls_print_errors();
355	return (0);
356    }
357
358    /*
359     * No returns without cleaning up. A good optimizer will replace multiple
360     * blocks of identical code by jumps to just one such block.
361     */
362#define TLS_TEXT_NAME_RETURN(x) do { \
363	char *__tls_text_name_temp = (x); \
364	OPENSSL_free(utf8_value); \
365	return (__tls_text_name_temp); \
366    } while (0)
367
368    /*
369     * Remove trailing null characters. They would give false alarms with the
370     * length check and with the embedded null check.
371     */
372#define TRIM0(s, l) do { while ((l) > 0 && (s)[(l)-1] == 0) --(l); } while (0)
373
374    TRIM0(utf8_value, utf8_length);
375
376    /*
377     * Enforce the length limit, because the caller will copy the result into
378     * a fixed-length buffer.
379     */
380    if (utf8_length >= CCERT_BUFSIZ) {
381	msg_warn("%s: %s: peer %s too long: %d",
382		 myname, TLScontext->namaddr, label, utf8_length);
383	TLS_TEXT_NAME_RETURN(0);
384    }
385
386    /*
387     * Reject embedded nulls in ASCII or UTF-8 names. OpenSSL is responsible
388     * for producing properly-formatted UTF-8.
389     */
390    if (utf8_length != strlen((char *) utf8_value)) {
391	msg_warn("%s: %s: NULL character in peer %s",
392		 myname, TLScontext->namaddr, label);
393	TLS_TEXT_NAME_RETURN(0);
394    }
395
396    /*
397     * Reject non-printable ASCII characters in UTF-8 content.
398     *
399     * Note: the code below does not find control characters in illegal UTF-8
400     * sequences. It's OpenSSL's job to produce valid UTF-8, and reportedly,
401     * it does validation.
402     */
403    for (cp = utf8_value; (ch = *cp) != 0; cp++) {
404	if (ISASCII(ch) && !ISPRINT(ch)) {
405	    msg_warn("%s: %s: non-printable content in peer %s",
406		     myname, TLScontext->namaddr, label);
407	    TLS_TEXT_NAME_RETURN(0);
408	}
409    }
410    TLS_TEXT_NAME_RETURN(mystrdup((char *) utf8_value));
411}
412
413/* tls_dns_name - Extract valid DNS name from subjectAltName value */
414
415const char *tls_dns_name(const GENERAL_NAME * gn,
416			         const TLS_SESS_STATE *TLScontext)
417{
418    const char *myname = "tls_dns_name";
419    char   *cp;
420    const char *dnsname;
421    int     len;
422
423    /*
424     * Peername checks are security sensitive, carefully scrutinize the
425     * input!
426     */
427    if (gn->type != GEN_DNS)
428	msg_panic("%s: Non DNS input argument", myname);
429
430    /*
431     * We expect the OpenSSL library to construct GEN_DNS extesion objects as
432     * ASN1_IA5STRING values. Check we got the right union member.
433     */
434    if (ASN1_STRING_type(gn->d.ia5) != V_ASN1_IA5STRING) {
435	msg_warn("%s: %s: invalid ASN1 value type in subjectAltName",
436		 myname, TLScontext->namaddr);
437	return (0);
438    }
439
440    /*
441     * Safe to treat as an ASCII string possibly holding a DNS name
442     */
443    dnsname = (char *) ASN1_STRING_data(gn->d.ia5);
444    len = ASN1_STRING_length(gn->d.ia5);
445    TRIM0(dnsname, len);
446
447    /*
448     * Per Dr. Steven Henson of the OpenSSL development team, ASN1_IA5STRING
449     * values can have internal ASCII NUL values in this context because
450     * their length is taken from the decoded ASN1 buffer, a trailing NUL is
451     * always appended to make sure that the string is terminated, but the
452     * ASN.1 length may differ from strlen().
453     */
454    if (len != strlen(dnsname)) {
455	msg_warn("%s: %s: internal NUL in subjectAltName",
456		 myname, TLScontext->namaddr);
457	return 0;
458    }
459
460    /*
461     * XXX: Should we be more strict and call valid_hostname()? So long as
462     * the name is safe to handle, if it is not a valid hostname, it will not
463     * compare equal to the expected peername, so being more strict than
464     * "printable" is likely excessive...
465     */
466    if (*dnsname && !allprint(dnsname)) {
467	cp = mystrdup(dnsname);
468	msg_warn("%s: %s: non-printable characters in subjectAltName: %.100s",
469		 myname, TLScontext->namaddr, printable(cp, '?'));
470	myfree(cp);
471	return 0;
472    }
473    return (dnsname);
474}
475
476/* tls_peer_CN - extract peer common name from certificate */
477
478char   *tls_peer_CN(X509 *peercert, const TLS_SESS_STATE *TLScontext)
479{
480    char   *cn;
481
482    cn = tls_text_name(X509_get_subject_name(peercert), NID_commonName,
483		       "subject CN", TLScontext, DONT_GRIPE);
484    return (cn ? cn : mystrdup(""));
485}
486
487/* tls_issuer_CN - extract issuer common name from certificate */
488
489char   *tls_issuer_CN(X509 *peer, const TLS_SESS_STATE *TLScontext)
490{
491    X509_NAME *name;
492    char   *cn;
493
494    name = X509_get_issuer_name(peer);
495
496    /*
497     * If no issuer CN field, use Organization instead. CA certs without a CN
498     * are common, so we only complain if the organization is also missing.
499     */
500    if ((cn = tls_text_name(name, NID_commonName,
501			    "issuer CN", TLScontext, DONT_GRIPE)) == 0)
502	cn = tls_text_name(name, NID_organizationName,
503			   "issuer Organization", TLScontext, DONT_GRIPE);
504    return (cn ? cn : mystrdup(""));
505}
506
507#endif
508