static void testKernelChecks( void )
	{
	CRYPT_HANDLE cryptHandle;
	int subType;

	printf( "Running kernel smoke test:\n  Contexts" );
	for( subType = 0; subType < 500; subType++ )
		{
		if( cryptStatusOK( cryptCreateContext( &cryptHandle, CRYPT_UNUSED,
											   subType ) ) )
			smokeTestAttributes( cryptHandle );
		}
	printf( "\n  Certs" );
	for( subType = 0; subType < 500; subType++ )
		{
		if( cryptStatusOK( cryptCreateCert( &cryptHandle, CRYPT_UNUSED,
											subType ) ) )
			smokeTestAttributes( cryptHandle );
		}
	printf( "\n  Envelopes" );
	for( subType = 0; subType < 500; subType++ )
		{
		if( cryptStatusOK( cryptCreateEnvelope( &cryptHandle, CRYPT_UNUSED,
												subType ) ) )
			smokeTestAttributes( cryptHandle );
		}
	printf( "\n  Sessions" );
	for( subType = 0; subType < 500; subType++ )
		{
		if( cryptStatusOK( cryptCreateSession( &cryptHandle, CRYPT_UNUSED,
											   subType ) ) )
			smokeTestAttributes( cryptHandle );
		}
	printf( "\n" );
	}
Example #2
0
static int connectOCSPDirect( void )
	{
	CRYPT_CERTIFICATE cryptCert;
	CRYPT_SESSION cryptSession;
	int status;

	printf( "Testing direct OCSP query...\n" );

	/* Get the EE certificate */
	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 certificate 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 );
	}
Example #3
0
static int connectRTCSDirect( void )
	{
	CRYPT_CERTIFICATE cryptCert;
	CRYPT_SESSION cryptSession;
	int status;

	printf( "Testing direct RTCS query...\n" );

	/* Get the EE certificate */
	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 certificate 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 );
	}
Example #4
0
static int connectOCSP( const CRYPT_SESSION_TYPE sessionType,
						const BOOLEAN revokedCert,
						const BOOLEAN multipleCerts,
						const BOOLEAN localSession )
	{
	CRYPT_SESSION cryptSession;
	CRYPT_CERTIFICATE cryptOCSPRequest;
	char filenameBuffer[ FILENAME_BUFFER_SIZE ];
#ifdef UNICODE_STRINGS
	wchar_t wcBuffer[ FILENAME_BUFFER_SIZE ];
#endif /* UNICODE_STRINGS */
	void *fileNamePtr = filenameBuffer;
#if OCSP_SERVER_NO == 7
	int complianceValue;
#endif /* OCSP servers that return broken resposnes */
	const BOOLEAN isServer = ( sessionType == CRYPT_SESSION_OCSP_SERVER ) ? \
							   TRUE : FALSE;
	int status;

	printf( "%sTesting %sOCSP session...\n", isServer ? "SVR: " : "",
			localSession ? "local " : "" );

	/* If we're the client, wait for the server to finish initialising */
	if( localSession && !isServer && waitMutex() == CRYPT_ERROR_TIMEOUT )
		{
		printf( "Timed out waiting for server to initialise, line %d.\n", 
				__LINE__ );
		return( FALSE );
		}

	/* 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 */
		filenameFromTemplate( filenameBuffer, SERVER_PRIVKEY_FILE_TEMPLATE, 1 );
#ifdef UNICODE_STRINGS
		mbstowcs( wcBuffer, filenameBuffer, strlen( filenameBuffer ) + 1 );
		fileNamePtr = wcBuffer;
#endif /* UNICODE_STRINGS */
		status = getPrivateKey( &cryptPrivateKey, fileNamePtr,
								USER_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD );
		if( cryptStatusOK( status ) )
			{
			status = cryptSetAttribute( cryptSession,
							CRYPT_SESSINFO_PRIVATEKEY, cryptPrivateKey );
			cryptDestroyContext( cryptPrivateKey );
			}
		if( cryptStatusError( status ) )
			return( attrErrorExit( cryptSession, "SVR: cryptSetAttribute()",
								   status, __LINE__ ) );

		/* Add the certificate 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, "SVR: cryptSetAttribute()",
								   status, __LINE__ ) );

		/* Tell the client that we're ready to go */
		if( localSession )
			releaseMutex();
		}
	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 certificate) */
		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__ ) );
			}
#if OCSP_SERVER_NO == 7
		/* Some OCSP server's responses are broken so we have to turn down 
		   the compliance level to allow them to be processed */
		cryptGetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CERT_COMPLIANCELEVEL,
						   &complianceValue );
		cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CERT_COMPLIANCELEVEL,
						   CRYPT_COMPLIANCELEVEL_OBLIVIOUS );
#endif /* OCSP servers that return broken resposnes */

		/* Wait for the server to finish initialising */
		if( localSession && waitMutex() == CRYPT_ERROR_TIMEOUT )
			{
			printf( "Timed out waiting for server to initialise, line %d.\n",
					__LINE__ );
			return( FALSE );
			}		
		}
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
#if OCSP_SERVER_NO == 7
	/* Restore normal certificate processing */
	cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CERT_COMPLIANCELEVEL,
					   complianceValue );
#endif /* OCSP servers that return broken resposnes */
	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__ );
#if OCSP_SERVER_NO == 5
		if( status == CRYPT_ERROR_SIGNATURE )
			{
			char errorMessage[ 512 ];
			int errorMessageLength;

			status = cryptGetAttributeString( cryptSession, 
											  CRYPT_ATTRIBUTE_ERRORMESSAGE,
											  errorMessage, &errorMessageLength );
			if( cryptStatusOK( status ) && errorMessageLength >= 29 && \
				!memcmp( errorMessage, "OCSP response doesn't contain", 29 ) )
				{
				cryptDestroySession( cryptSession );
				puts( "  (Verisign's OCSP responder sends broken responses, "
					  "continuing...)\n" );
				return( CRYPT_ERROR_FAILED );
				}
			}
#endif /* Verisign's broken OCSP responder */
		if( !isServer && isServerDown( cryptSession, status ) )
			{
			puts( "  (Server could be down, faking it and continuing...)\n" );
			cryptDestroySession( cryptSession );
			return( CRYPT_ERROR_FAILED );
			}
		cryptDestroySession( cryptSession );
		return( FALSE );
		}

	/* Obtain the response information */
	if( !isServer )
		{
		CRYPT_CERTIFICATE cryptOCSPResponse;
		
		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 );
		cryptDestroyCert( 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 */

	/* 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 );
	}
Example #5
0
static int connectCertstoreServer( void )
	{
	CRYPT_SESSION cryptSession;
	CRYPT_KEYSET cryptCertStore;
	int connectionActive, status;

	puts( "Testing HTTP certstore server session..." );

	/* Create the HTTP certstore session */
	status = cryptCreateSession( &cryptSession, CRYPT_UNUSED,
								 CRYPT_SESSION_CERTSTORE_SERVER );
	if( status == CRYPT_ERROR_PARAM3 )	/* Certstore 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( !setLocalConnect( cryptSession, 80 ) )
		return( FALSE );

	/* Add the certificate store that we'll be using to provide certs (it's
	   actually just the generic database keyset and not the full 
	   certificate store, because this contains more test certs) */
	status = cryptKeysetOpen( &cryptCertStore, CRYPT_UNUSED,
							  DATABASE_KEYSET_TYPE, DATABASE_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 HTTP certstore "
				  "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, "SVR: cryptSetAttribute()",
							   status, __LINE__ ) );

	/* Activate the server */
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
	printConnectInfo( cryptSession );
	if( cryptStatusError( status ) )
		{
		printExtError( cryptSession, "SVR: Attempt to activate HTTP "
					   "certstore server session", status, __LINE__ );
		cryptDestroySession( cryptSession );
		return( FALSE );
		}

	/* Check whether the session connection is still open */
	status = cryptGetAttribute( cryptSession, CRYPT_SESSINFO_CONNECTIONACTIVE,
								&connectionActive );
	if( cryptStatusError( status ) || !connectionActive )
		{
		printExtError( cryptSession, "SVR: Persistent connection has been "
					   "closed, operation", status, __LINE__ );
		return( FALSE );
		}

	/* Activate the connection to handle two more requests */
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
	if( cryptStatusError( status ) )
		{
		printExtError( cryptSession, "SVR: Attempt to perform second HTTP "
					   "certstore server transaction", status, __LINE__ );
		cryptDestroySession( cryptSession );
		return( status );
		}
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
	if( cryptStatusError( status ) )
		{
		printExtError( cryptSession, "SVR: Attempt to perform third HTTP "
					   "certstore server transaction", status, __LINE__ );
		cryptDestroySession( cryptSession );
		return( status );
		}

	/* Clean up */
	status = cryptDestroySession( cryptSession );
	if( cryptStatusError( status ) )
		{
		printf( "cryptDestroySession() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}

	puts( "SVR: HTTP certstore server session succeeded.\n" );
	return( TRUE );
	}
Example #6
0
static int connectRTCS( const CRYPT_SESSION_TYPE sessionType,
						const BOOLEAN multipleCerts,
						const BOOLEAN localSession )
	{
	CRYPT_SESSION cryptSession;
	CRYPT_CERTIFICATE cryptRTCSRequest;
	char filenameBuffer[ FILENAME_BUFFER_SIZE ];
#ifdef UNICODE_STRINGS
	wchar_t wcBuffer[ FILENAME_BUFFER_SIZE ];
#endif /* UNICODE_STRINGS */
	void *fileNamePtr = filenameBuffer;
	const BOOLEAN isServer = ( sessionType == CRYPT_SESSION_RTCS_SERVER ) ? \
							   TRUE : FALSE;
	int status;

	printf( "%sTesting %sRTCS session...\n", isServer ? "SVR: " : "",
			localSession ? "local " : "" );

	/* If we're the client, wait for the server to finish initialising */
	if( localSession && !isServer && waitMutex() == CRYPT_ERROR_TIMEOUT )
		{
		printf( "Timed out waiting for server to initialise, line %d.\n", 
				__LINE__ );
		return( FALSE );
		}

	/* Create the RTCS session */
	status = cryptCreateSession( &cryptSession, CRYPT_UNUSED, sessionType );
	if( status == CRYPT_ERROR_PARAM3 )	/* RTCS 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 */
		filenameFromTemplate( filenameBuffer, SERVER_PRIVKEY_FILE_TEMPLATE, 1 );
#ifdef UNICODE_STRINGS
		mbstowcs( wcBuffer, filenameBuffer, strlen( filenameBuffer ) + 1 );
		fileNamePtr = wcBuffer;
#endif /* UNICODE_STRINGS */
		status = getPrivateKey( &cryptPrivateKey, fileNamePtr, 
								USER_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD );
		if( cryptStatusOK( status ) )
			{
			status = cryptSetAttribute( cryptSession,
							CRYPT_SESSINFO_PRIVATEKEY, cryptPrivateKey );
			cryptDestroyContext( cryptPrivateKey );
			}
		if( cryptStatusError( status ) )
			return( attrErrorExit( cryptSession, "SVR: cryptSetAttribute()",
								   status, __LINE__ ) );

		/* Add the certificate 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 RTCS "
				  "responder test.\n" );
			cryptDestroySession( cryptSession );
			return( CRYPT_ERROR_NOTAVAIL );
			}
		if( status == CRYPT_ERROR_OPEN )
			{
			/* The keyset is available, but it hasn't been created yet by an
			   earlier self-test, this isn't a reason to abort processing */
			puts( "SVR: Certificate store hasn't been created yet by "
				  "earlier tests, aborting\n     RTCS 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, "SVR: cryptSetAttribute()",
								   status, __LINE__ ) );

		/* Tell the client that we're ready to go */
		if( localSession )
			releaseMutex();
		}
	else
		{
		CRYPT_KEYSET cryptKeyset;
		CRYPT_CERTIFICATE cryptCert = DUMMY_INIT;

		/* Get the certificate whose status we're checking */
		status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED,
								  DATABASE_KEYSET_TYPE, CERTSTORE_KEYSET_NAME,
								  CRYPT_KEYOPT_READONLY );
		if( cryptStatusOK( status ) )
			{
			status = cryptGetPublicKey( cryptKeyset, &cryptCert, 
										CRYPT_KEYID_NAME, 
										TEXT( "Test user 1" ) );
			cryptKeysetClose( cryptKeyset );
			}
		if( cryptStatusError( status ) )
			{
			printf( "Couldn't read certificate for RTCS status check, error "
					"code %d, line %d.\n", status, __LINE__ );
			return( FALSE );
			}

		/* Create the RTCS request */
		if( !initRTCS( &cryptRTCSRequest, cryptCert, localSession ? \
							1 : RTCS_SERVER_NO, multipleCerts ) )
			return( FALSE );
		cryptDestroyCert( cryptCert );

		/* Set up the server information and activate the session.  In
		   theory the RTCS 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 RTCS request (via the certificate) */
		status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_REQUEST,
									cryptRTCSRequest );
		if( cryptStatusError( status ) )
			return( attrErrorExit( cryptSession, "cryptSetAttribute()",
								   status, __LINE__ ) );
		cryptDestroyCert( cryptRTCSRequest );
		if( localSession && !setLocalConnect( cryptSession, 80 ) )
			return( FALSE );
#ifdef RTCS_SERVER_NAME
		if( !localSession )
			{
			printf( "Setting RTCS server to %s.\n", RTCS_SERVER_NAME );
			cryptDeleteAttribute( cryptSession, CRYPT_SESSINFO_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 */

		/* Wait for the server to finish initialising */
		if( localSession && waitMutex() == CRYPT_ERROR_TIMEOUT )
			{
			printf( "Timed out waiting for server to initialise, line %d.\n",
					__LINE__ );
			return( FALSE );
			}		
		}
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
	if( isServer )
		printConnectInfo( cryptSession );
	if( cryptStatusError( status ) )
		{
		printExtError( cryptSession, isServer ? \
					   "SVR: Attempt to activate RTCS server session" : \
					   "Attempt to activate RTCS client session", status,
					   __LINE__ );
		if( !isServer && isServerDown( cryptSession, status ) )
			{
			puts( "  (Server could be down, faking it and continuing...)\n" );
			cryptDestroySession( cryptSession );
			return( CRYPT_ERROR_FAILED );
			}
		cryptDestroySession( cryptSession );
		return( FALSE );
		}

	/* Obtain the response information */
	if( !isServer )
		{
		CRYPT_CERTIFICATE cryptRTCSResponse;
		
		status = cryptGetAttribute( cryptSession, CRYPT_SESSINFO_RESPONSE,
									&cryptRTCSResponse );
		if( cryptStatusError( status ) )
			{
			printf( "cryptGetAttribute() failed with error code %d, line "
					"%d.\n", status, __LINE__ );
			return( FALSE );
			}
		printCertInfo( cryptRTCSResponse );
		cryptDestroyCert( cryptRTCSResponse );
		}

	/* 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: RTCS server session succeeded.\n" : \
					 "RTCS client session succeeded.\n" );
	return( TRUE );
	}
Example #7
0
static int connectTSP( const CRYPT_SESSION_TYPE sessionType,
					   const CRYPT_HANDLE externalCryptContext,
					   const BOOLEAN persistentConnection,
					   const BOOLEAN localSession )
	{
	CRYPT_SESSION cryptSession;
	const BOOLEAN isServer = ( sessionType == CRYPT_SESSION_TSP_SERVER ) ? \
							   TRUE : FALSE;
	const BOOLEAN useAltHash = ( !isServer && 0 ) ? TRUE : FALSE;
	int status;

	printf( "%sTesting %sTSP session...\n", isServer ? "SVR: " : "",
			localSession ? "local " : "" );

	/* Acquire the init mutex if we're the server */
	if( localSession && isServer )
		waitMutex();

	/* Create the TSP session */
	status = cryptCreateSession( &cryptSession, CRYPT_UNUSED, sessionType );
	if( status == CRYPT_ERROR_PARAM3 )	/* TSP session access not available */
		return( CRYPT_ERROR_NOTAVAIL );
	if( cryptStatusError( status ) )
		{
		printf( "%scryptCreateSession() failed with error code %d, line "
				"%d.\n", isServer ? "SVR: " : "", status, __LINE__ );
		return( FALSE );
		}

	/* Set up the server information and activate the session.  Since this 
	   test explicitly tests the ability to handle persistent connections, 
	   we don't use the general-purpose request/response server wrapper, 
	   which only uses persistent connections opportunistically */
	if( isServer )
		{
		CRYPT_CONTEXT privateKey = externalCryptContext;

		if( !setLocalConnect( cryptSession, 318 ) )
			return( FALSE );
		if( externalCryptContext == CRYPT_UNUSED )
			status = getPrivateKey( &privateKey, TSA_PRIVKEY_FILE,
									USER_PRIVKEY_LABEL,
									TEST_PRIVKEY_PASSWORD );
		if( cryptStatusOK( status ) )
			{
			status = cryptSetAttribute( cryptSession,
							CRYPT_SESSINFO_PRIVATEKEY, privateKey );
			if( externalCryptContext == CRYPT_UNUSED )
				cryptDestroyContext( privateKey );
			}
		}
	else
		{
		if( localSession )
			{
			if( !setLocalConnect( cryptSession, 318 ) )
				return( FALSE );
			}
		else
			{
			status = cryptSetAttributeString( cryptSession,
							CRYPT_SESSINFO_SERVER_NAME, TSP_SERVER_NAME,
							paramStrlen( TSP_SERVER_NAME ) );
			}
		}
	if( cryptStatusError( status ) )
		{
		printf( "cryptSetAttribute/cryptSetAttributeString() failed with "
				"error code %d, line %d.\n", status, __LINE__ );
		return( FALSE );
		}
	status = testTSP( cryptSession, isServer, FALSE, useAltHash, localSession );
	if( status <= 0 )
		return( status );

	/* Check whether the session connection is still open */
	if( persistentConnection )
		{
		int connectionActive;

		status = cryptGetAttribute( cryptSession, CRYPT_SESSINFO_CONNECTIONACTIVE,
									&connectionActive );
		if( cryptStatusError( status ) || !connectionActive )
			{
			printExtError( cryptSession, isServer ? \
						   "SVR: Persistent connection has been closed, "
							"operation" : \
						   "Persistent connection has been closed, operation",
						   status, __LINE__ );
			return( FALSE );
			}

		/* Activate the connection to handle two more requests */
		status = testTSP( cryptSession, isServer, TRUE, FALSE, FALSE );
		if( status <= 0 )
			return( status );
		status = testTSP( cryptSession, isServer, TRUE, FALSE, FALSE );
		if( status <= 0 )
			return( status );
		}

	/* Clean up */
	status = cryptDestroySession( cryptSession );
	if( cryptStatusError( status ) )
		{
		printf( "cryptDestroySession() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}

	printf( isServer ? "SVR: %sTSP server session succeeded.\n\n" : \
					   "%sTSP client session succeeded.\n\n",
			persistentConnection ? "Persistent " : "" );
	return( TRUE );
	}
Example #8
0
static int fuzzSession( const CRYPT_SESSION_TYPE sessionType )
	{
	CRYPT_SESSION cryptSession;
	const BOOLEAN isServer = \
			( sessionType == CRYPT_SESSION_SSH_SERVER || \
			  sessionType == CRYPT_SESSION_SSL_SERVER || \
			  sessionType == CRYPT_SESSION_OCSP_SERVER || \
			  sessionType == CRYPT_SESSION_TSP_SERVER || \
			  sessionType == CRYPT_SESSION_CMP_SERVER || \
			  sessionType == CRYPT_SESSION_SCEP_SERVER ) ? \
			TRUE : FALSE;
	int status;

	/* Create the session */
	status = cryptCreateSession( &cryptSession, CRYPT_UNUSED, sessionType );
	if( cryptStatusError( status ) )
		return( status );

	/* Set up the various attributes needed to establish a minimal session */
	if( !isServer )
		{
		status = cryptSetAttributeString( cryptSession,
										  CRYPT_SESSINFO_SERVER_NAME,
										  "www.example.com", 15 );
		if( cryptStatusError( status ) )
			return( status );
		}
	if( isServer )
		{
		CRYPT_CONTEXT cryptPrivKey;
		char filenameBuffer[ FILENAME_BUFFER_SIZE ];

		filenameFromTemplate( filenameBuffer, 
								  SERVER_PRIVKEY_FILE_TEMPLATE, 1 );
		status = getPrivateKey( &cryptPrivKey, filenameBuffer, 
								USER_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD );
		if( cryptStatusOK( status ) )
			{
			status = cryptSetAttribute( cryptSession,
										CRYPT_SESSINFO_PRIVATEKEY, 
										cryptPrivKey );
			cryptDestroyContext( cryptPrivKey );
			}
		if( cryptStatusError( status ) )
			return( status );
		}
	if( sessionType == CRYPT_SESSION_SSH || \
		sessionType == CRYPT_SESSION_SSH_SERVER )
		{
		status = cryptSetAttributeString( cryptSession,
										  CRYPT_SESSINFO_USERNAME,
										  SSH_USER_NAME,
										  paramStrlen( SSH_USER_NAME ) );
		if( cryptStatusOK( status ) )
			{
			status = cryptSetAttributeString( cryptSession,
											  CRYPT_SESSINFO_PASSWORD,
											  SSH_PASSWORD,
											  paramStrlen( SSH_PASSWORD ) );
			}
		if( cryptStatusError( status ) )
			return( status );
		}
	status = cryptSetFuzzData( cryptSession, NULL, 0 );
	cryptDestroySession( cryptSession );

	return( CRYPT_OK );
	}
Example #9
0
static int exec_cmpcli_init(int argc, char **argv) {
  CRYPT_SESSION session;
  CRYPT_CERTIFICATE cert, cacert, req;
  CRYPT_CONTEXT keypair;
  CRYPT_KEYSET privkeys;
  const char *cmd, *uid, *ipwd, *crtfilename, *cacrtfilename, *kpfilename;
  void *crtdata;
  int status, data_len;

  if (argc != 6) { fprintf(stderr, "cmpcli argv!=6\n"); return 1; }
  cmd = argv[0]; uid = argv[1]; ipwd = argv[2]; crtfilename=argv[3]; cacrtfilename=argv[4]; kpfilename = argv[5];
  fprintf(stderr, "uid=\"%s\" ipwd=\"%s\"\n", uid, ipwd);
#if 0
  crtdata = read_full_file(crtfilename, &data_len);
  if (!crtdata) return 1;
  status = cryptImportCert(crtdata, data_len, CRYPT_UNUSED, &cert);
  WARN_AND_RETURN_IF(status);
  free(crtdata);
#endif
  crtdata = read_full_file(cacrtfilename, &data_len);
  if (!crtdata) return 1;
  status = cryptImportCert(crtdata, data_len, CRYPT_UNUSED, &cacert);
  WARN_AND_RETURN_IF(status);
  free(crtdata);

  status = create_keypair(&keypair, DEFAULT_PRIVKEY_LABEL);
  WARN_AND_RETURN_IF(status);

  status = cryptKeysetOpen(&privkeys, CRYPT_UNUSED, CRYPT_KEYSET_FILE, kpfilename, CRYPT_KEYOPT_CREATE);
  WARN_AND_RETURN_IF(status);
  status = cryptAddPrivateKey(privkeys, keypair, DEFAULT_PASSWORD);
  WARN_AND_RETURN_IF(status);


  status = cryptCreateCert(&req, CRYPT_UNUSED, CRYPT_CERTTYPE_REQUEST_CERT);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(req, CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, keypair);
  WARN_AND_RETURN_IF(status);
  status = cryptSignCert(req, keypair);
  WARN_AND_RETURN_IF(status);

  status = cryptCreateSession(&session, CRYPT_UNUSED, CRYPT_SESSION_CMP);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(session, CRYPT_SESSINFO_CMP_REQUESTTYPE, CRYPT_REQUESTTYPE_INITIALIZATION);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(session, CRYPT_SESSINFO_CACERTIFICATE, cacert);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(session, CRYPT_SESSINFO_REQUEST, req);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttributeString(session, CRYPT_SESSINFO_USERNAME, uid, strlen(uid));
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttributeString(session, CRYPT_SESSINFO_PASSWORD, ipwd, strlen(ipwd));
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttributeString(session, CRYPT_SESSINFO_SERVER_NAME, "127.0.0.1", 9);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(session, CRYPT_SESSINFO_SERVER_PORT, 65000);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(session, CRYPT_SESSINFO_ACTIVE, 1);
  WARN_AND_RETURN_IF(status);
  status = cryptGetAttribute(session, CRYPT_SESSINFO_RESPONSE, &cert);
  WARN_AND_RETURN_IF(status);
  status = export_cert(cert, crtfilename);
  WARN_AND_RETURN_IF(status);
  status = cryptAddPublicKey(privkeys, cert);
  WARN_AND_RETURN_IF(status);

  status = cryptKeysetClose(privkeys);
  WARN_AND_RETURN_IF(status);
  status = cryptDestroySession(session);
  WARN_AND_RETURN_IF(status);
  status = cryptDestroyCert(cacert);
  WARN_AND_RETURN_IF(status);
  status = cryptDestroyCert(cert);
  WARN_AND_RETURN_IF(status);
  status = cryptDestroyCert(req);
  WARN_AND_RETURN_IF(status);
  status = cryptDestroyContext(keypair);
  return 0;
}
Example #10
0
static int exec_cmpcli_revoke(int argc, char **argv) {
  CRYPT_SESSION session;
  CRYPT_CONTEXT privkey;
  CRYPT_KEYSET privkeys;
  CRYPT_CERTIFICATE cert, cacert, revreq;
  const char *cmd, *crtfilename, *cacrtfilename, *kpfilename;
  void *crtdata;
  int status, data_len;

  if (argc != 4) { fprintf(stderr, "cmpcli revoke argv!=4\n"); return 1; }
  cmd = argv[0]; crtfilename=argv[1]; cacrtfilename=argv[2]; kpfilename = argv[3];
  if (strcmp(cmd, "revoke") != 0) { fprintf(stderr, "cmpcli knows revoke only\n"); return 1; }

  crtdata = read_full_file(crtfilename, &data_len);
  if (!crtdata) return 1;
  status = cryptImportCert(crtdata, data_len, CRYPT_UNUSED, &cert);
  WARN_AND_RETURN_IF(status);
  free(crtdata);

  crtdata = read_full_file(cacrtfilename, &data_len);
  if (!crtdata) return 1;
  status = cryptImportCert(crtdata, data_len, CRYPT_UNUSED, &cacert);
  WARN_AND_RETURN_IF(status);
  free(crtdata);

  status = cryptKeysetOpen(&privkeys, CRYPT_UNUSED, CRYPT_KEYSET_FILE, kpfilename, CRYPT_KEYOPT_NONE);
  WARN_AND_RETURN_IF(status);
  status = cryptGetPrivateKey(privkeys, &privkey, CRYPT_KEYID_NAME, DEFAULT_PRIVKEY_LABEL, DEFAULT_PASSWORD);
  WARN_AND_RETURN_IF(status);
  status = cryptKeysetClose(privkeys);
  WARN_AND_RETURN_IF(status);


  status = cryptCreateCert(&revreq, CRYPT_UNUSED, CRYPT_CERTTYPE_REQUEST_REVOCATION);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(revreq, CRYPT_CERTINFO_CERTIFICATE, cert);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(revreq, CRYPT_CERTINFO_CRLREASON, CRYPT_CRLREASON_AFFILIATIONCHANGED);
  WARN_AND_RETURN_IF(status);
  #if 0
  status = cryptSignCert(revreq, privkey);
  WARN_AND_RETURN_IF(status);
  #endif

  status = cryptCreateSession(&session, CRYPT_UNUSED, CRYPT_SESSION_CMP);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(session, CRYPT_SESSINFO_CMP_REQUESTTYPE, CRYPT_REQUESTTYPE_REVOCATION);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(session, CRYPT_SESSINFO_PRIVATEKEY, privkey);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(session, CRYPT_SESSINFO_REQUEST, revreq);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(session, CRYPT_SESSINFO_CACERTIFICATE, cacert);
  WARN_AND_RETURN_IF(status);

  #if 0
  status = cryptSetAttributeString(session, CRYPT_SESSINFO_USERNAME, uid, strlen(uid));
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttributeString(session, CRYPT_SESSINFO_PASSWORD, rpwd, strlen(rpwd));
  WARN_AND_RETURN_IF(status);
  #endif

  status = cryptSetAttributeString(session, CRYPT_SESSINFO_SERVER_NAME, "127.0.0.1", 9);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(session, CRYPT_SESSINFO_SERVER_PORT, 65000);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(session, CRYPT_SESSINFO_ACTIVE, 1);
  if (!cryptStatusOK(status)) {
    CRYPT_ERRTYPE_TYPE errtype;
    CRYPT_ATTRIBUTE_TYPE locus;
    char *errstring;
    int errstringlen;
    cryptGetAttribute(session, CRYPT_ATTRIBUTE_ERRORTYPE, (int *)&errtype);
    cryptGetAttribute(session, CRYPT_ATTRIBUTE_ERRORLOCUS, (int *)&locus);
    fprintf(stderr, "session errtype %d locus %d\n", errtype, locus);
    cryptGetAttribute(revreq, CRYPT_ATTRIBUTE_ERRORTYPE, (int *)&errtype);
    cryptGetAttribute(revreq, CRYPT_ATTRIBUTE_ERRORLOCUS, (int *)&locus);
    fprintf(stderr, "revreq errtype %d locus %d\n", errtype, locus);
    cryptGetAttribute(cert, CRYPT_ATTRIBUTE_ERRORTYPE, (int *)&errtype);
    cryptGetAttribute(cert, CRYPT_ATTRIBUTE_ERRORLOCUS, (int *)&locus);
    fprintf(stderr, "cert errtype %d locus %d\n", errtype, locus);
    cryptGetAttribute(cacert, CRYPT_ATTRIBUTE_ERRORTYPE, (int *)&errtype);
    cryptGetAttribute(cacert, CRYPT_ATTRIBUTE_ERRORLOCUS, (int *)&locus);
    fprintf(stderr, "cacert errtype %d locus %d\n", errtype, locus);
    cryptGetAttributeString(session, CRYPT_ATTRIBUTE_ERRORMESSAGE, NULL, &errstringlen);
    errstring = malloc(errstringlen + 10);
    cryptGetAttributeString(session, CRYPT_ATTRIBUTE_ERRORMESSAGE, errstring, &errstringlen);
    errstring[errstringlen] = 0;
    fprintf(stderr, "session errmsg: %s\n", errstring);
    free(errstring);
  }
  WARN_AND_RETURN_IF(status);

  status = cryptDestroyContext(privkey);
  WARN_AND_RETURN_IF(status);
  status = cryptDestroySession(session);
  WARN_AND_RETURN_IF(status);
  status = cryptDestroyCert(cacert);
  WARN_AND_RETURN_IF(status);
  status = cryptDestroyCert(cert);
  WARN_AND_RETURN_IF(status);
  status = cryptDestroyCert(revreq);
  WARN_AND_RETURN_IF(status);
  return 0;
}
Example #11
0
static int exec_cmpsvr(int argc, char **argv) {
  CRYPT_KEYSET cakeys, store;
  CRYPT_SESSION session;
  CRYPT_CONTEXT ca_privkey;
  int status;
  const char *dbfilename = argv[0];
  char cakeysfilename[4096]; /* PATH_MAX */

  if (argc < 1) { fprintf(stderr, "missing dbfilename\n"); return 1; }

  status = cryptCreateSession(&session, CRYPT_UNUSED, CRYPT_SESSION_CMP_SERVER);
  WARN_AND_RETURN_IF(status);

  /* open store */
  status = cryptKeysetOpen(&store, CRYPT_UNUSED, CRYPT_KEYSET_DATABASE_STORE, dbfilename, CRYPT_KEYOPT_NONE);
  WARN_AND_RETURN_IF(status);

  /* get ca privkey */
  snprintf(cakeysfilename, 4095, "%s.keys", dbfilename);
  cakeysfilename[4095] = '\0';
  status = cryptKeysetOpen(&cakeys, CRYPT_UNUSED, CRYPT_KEYSET_FILE, cakeysfilename, CRYPT_KEYOPT_NONE);
  WARN_AND_RETURN_IF(status);
  status = cryptGetPrivateKey(cakeys, &ca_privkey, CRYPT_KEYID_NAME, DEFAULT_CA_PRIVKEY_LABEL, DEFAULT_PASSWORD);
  WARN_AND_RETURN_IF(status);
  status = cryptKeysetClose(cakeys);
  WARN_AND_RETURN_IF(status);

  status = cryptSetAttribute(session, CRYPT_SESSINFO_KEYSET, store);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(session, CRYPT_SESSINFO_PRIVATEKEY, ca_privkey);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttributeString(session, CRYPT_SESSINFO_SERVER_NAME, "127.0.0.1", 9);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(session, CRYPT_SESSINFO_SERVER_PORT, 65000);
  WARN_AND_RETURN_IF(status);
  fprintf(stderr, "before setting ACTIVE\n");
  status = cryptSetAttribute(session, CRYPT_SESSINFO_ACTIVE, 1);
  if (!cryptStatusOK(status)) {
    CRYPT_ERRTYPE_TYPE errtype;
    CRYPT_ATTRIBUTE_TYPE locus;
    char *errstring;
    int errstringlen;
    cryptGetAttribute(session, CRYPT_ATTRIBUTE_ERRORTYPE, (int *)&errtype);
    cryptGetAttribute(session, CRYPT_ATTRIBUTE_ERRORLOCUS, (int *)&locus);
    fprintf(stderr, "session errtype %d locus %d\n", errtype, locus);
    cryptGetAttributeString(session, CRYPT_ATTRIBUTE_ERRORMESSAGE, NULL, &errstringlen);
    errstring = malloc(errstringlen + 10);
    cryptGetAttributeString(session, CRYPT_ATTRIBUTE_ERRORMESSAGE, errstring, &errstringlen);
    errstring[errstringlen] = 0;
    fprintf(stderr, "session errmsg: %s\n", errstring);
    free(errstring);
  }
  WARN_AND_RETURN_IF(status);

  status = cryptKeysetClose(store);
  WARN_AND_RETURN_IF(status);
  status = cryptDestroyContext(ca_privkey);
  WARN_AND_RETURN_IF(status);
  status = cryptDestroySession(session);
  WARN_AND_RETURN_IF(status);
  return 0;
}
Example #12
0
static int fuzzSession( const CRYPT_SESSION_TYPE sessionType,
						const char *fuzzFileName )
	{
	CRYPT_SESSION cryptSession;
	CRYPT_CONTEXT cryptPrivKey = CRYPT_UNUSED;
	BYTE buffer[ 4096 ];
	const BOOLEAN isServer = \
			( sessionType == CRYPT_SESSION_SSH_SERVER || \
			  sessionType == CRYPT_SESSION_SSL_SERVER || \
			  sessionType == CRYPT_SESSION_OCSP_SERVER || \
			  sessionType == CRYPT_SESSION_RTCS_SERVER || \
			  sessionType == CRYPT_SESSION_TSP_SERVER || \
			  sessionType == CRYPT_SESSION_CMP_SERVER || \
			  sessionType == CRYPT_SESSION_SCEP_SERVER ) ? \
			TRUE : FALSE;
	int length, status;

	/* Create the session */
	status = cryptCreateSession( &cryptSession, CRYPT_UNUSED, sessionType );
	if( cryptStatusError( status ) )
		return( status );

	/* Set up the various attributes needed to establish a minimal session */
	if( !isServer )
		{
		status = cryptSetAttributeString( cryptSession,
										  CRYPT_SESSINFO_SERVER_NAME,
										  "localhost", 9 );
		if( cryptStatusError( status ) )
			return( status );
		}
	if( isServer )
		{
		if( !loadRSAContexts( CRYPT_UNUSED, NULL, &cryptPrivKey ) )
			return( CRYPT_ERROR_FAILED );
		}
	if( sessionType == CRYPT_SESSION_SSH || \
		sessionType == CRYPT_SESSION_CMP )
		{
		status = cryptSetAttributeString( cryptSession,
										  CRYPT_SESSINFO_USERNAME,
										  SSH_USER_NAME,
										  paramStrlen( SSH_USER_NAME ) );
		if( cryptStatusOK( status ) )
			{
			status = cryptSetAttributeString( cryptSession,
											  CRYPT_SESSINFO_PASSWORD,
											  SSH_PASSWORD,
											  paramStrlen( SSH_PASSWORD ) );
			}
		if( cryptStatusError( status ) )
			return( status );
		}
	if( sessionType == CRYPT_SESSION_CMP )
		{
		status = cryptSetAttribute( cryptSession,
									CRYPT_SESSINFO_CMP_REQUESTTYPE,
									CRYPT_REQUESTTYPE_INITIALISATION );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* Perform any final session initialisation */
	cryptFuzzInit( cryptSession, cryptPrivKey );

	/* We're ready to go, start the forkserver and read the mutable data */
#ifndef __WINDOWS__
	__afl_manual_init();
#endif /* !__WINDOWS__ */
	length = readFileData( fuzzFileName, fuzzFileName, buffer, 4096, 32, 
						   TRUE );
	if( length < 32 )
		return( CRYPT_ERROR_READ );

	/* Perform the fuzzing */
	( void ) cryptSetFuzzData( cryptSession, buffer, length );
	cryptDestroySession( cryptSession );
	if( cryptPrivKey != CRYPT_UNUSED )
		cryptDestroyContext( cryptPrivKey );

	return( CRYPT_OK );
	}
Example #13
0
static int suitebClient( const int testNo, const char *hostName, 
						 const int port, const int flags,
						 const BOOLEAN isServerTest )
	{
	CRYPT_SESSION cryptSession;
	const SUITEB_TEST_INFO *testInfoPtr = isServerTest ? \
					&serverTestInfo[ testNo ] : &clientTestInfo[ testNo ];
	const BOOLEAN isLoopbackTest = \
			( !strcmp( hostName, "localhost" ) && port == 0 ) ? TRUE : FALSE;
	const BOOLEAN sendHTTP = \
			( flags & TESTFLAG_SENDHTTPREQ ) ? TRUE : FALSE;
	const char *testName = testInfoPtr->testName;
	SPECIAL_HANDLING_TYPE handlingTypeAlt = SPECIAL_NONE;
	int status;

	/* Make sure that we've been given a valid test number to run */
	if( isServerTest )
		{
		if( testNo < SUITEB_FIRST_SERVER || testNo > SUITEB_LAST_SERVER )
			return( FALSE );
		}
	else
		{
		if( testNo < SUITEB_FIRST_CLIENT || testNo > SUITEB_LAST_CLIENT )
			return( FALSE );
		}

	/* If it's an alias for another test, select the base test */
	if( testInfoPtr->aliasTestName != NULL )
		{
		handlingTypeAlt = testInfoPtr->handlingType;
		testInfoPtr = findAliasTest( isServerTest ? \
								&serverTestInfo[ 1 ] : &clientTestInfo[ 1 ],
								testInfoPtr->aliasTestName );
		if( testInfoPtr == NULL )
			{
			assert( 0 );
			return( FALSE );
			}
		}

	/* Wait for the server to finish initialising */
	if( waitMutex() == CRYPT_ERROR_TIMEOUT )
		{
		printf( "Timed out waiting for server to initialise, line %d.\n", 
				__LINE__ );
		return( FALSE );
		}
	if( !isLoopbackTest )
		{
		/* Clear any custom config, provided we're not running a loopback 
		   test, in which case we'd be overwriting the options that have 
		   already been set by the server */
		cryptSuiteBTestConfig( SUITEB_TEST_NONE );
		}

	printf( "Running Suite B client " );
	if( flags & TESTFLAG_GENERIC )
		printf( "as generic test client.\n" );
	else
		printf( "with test %s.\n", testInfoPtr->testName );

	/* Create the SSL/TLS session */
	status = cryptCreateSession( &cryptSession, CRYPT_UNUSED, 
								 CRYPT_SESSION_SSL );
	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 );
		}
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_VERSION, 3 );
	if( cryptStatusOK( status ) && testInfoPtr->clientOptions != 0 )
		{
		status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_SSL_OPTIONS, 
									testInfoPtr->clientOptions );
		}
	if( cryptStatusError( status ) )
		{
		printf( "cryptSetAttribute() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}

	/* Set up the client information */
	if( isLoopbackTest )
		{
		/* We're running the loopback test, set up a local connect */
		if( !setLocalConnect( cryptSession, 443 ) )
			return( FALSE );
		}
	else
		{
		status = cryptSetAttributeString( cryptSession,
										  CRYPT_SESSINFO_SERVER_NAME,
										  hostName, strlen( hostName ) );
		if( cryptStatusOK( status ) && port != 0 && port != 443 )
			status = cryptSetAttribute( cryptSession, 
										CRYPT_SESSINFO_SERVER_PORT, port );
		if( cryptStatusError( status ) )
			{
			printf( "cryptSetAttribute()/cryptSetAttributeString() failed "
					"with error code %d, line %d.\n", status, __LINE__ );
			return( FALSE );
			}
		}
	if( cryptStatusOK( status ) && \
		testInfoPtr->clientAuthKeySizeBits > 0 )
		{
		CRYPT_CONTEXT privateKey;
		char filenameBuffer[ FILENAME_BUFFER_SIZE ];
#ifdef UNICODE_STRINGS
		wchar_t wcBuffer[ FILENAME_BUFFER_SIZE ];
#endif /* UNICODE_STRINGS */
		void *fileNamePtr = filenameBuffer;

		/* Depending on which server we're testing against we need to use 
		   different private keys */
		filenameFromTemplate( filenameBuffer, SERVER_ECPRIVKEY_FILE_TEMPLATE, 
							  testInfoPtr->clientAuthKeySizeBits );
#ifdef UNICODE_STRINGS
		mbstowcs( wcBuffer, filenameBuffer, strlen( filenameBuffer ) + 1 );
		fileNamePtr = wcBuffer;
#endif /* UNICODE_STRINGS */
		status = getPrivateKey( &privateKey, fileNamePtr, 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 );
		}

	/* For the loopback test we also increase the connection timeout to a 
	   higher-than-normal level, since this gives us more time for tracing 
	   through the code when debugging */
	cryptSetAttribute( cryptSession, CRYPT_OPTION_NET_CONNECTTIMEOUT, 120 );

	/* Set any custom client configuration that may be required */
	switch( testInfoPtr->handlingType )
		{
		case SPECIAL_CLI_INVALIDCURVE:
			/* Client sends non-Suite B curve */
			status = cryptSuiteBTestConfig( SUITEB_TEST_CLIINVALIDCURVE );
			break;

		case SPECIAL_BOTH_SUPPALGO:
			/* Client must send supported_curves extension for both P256 
			   and P384 curves */
			status = cryptSuiteBTestConfig( SUITEB_TEST_BOTHSIGALGOS );
			break;
		}
	if( cryptStatusError( status ) )
		{
		printf( "Custom config set failed with error code %d, line %d.\n", 
				status, __LINE__ );
		return( FALSE );
		}

	/* Activate the client session */
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
	if( ( testInfoPtr->result && !cryptStatusOK( status ) ) || \
		( !testInfoPtr->result && !cryptStatusError( status ) ) )
		{
		if( testInfoPtr->result )
			printf( "Test %s failed, should have succeeded.\n", testName );
		else
			printf( "Test %s succeeded, should have failed.\n", testName );
		if( cryptStatusError( status ) )
			{
			printExtError( cryptSession, "Failure reason is:", status, 
						   __LINE__ );
			}
		cryptDestroySession( cryptSession );

		return( FALSE );
		}

	/* Perform any custom post-activation checking that may be required */
	if( testInfoPtr->handlingType != 0 || handlingTypeAlt != 0 )
		{
		const SPECIAL_HANDLING_TYPE handlingType = \
				( handlingTypeAlt != 0 ) ? handlingTypeAlt : \
										   testInfoPtr->handlingType;
		BYTE buffer[ 1024 ];
		int length;

		switch( handlingType )
			{
			case SPECIAL_CLI_INVALIDCURVE:
			case SPECIAL_BOTH_SUPPALGO:
				/* Handled by checking whether the session activation 
				   failed/succeeded */
				break;

			case SPECIAL_SVR_TLSALERT:
				status = cryptGetAttributeString( cryptSession, 
									CRYPT_ATTRIBUTE_ERRORMESSAGE, buffer, 
									&length );
				if( cryptStatusError( status ) || \
					memcmp( buffer, "Received TLS alert", 18 ) )
					{
					printf( "Test %s should have returned a TLS alert but "
							"didn't.\n", testName );
					return( FALSE );
					}
				break;

			case SPECIAL_SVR_INVALIDCURVE:
				/* Handled/checked on the server */
				break;

			default:
				assert( 0 );
				return( FALSE );
			}
		}

	/* If we're being asked to send HTTP data, send a basic GET */
	if( sendHTTP )
		{
		const char *fetchString = "GET / HTTP/1.0\r\n\r\n";
		const int fetchStringLen = sizeof( fetchString ) - 1;
		int bytesCopied;

		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 );
			}
		}

	/* Clean up */
	status = cryptDestroySession( cryptSession );
	if( cryptStatusError( status ) )
		{
		printf( "cryptDestroySession() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	printf( "Suite B client test %s succeeded.\n", testName );

	return( TRUE );
	}
Example #14
0
static int suitebServer( const int testNo, const char *hostName, 
						 const int port, const int flags,
						 const BOOLEAN isServerTest )
	{
	CRYPT_SESSION cryptSession;
	CRYPT_CONTEXT privateKey;
	const SUITEB_TEST_INFO *testInfoPtr = isServerTest ? \
					&serverTestInfo[ testNo ] : &clientTestInfo[ testNo ];
	const char *testName = testInfoPtr->testName;
	const BOOLEAN isLoopbackTest = \
			( !strcmp( hostName, "localhost" ) && port == 0 ) ? TRUE : FALSE;
	const BOOLEAN sendHTTP = \
			( flags & TESTFLAG_SENDHTTPREQ ) ? TRUE : FALSE;
	char filenameBuffer[ FILENAME_BUFFER_SIZE ];
#ifdef UNICODE_STRINGS
	wchar_t wcBuffer[ FILENAME_BUFFER_SIZE ];
#endif /* UNICODE_STRINGS */
	SPECIAL_HANDLING_TYPE handlingTypeAlt = SPECIAL_NONE;
	void *fileNamePtr = filenameBuffer;
	int status;

	/* Make sure that we've been given a valid test number to run */
	if( isServerTest )
		{
		if( testNo < SUITEB_FIRST_SERVER || testNo > SUITEB_LAST_SERVER )
			return( FALSE );
		}
	else
		{
		if( testNo < SUITEB_FIRST_CLIENT || testNo > SUITEB_LAST_CLIENT )
			return( FALSE );
		}

	/* If it's an alias for another test, select the base test */
	if( testInfoPtr->aliasTestName != NULL )
		{
		handlingTypeAlt = testInfoPtr->handlingType;
		testInfoPtr = findAliasTest( isServerTest ? \
								&serverTestInfo[ 1 ] : &clientTestInfo[ 1 ],
								testInfoPtr->aliasTestName );
		if( testInfoPtr == NULL )
			{
			assert( 0 );
			return( FALSE );
			}
		}

	/* Acquire the init mutex */
	acquireMutex();
	cryptSuiteBTestConfig( SUITEB_TEST_NONE );	/* Clear any custom config */

	printf( "SVR: Running Suite B server " );
	if( flags & TESTFLAG_GENERIC )
		printf( "as generic test server.\n" );
	else
		printf( "with test %s.\n", testInfoPtr->testName );

	/* Create the SSL/TLS session */
	status = cryptCreateSession( &cryptSession, CRYPT_UNUSED, 
								 CRYPT_SESSION_SSL_SERVER );
	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 );
		}
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_VERSION, 3 );
	if( cryptStatusOK( status ) && testInfoPtr->serverOptions != 0 )
		{
		status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_SSL_OPTIONS, 
									testInfoPtr->serverOptions );
		}
	if( testInfoPtr->clientAuthKeySizeBits > 0 ) 
		{
		/* Tell the test code to expect a client certificate */
		cryptSuiteBTestConfig( 1000 );
		}
	if( cryptStatusError( status ) )
		{
		printf( "cryptSetAttribute() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}

	/* Set up the server information */
	if( isLoopbackTest )
		{
		/* We're running the loopback test, set up a local connect */
		if( !setLocalConnect( cryptSession, 443 ) )
			return( FALSE );
		}
	else
		{
		status = cryptSetAttributeString( cryptSession,
										  CRYPT_SESSINFO_SERVER_NAME,
										  hostName, strlen( hostName ) );
		if( cryptStatusOK( status ) && port != 0 && port != 443 )
			status = cryptSetAttribute( cryptSession, 
										CRYPT_SESSINFO_SERVER_PORT, port );
		if( cryptStatusError( status ) )
			{
			printf( "cryptSetAttribute()/cryptSetAttributeString() failed "
					"with error code %d, line %d.\n", status, __LINE__ );
			return( FALSE );
			}
		}

	/* Set any custom server configuration that may be required.  We have to 
	   do this before we set the server key since some of the tests involve
	   invalid server keys */
	switch( testInfoPtr->handlingType )
		{
		case SPECIAL_SVR_INVALIDCURVE:
			/* Server sends non-Suite B curve */
			status = cryptSuiteBTestConfig( SUITEB_TEST_SVRINVALIDCURVE );
			break;

		case SPECIAL_BOTH_SUPPCURVES:
			/* Client must send both P256 and P384 in supported curves 
			   extension */
			status = cryptSuiteBTestConfig( SUITEB_TEST_BOTHCURVES );
			break;

		case SPECIAL_BOTH_SIGALGO:
			/* Client must send both SHA256 and SHA384 in signature algos
			   extension */
			status = cryptSuiteBTestConfig( SUITEB_TEST_BOTHSIGALGOS );
			break;
		}
	if( cryptStatusError( status ) )
		{
		printf( "Custom config set failed with error code %d, line %d.\n", 
				status, __LINE__ );
		return( FALSE );
		}

	/* Add the server key */
	filenameFromTemplate( filenameBuffer, SERVER_ECPRIVKEY_FILE_TEMPLATE, 
						  testInfoPtr->serverKeySizeBits );
#ifdef UNICODE_STRINGS
	mbstowcs( wcBuffer, filenameBuffer, strlen( filenameBuffer ) + 1 );
	fileNamePtr = wcBuffer;
#endif /* UNICODE_STRINGS */
	status = getPrivateKey( &privateKey, fileNamePtr, USER_PRIVKEY_LABEL,
							TEST_PRIVKEY_PASSWORD );
	if( cryptStatusOK( status ) )
		{
		status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_PRIVATEKEY,
									privateKey );
		cryptDestroyContext( privateKey );
		}
	if( cryptStatusError( status ) )
		{
		printf( "SVR: cryptSetAttribute/AttributeString() failed with error "
				"code %d, line %d.\n", status, __LINE__ );
		return( FALSE );
		}

	/* For the loopback test we also increase the connection timeout to a 
	   higher-than-normal level, since this gives us more time for tracing 
	   through the code when debugging */
	cryptSetAttribute( cryptSession, CRYPT_OPTION_NET_CONNECTTIMEOUT, 120 );

	/* Tell the client that we're ready to go */
	releaseMutex();

	/* Activate the server session */
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
	if( ( testInfoPtr->result && !cryptStatusOK( status ) ) || \
		( !testInfoPtr->result && !cryptStatusError( status ) ) )
		{
		if( testInfoPtr->result )
			printf( "SVR: Test %s failed, should have succeeded.\n",
					testName );
		else
			printf( "SVR: Test %s succeeded, should have failed.\n",
					testName );
		if( cryptStatusError( status ) )
			{
			printExtError( cryptSession, "SVR: Failure reason is:", status, 
						   __LINE__ );
			}
		cryptDestroySession( cryptSession );

		return( FALSE );
		}

	/* Perform any custom post-activation checking that may be required */
	if( testInfoPtr->handlingType != 0 || handlingTypeAlt != 0 )
		{
		const SPECIAL_HANDLING_TYPE handlingType = \
				( handlingTypeAlt != 0 ) ? handlingTypeAlt : \
										   testInfoPtr->handlingType;
		BYTE buffer[ 1024 ];
		int length;

		switch( handlingType )
			{
			case SPECIAL_CLI_TLSALERT:
				status = cryptGetAttributeString( cryptSession, 
									CRYPT_ATTRIBUTE_ERRORMESSAGE, buffer, 
									&length );
				if( cryptStatusError( status ) || \
					memcmp( buffer, "Received TLS alert", 18 ) )
					{
					printf( "SVR: Test %s should have returned a TLS alert "
							"but didn't.\n", testName );
					return( FALSE );
					}
				break;
			}
		}

	/* If we're being asked to send HTTP data, return a basic HTML page */
	if( sendHTTP )
		{
		const char serverReply[] = \
			"HTTP/1.0 200 OK\n"
			"Date: Fri, 7 September 2010 20:02:07 GMT\n"
			"Server: cryptlib Suite B test\n"
			"Content-Type: text/html\n"
			"Connection: Close\n"
			"\n"
			"<!DOCTYPE HTML SYSTEM \"html.dtd\">\n"
			"<html>\n"
			"<head>\n"
			"<title>cryptlib Suite B test page</title>\n"
			"<body>\n"
			"Test message from the cryptlib Suite B server.<p>\n"
			"</body>\n"
			"</html>\n";
		char buffer[ FILEBUFFER_SIZE ];
		int bytesCopied;

		/* 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';
		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 );
			}
		}

	/* Clean up */
	status = cryptDestroySession( cryptSession );
	if( cryptStatusError( status ) )
		{
		printf( "cryptDestroySession() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	printf( "SVR: Suite B server test %s succeeded.\n", testName );

	return( TRUE );
	}
Example #15
0
int main(int argc, char **argv) {
  char  *host = "https://www.pcwebshop.co.uk/";
  int   port  = 443;
  char  *cafile;
  int   status;
  char* serverName;


  CRYPT_CERTIFICATE cryptCert;
  CRYPT_SESSION cryptSession;
  CRYPT_CERTIFICATE trustedCert;
  CRYPT_ATTRIBUTE_TYPE errorLocus;
  CRYPT_ERRTYPE_TYPE errorType;

  if (argc == 4) {
    host = argv[1];
	  port = atoi(argv[2]);
	  cafile = argv[3];
  }  else {
    printf("!!Incorrect arguments");
    return -1;
  }

  memset(&cryptSession, 0, sizeof(cryptSession));

  status = cryptInit();
  if (status != CRYPT_OK) {
    TRACE("Failed to initialize library : %d\n", status);
    return -1;
  }

  if(add_globally_trusted_cert(&trustedCert, cafile) == FALSE) {
    return -1;
  }

  //Create the session
  status = cryptCreateSession(&cryptSession, CRYPT_UNUSED, CRYPT_SESSION_SSL );
  if (status != CRYPT_OK) {
    TRACE("Failed to crate session : %d\n", status);
    return -1;
  }


  serverName = host;
  status = cryptSetAttributeString( cryptSession,
								CRYPT_SESSINFO_SERVER_NAME, serverName,
								paramStrlen( serverName ) );
  if (status != CRYPT_OK) {
    TRACE("Failed cryptSetAttribute CRYPT_SESSINFO_SERVER_NAME: %d\n", status);
    return -1;
  }


  //Specify the Port
  status = cryptSetAttribute( cryptSession,
                             CRYPT_SESSINFO_SERVER_PORT, port );
  if (status != CRYPT_OK) {
    TRACE("Failed cryptSetAttribute CRYPT_SESSINFO_SERVER_PORT: %d\n", status);
    return -1;
  }

  // Activate the session
  status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );

  if( cryptStatusError( status ) ) {
    if (status == CRYPT_ERROR_INVALID) {
      printf("%d\n",CRYPT_ERROR_INVALID);


#ifdef __DETAILED__

      BYTE buffer[ 1024 ];
    	int length;

      status = cryptGetAttributeString( cryptSession,
									CRYPT_ATTRIBUTE_ERRORMESSAGE, buffer,
									&length );

      puts(buffer);

      CRYPT_CERTIFICATE cryptCertificate;

      status = cryptGetAttribute( cryptSession, CRYPT_SESSINFO_RESPONSE, &cryptCertificate );


      if( cryptStatusError( status ) ) {
        TRACE( "Couldn't get certificate, status %d, line %d.\n",
					status, __LINE__ );
        return 0;
			}
      int errorType, errorLocus;

      status = cryptGetAttribute( cryptCertificate, CRYPT_ATTRIBUTE_ERRORTYPE,
									&errorType );
      printf("errorType = %d\n", errorType);

      if( cryptStatusError( status ) ) {
        status = cryptGetAttribute( cryptCertificate,
										CRYPT_ATTRIBUTE_ERRORLOCUS,
										&errorLocus );
        printf("errorLocus = %d\n", errorLocus);
      }

      /*if( cryptStatusOK( status ) && \
			errorType == CRYPT_ERRTYPE_CONSTRAINT && \
			errorLocus == CRYPT_CERTINFO_VALIDFROM )
      */

#endif
      return 0;

    }
    else {
      TRACE("Failed to setup connection : %d\n", status);
      return -1;
    }
  }
  else
    printf("%d\n",CRYPT_OK);


  delete_globally_trusted_cert(trustedCert);
  return CRYPT_OK;

}