--- /dev/null
+/*
+ * sslProt.cpp - test SSL protocol negotiation, client and server side
+ *
+ * This executes a preposterously exhaustive set of client/server runs
+ * in which just about every permutation of server and client
+ * protocol enables (using both SSLSetProtocolVersionEnabled and
+ * SSLSetProtocolVersion) is examined. Resulting negotiated protocols
+ * and error returns are verified.
+ *
+ * There are three different basic negotiation scenarios:
+ *
+ * -- Normal case, server and client agree.
+ *
+ * -- Server detects negotiation error. This can happen in two ways:
+ * -- server doesn't allow SSL3 or TLS1 but gets an SSL3 client hello
+ * (regardless of the requested protocol version in the packet)
+ * -- server gets a client hello containing a protocol version
+ * when the server supports neither that version not any
+ * version below that. For example, server allows TLS1 only and
+ * gets an SSL3 hello with requested version SSL3.
+ *
+ * -- Client detects negotiation error. In this case the server hello
+ * contains a different version than the client hello (I.e., server
+ * downgraded), but the client doesn't support the version the
+ * server requested.
+ *
+ * In both of the failure cases, the peer which detects the error
+ * drops the connection and returns errSSLNegotiation from its
+ * SSLHandshake() call. The other peer sees a dropped connection
+ * and returns errSSLClosedAbort from its SSLHandshake() call.
+ * IN both cases, the negotiated protocol seen by the client is
+ * kSSLProtocolUnknown. However when the client detects the error, the
+ * server will see a valid negotiated protocol containing whatever it
+ * sent to the client in its server hello message.
+ */
+#include <Security/SecureTransport.h>
+#include <Security/Security.h>
+#include <clAppUtils/sslAppUtils.h>
+#include <clAppUtils/ioSock.h>
+#include <clAppUtils/sslThreading.h>
+#include <security_cdsa_utils/cuFileIo.h>
+#include <utilLib/common.h>
+#include <security_cdsa_utils/cuPrintCert.h>
+#include <security_utilities/threading.h>
+#include <security_utilities/devrandom.h>
+#include "dhParams512.h"
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+#include <ctype.h>
+#include <sys/param.h>
+
+#define STARTING_PORT 3000
+
+/*
+ * localcert is a KC containing server cert and signing key
+ * assumptions:
+ * -- common name = "localcert"
+ * -- password of KC = "localcert"
+ */
+#define SERVER_KC "localcert"
+#define SERVER_ROOT "localcert.cer"
+
+/* main() fills this in using sslKeychainPath() */
+static char serverKcPath[MAXPATHLEN];
+
+static void usage(char **argv)
+{
+ printf("Usage: %s [options]\n", argv[0]);
+ printf("options:\n");
+ printf(" q(uiet)\n");
+ printf(" v(erbose)\n");
+ printf(" d (Diffie-Hellman, no keychain needed)\n");
+ printf(" p=startingPortNum\n");
+ printf(" t=startTestNum\n");
+ printf(" b (non blocking I/O)\n");
+ printf(" s=serverCertName; default %s\n", SERVER_ROOT);
+ printf(" R (ringBuffer I/O)\n");
+ exit(1);
+}
+
+/*
+ * Parameters defining one run
+ */
+typedef struct {
+ const char *groupDesc; // optional
+ const char *testDesc; // required
+ bool noServeProt; // don't set server protocol version
+ SSLProtocol servTryVersion;
+ const char *serveAcceptProts; // use TryVersion if this is NULL
+ SSLProtocol expectServerProt; // expected negotiated result
+ OSStatus serveStatus; // expected OSStatus
+ bool noClientProt; // don't set client protocol version
+ SSLProtocol clientTryVersion;
+ const char *clientAcceptProts;
+ SSLProtocol expectClientProt;
+ OSStatus clientStatus;
+ bool serverAbort; // allows server to close connection early
+} SslProtParams;
+
+SslProtParams protTestParams[] =
+{
+/*
+ * FIXME this fails to compile to to radar 4104919. I really don't want to
+ * remove these pragmas unless/until I hear a positive confirmation that that
+ * Radar is not to be fixed.
+ */
+// #pragma mark Unrestricted server via SSLSetProtocolVersion
+ {
+ "unrestricted server via SSLSetProtocolVersion",
+ "client SSLSetProtocolVersion(TLS1)",
+ false, kTLSProtocol1, NULL, kTLSProtocol1, noErr,
+ false, kTLSProtocol1, NULL, kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(TLS1 only)",
+ false, kTLSProtocol1, NULL, kTLSProtocol1, noErr,
+ false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL3)",
+ false, kTLSProtocol1, NULL, kSSLProtocol3, noErr,
+ false, kSSLProtocol3, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL3 only)",
+ false, kTLSProtocol1, NULL, kSSLProtocol3, noErr,
+ false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL2)",
+ false, kTLSProtocol1, NULL, kSSLProtocol2, noErr,
+ false, kSSLProtocol2, NULL, kSSLProtocol2, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(t)",
+ false, kTLSProtocol1, NULL, kTLSProtocol1, noErr,
+ false, kTLSProtocol1, "t", kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(3t)",
+ false, kTLSProtocol1, NULL, kTLSProtocol1, noErr,
+ false, kTLSProtocol1, "3t", kTLSProtocol1, noErr, false
+ },
+ /* make sure default client is the same as "3t" - Radar 4233139 -
+ * SSLv3 no longer enabled by default */
+ {
+ NULL, "client default",
+ false, kTLSProtocol1, NULL, kTLSProtocol1, noErr,
+ true, kSSLProtocolUnknown, NULL, kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(23t)",
+ false, kTLSProtocol1, NULL, kTLSProtocol1, noErr,
+ false, kTLSProtocol1, "23t", kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(3)",
+ false, kTLSProtocol1, NULL, kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "3", kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(23)",
+ false, kTLSProtocol1, NULL, kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "23", kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(2)",
+ false, kTLSProtocol1, NULL, kSSLProtocol2, noErr,
+ false, kTLSProtocol1, "2", kSSLProtocol2, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(2t)",
+ false, kTLSProtocol1, NULL, kTLSProtocol1, noErr,
+ false, kTLSProtocol1, "2t", kTLSProtocol1, noErr, false
+ },
+
+ // #pragma mark === Server SSLSetProtocolVersion(TLS1 only)
+ {
+ "server SSLSetProtocolVersion(TLS1 only)",
+ "client SSLSetProtocolVersion(TLS1)",
+ false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr,
+ false, kTLSProtocol1, NULL, kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(TLS1 only)",
+ false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr,
+ false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL3)",
+ false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLNegotiation,
+ false, kSSLProtocol3, NULL, kSSLProtocolUnknown, errSSLClosedAbort,
+ false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL3 only)",
+ false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLNegotiation,
+ false, kSSLProtocol3Only, NULL, kSSLProtocolUnknown, errSSLConnectionRefused,
+ true
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL2)",
+ false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLNegotiation,
+ false, kSSLProtocol2, NULL, kSSLProtocolUnknown, errSSLClosedAbort,
+ true
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(t)",
+ false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr,
+ false, kTLSProtocol1, "t", kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(3t)",
+ false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr,
+ false, kTLSProtocol1, "3t", kTLSProtocol1, noErr, false
+ },
+ /* make sure default client is the same as "3t" */
+ {
+ NULL, "client default",
+ false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr,
+ true, kSSLProtocolUnknown, NULL, kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(23t)",
+ false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr,
+ false, kTLSProtocol1, "23t", kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(3)",
+ false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLNegotiation,
+ false, kTLSProtocol1, "3", kSSLProtocolUnknown, errSSLConnectionRefused,
+ true
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(23)",
+ false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLNegotiation,
+ false, kTLSProtocol1, "23", kSSLProtocolUnknown, errSSLClosedAbort,
+ true
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(2)",
+ false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLNegotiation,
+ false, kTLSProtocol1, "2", kSSLProtocolUnknown, errSSLClosedAbort,
+ true
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(2t)",
+ false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr,
+ false, kTLSProtocol1, "2t", kTLSProtocol1, noErr, false
+ },
+
+ // #pragma mark === Server SSLSetProtocolVersion(SSL3)
+ {
+ "server SSLSetProtocolVersion(SSL3)",
+ "client SSLSetProtocolVersion(TLS1)",
+ false, kSSLProtocol3, NULL, kSSLProtocol3, noErr,
+ false, kTLSProtocol1, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(TLS1 only)",
+ /* negotiation error detected by client, not server */
+ false, kSSLProtocol3, NULL, kSSLProtocol3, errSSLClosedAbort,
+ false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLNegotiation,
+ false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL3)",
+ false, kSSLProtocol3, NULL, kSSLProtocol3, noErr,
+ false, kSSLProtocol3, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL3 only)",
+ false, kSSLProtocol3, NULL, kSSLProtocol3, noErr,
+ false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL2)",
+ false, kSSLProtocol3, NULL, kSSLProtocol3, noErr,
+ false, kSSLProtocol3, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(t)",
+ false, kSSLProtocol3, NULL, kSSLProtocol3, errSSLClosedAbort,
+ false, kTLSProtocol1, "t", kSSLProtocolUnknown, errSSLNegotiation,
+ false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(3t)",
+ false, kSSLProtocol3, NULL, kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "3t", kSSLProtocol3, noErr, false
+ },
+ /* make sure default client is the same as "3t" */
+ {
+ NULL, "client default",
+ false, kSSLProtocol3, NULL, kSSLProtocol3, noErr,
+ true, kSSLProtocolUnknown, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(23t)",
+ false, kSSLProtocol3, NULL, kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "23t", kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(3)",
+ false, kSSLProtocol3, NULL, kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "3", kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(23)",
+ false, kSSLProtocol3, NULL, kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "23", kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(2)",
+ false, kSSLProtocol3, NULL, kSSLProtocol2, noErr,
+ false, kTLSProtocol1, "2", kSSLProtocol2, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(2t)",
+ false, kSSLProtocol3, NULL, kSSLProtocol2, noErr,
+ false, kTLSProtocol1, "2", kSSLProtocol2, noErr, false
+ },
+
+ // #pragma mark === Server SSLSetProtocolVersion(SSL3 only)
+ {
+ "server SSLSetProtocolVersion(SSL3 only)",
+ "client SSLSetProtocolVersion(TLS1)",
+ false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr,
+ false, kTLSProtocol1, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(TLS1 only)",
+ /* negotiation error detected by client, not server */
+ false, kSSLProtocol3Only, NULL, kSSLProtocol3, errSSLClosedAbort,
+ false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLNegotiation,
+ false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL3)",
+ false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr,
+ false, kSSLProtocol3, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL3 only)",
+ false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr,
+ false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL2)",
+ false, kSSLProtocol3Only, NULL, kSSLProtocolUnknown, errSSLNegotiation,
+ false, kSSLProtocol2, NULL, kSSLProtocolUnknown, errSSLClosedAbort,
+ true
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(t)",
+ false, kSSLProtocol3Only, NULL, kSSLProtocol3, errSSLClosedAbort,
+ false, kTLSProtocol1, "t", kSSLProtocolUnknown, errSSLNegotiation,
+ false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(3t)",
+ false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "3t", kSSLProtocol3, noErr, false
+ },
+ /* make sure default client is the same as "3t" */
+ {
+ NULL, "client default",
+ false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr,
+ true, kSSLProtocolUnknown, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(23t)",
+ false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "23t", kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(3)",
+ false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "3", kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(23)",
+ false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "23", kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(2)",
+ false, kSSLProtocol3Only, NULL, kSSLProtocolUnknown, errSSLNegotiation,
+ false, kTLSProtocol1, "2", kSSLProtocolUnknown, errSSLClosedAbort,
+ false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(2t)",
+ false, kSSLProtocol3Only, NULL, kSSLProtocol3, errSSLClosedAbort,
+ false, kTLSProtocol1, "2t", kSSLProtocolUnknown, errSSLNegotiation,
+ false
+ },
+
+ // #pragma mark === Server SSLSetProtocolVersion(SSL2)
+ {
+ "server SSLSetProtocolVersion(SSL2)",
+ "client SSLSetProtocolVersion(TLS1)",
+ false, kSSLProtocol2, NULL, kSSLProtocol2, noErr,
+ false, kTLSProtocol1, NULL, kSSLProtocol2, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(TLS1 only)",
+ /* server won't even accept the non-SSL2 hello */
+ false, kSSLProtocol2, NULL, kSSLProtocolUnknown, errSSLNegotiation,
+ false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLConnectionRefused,
+ true
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL3)",
+ false, kSSLProtocol2, NULL, kSSLProtocol2, noErr,
+ false, kSSLProtocol3, NULL, kSSLProtocol2, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL3 only)",
+ false, kSSLProtocol2, NULL, kSSLProtocolUnknown, errSSLNegotiation,
+ false, kSSLProtocol3Only, NULL, kSSLProtocolUnknown, errSSLConnectionRefused,
+ true
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL2)",
+ false, kSSLProtocol2, NULL, kSSLProtocol2, noErr,
+ false, kSSLProtocol2, NULL, kSSLProtocol2, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(t)",
+ false, kSSLProtocol2, NULL, kSSLProtocolUnknown, errSSLNegotiation,
+ false, kTLSProtocol1, "t", kSSLProtocolUnknown, errSSLConnectionRefused,
+ true
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(3t)",
+ false, kSSLProtocol2, NULL, kSSLProtocolUnknown, errSSLNegotiation,
+ false, kTLSProtocol1, "3t", kSSLProtocolUnknown, errSSLConnectionRefused,
+ true
+ },
+ /* make sure default client is the same as "3t" */
+ {
+ NULL, "client default",
+ false, kSSLProtocol2, NULL, kSSLProtocolUnknown, errSSLNegotiation,
+ true, kSSLProtocolUnknown, NULL, kSSLProtocolUnknown, errSSLConnectionRefused,
+ true
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(23t)",
+ false, kSSLProtocol2, NULL, kSSLProtocol2, noErr,
+ false, kTLSProtocol1, "23t", kSSLProtocol2, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(3)",
+ false, kSSLProtocol2, NULL, kSSLProtocolUnknown, errSSLNegotiation,
+ false, kTLSProtocol1, "3", kSSLProtocolUnknown, errSSLConnectionRefused,
+ true
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(23)",
+ false, kSSLProtocol2, NULL, kSSLProtocol2, noErr,
+ false, kTLSProtocol1, "23", kSSLProtocol2, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(2)",
+ false, kSSLProtocol2, NULL, kSSLProtocol2, noErr,
+ false, kTLSProtocol1, "2", kSSLProtocol2, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(2t)",
+ false, kSSLProtocol2, NULL, kSSLProtocol2, noErr,
+ false, kTLSProtocol1, "2t", kSSLProtocol2, noErr, false
+ },
+
+ //#pragma mark === Unrestricted server via SSLSetProtocolVersionEnabled
+ {
+ "unrestricted server via SSLSetProtocolVersionEnabled",
+ "client SSLSetProtocolVersion(TLS1)",
+ false, kTLSProtocol1, "23t", kTLSProtocol1, noErr,
+ false, kTLSProtocol1, NULL, kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(TLS1 only)",
+ false, kTLSProtocol1, "23t", kTLSProtocol1, noErr,
+ false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL3)",
+ false, kTLSProtocol1, "23t", kSSLProtocol3, noErr,
+ false, kSSLProtocol3, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL3 only)",
+ false, kTLSProtocol1, "23t", kSSLProtocol3, noErr,
+ false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL2)",
+ false, kTLSProtocol1, "23t", kSSLProtocol2, noErr,
+ false, kSSLProtocol2, NULL, kSSLProtocol2, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(t)",
+ false, kTLSProtocol1, "23t", kTLSProtocol1, noErr,
+ false, kTLSProtocol1, "t", kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(3t)",
+ false, kTLSProtocol1, "23t", kTLSProtocol1, noErr,
+ false, kTLSProtocol1, "3t", kTLSProtocol1, noErr
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(23t)",
+ false, kTLSProtocol1, "23t", kTLSProtocol1, noErr,
+ false, kTLSProtocol1, "23t", kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(3)",
+ false, kTLSProtocol1, "23t", kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "3", kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(23)",
+ false, kTLSProtocol1, "23t", kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "23", kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(2)",
+ false, kTLSProtocol1, "23t", kSSLProtocol2, noErr,
+ false, kTLSProtocol1, "2", kSSLProtocol2, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(2t)",
+ false, kTLSProtocol1, "23t", kTLSProtocol1, noErr,
+ false, kTLSProtocol1, "2t", kTLSProtocol1, noErr, false
+ },
+
+ // #pragma mark === Server SSLSetProtocolVersionEnabled(t)
+
+ {
+ "server SSLSetProtocolVersionEnabled(t)",
+ "client SSLSetProtocolVersion(TLS1)",
+ false, kTLSProtocol1, "t", kTLSProtocol1, noErr,
+ false, kTLSProtocol1, NULL, kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(TLS1 only)",
+ false, kTLSProtocol1, "t", kTLSProtocol1, noErr,
+ false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL3)",
+ false, kTLSProtocol1, "t", kSSLProtocolUnknown, errSSLNegotiation,
+ false, kSSLProtocol3, NULL, kSSLProtocolUnknown, errSSLClosedAbort, true
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL3 only)",
+ false, kTLSProtocol1, "t", kSSLProtocolUnknown, errSSLNegotiation,
+ false, kSSLProtocol3Only, NULL, kSSLProtocolUnknown, errSSLConnectionRefused, true
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL2)",
+ false, kTLSProtocol1, "t", kSSLProtocolUnknown, errSSLNegotiation,
+ false, kSSLProtocol2, NULL, kSSLProtocolUnknown, errSSLClosedAbort, true
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(t)",
+ false, kTLSProtocol1, "t", kTLSProtocol1, noErr,
+ false, kTLSProtocol1, "t", kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(3t)",
+ false, kTLSProtocol1, "t", kTLSProtocol1, noErr,
+ false, kTLSProtocol1, "3t", kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(23t)",
+ false, kTLSProtocol1, "t", kTLSProtocol1, noErr,
+ false, kTLSProtocol1, "23t", kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(3)",
+ false, kTLSProtocol1, "t", kSSLProtocolUnknown, errSSLNegotiation,
+ false, kTLSProtocol1, "3", kSSLProtocolUnknown, errSSLConnectionRefused,
+ true
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(23)",
+ false, kTLSProtocol1, "t", kSSLProtocolUnknown, errSSLNegotiation,
+ false, kTLSProtocol1, "23", kSSLProtocolUnknown, errSSLClosedAbort,
+ true
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(2)",
+ false, kTLSProtocol1, "t", kSSLProtocolUnknown, errSSLNegotiation,
+ false, kTLSProtocol1, "2", kSSLProtocolUnknown, errSSLClosedAbort,
+ true
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(2t)",
+ false, kTLSProtocol1, "t", kTLSProtocol1, noErr,
+ false, kTLSProtocol1, "2t", kTLSProtocol1, noErr, false
+ },
+
+ // #pragma mark === Server SSLSetProtocolVersionEnabled(23)
+ {
+ "server SSLSetProtocolVersionEnabled(23)",
+ "client SSLSetProtocolVersion(TLS1)",
+ false, kSSLProtocol2, "23", kSSLProtocol3, noErr,
+ false, kTLSProtocol1, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(TLS1 only)",
+ /* negotiation error detected by client, not server */
+ false, kSSLProtocol2, "23", kSSLProtocol3, errSSLClosedAbort,
+ false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLNegotiation, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL3)",
+ false, kSSLProtocol2, "23", kSSLProtocol3, noErr,
+ false, kSSLProtocol3, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL3 only)",
+ false, kSSLProtocol2, "23", kSSLProtocol3, noErr,
+ false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL2)",
+ false, kSSLProtocol2, "23", kSSLProtocol3, noErr,
+ false, kSSLProtocol3, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(t)",
+ false, kSSLProtocol2, "23", kSSLProtocol3, errSSLClosedAbort,
+ false, kTLSProtocol1, "t", kSSLProtocolUnknown, errSSLNegotiation, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(3t)",
+ false, kSSLProtocol2, "23", kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "3t", kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(23t)",
+ false, kSSLProtocol2, "23", kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "23t", kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(3)",
+ false, kSSLProtocol2, "23", kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "3", kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(23)",
+ false, kSSLProtocol2, "23", kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "23", kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(2)",
+ false, kSSLProtocol2, "23", kSSLProtocol2, noErr,
+ false, kTLSProtocol1, "2", kSSLProtocol2, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(2t)",
+ false, kSSLProtocol2, "23", kSSLProtocol2, noErr,
+ false, kTLSProtocol1, "2", kSSLProtocol2, noErr, false
+ },
+
+ // #pragma mark === Server SSLSetProtocolVersionEnabled(3)
+ {
+ "server SSLSetProtocolVersionEnabled(3)",
+ "client SSLSetProtocolVersion(TLS1)",
+ false, kSSLProtocol2, "3", kSSLProtocol3, noErr,
+ false, kTLSProtocol1, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(TLS1 only)",
+ /* negotiation error detected by client, not server */
+ false, kSSLProtocol2, "3", kSSLProtocol3, errSSLClosedAbort,
+ false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLNegotiation, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL3)",
+ false, kSSLProtocol2, "3", kSSLProtocol3, noErr,
+ false, kSSLProtocol3, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL3 only)",
+ false, kSSLProtocol2, "3", kSSLProtocol3, noErr,
+ false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL2)",
+ false, kSSLProtocol2, "3", kSSLProtocolUnknown, errSSLNegotiation,
+ false, kSSLProtocol2, NULL, kSSLProtocolUnknown, errSSLClosedAbort, true
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(t)",
+ false, kSSLProtocol2, "3", kSSLProtocol3, errSSLClosedAbort,
+ false, kTLSProtocol1, "t", kSSLProtocolUnknown, errSSLNegotiation, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(3t)",
+ false, kSSLProtocol2, "3", kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "3t", kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(23t)",
+ false, kSSLProtocol2, "3", kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "23t", kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(3)",
+ false, kSSLProtocol2, "3", kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "3", kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(23)",
+ false, kSSLProtocol2, "3", kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "23", kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(2)",
+ false, kSSLProtocol2, "3", kSSLProtocolUnknown, errSSLNegotiation,
+ false, kTLSProtocol1, "2", kSSLProtocolUnknown, errSSLClosedAbort, true
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(2t)",
+ false, kSSLProtocol2, "3", kSSLProtocol3, errSSLClosedAbort,
+ false, kTLSProtocol1, "2t", kSSLProtocolUnknown, errSSLNegotiation, false
+ },
+
+ /*
+ * This is the real difference between
+ * SSLSetProtocolVersionEnabled and SSLSetProtocolVersion
+ */
+ // #pragma mark === Server SSLSetProtocolVersionEnabled(3t)
+ {
+ "server SSLSetProtocolVersionEnabled(3t)",
+ "client SSLSetProtocolVersion(TLS1)",
+ false, kSSLProtocol2, "t3", kTLSProtocol1, noErr,
+ false, kTLSProtocol1, NULL, kTLSProtocol1, noErr, false
+ },
+ /* make sure default server is the same as "t3" */
+ {
+ NULL,
+ "client SSLSetProtocolVersion(TLS1), server default",
+ true, kSSLProtocolUnknown, NULL, kTLSProtocol1, noErr,
+ false, kTLSProtocol1, NULL, kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(TLS1 only)",
+ false, kSSLProtocol2, "t3", kTLSProtocol1, noErr,
+ false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL3)",
+ false, kSSLProtocol2, "t3", kSSLProtocol3, noErr,
+ false, kSSLProtocol3, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL3 only)",
+ false, kSSLProtocol2, "t3", kSSLProtocol3, noErr,
+ false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersion(SSL2)",
+ false, kSSLProtocol2, "t3", kSSLProtocolUnknown, errSSLNegotiation,
+ false, kSSLProtocol2, NULL, kSSLProtocolUnknown, errSSLClosedAbort, true
+ },
+ /* make sure default server is the same as "t3" */
+ {
+ NULL, "client SSLSetProtocolVersion(SSL2), server default",
+ true, kSSLProtocolUnknown, NULL, kSSLProtocolUnknown, errSSLNegotiation,
+ false, kSSLProtocol2, NULL, kSSLProtocolUnknown, errSSLClosedAbort, true
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(t)",
+ false, kSSLProtocol2, "t3", kTLSProtocol1, noErr,
+ false, kTLSProtocol1, "t", kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(3t)",
+ false, kSSLProtocol2, "t3", kTLSProtocol1, noErr,
+ false, kTLSProtocol1, "3t", kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(23t)",
+ false, kSSLProtocol2, "t3", kTLSProtocol1, noErr,
+ false, kTLSProtocol1, "23t", kTLSProtocol1, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(3)",
+ false, kSSLProtocol2, "t3", kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "3", kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(23)",
+ false, kSSLProtocol2, "t3", kSSLProtocol3, noErr,
+ false, kTLSProtocol1, "23", kSSLProtocol3, noErr, false
+ },
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(2)",
+ false, kSSLProtocol2, "t3", kSSLProtocolUnknown, errSSLNegotiation,
+ false, kTLSProtocol1, "2", kSSLProtocolUnknown, errSSLClosedAbort, true
+ },
+ /* make sure default server is the same as "t3" */
+ {
+ NULL, "client SSLSetProtocolVersionEnabled(2)",
+ false, kSSLProtocol2, "t3", kSSLProtocolUnknown, errSSLNegotiation,
+ false, kTLSProtocol1, "2", kSSLProtocolUnknown, errSSLClosedAbort, true
+ },
+ {
+ "server default", "client SSLSetProtocolVersionEnabled(2t)",
+ true, kSSLProtocolUnknown, NULL, kTLSProtocol1, noErr,
+ false, kTLSProtocol1, "2t", kTLSProtocol1, noErr, false
+ },
+};
+
+#define NUM_SSL_PROT_TESTS (sizeof(protTestParams) / sizeof(protTestParams[0]))
+
+#define IGNORE_SIGPIPE 1
+#if IGNORE_SIGPIPE
+#include <signal.h>
+
+void sigpipe(int sig)
+{
+}
+#endif /* IGNORE_SIGPIPE */
+
+#define CERT_VFY_DISABLE false
+
+/*
+ * Default params for each test. Main() will make a copy of this and
+ * adjust its copy on a per-test basis.
+ */
+SslAppTestParams serverDefaults =
+{
+ "no name here",
+ false, // skipHostNameCHeck
+ 0, // port - test must set this
+ NULL, NULL, // RingBuffers
+ false, // noProtSpec
+ kTLSProtocol1,
+ NULL, // acceptedProts
+ serverKcPath, // myCerts
+ SERVER_KC, // password
+ true, // idIsTrustedRoot
+ CERT_VFY_DISABLE, // disableCertVerify
+ NULL, // anchorFile
+ false, // replaceAnchors
+ kNeverAuthenticate,
+ false, // resumeEnable
+ NULL, // ciphers,
+ false, // nonBlocking
+ NULL, // dhParams
+ 0, // dhParamsLen
+ noErr, // expectRtn
+ kTLSProtocol1, // expectVersion
+ kSSLClientCertNone,
+ SSL_CIPHER_IGNORE,
+ false, // quiet
+ false, // silent
+ false, // verbose
+ {0}, // lock
+ {0}, // cond
+ false, // serverReady
+ 0, // clientDone
+ false, // serverAbort
+ /* returned */
+ kSSLProtocolUnknown,
+ SSL_NULL_WITH_NULL_NULL,
+ kSSLClientCertNone,
+ noHardwareErr
+
+};
+
+SslAppTestParams clientDefaults =
+{
+ "localhost",
+ false, // skipHostNameCHeck
+ 0, // port - test must set this
+ NULL, NULL, // RingBuffers
+ false, // noProtSpec
+ kTLSProtocol1,
+ NULL, // acceptedProts
+ NULL, // myCertKcName
+ NULL, // password
+ false, // idIsTrustedRoot
+ CERT_VFY_DISABLE, // disableCertVerify
+ SERVER_ROOT, // anchorFile
+ false, // replaceAnchors
+ kNeverAuthenticate,
+ false, // resumeEnable
+ NULL, // ciphers
+ false, // nonBlocking
+ NULL, // dhParams
+ 0, // dhParamsLen
+ noErr, // expectRtn
+ kTLSProtocol1, // expectVersion
+ kSSLClientCertNone,
+ SSL_CIPHER_IGNORE,
+ false, // quiet
+ false, // silent
+ false, // verbose
+ {0}, // lock
+ {0}, // cond
+ false, // serverReady
+ 0, // clientDone
+ false, // serverAbort
+ /* returned */
+ kSSLProtocolUnknown,
+ SSL_NULL_WITH_NULL_NULL,
+ kSSLClientCertNone,
+ noHardwareErr
+};
+
+
+int main(int argc, char **argv)
+{
+ int ourRtn = 0;
+ char *argp;
+ SslAppTestParams clientParams;
+ SslAppTestParams serverParams;
+ unsigned short portNum = STARTING_PORT;
+ SslProtParams *protParams;
+ unsigned testNum;
+ int thisRtn;
+ unsigned startTest = 0;
+ SSLCipherSuite ciphers[2]; // for Diffie-Hellman
+ bool diffieHellman = false;
+ RingBuffer serverToClientRing;
+ RingBuffer clientToServerRing;
+ bool ringBufferIo = false;
+
+ for(int arg=1; arg<argc; arg++) {
+ argp = argv[arg];
+ switch(argp[0]) {
+ case 'q':
+ serverDefaults.quiet = clientDefaults.quiet = true;
+ break;
+ case 'v':
+ serverDefaults.verbose = clientDefaults.verbose = true;
+ break;
+ case 'p':
+ portNum = atoi(&argp[2]);
+ break;
+ case 't':
+ startTest = atoi(&argp[2]);
+ break;
+ case 'd':
+ diffieHellman = true;
+ break;
+ case 'b':
+ serverDefaults.nonBlocking = clientDefaults.nonBlocking =
+ true;
+ break;
+ case 's':
+ clientDefaults.anchorFile = &argp[2];
+ break;
+ case 'R':
+ ringBufferIo = true;
+ break;
+ default:
+ usage(argv);
+ }
+ }
+
+ if(sslCheckFile(clientDefaults.anchorFile)) {
+ exit(1);
+ }
+ if(ringBufferIo) {
+ /* set up ring buffers */
+ ringBufSetup(&serverToClientRing, "serveToClient", DEFAULT_NUM_RB_BUFS, DEFAULT_BUF_RB_SIZE);
+ ringBufSetup(&clientToServerRing, "clientToServe", DEFAULT_NUM_RB_BUFS, DEFAULT_BUF_RB_SIZE);
+ serverDefaults.serverToClientRing = &serverToClientRing;
+ serverDefaults.clientToServerRing = &clientToServerRing;
+ clientDefaults.serverToClientRing = &serverToClientRing;
+ clientDefaults.clientToServerRing = &clientToServerRing;
+ }
+
+ #if IGNORE_SIGPIPE
+ signal(SIGPIPE, sigpipe);
+ #endif
+
+ /* convert keychain names to paths for root */
+ sslKeychainPath(SERVER_KC, serverKcPath);
+
+ testStartBanner("sslProt", argc, argv);
+
+ serverParams.port = portNum - 1; // gets incremented by SSL_THR_SETUP
+ if(diffieHellman) {
+ ciphers[0] = SSL_DH_anon_WITH_RC4_128_MD5;
+ ciphers[1] = SSL_NO_SUCH_CIPHERSUITE;
+ serverDefaults.ciphers = ciphers;
+ serverDefaults.dhParams = dhParams512;
+ serverDefaults.dhParamsLen = sizeof(dhParams512);
+ serverDefaults.myCertKcName = NULL;
+ clientDefaults.anchorFile = NULL;
+ }
+ for(testNum=startTest; testNum<NUM_SSL_PROT_TESTS; testNum++) {
+ protParams = &protTestParams[testNum];
+
+ /*
+ * Hack for Diffie-Hellman: just skip any tests which attempt
+ * or expect SSL2 negotiation, since SSL2 doesn't have DH.
+ */
+ if(diffieHellman) {
+ if((protParams->servTryVersion == kSSLProtocol2) ||
+ (protParams->clientTryVersion == kSSLProtocol2) ||
+ (protParams->serveAcceptProts &&
+ !strcmp(protParams->serveAcceptProts, "2")) ||
+ (protParams->clientAcceptProts &&
+ !strcmp(protParams->clientAcceptProts, "2"))) {
+ if(serverDefaults.verbose) {
+ printf("...skipping %s for D-H\n",
+ protParams->testDesc);
+ }
+ continue;
+ }
+ }
+ if(protParams->groupDesc && !serverDefaults.quiet) {
+ printf("...%s\n", protParams->groupDesc);
+ }
+ SSL_THR_SETUP(serverParams, clientParams, clientDefaults,
+ serverDefault);
+ if(ringBufferIo) {
+ ringBufferReset(&serverToClientRing);
+ ringBufferReset(&clientToServerRing);
+ }
+ serverParams.tryVersion = protParams->servTryVersion;
+ clientParams.tryVersion = protParams->clientTryVersion;
+ serverParams.acceptedProts = protParams->serveAcceptProts;
+ clientParams.acceptedProts = protParams->clientAcceptProts;
+ serverParams.expectVersion = protParams->expectServerProt;
+ clientParams.expectVersion = protParams->expectClientProt;
+ serverParams.expectRtn = protParams->serveStatus;
+ clientParams.expectRtn = protParams->clientStatus;
+ serverParams.serverAbort = protParams->serverAbort;
+
+ SSL_THR_RUN_NUM(serverParams, clientParams, protParams->testDesc,
+ ourRtn, testNum);
+ }
+
+done:
+ if(!clientParams.quiet) {
+ if(ourRtn == 0) {
+ printf("===== sslProt test PASSED =====\n");
+ }
+ else {
+ printf("****FAIL: %d errors detected\n", ourRtn);
+ }
+ }
+
+ return ourRtn;
+}