📄 sreqresp.c
字号:
{
printf( "cryptGetAttribute() failed with error code %d, line "
"%d.\n", status, __LINE__ );
return( FALSE );
}
printCertInfo( cryptRTCSResponse );
}
/* Clean up */
cryptDestroyCert( cryptRTCSResponse );
status = cryptDestroySession( cryptSession );
if( cryptStatusError( status ) )
{
printf( "cryptDestroySession() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
puts( isServer ? "SVR: RTCS server session succeeded.\n" : \
"RTCS client session succeeded.\n" );
return( TRUE );
}
static int connectRTCSDirect( void )
{
CRYPT_CERTIFICATE cryptCert;
CRYPT_SESSION cryptSession;
int status;
printf( "Testing direct RTCS query...\n" );
/* Get the EE cert */
status = importCertFromTemplate( &cryptCert, RTCS_FILE_TEMPLATE,
RTCS_SERVER_NO );
if( cryptStatusError( status ) )
{
printf( "EE cryptImportCert() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
/* Create the RTCS session and add the server URL */
status = cryptCreateSession( &cryptSession, CRYPT_UNUSED,
CRYPT_SESSION_RTCS );
if( status == CRYPT_ERROR_PARAM3 ) /* RTCS session access not available */
return( CRYPT_ERROR_NOTAVAIL );
#ifdef RTCS_SERVER_NAME
status = cryptSetAttributeString( cryptSession,
CRYPT_SESSINFO_SERVER_NAME, RTCS_SERVER_NAME,
paramStrlen( RTCS_SERVER_NAME ) );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptSession, "cryptSetAttributeString()",
status, __LINE__ ) );
#endif /* Kludges for incorrect/missing authorityInfoAccess values */
/* Check the cert directly against the server */
status = cryptCheckCert( cryptCert, cryptSession );
printf( "Certificate status check returned %d.\n", status );
/* Clean up */
cryptDestroyCert( cryptCert );
cryptDestroySession( cryptSession );
puts( "RTCS direct query succeeded.\n" );
return( TRUE );
}
int testSessionRTCS( void )
{
if( !connectRTCS( CRYPT_SESSION_RTCS, FALSE, FALSE ) )
return( FALSE );
if( !connectRTCSDirect() )
return( FALSE );
#if RTCS_SERVER_NO == 1
return( connectRTCS( CRYPT_SESSION_RTCS, TRUE, FALSE ) );
#else
return( TRUE );
#endif /* Server that has a revoked cert */
}
int testSessionRTCSServer( void )
{
return( connectRTCS( CRYPT_SESSION_RTCS_SERVER, FALSE, FALSE ) );
}
/* Perform a client/server loopback test */
#ifdef WINDOWS_THREADS
unsigned __stdcall rtcsServerThread( void *dummy )
{
connectRTCS( CRYPT_SESSION_RTCS_SERVER, FALSE, TRUE );
_endthreadex( 0 );
return( 0 );
}
int testSessionRTCSClientServer( void )
{
HANDLE hThread;
unsigned threadID;
int status;
/* Start the server and wait for it to initialise */
hThread = ( HANDLE ) _beginthreadex( NULL, 0, &rtcsServerThread,
NULL, 0, &threadID );
Sleep( 2000 );
/* Connect to the local server */
status = connectRTCS( CRYPT_SESSION_RTCS, 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 aka SmartTrust
AuthorityInfoAccess doesn't match the real server URL, requires
the SmartTrust server name below to override the AIA value.
Currently not active.
#3 - Identrus aka Xetex:
AuthorityInfoAccess doesn't match the real server URL, requires
the Xetex server name below to override the AIA value. Currently
not active.
#4 - Thawte aka Valicert
No AuthorityInfoAccess, requires the Valicert server name below
to provide a server. Since all Thawte CA certs are invalid (no
keyUsage, meaning they're non-CA certs) cryptlib will reject them
for OCSPv1 queries.
#5 - Verisign
No AuthorityInfoAccess, requires the Verisign server name below
to provide a server.
#6 - Diginotar
Have an invalid CA certificate, and (apparently) a broken OCSP
implementation that gets the IDs wrong (this is par for the
course for this particular CA) */
#define OCSP_SERVER_NO 5
#if OCSP_SERVER_NO == 2
#define OCSP_SERVER_NAME TEXT( "http://ocsp.smarttrust.com:82/ocsp" )
#elif OCSP_SERVER_NO == 3
#define OCSP_SERVER_NAME TEXT( "http://ocsp.xetex.com:8080/servlet/ocsp" )
#elif OCSP_SERVER_NO == 4
#define OCSP_SERVER_NAME TEXT( "http://ocsp2.valicert.net" )
#elif OCSP_SERVER_NO == 5
#define OCSP_SERVER_NAME TEXT( "http://ocsp.verisign.com/ocsp/status" )
#endif /* OCSP server name kludge */
/* Perform an OCSP test */
static int connectOCSP( const CRYPT_SESSION_TYPE sessionType,
const BOOLEAN revokedCert,
const BOOLEAN multipleCerts,
const BOOLEAN localSession )
{
CRYPT_SESSION cryptSession;
CRYPT_CERTIFICATE cryptOCSPRequest, cryptOCSPResponse;
const BOOLEAN isServer = ( sessionType == CRYPT_SESSION_OCSP_SERVER ) ? \
TRUE : FALSE;
int status;
printf( "%sTesting %sOCSP session...\n", isServer ? "SVR: " : "",
localSession ? "local " : "" );
/* Create the OCSP session */
status = cryptCreateSession( &cryptSession, CRYPT_UNUSED, sessionType );
if( status == CRYPT_ERROR_PARAM3 ) /* OCSP 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( isServer )
{
CRYPT_CONTEXT cryptPrivateKey;
CRYPT_KEYSET cryptCertStore;
if( !setLocalConnect( cryptSession, 80 ) )
return( FALSE );
/* Add the responder private key */
status = getPrivateKey( &cryptPrivateKey, SERVER_PRIVKEY_FILE,
USER_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD );
if( cryptStatusOK( status ) )
{
status = cryptSetAttribute( cryptSession,
CRYPT_SESSINFO_PRIVATEKEY, cryptPrivateKey );
cryptDestroyContext( cryptPrivateKey );
}
if( cryptStatusError( status ) )
return( attrErrorExit( cryptSession, "cryptSetAttribute()",
status, __LINE__ ) );
/* Add the cert store that we'll be using to provide revocation
information */
status = cryptKeysetOpen( &cryptCertStore, CRYPT_UNUSED,
DATABASE_KEYSET_TYPE, CERTSTORE_KEYSET_NAME,
CRYPT_KEYOPT_READONLY );
if( status == CRYPT_ERROR_PARAM3 )
{
/* This type of keyset access isn't available, return a special
error code to indicate that the test wasn't performed, but
that this isn't a reason to abort processing */
puts( "SVR: No certificate store available, aborting OCSP "
"responder test.\n" );
cryptDestroySession( cryptSession );
return( CRYPT_ERROR_NOTAVAIL );
}
if( cryptStatusOK( status ) )
{
status = cryptSetAttribute( cryptSession,
CRYPT_SESSINFO_KEYSET, cryptCertStore );
cryptKeysetClose( cryptCertStore );
}
if( cryptStatusError( status ) )
return( attrErrorExit( cryptSession, "cryptSetAttribute()",
status, __LINE__ ) );
}
else
{
/* Create the OCSP request */
if( !initOCSP( &cryptOCSPRequest, localSession ? 1 : OCSP_SERVER_NO,
FALSE, revokedCert, multipleCerts,
CRYPT_SIGNATURELEVEL_NONE, CRYPT_UNUSED ) )
return( FALSE );
/* Set up the server information and activate the session. In
theory the OCSP request will contain all the information needed
for the session so there'd be nothing else to add before we
activate it, however many certs contain incorrect server URLs so
we set the server name manually if necessary, overriding the
value present in the OCSP request (via the cert) */
status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_REQUEST,
cryptOCSPRequest );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptSession, "cryptSetAttribute()",
status, __LINE__ ) );
cryptDestroyCert( cryptOCSPRequest );
if( localSession && !setLocalConnect( cryptSession, 80 ) )
return( FALSE );
#ifdef OCSP_SERVER_NAME
if( !localSession )
{
printf( "Setting OCSP server to %s.\n", OCSP_SERVER_NAME );
cryptDeleteAttribute( cryptSession, CRYPT_SESSINFO_SERVER_NAME );
status = cryptSetAttributeString( cryptSession,
CRYPT_SESSINFO_SERVER_NAME, OCSP_SERVER_NAME,
paramStrlen( OCSP_SERVER_NAME ) );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptSession,
"cryptSetAttributeString()", status,
__LINE__ ) );
}
#endif /* Kludges for incorrect/missing authorityInfoAccess values */
if( OCSP_SERVER_NO == 1 || localSession )
{
/* The cryptlib server doesn't handle the weird v1 certIDs */
status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_VERSION,
2 );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptSession, "cryptSetAttribute()",
status, __LINE__ ) );
}
}
status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
if( isServer )
printConnectInfo( cryptSession );
if( cryptStatusError( status ) )
{
printExtError( cryptSession, isServer ? \
"SVR: Attempt to activate OCSP server session" : \
"Attempt to activate OCSP client session", status,
__LINE__ );
cryptDestroySession( cryptSession );
if( status == CRYPT_ERROR_OPEN || status == CRYPT_ERROR_NOTFOUND || \
status == CRYPT_ERROR_TIMEOUT || status == CRYPT_ERROR_PERMISSION )
{
/* These servers are constantly appearing and disappearing so if
we get a straight connect error we don't treat it as a serious
failure. In addition we can get server busy and no permission
to access errors that are also treated as soft errors */
puts( " (Server could be down or busy or unavailable, faking it "
"and continuing...)\n" );
return( CRYPT_ERROR_FAILED );
}
return( FALSE );
}
/* Obtain the response information */
if( !isServer )
{
status = cryptGetAttribute( cryptSession, CRYPT_SESSINFO_RESPONSE,
&cryptOCSPResponse );
if( cryptStatusError( status ) )
{
printf( "cryptGetAttribute() failed with error code %d, line "
"%d.\n", status, __LINE__ );
return( FALSE );
}
printCertInfo( cryptOCSPResponse );
}
/* There are so many weird ways to delegate trust and signing authority
mentioned in the OCSP RFC without any indication of which one
implementors will follow that we can't really perform any sort of
automated check since every responder seems to interpret this
differently, and many require manual installation of responder certs
in order to function */
#if 0
status = cryptCheckCert( cryptOCSPResponse , CRYPT_UNUSED );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptOCSPResponse , "cryptCheckCert()",
status, __LINE__ ) );
#endif /* 0 */
cryptDestroyCert( cryptOCSPResponse );
/* Clean up */
status = cryptDestroySession( cryptSession );
if( cryptStatusError( status ) )
{
printf( "cryptDestroySession() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
puts( isServer ? "SVR: OCSP server session succeeded.\n" : \
"OCSP client session succeeded.\n" );
return( TRUE );
}
static int connectOCSPDirect( void )
{
CRYPT_CERTIFICATE cryptCert;
CRYPT_SESSION cryptSession;
int status;
printf( "Testing direct OCSP query...\n" );
/* Get the EE cert */
status = importCertFromTemplate( &cryptCert, OCSP_EEOK_FILE_TEMPLATE,
OCSP_SERVER_NO );
if( cryptStatusError( status ) )
{
printf( "EE cryptImportCert() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
/* Create the OCSP session and add the server URL */
status = cryptCreateSession( &cryptSession, CRYPT_UNUSED,
CRYPT_SESSION_OCSP );
if( status == CRYPT_ERROR_PARAM3 ) /* OCSP session access not available */
return( CRYPT_ERROR_NOTAVAIL );
#ifdef OCSP_SERVER_NAME
status = cryptSetAttributeString( cryptSession,
CRYPT_SESSINFO_SERVER_NAME, OCSP_SERVER_NAME,
paramStrlen( OCSP_SERVER_NAME ) );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptSession, "cryptSetAttributeString()",
status, __LINE__ ) );
#endif /* Kludges for incorrect/missing authorityInfoAccess values */
/* Check the cert directly against the server. This check quantises the
result into a basic pass/fail that doesn't provide as much detail as
the low-level OCSP check, so it's not unusual to get
CRYPT_ERROR_INVALID whent he low-level check returns
CRYPT_OCSPSTATUS_UNKNOWN */
status = cryptCheckCert( cryptCert, cryptSession );
printf( "Certificate status check returned %d.\n", status );
/* Clean up */
cryptDestroyCert( cryptCert );
cryptDestroySession( cryptSession );
puts( "OCSP direct query succeeded.\n" );
return( TRUE );
}
int testSessionOCSP( void )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -