📄 testsess.c
字号:
const int trueVal = TRUE;
char buffer[ 2048 ];
int cryptAlgo, keySize, version, bytesCopied, timeout, status;
printf( "Testing %s%s%s session%s...\n", localSession ? "local " : "",
isSSL ? "SSL" : "TLS", isServer ? " server" : "",
useClientCert ? " with client certs" : "" );
/* Create the SSL/TLS session */
status = cryptCreateSession( &cryptSession, CRYPT_UNUSED, sessionType );
if( status == CRYPT_ERROR_PARAM3 ) /* SSL/TLS session access not available */
return( CRYPT_ERROR_NOTAVAIL );
if( cryptStatusError( status ) )
{
printf( "cryptCreateSession() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
if( !isSSL )
{
status = cryptSetAttribute( cryptSession,
CRYPT_SESSINFO_PROTOCOLVERSION,
CRYPT_PROTOCOLVERSION_TLS );
if( cryptStatusError( status ) )
{
printf( "cryptSetAttribute() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
}
/* Set up the server information and activate the session */
if( isServer )
{
CRYPT_CONTEXT privateKey;
if( !setLocalConnect( cryptSession, 443, TRUE ) )
return( FALSE );
status = getPrivateKey( &privateKey, SERVER_PRIVKEY_FILE,
USER_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD );
if( cryptStatusOK( status ) )
{
status = cryptSetAttribute( cryptSession,
CRYPT_SESSINFO_PRIVATEKEY, privateKey );
cryptDestroyContext( privateKey );
}
if( cryptStatusOK( status ) && useClientCert )
{
CRYPT_KEYSET cryptKeyset;
status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED,
DATABASE_KEYSET_TYPE, DATABASE_KEYSET_NAME,
CRYPT_KEYOPT_READONLY );
if( cryptStatusError( status ) )
{
printf( "Client cert keyset open failed with error code %d, "
"line %d.\n", status, __LINE__ );
return( FALSE );
}
status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_KEYSET,
cryptKeyset );
cryptKeysetClose( cryptKeyset );
}
}
else
{
if( localSession )
{
if( !setLocalConnect( cryptSession, 443, FALSE ) )
return( FALSE );
}
else
status = cryptSetAttributeString( cryptSession,
CRYPT_SESSINFO_SERVER_NAME, serverName,
strlen( serverName ) );
if( cryptStatusOK( status ) && useClientCert )
{
CRYPT_CONTEXT privateKey;
status = getPrivateKey( &privateKey, USER_PRIVKEY_FILE,
USER_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD );
if( cryptStatusOK( status ) )
{
status = cryptSetAttribute( cryptSession,
CRYPT_SESSINFO_PRIVATEKEY, privateKey );
cryptDestroyContext( privateKey );
}
}
}
if( cryptStatusError( status ) )
{
printf( "cryptSetAttribute/AttributeString() failed with error code "
"%d, line %d.\n", status, __LINE__ );
return( FALSE );
}
status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
if( isServer )
printConnectInfo( cryptSession );
if( cryptStatusError( status ) )
{
char strBuffer[ 128 ];
sprintf( strBuffer, "Attempt to activate %s%s session",
localSession ? "local " : "", isSSL ? "SSL" : "TLS" );
printExtError( cryptSession, strBuffer, status, __LINE__ );
cryptDestroySession( cryptSession );
if( status == CRYPT_ERROR_OPEN )
{
/* 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 );
}
return( FALSE );
}
/* Report the session security info details */
status = cryptGetAttribute( cryptSession, CRYPT_CTXINFO_ALGO,
&cryptAlgo );
if( cryptStatusOK( status ) )
status = cryptGetAttribute( cryptSession, CRYPT_CTXINFO_KEYSIZE,
&keySize );
if( cryptStatusOK( status ) )
status = cryptGetAttribute( cryptSession, CRYPT_SESSINFO_PROTOCOLVERSION,
&version );
if( cryptStatusError( status ) )
{
printf( "Couldn't query session details, status %d, line %d.\n",
status, __LINE__ );
return( status );
}
printf( "%s session is protected using algorithm %d with a %d bit key,\n"
" protocol version %d.\n", isServer ? "Server" : "Client",
cryptAlgo, keySize * 8, version );
if( !localSession && ( !isServer || useClientCert ) )
{
CRYPT_CERTIFICATE cryptCertificate;
status = cryptGetAttribute( cryptSession, CRYPT_SESSINFO_RESPONSE,
&cryptCertificate );
if( cryptStatusError( status ) )
{
printf( "Couldn't get %s certificate, status %d, line %d.\n",
isServer ? "client" : "server", status, __LINE__ );
return( status );
}
printCertChainInfo( cryptCertificate );
cryptDestroyCert( cryptCertificate );
}
/* Send data over the SSL/TLS link */
cryptGetAttribute( CRYPT_UNUSED, CRYPT_OPTION_NET_TIMEOUT, &timeout );
cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_NET_TIMEOUT, 5 );
if( isServer )
{
const char serverReply[] = \
"HTTP/1.0 200 OK\n"
"Date: Fri, 7 June 1999 20:02:07 GMT\n"
"Server: cryptlib SSL/TLS test\n"
"Content-Type: text/html\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";
/* Print the text of the request from the client */
status = cryptPopData( cryptSession, buffer, 2048, &bytesCopied );
if( cryptStatusError( status ) )
{
printf( "Couldn't read data from client, status %d, line %d.\n",
status, __LINE__ );
return( status );
}
buffer[ bytesCopied ] = '\0';
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 )
{
printf( "Couldn't send data to client, status %d, line %d.\n",
status, __LINE__ );
return( status );
}
}
else
{
/* Send a fetch request to the server */
status = cryptPushData( cryptSession, "GET / HTTP/1.0\n\n", 16,
&bytesCopied );
if( cryptStatusOK( status ) )
status = cryptFlushData( cryptSession );
if( cryptStatusError( status ) || bytesCopied != 16 )
{
printf( "Couldn't send data to server, status %d, line %d.\n",
status, __LINE__ );
return( status );
}
/* Print the text of the reply from the server */
status = cryptPopData( cryptSession, buffer, 2048, &bytesCopied );
if( cryptStatusError( status ) )
{
printf( "Couldn't read data from server, status %d, line %d.\n",
status, __LINE__ );
return( status );
}
buffer[ bytesCopied ] = '\0';
printf( "---- Server sent %d bytes ----\n", bytesCopied );
puts( buffer );
puts( "---- End of output ----" );
}
cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_NET_TIMEOUT, timeout );
/* Clean up */
status = cryptDestroySession( cryptSession );
if( cryptStatusError( status ) )
{
printf( "cryptDestroySession() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
printf( "%s %s session succeeded.\n\n", isSSL ? "SSL" : "TLS",
isServer ? "server" : "client" );
return( TRUE );
}
int testSessionSSL( void )
{
return( connectSSLTLS( CRYPT_SESSION_SSL, TRUE, FALSE, FALSE ) );
}
int testSessionSSLClientCert( void )
{
return( connectSSLTLS( CRYPT_SESSION_SSL, TRUE, TRUE, FALSE ) );
}
int testSessionTLS( void )
{
return( connectSSLTLS( CRYPT_SESSION_SSL, FALSE, FALSE, FALSE ) );
}
int testSessionSSLServer( void )
{
return( connectSSLTLS( CRYPT_SESSION_SSL_SERVER, TRUE, FALSE, FALSE ) );
}
int testSessionSSLServerClientCert( void )
{
return( connectSSLTLS( CRYPT_SESSION_SSL_SERVER, TRUE, TRUE, FALSE ) );
}
int testSessionTLSServer( void )
{
return( connectSSLTLS( CRYPT_SESSION_SSL_SERVER, FALSE, FALSE, FALSE ) );
}
/* Perform a local client/server test */
#ifdef WINDOWS_THREADS
unsigned __stdcall sslServerThread( void *dummy )
{
connectSSLTLS( CRYPT_SESSION_SSL_SERVER, TRUE, FALSE, TRUE );
_endthreadex( 0 );
return( 0 );
}
int testSessionSSLClientServer( void )
{
HANDLE hThread;
unsigned threadID;
int status;
/* Start the server and wait for it to initialise */
hThread = ( HANDLE ) _beginthreadex( NULL, 0, &sslServerThread,
NULL, 0, &threadID );
Sleep( 1000 );
/* Connect to the local server */
status = connectSSLTLS( CRYPT_SESSION_SSL, TRUE, FALSE, TRUE );
if( WaitForSingleObject( hThread, 15000 ) == WAIT_TIMEOUT )
{
puts( "Warning: Server thread is still active due to session "
"negotiation failure,\n this will cause an error "
"condition when cryptEnd() is called due\n to "
"resources remaining allocated. Press a key to continue." );
getchar();
}
CloseHandle( hThread );
return( status );
}
unsigned __stdcall sslClientCertServerThread( void *dummy )
{
connectSSLTLS( CRYPT_SESSION_SSL_SERVER, TRUE, TRUE, TRUE );
_endthreadex( 0 );
return( 0 );
}
int testSessionSSLClientCertClientServer( void )
{
HANDLE hThread;
unsigned threadID;
int status;
/* Start the server and wait for it to initialise */
hThread = ( HANDLE ) _beginthreadex( NULL, 0, &sslClientCertServerThread,
NULL, 0, &threadID );
Sleep( 1000 );
/* Connect to the local server */
status = connectSSLTLS( CRYPT_SESSION_SSL, TRUE, TRUE, TRUE );
if( WaitForSingleObject( hThread, 15000 ) == WAIT_TIMEOUT )
{
puts( "Warning: Server thread is still active due to session "
"negotiation failure,\n this will cause an error "
"condition when cryptEnd() is called due\n to "
"resources remaining allocated. Press a key to continue." );
getchar();
}
CloseHandle( hThread );
return( status );
}
unsigned __stdcall tlsServerThread( void *dummy )
{
connectSSLTLS( CRYPT_SESSION_SSL_SERVER, FALSE, FALSE, TRUE );
_endthreadex( 0 );
return( 0 );
}
int testSessionTLSClientServer( void )
{
HANDLE hThread;
unsigned threadID;
int status;
/* Start the server and wait for it to initialise */
hThread = ( HANDLE ) _beginthreadex( NULL, 0, &tlsServerThread,
NULL, 0, &threadID );
Sleep( 1000 );
/* Connect to the local server */
status = connectSSLTLS( CRYPT_SESSION_SSL, FALSE, FALSE, TRUE );
if( WaitForSingleObject( hThread, 15000 ) == WAIT_TIMEOUT )
{
puts( "Warning: Server thread is still active due to session "
"negotiation failure,\n this will cause an error "
"condition when cryptEnd() is called due\n to "
"resources remaining allocated. Press a key to continue." );
getchar();
}
CloseHandle( hThread );
return( status );
}
#endif /* WINDOWS_THREADS */
/****************************************************************************
* *
* OCSP Routines Test *
* *
****************************************************************************/
/* There are various test OCSP servers running, the following remapping
allows us to switch between them. Implementation peculiarities:
#1 - cryptlib:
None
#2 - iD2
AuthorityInfoAccess doesn't match the real server URL, requires
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -