diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | NEWS | 7 | ||||
-rw-r--r-- | configure.in | 5 | ||||
-rw-r--r-- | doc/ref/clicert.xml | 4 | ||||
-rw-r--r-- | macros/ChangeLog | 14 | ||||
-rw-r--r-- | macros/neon.m4 | 17 | ||||
-rw-r--r-- | src/ChangeLog | 13 | ||||
-rw-r--r-- | src/ne_207.h | 7 | ||||
-rw-r--r-- | src/ne_openssl.c | 46 | ||||
-rw-r--r-- | src/ne_socket.c | 12 | ||||
-rw-r--r-- | test/ChangeLog | 21 | ||||
-rw-r--r-- | test/Makefile.in | 14 | ||||
-rwxr-xr-x | test/makekeys.sh | 13 | ||||
-rw-r--r-- | test/openssl.conf | 6 | ||||
-rw-r--r-- | test/socket.c | 8 | ||||
-rw-r--r-- | test/ssl.c | 20 |
16 files changed, 173 insertions, 40 deletions
@@ -1,3 +1,9 @@ +Sun Sep 14 11:13:36 2003 Joe Orton <joe@manyfish.co.uk> + + * configure.in: Run NEON_TEST before LIBNEON_SOURCE_CHECKS, to + help prevent time_t format string detection failing due to changed + CFLAGS. + Fri Jun 20 17:51:05 2003 Joe Orton <joe@manyfish.co.uk> * configure.in, neon-config.in: Don't pass user-supplied CPPFLAGS @@ -1,3 +1,10 @@ +Changes in release 0.24.2: +* Fix name resolver with some old versions of glibc. +* Fix problems with configure's "time_t format string" detection. +* Fix problems when a broken Kerberos installation is found. +* When verifying SSL certificates, check iPaddress names in the + subjectAltName extension. + Changes in release 0.24.1: * Add support for "GSS-Negotiate" Kerberos authentication scheme (from Risko Gergely and Burjan Gabor). diff --git a/configure.in b/configure.in index c7a2f3d..f0dfa7e 100644 --- a/configure.in +++ b/configure.in @@ -63,12 +63,13 @@ NEON_VERSIONS # Pass the interface version on to libtool when linking libneon.la NEON_LINK_FLAGS="-version-info ${NEON_INTERFACE_VERSION}" +# Checks to compile test suite +NEON_TEST + LIBNEON_SOURCE_CHECKS # Use the libtool-type build. NEON_LIBTOOL_BUILD -# Checks to compile test suite -NEON_TEST # Find an XML parser NEON_XML_PARSER # Extra checks for debugging, compiler warnings diff --git a/doc/ref/clicert.xml b/doc/ref/clicert.xml index c61404c..49f95cf 100644 --- a/doc/ref/clicert.xml +++ b/doc/ref/clicert.xml @@ -86,9 +86,9 @@ more than once using different passwords.</para> <para>A client certificate can be given a "friendly name" when it - is created; <function>ne_ssl_clicert_owner</function> will return + is created; <function>ne_ssl_clicert_name</function> will return this name (or &null; if no friendly name was specified). - <function>ne_ssl_clicert_owner</function> can be used when the + <function>ne_ssl_clicert_name</function> can be used when the client certificate is in either the encrypted or decrypted state, and will return the same string for the lifetime of the object.</para> diff --git a/macros/ChangeLog b/macros/ChangeLog index b0a789c..bcf9359 100644 --- a/macros/ChangeLog +++ b/macros/ChangeLog @@ -1,3 +1,13 @@ +Sun Sep 14 10:51:34 2003 Joe Orton <joe@manyfish.co.uk> + + * neon.m4 (LIBNEON_SOURCE_CHECKS): Check for working AI_ADDRCONFIG + flag for getaddrinfo(). + +Wed Sep 10 21:45:10 2003 Joe Orton <joe@manyfish.co.uk> + + * neon.m4 (NEON_GSSAPI): Restore CPPFLAGS and NEON_LIBS if GSSAPI + detection fails. + Thu Sep 4 21:29:06 2003 Joe Orton <joe@manyfish.co.uk> * neon.m4 (LIBNEON_SOURCE_CHECKS): Check for netinet/tcp.h. @@ -44,6 +54,10 @@ Sun Mar 16 09:06:41 2003 Joe Orton <joe@manyfish.co.uk> * neon-xml-parser.m4 (NEON_XML_PARSER): Fix --with-included-expat support. +Sun Mar 9 10:08:57 2003 Joe Orton <joe@manyfish.co.uk> + + * neon.m4 (NEON_SSL): Fail if --with-ssl is given an argument. + Sun Mar 9 08:55:04 2003 Joe Orton <joe@manyfish.co.uk> * neon.m4 (NE_SEARCH_LIBS): Bug fix to always compare against diff --git a/macros/neon.m4 b/macros/neon.m4 index f18c560..698487c 100644 --- a/macros/neon.m4 +++ b/macros/neon.m4 @@ -122,7 +122,7 @@ AC_DEFUN([NEON_VERSIONS], [ # Define the current versions. NEON_VERSION_MAJOR=0 NEON_VERSION_MINOR=24 -NEON_VERSION_RELEASE=1 +NEON_VERSION_RELEASE=2 NEON_VERSION_TAG= NEON_VERSION="${NEON_VERSION_MAJOR}.${NEON_VERSION_MINOR}.${NEON_VERSION_RELEASE}${NEON_VERSION_TAG}" @@ -501,6 +501,15 @@ ne_enable_gai=yes NE_CHECK_FUNCS(getaddrinfo gai_strerror inet_ntop,,[ne_enable_gai=no; break]) if test $ne_enable_gai = yes; then AC_DEFINE(USE_GETADDRINFO, 1, [Define if getaddrinfo() should be used]) + AC_CACHE_CHECK([for working AI_ADDRCONFIG], [ne_cv_gai_addrconfig], [ + AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <netdb.h>], +[struct addrinfo hints = {0}, *result; +hints.ai_flags = AI_ADDRCONFIG; +if (getaddrinfo("localhost", NULL, &hints, &result) != 0) return 1;])], + ne_cv_gai_addrconfig=yes, ne_cv_gai_addrconfig=no)]) + if test $ne_cv_gai_addrconfig = yes; then + AC_DEFINE(USE_GAI_ADDRCONFIG, 1, [Define if getaddrinfo supports AI_ADDRCONFIG]) + fi else # Checks for non-getaddrinfo() based resolver interfaces. NE_SEARCH_LIBS(hstrerror, resolv,,[:]) @@ -771,11 +780,15 @@ dnl Check for Kerberos installation AC_DEFUN([NEON_GSSAPI], [ AC_PATH_PROG([KRB5_CONFIG], krb5-config, none, $PATH:/usr/kerberos/bin) if test "x$KRB5_CONFIG" != "xnone"; then + ne_save_CPPFLAGS=$CPPFLAGS + ne_save_LIBS=$NEON_LIBS NEON_LIBS="$NEON_LIBS `${KRB5_CONFIG} --libs gssapi`" CPPFLAGS="$CPPFLAGS `${KRB5_CONFIG} --cflags gssapi`" # MIT and Heimdal put gssapi.h in different places AC_CHECK_HEADERS(gssapi/gssapi.h gssapi.h, [ NE_CHECK_FUNCS(gss_init_sec_context, [ + ne_save_CPPFLAGS=$CPPFLAGS + ne_save_LIBS=$NEON_LIBS AC_MSG_NOTICE([GSSAPI authentication support enabled]) AC_DEFINE(HAVE_GSSAPI, 1, [Define if GSSAPI support is enabled]) # MIT Kerberos lacks GSS_C_NT_HOSTBASED_SERVICE @@ -789,6 +802,8 @@ if test "x$KRB5_CONFIG" != "xnone"; then #endif])]) break ]) + CPPFLAGS=$ne_save_CPPFLAGS + NEON_LIBS=$ne_save_LIBS fi]) dnl Adds an --enable-warnings argument to configure to allow enabling diff --git a/src/ChangeLog b/src/ChangeLog index 3aa1649..36022c8 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ +Sun Sep 14 10:50:01 2003 Joe Orton <joe@manyfish.co.uk> + + * ne_socket.c (ne_addr_resolve): Use result of autoconf test for + working AI_ADDRCONFIG support. + +Sat Sep 6 12:05:00 2003 Joe Orton <joe@manyfish.co.uk> + + * ne_openssl.c (check_identity): Take an optional server address + argument; check identity against IPaddress extension too if given. + (check_certificate): Optionally pass server address to + check_identity. + (populate_cert): Adjust accordingly. + Thu Sep 4 21:41:38 2003 Joe Orton <joe@manyfish.co.uk> * ne_socket.c (ne_sock_init): Succeed even if PRNG was not seeded. diff --git a/src/ne_207.h b/src/ne_207.h index 890ce84..65fe471 100644 --- a/src/ne_207.h +++ b/src/ne_207.h @@ -85,7 +85,12 @@ int ne_accept_207(void *userdata, ne_request *req, const ne_status *status); void *ne_207_get_current_propstat(ne_207_parser *p); void *ne_207_get_current_response(ne_207_parser *p); -/* Dispatch a DAV request and handle a 207 error response appropriately */ +/* Dispatch request 'req', returning: + * NE_ERROR: for a dispatch error, or a non-2xx response, or a + * 207 response which contained a non-2xx propstat + * NE_OK: for a 2xx response or a 207 response which contained + * only 2xx-class propstats. + * The request object is destroyed in both cases. */ int ne_simple_request(ne_session *sess, ne_request *req); END_NEON_DECLS diff --git a/src/ne_openssl.c b/src/ne_openssl.c index 359f7a4..d48dbb3 100644 --- a/src/ne_openssl.c +++ b/src/ne_openssl.c @@ -168,8 +168,8 @@ void ne_ssl_cert_validity(const ne_ssl_certificate *cert, } /* Return non-zero if hostname from certificate (cn) matches hostname - * used for session (hostname). TODO: could do more advanced wildcard - * matching using fnmatch() here, if fnmatch is present. */ + * used for session (hostname). (Wildcard matching is no longer + * mandated by RFC3280, but certs are deployed which use wildcards) */ static int match_hostname(char *cn, const char *hostname) { const char *dot; @@ -192,35 +192,57 @@ static int match_hostname(char *cn, const char *hostname) /* Check certificate identity. Returns zero if identity matches; 1 if * identity does not match, or <0 if the certificate had no identity. * If 'identity' is non-NULL, store the malloc-allocated identity in - * *identity. */ -static int check_identity(const char *hostname, X509 *cert, char **identity) + * *identity. If 'server' is non-NULL, it must be the network address + * of the server in use, and identity must be NULL. */ +static int check_identity(const char *hostname, X509 *cert, char **identity, + const ne_inet_addr *server) { STACK_OF(GENERAL_NAME) *names; int match = 0, found = 0; names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); if (names) { - /* Got a subject alt. name extension. */ int n; + /* subjectAltName contains a sequence of GeneralNames */ for (n = 0; n < sk_GENERAL_NAME_num(names) && !match; n++) { GENERAL_NAME *nm = sk_GENERAL_NAME_value(names, n); - /* only care about this if it is a DNS name. */ + /* handle dNSName and iPAddress name extensions only. */ if (nm->type == GEN_DNS) { char *name = ne_strndup(nm->d.ia5->data, nm->d.ia5->length); if (identity && !found) *identity = ne_strdup(name); match = match_hostname(name, hostname); ne_free(name); found = 1; - } + } else if (nm->type == GEN_IPADD && server) { + /* compare IP address with server IP address. */ + ne_inet_addr *ia; + if (nm->d.ip->length == 4) + ia = ne_iaddr_make(ne_iaddr_ipv4, nm->d.ip->data); + else if (nm->d.ip->length == 16) + ia = ne_iaddr_make(ne_iaddr_ipv6, nm->d.ip->data); + else + ia = NULL; + /* ne_iaddr_make returns NULL if address type is unsupported */ + if (ia != NULL) { /* address type was supported. */ + match = ne_iaddr_cmp(server, ia) == 0; + found = 1; + ne_iaddr_free(ia); + } else { + NE_DEBUG(NE_DBG_SSL, "iPAddress name with unsupported " + "address type (length %d), skipped.\n", + nm->d.ip->length); + } + } /* TODO: handle uniformResourceIdentifier too */ + } /* free the whole stack. */ sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free); } /* Check against the commonName if no DNS alt. names were found, - * as per RFC2818. */ + * as per RFC3280. */ if (!found) { X509_NAME *subj = X509_get_subject_name(cert); X509_NAME_ENTRY *entry; @@ -260,7 +282,7 @@ static ne_ssl_certificate *populate_cert(ne_ssl_certificate *cert, X509 *x5) cert->subject = x5; /* Retrieve the cert identity; pass a dummy hostname to match. */ cert->identity = NULL; - check_identity("", x5, &cert->identity); + check_identity("", x5, &cert->identity, NULL); return cert; } @@ -307,8 +329,10 @@ static int check_certificate(ne_session *sess, SSL *ssl, ne_ssl_certificate *cha else if (X509_cmp_current_time(notAfter) <= 0) failures |= NE_SSL_EXPIRED; - /* Check certificate was issued to this server. */ - ret = check_identity(sess->server.hostname, cert, NULL); + /* Check certificate was issued to this server; pass network + * address of server if a proxy is not in use. */ + ret = check_identity(sess->server.hostname, cert, NULL, + sess->use_proxy ? NULL : sess->server.current); if (ret < 0) { ne_set_error(sess, _("Server certificate was missing commonName " "attribute in subject name")); diff --git a/src/ne_socket.c b/src/ne_socket.c index fd8afdb..80ca607 100644 --- a/src/ne_socket.c +++ b/src/ne_socket.c @@ -116,9 +116,7 @@ typedef struct addrinfo ne_inet_addr; /* To avoid doing AAAA queries unless absolutely necessary, either use * AI_ADDRCONFIG where available, or a run-time check for working IPv6 * support; the latter is only known to work on Linux. */ -#if defined(AI_ADDRCONFIG) && defined(EAI_BADFLAGS) -#define USE_ADDRCONFIG -#elif defined(__linux__) +#if !defined(USE_GAI_ADDRCONFIG) && defined(__linux__) #define USE_CHECK_IPV6 #endif @@ -663,18 +661,14 @@ ne_sock_addr *ne_addr_resolve(const char *hostname, int flags) addr->errnum = getaddrinfo(hn, NULL, &hints, &addr->result); ne_free(hn); } else { -#ifdef USE_ADDRCONFIG /* added in the RFC3493 API */ +#ifdef USE_GAI_ADDRCONFIG /* added in the RFC3493 API */ hints.ai_flags = AI_ADDRCONFIG; hints.ai_family = AF_UNSPEC; addr->errnum = getaddrinfo(hostname, NULL, &hints, &addr->result); - if (addr->errnum != EAI_BADFLAGS) - return addr; - /* Retry without AI_ADDRCONFIG if this libc doesn't grok it */ - hints.ai_flags = 0; #else hints.ai_family = ipv6_disabled ? AF_INET : AF_UNSPEC; -#endif addr->errnum = getaddrinfo(hostname, NULL, &hints, &addr->result); +#endif } #else /* Use gethostbyname() */ unsigned long laddr; diff --git a/test/ChangeLog b/test/ChangeLog index 2ea156c..5f2fa4a 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,24 @@ +Sun Sep 14 12:27:22 2003 Joe Orton <joe@manyfish.co.uk> + + * socket.c (write_reset, read_reset): Skip if no RESET was + returned. + +Sun Sep 14 11:01:08 2003 Joe Orton <joe@manyfish.co.uk> + + * Makefile.in: Fix building the 'resolve' tool. + +Sat Sep 6 12:29:53 2003 Joe Orton <joe@manyfish.co.uk> + + * makekeys.sh, openssl.conf: Generate altname5.cert with an IPv4 + address in the subjectAltName attribute. + + * ssl.c (ipaddr_altname): Test for IPv4 address in subjectAltName. + +Sat Sep 6 12:28:55 2003 Joe Orton <joe@manyfish.co.uk> + + * Makefile.in: Clear the SUFFIXES list; use standard make syntax; + fix build of 'basic' on some platforms. + Sat Aug 30 18:59:24 2003 Joe Orton <joe@manyfish.co.uk> * Makefile.in: Rewrite to use libtool to build object files and diff --git a/test/Makefile.in b/test/Makefile.in index be5a6ef..23fe132 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -36,21 +36,23 @@ OBJDEPS = $(srcdir)/common/tests.h $(srcdir)/common/child.h $(srcdir)/utils.h \ DEPS = $(LIBTEST) LIBTEST = libtest.la +LIBNEON = $(top_builddir)/src/libneon.la LIBTOOL = @LIBTOOL@ --silent LINK = $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -no-install COMPILE = $(LIBTOOL) --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) +.SUFFIXES: .SUFFIXES: .lo .c # By default, compile but don't run the tests. all: $(TESTS) clean: - rm -f $(TESTS) $(HELPERS) *.o *.lo common/*.o libtest.a *.log + rm -f $(TESTS) $(HELPERS) *.*o common/*.*o libtest.a *.log rm -rf ca .libs rm -f ca-stamp client.key *.csr ssigned.pem wrongcn.pem \ - server.cert client.cert client.p12 + server.cert client.cert client.p12 *.cert check: $(TESTS) $(HELPERS) @SRCDIR=$(srcdir) $(SHELL) $(srcdir)/run.sh $(TESTS) @@ -100,12 +102,12 @@ Makefile: $(srcdir)/Makefile.in LIBOBJS = common/tests.lo common/child.lo utils.lo $(LIBTEST): $(LIBOBJS) - $(LINK) -o $(LIBTEST) $(LIBOBJS) $(top_builddir)/src/libneon.la + $(LINK) -o $(LIBTEST) $(LIBOBJS) $(LIBNEON) .c.lo: $(COMPILE) -c $< -o $@ -%:%.lo +.lo: $(LINK) -o $@ $< $(LIBS) # Recompile socket.c with SOCKET_SSL defined @@ -115,6 +117,9 @@ socket-ssl.lo: $(srcdir)/socket.c $(HDRS) socket-ssl: socket-ssl.lo $(LIBTEST) $(LINK) -o $@ socket-ssl.lo $(LIBS) +resolve: resolve.lo $(LIBNEON) + $(LINK) -o $@ resolve.lo $(LIBNEON) + auth.lo: $(srcdir)/auth.c $(OBJDEPS) uri-tests.lo: $(srcdir)/uri-tests.c $(OBJDEPS) util-tests.lo: $(srcdir)/util-tests.c $(OBJDEPS) @@ -134,6 +139,7 @@ basic.lo: $(srcdir)/basic.c $(OBJDEPS) ssl.lo: $(srcdir)/ssl.c $(OBJDEPS) auth: auth.lo $(DEPS) +basic: basic.lo $(DEPS) uri-tests: uri-tests.lo $(DEPS) util-tests: util-tests.lo $(DEPS) string-tests: string-tests.lo $(DEPS) diff --git a/test/makekeys.sh b/test/makekeys.sh index 59a1e51..bcf85b2 100755 --- a/test/makekeys.sh +++ b/test/makekeys.sh @@ -58,7 +58,7 @@ csr_fields "Upper Case Dept" lOcALhost | \ ${REQ} -new -key ${srcdir}/server.key -out caseless.csr csr_fields "Use AltName Dept" nowhere.example.com | \ -${REQ} -new -key ${srcdir}/server.key -out altname.csr +${REQ} -new -key ${srcdir}/server.key -out altname1.csr csr_fields "Two AltName Dept" nowhere.example.com | \ ${REQ} -new -key ${srcdir}/server.key -out altname2.csr @@ -69,6 +69,9 @@ ${REQ} -new -key ${srcdir}/server.key -out altname3.csr csr_fields "Fourth AltName Dept" localhost | \ ${REQ} -new -key ${srcdir}/server.key -out altname4.csr +csr_fields "Fifth Altname Dept" localhost | \ +${REQ} -new -key ${srcdir}/server.key -out altname5.csr + csr_fields "Self-Signed" | \ ${MKCERT} -key ${srcdir}/server.key -out ssigned.pem @@ -126,10 +129,10 @@ for f in server client twocn caseless cnfirst missingcn justmail; do ${CA} -days 900 -in ${f}.csr -out ${f}.cert done -${CA} -extensions altExt -days 900 -in altname.csr -out altname.cert -${CA} -extensions altExt2 -days 900 -in altname2.csr -out altname2.cert -${CA} -extensions altExt3 -days 900 -in altname3.csr -out altname3.cert -${CA} -extensions altExt4 -days 900 -in altname4.csr -out altname4.cert +for n in 1 2 3 4 5; do + ${CA} -extensions altExt${n} -days 900 \ + -in altname${n}.csr -out altname${n}.cert +done # generate a PKCS12 cert from the client cert: -passOUT because it's the # passphrase on the OUTPUT cert, confusing... diff --git a/test/openssl.conf b/test/openssl.conf index 9180b49..b8f2fd0 100644 --- a/test/openssl.conf +++ b/test/openssl.conf @@ -32,7 +32,7 @@ basicConstraints = CA:true basicConstraints = CA:false # subjectAltName extension sections -[altExt] +[altExt1] subjectAltName = DNS:localhost # 2+3: AltNames with multiple entries to test the matching logic @@ -47,6 +47,10 @@ subjectAltName = DNS:localhost, DNS:nohost.example.com [altExt4] subjectAltName = email:neon@webdav.org +# an AltName with IP address +[altExt5] +subjectAltName = IP:127.0.0.1 + [reqDN] countryName = Country Name stateOrProvinceName = State or Province Name diff --git a/test/socket.c b/test/socket.c index 26b107b..58c5a6e 100644 --- a/test/socket.c +++ b/test/socket.c @@ -858,6 +858,10 @@ static int write_reset(void) CALL(full_write(sock, "a", 1)); CALL(await_server()); ret = ne_sock_fullwrite(sock, "a", 1); + if (ret == 0) { + ne_sock_close(sock); + return SKIP; + } ONV(ret != NE_SOCK_RESET, ("write got %d not reset", ret)); return good_close(sock); } @@ -870,6 +874,10 @@ static int read_reset(void) CALL(full_write(sock, "a", 1)); CALL(await_server()); ret = ne_sock_read(sock, buffer, 1); + if (ret == NE_SOCK_CLOSED) { + ne_sock_close(sock); + return SKIP; + } ONV(ret != NE_SOCK_RESET, ("read got %" NE_FMT_SSIZE_T " not reset", ret)); return good_close(sock); } @@ -365,15 +365,21 @@ static int load_client_cert(void) /* Test that 'cert', which is signed by CA_CERT, is accepted * unconditionaly. */ -static int accept_signed_cert(char *cert) +static int accept_signed_cert_for_hostname(char *cert, const char *hostname) { - ne_session *sess = DEFSESS; + ne_session *sess = ne_session_create("https", hostname, 7777); /* no verify callback needed. */ CALL(any_ssl_request(sess, serve_ssl, cert, CA_CERT, NULL, NULL)); ne_session_destroy(sess); return OK; } + +static int accept_signed_cert(char *cert) +{ + return accept_signed_cert_for_hostname(cert, "localhost"); +} + static int simple(void) { return accept_signed_cert(SERVER_CERT); @@ -506,7 +512,7 @@ static int caseless_match(void) * commonName attribute */ static int subject_altname(void) { - return accept_signed_cert("altname.cert"); + return accept_signed_cert("altname1.cert"); } /* tests for multiple altNames. */ @@ -527,6 +533,11 @@ static int notdns_altname(void) return accept_signed_cert("altname4.cert"); } +static int ipaddr_altname(void) +{ + return accept_signed_cert_for_hostname("altname5.cert", "127.0.0.1"); +} + /* test that the *most specific* commonName attribute is used. */ static int multi_commonName(void) { @@ -1121,7 +1132,7 @@ static int cert_identities(void) const char *fname, *identity; } certs[] = { { "twocn.cert", "localhost" }, - { "altname.cert", "localhost" }, + { "altname1.cert", "localhost" }, { "altname2.cert", "nohost.example.com" }, { "altname4.cert", "localhost" }, { "ca4.pem", "fourth.example.com" }, @@ -1455,6 +1466,7 @@ ne_test tests[] = { T(two_subject_altname), T(two_subject_altname2), T(notdns_altname), + T(ipaddr_altname), T(multi_commonName), T(commonName_first), |