⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssl.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 4 页
字号:
#else
			/* If we're using a dummy local socket, we'll get a R/W error at
			   this point since it's not connected to anything, so we
			   intercept it before it gets any further */
			if( status == CRYPT_ERROR_READ || status == CRYPT_ERROR_WRITE )
				{
				cryptDestroySession( cryptSession );
				return( TRUE );
				}
#endif /* __WINDOWS__ && !_WIN32_WCE */
			}
		if( sessionID != CRYPT_UNUSED )
			printf( "%02d: ", sessionID );
		sprintf( strBuffer, "%sAttempt to activate %s%s session",
				 isServer ? "SVR: " : "", localSession ? "local " : "",
				 versionStr[ version ] );
		printExtError( cryptSession, strBuffer, status, __LINE__ );
		cryptDestroySession( cryptSession );
		if( testType == SSL_TEST_BULKTRANSER )
			free( bulkBuffer );
		if( !isServer && \
			( status == CRYPT_ERROR_OPEN || status == CRYPT_ERROR_NOTFOUND ) )
			{
			/* These servers are constantly appearing and disappearing so if
			   we get a straight connect error we don't treat it as a serious
			   failure */
			puts( "  (Server could be down, faking it and continuing...)\n" );
			return( CRYPT_ERROR_FAILED );
			}
		if( testType == SSL_TEST_PSK_CLIONLY || \
			testType == SSL_TEST_PSK_SVRONLY )
			{
			/* The CLIONLY/SVRONLY test is supposed to fail, so if this
			   happens then the overall test has succeeded */
			puts( "  (This test checks error handling, so the failure "
				  "response is correct).\n" );
			return( TRUE );
			}
		return( FALSE );
		}
	else
		/* The CLIONLY/SVRONLY test is supposed to fail, if this doesn't
		   happen then there's a problem */
		if( testType == SSL_TEST_PSK_CLIONLY || \
			testType == SSL_TEST_PSK_SVRONLY )
			{
			printf( "%sTLS-PSK handshake without password should have "
					"failed but succeeded,\nline %d.\n",
					isServer ? "SVR: " : "", __LINE__  );
			return( FALSE );
			}

	/* Report the session security info */
	if( testType != SSL_TEST_MULTITHREAD && \
		!printSecurityInfo( cryptSession, isServer,
							( testType != SSL_TEST_PSK ) ) )
		return( FALSE );
	if( ( !localSession && !isServer ) ||
		( localSession && isServer && testType == SSL_TEST_CLIENTCERT ) )
		{
		CRYPT_CERTIFICATE cryptCertificate;

		status = cryptGetAttribute( cryptSession, CRYPT_SESSINFO_RESPONSE,
									&cryptCertificate );
		if( cryptStatusError( status ) )
			{
			printf( "%sCouldn't get %s certificate, status %d, line %d.\n",
					isServer ? "SVR: " : "", isServer ? "client" : "server",
					status, __LINE__ );
			return( FALSE );
			}
		puts( localSession ? "SVR: Client cert details are:" : \
							 "Server cert details are:" );
		printCertChainInfo( cryptCertificate );
		cryptDestroyCert( cryptCertificate );
		}
	if( isServer && testType == SSL_TEST_PSK )
		{
		C_CHR userNameBuffer[ CRYPT_MAX_TEXTSIZE + 1 ];
		int length;

		status = cryptGetAttributeString( cryptSession,
										  CRYPT_SESSINFO_USERNAME,
										  userNameBuffer, &length );
		if( cryptStatusError( status ) )
			{
			printf( "SVR: Couldn't read client user name, status %d, line "
					"%d.\n", status, __LINE__ );
			return( FALSE );
			}
#ifdef UNICODE_STRINGS
		userNameBuffer[ length / sizeof( wchar_t ) ] = TEXT( '\0' );
		printf( "SVR: Client user name = '%S'.\n", userNameBuffer );
#else
		userNameBuffer[ length ] = '\0';
		printf( "SVR: Client user name = '%s'.\n", userNameBuffer );
#endif /* UNICODE_STRINGS */
		}

	/* Send data over the SSL/TLS link.  If we're doing a bulk transfer
	   we use fully asynchronous I/O to verify the timeout handling in
	   the session code */
#if SSL_SERVER_NO == 3
	/* This server has a large amount of data on it, used to test high-
	   latency bulk transfers, so we set a larger timeout for the read */
	status = cryptSetAttribute( cryptSession, CRYPT_OPTION_NET_READTIMEOUT,
								15 );
#else
	status = cryptSetAttribute( cryptSession, CRYPT_OPTION_NET_READTIMEOUT,
								( testType == SSL_TEST_BULKTRANSER ) ? 0 : 5 );
#endif /* SSL_SERVER_NO == 3 */
	if( testType == SSL_TEST_BULKTRANSER )
		{
		if( isServer )
			{
			long byteCount = 0;

			do
				{
				status = cryptPushData( cryptSession, bulkBuffer + byteCount,
										BULKDATA_BUFFER_SIZE - byteCount,
										&bytesCopied );
				byteCount += bytesCopied;
				}
			while( ( cryptStatusOK( status ) || \
					 status == CRYPT_ERROR_TIMEOUT ) && \
				   byteCount < BULKDATA_BUFFER_SIZE );
			if( cryptStatusError( status ) )
				{
				printExtError( cryptSession,
							   "SVR: Send of bulk data to client", status,
							   __LINE__ );
				return( FALSE );
				}
			status = cryptFlushData( cryptSession );
			if( cryptStatusError( status ) )
				{
				printExtError( cryptSession,
							   "SVR: Flush of bulk data to client", status,
							   __LINE__ );
				return( FALSE );
				}
			if( byteCount != BULKDATA_BUFFER_SIZE )
				{
				printf( "Only sent %ld of %ld bytes, line %d.\n", byteCount,
						BULKDATA_BUFFER_SIZE, __LINE__ );
				return( FALSE );
				}
			}
		else
			{
			long byteCount = 0;

			do
				{
				status = cryptPopData( cryptSession, bulkBuffer + byteCount,
									   BULKDATA_BUFFER_SIZE - byteCount,
									   &bytesCopied );
				byteCount += bytesCopied;
				}
			while( ( cryptStatusOK( status ) || \
					 status == CRYPT_ERROR_TIMEOUT ) && \
				   byteCount < BULKDATA_BUFFER_SIZE );
			if( cryptStatusError( status ) )
				{
				char strBuffer[ 256 ];

				sprintf( strBuffer, "Read of bulk data from server aborted "
									"after %ld of %ld bytes were read\n(last "
									"read = %d bytes), transfer",
									byteCount, BULKDATA_BUFFER_SIZE,
									bytesCopied );
				printExtError( cryptSession, strBuffer, status, __LINE__ );
				return( FALSE );
				}
			if( byteCount != BULKDATA_BUFFER_SIZE )
				{
				printf( "Only received %ld of %ld bytes, line %d.\n", 
						byteCount, BULKDATA_BUFFER_SIZE, __LINE__ );
				return( FALSE );
				}
			if( !handleBulkBuffer( bulkBuffer, FALSE ) )
				{
				printf( "Received buffer contents don't match sent buffer "
						"contents, line %d.", __LINE__ );
				return( FALSE );
				}
			}

		free( bulkBuffer );
		}
	else
		/* It's a standard transfer, send/receive and HTTP request/response.
		   We clean up if we exit due to an error, if we're running a local
		   loopback test the client and server threads can occasionally lose
		   sync, which isn't a fatal error but can turn into a
		   CRYPT_ERROR_INCOMPLETE once all the tests are finished */
		if( isServer )
			{
#if defined( __MVS__ ) || defined( __VMCMS__ )
  #pragma convlit( resume )
#endif /* IBM big iron */
#if defined( __ILEC400__ )
  #pragma convert( 819 )
#endif /* IBM medium iron */
			const char serverReply[] = \
				"HTTP/1.0 200 OK\n"
				"Date: Fri, 7 June 2005 20:02:07 GMT\n"
				"Server: cryptlib SSL/TLS test\n"
				"Content-Type: text/html\n"
				"Connection: Close\n"
				"\n"
				"<!DOCTYPE HTML SYSTEM \"html.dtd\">\n"
				"<html>\n"
				"<head>\n"
				"<title>cryptlib SSL/TLS test page</title>\n"
				"<body>\n"
				"Test message from the cryptlib SSL/TLS server<p>\n"
				"</body>\n"
				"</html>\n";
#if defined( __MVS__ ) || defined( __VMCMS__ )
  #pragma convlit( suspend )
#endif /* IBM big iron */
#if defined( __ILEC400__ )
  #pragma convert( 0 )
#endif /* IBM medium iron */

			/* Print the text of the request from the client */
			status = cryptPopData( cryptSession, buffer, FILEBUFFER_SIZE,
								   &bytesCopied );
			if( cryptStatusError( status ) )
				{
				printExtError( cryptSession, "SVR: Attempt to read data "
							   "from client", status, __LINE__ );
				cryptDestroySession( cryptSession );
				return( FALSE );
				}
			buffer[ bytesCopied ] = '\0';
#if defined( __MVS__ ) || defined( __VMCMS__ )
			asciiToEbcdic( buffer, bytesCopied );
#endif /* EBCDIC systems */
			if( testType != SSL_TEST_MULTITHREAD )
				{
				printf( "---- Client sent %d bytes ----\n", bytesCopied );
				puts( buffer );
				puts( "---- End of output ----" );
				}

			/* Send a reply */
			status = cryptPushData( cryptSession, serverReply,
									sizeof( serverReply ) - 1, &bytesCopied );
			if( cryptStatusOK( status ) )
				status = cryptFlushData( cryptSession );
			if( cryptStatusError( status ) || \
				bytesCopied != sizeof( serverReply ) - 1 )
				{
				printExtError( cryptSession, "Attempt to send data to "
							   "client", status, __LINE__ );
				cryptDestroySession( cryptSession );
				return( FALSE );
				}

			/* Wait for the data to be flushed through to the client before
			   we close the session */
			delayThread( 1 );
			}
		else
			{
			char fetchString[ 128 ];
			int fetchStringLen;

			/* Send a fetch request to the server */
			if( testType == SSL_TEST_STARTTLS )
				{
				switch( protocol )
					{
					case PROTOCOL_SMTP:
						strcpy( fetchString, "EHLO foo.bar.com\r\n" );
						break;

					case PROTOCOL_POP:
						strcpy( fetchString, "CAPA\r\n" );
						break;

					case PROTOCOL_IMAP:
						strcpy( fetchString, "a003 CAPABILITY\r\n" );
						break;

					default:
						strcpy( fetchString, "USER test\r\n" );
					}
				}
			else
				{
				sprintf( fetchString, "GET %s HTTP/1.0\r\n\r\n",
						 sslInfo[ SSL_SERVER_NO ].path );
				}
			fetchStringLen = strlen( fetchString );
#if defined( __MVS__ ) || defined( __VMCMS__ )
			ebcdicToAscii( fetchString, fetchStringLen );
#endif /* EBCDIC systems */
			status = cryptPushData( cryptSession, fetchString,
									fetchStringLen, &bytesCopied );
			if( cryptStatusOK( status ) )
				status = cryptFlushData( cryptSession );
			if( cryptStatusError( status ) || bytesCopied != fetchStringLen )
				{
				printExtError( cryptSession, "Attempt to send data to "
							   "server", status, __LINE__ );
				cryptDestroySession( cryptSession );
				return( FALSE );
				}

			/* Print the text of the reply from the server */
			status = cryptPopData( cryptSession, buffer, FILEBUFFER_SIZE,
								   &bytesCopied );
			if( cryptStatusError( status ) )
				{
				printExtError( cryptSession, "Attempt to read data from "
							   "server", status, __LINE__ );
				cryptDestroySession( cryptSession );
				return( FALSE );
				}
			if( bytesCopied == 0 )
				{
				/* We've set a 5s timeout, we should get at least some
				   data */
				puts( "Server returned no data in response to our request." );
				cryptDestroySession( cryptSession );
				return( FALSE );
				}
			buffer[ min( bytesCopied, 4096 ) ] = '\0';
#if defined( __MVS__ ) || defined( __VMCMS__ )
			asciiToEbcdic( buffer, bytesCopied );
#endif /* EBCDIC systems */
			if( testType != SSL_TEST_MULTITHREAD )
				{
				printf( "---- Server sent %d bytes ----\n", bytesCopied );
				puts( buffer );
				if( bytesCopied > 4096 )
					printf( "  (Further %d bytes data omitted)\n", 
							bytesCopied - 4096 );
				puts( "---- End of output ----" );
				}

#if SSL_SERVER_NO == 3
			/* If we're reading a lot of data, more may have arrived in the
			   meantime */
			status = cryptPopData( cryptSession, buffer, FILEBUFFER_SIZE,
								   &bytesCopied );
			if( cryptStatusError( status ) )
				{
				if( status == CRYPT_ERROR_READ )
					/* Since this is HTTP, the other side can close the
					   connection with no further warning, even though SSL
					   says you shouldn't really do this */
					puts( "Remote system closed connection." );
				else
					{
					printExtError( cryptSession, "Attempt to read data from "
								   "server", status, __LINE__ );
					cryptDestroySession( cryptSession );
					return( FALSE );
					}
				}
			else
				{
				buffer[ bytesCopied ] = '\0';
#if defined( __MVS__ ) || defined( __VMCMS__ )
				asciiToEbcdic( buffer, bytesCopied );
#endif /* EBCDIC systems */
				if( testType != SSL_TEST_MULTITHREAD )
					{
					printf( "---- Server sent further %d bytes ----\n",
							bytesCopied );
					puts( buffer );
					puts( "---- End of output ----" );
					}
				}
#endif /* SSL_SERVER_NO == 3 */

			/* If it's a chatty protocol, exchange some more pleasantries */
			if( testType == SSL_TEST_STARTTLS )
				{
				if( protocol == PROTOCOL_SMTP )
					strcpy( fetchString, "QUIT\r\n" );
				else
					if( protocol == PROTOCOL_POP )
						strcpy( fetchString, "USER test\r\n" );
					else
						if( protocol == PROTOCOL_IMAP )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -