Ejemplo n.º 1
0
void check( int n, CRYPT_HANDLE c, char *s )
{
    int status;
    int locus = 0;
    int type = 0;
    int length = 0;

    if ( n == CRYPT_OK )
        return;

    cryptGetAttribute( c, CRYPT_ATTRIBUTE_ERRORLOCUS, &locus );
    cryptGetAttribute( c, CRYPT_ATTRIBUTE_ERRORTYPE, &type );

    fprintf( stderr, "%s failed.\n", s );
    fprintf( stderr, "\tError code: %d\n", n );
    if ( locus != 0 )
        fprintf( stderr, "\tError locus: %d\n", locus );
    if ( type != 0 )
        fprintf( stderr, "\tError type: %d\n", type );

    status = cryptGetAttributeString( c, CRYPT_ATTRIBUTE_ERRORMESSAGE,
                                      0, &length );
    if ( cryptStatusOK( status ) ) {
        char * err = malloc( length );
        if ( !err )
            exit( -1 );
        status = cryptGetAttributeString( c, CRYPT_ATTRIBUTE_ERRORMESSAGE,
                                          err, &length );
        if ( cryptStatusOK( status ) )
            fprintf( stderr, "\tError message: %s\n", err );
    }

    exit( -1 );
}
Ejemplo n.º 2
0
static int exec_enroll(int argc, char **argv) {
  const char *dbfilename, *dn;
  CRYPT_KEYSET keyset;
  CRYPT_CERTIFICATE pki_user;
  char userID[CRYPT_MAX_TEXTSIZE + 1], issuePW[CRYPT_MAX_TEXTSIZE + 1], revPW[CRYPT_MAX_TEXTSIZE + 1];
  int userIDlen, issuePWlen, revPWlen;
  int status;

  /* get args */
  if (argc != 2) {
    fprintf(stderr, "usage: enroll dbfilename dn\n");
    return 1;
  }
  dbfilename = argv[0]; dn = argv[1];

  status = cryptKeysetOpen(&keyset, CRYPT_UNUSED, CRYPT_KEYSET_DATABASE_STORE, dbfilename, CRYPT_KEYOPT_NONE);
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "(%s:%d) cryptlib error %d while closing CA privkey keyset\n", __FILE__, __LINE__, status);
    return 1;
  }

  status = cryptCreateCert(&pki_user, CRYPT_UNUSED, CRYPT_CERTTYPE_PKIUSER);
  WARN_IF(status);

  status = cryptSetAttributeString(pki_user, CRYPT_CERTINFO_DN, dn, strlen(dn));
  WARN_IF(status);

  status = cryptCAAddItem(keyset, pki_user);
  WARN_IF(status);

  status = cryptKeysetClose(keyset);
  WARN_IF(status);

  status = cryptGetAttributeString(pki_user, CRYPT_CERTINFO_PKIUSER_ID, userID, &userIDlen);
  WARN_IF(status);
  userID[userIDlen] = '\0';
  status = cryptGetAttributeString(pki_user, CRYPT_CERTINFO_PKIUSER_ISSUEPASSWORD, issuePW, &issuePWlen);
  WARN_IF(status);
  issuePW[issuePWlen] = '\0';
  status = cryptGetAttributeString(pki_user, CRYPT_CERTINFO_PKIUSER_REVPASSWORD, revPW, &revPWlen);
  WARN_IF(status);
  revPW[revPWlen] = '\0';

  fprintf(stdout, "%s\n", userID);
  fprintf(stdout, "%s\n", issuePW);
  fprintf(stdout, "%s\n", revPW);

  status = cryptDestroyCert(pki_user);
  WARN_IF(status);

  return 0;
}
Ejemplo n.º 3
0
static int gen_sha2(
    uchar * inbufp,
    int bsize,
    uchar * outbufp)
{
    CRYPT_CONTEXT hashContext;
    uchar hash[40];
    int ansr;

    memset(hash, 0, 40);
    if (cryptInit() != CRYPT_OK)
    {
        FATAL(MSG_ERROR, "initializing cryptlib");
    }
    if (cryptCreateContext(&hashContext, CRYPT_UNUSED, CRYPT_ALGO_SHA2) != CRYPT_OK)
    {
        FATAL(MSG_ERROR, "creating cryptlib hash context");
    }
    cryptEncrypt(hashContext, inbufp, bsize);
    cryptEncrypt(hashContext, inbufp, 0);
    cryptGetAttributeString(hashContext, CRYPT_CTXINFO_HASHVALUE, hash, &ansr);
    cryptDestroyContext(hashContext);
    cryptEnd();
    memcpy(outbufp, hash, ansr);
    return ansr;
}
Ejemplo n.º 4
0
int gen_hash(
    unsigned char *inbufp,
    int bsize,
    unsigned char *outbufp,
    CRYPT_ALGO_TYPE alg)
{
    CRYPT_CONTEXT hashContext;
    unsigned char hash[40];
    int ansr = -1;

    if (alg != CRYPT_ALGO_SHA1 && alg != CRYPT_ALGO_SHA2)
        return -1;
    memset(hash, 0, 40);
    if (cryptInit_wrapper() != CRYPT_OK)
        return -1;

    if (cryptCreateContext(&hashContext, CRYPT_UNUSED, alg) != CRYPT_OK)
        return -1;
    cryptEncrypt(hashContext, inbufp, bsize);
    cryptEncrypt(hashContext, inbufp, 0);
    if (cryptGetAttributeString(
            hashContext, CRYPT_CTXINFO_HASHVALUE, hash, &ansr) != CRYPT_OK)
    {
        return -1;
    }
    cryptDestroyContext(hashContext);
    if (ansr > 0)
        memcpy(outbufp, hash, ansr);
    return ansr;
}
Ejemplo n.º 5
0
static int exec_info(int argc, char **argv) {
  const char *dbfilename;
  CRYPT_KEYSET keyset;
  CRYPT_CERTIFICATE pki_user;
  char userID[CRYPT_MAX_TEXTSIZE + 1], issuePW[CRYPT_MAX_TEXTSIZE + 1], revPW[CRYPT_MAX_TEXTSIZE + 1];
  int userIDlen, issuePWlen, revPWlen;
  int status;
  CRYPT_KEYID_TYPE id_type;
  const char *id;
  if (argc < 3) return 1;
  dbfilename = argv[0];
  status = cryptKeysetOpen(&keyset, CRYPT_UNUSED, CRYPT_KEYSET_DATABASE_STORE, dbfilename, CRYPT_KEYOPT_NONE);
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "(%s:%d) cryptlib error %d while closing CA privkey keyset\n", __FILE__, __LINE__, status);
    return 1;
  }
  id = argv[2];
  if (strcmp(argv[1], "-e") == 0) {
    id_type = CRYPT_KEYID_EMAIL;
  }
  else if (strcmp(argv[1], "-n") == 0) {
    id_type = CRYPT_KEYID_NAME;
  }
  status = cryptCAGetItem(keyset, &pki_user, CRYPT_CERTTYPE_PKIUSER, id_type, id);
  WARN_IF(status);
  status = cryptKeysetClose(keyset);
  WARN_IF(status);
  status = cryptGetAttributeString(pki_user, CRYPT_CERTINFO_PKIUSER_ID, userID, &userIDlen);
  WARN_IF(status);
  userID[userIDlen] = '\0';
  status = cryptGetAttributeString(pki_user, CRYPT_CERTINFO_PKIUSER_ISSUEPASSWORD, issuePW, &issuePWlen);
  WARN_IF(status);
  issuePW[issuePWlen] = '\0';
  status = cryptGetAttributeString(pki_user, CRYPT_CERTINFO_PKIUSER_REVPASSWORD, revPW, &revPWlen);
  WARN_IF(status);
  revPW[revPWlen] = '\0';

  fprintf(stdout, "%s\n", userID);
  fprintf(stdout, "%s\n", issuePW);
  fprintf(stdout, "%s\n", revPW);

  status = cryptDestroyCert(pki_user);
  WARN_IF(status);
  return 0;

}
Ejemplo n.º 6
0
static void testStressObjects( void )
	{
	CRYPT_HANDLE *handleArray = malloc( NO_OBJECTS * sizeof( CRYPT_HANDLE ) );
	BYTE hash[ CRYPT_MAX_HASHSIZE ];
	int i, length, status;

	printf( "Running object stress test." );
	assert( handleArray  != NULL );
	for( i = 0; i < NO_OBJECTS; i++ )
		{
		status = cryptCreateContext( &handleArray[ i ], CRYPT_UNUSED,
									 CRYPT_ALGO_SHA );
		if( cryptStatusError( status ) )
			printf( "cryptEncrypt() failed at %d with status %d.\n", i,
					status );
		}
	printf( "." );
	for( i = 0; i < NO_OBJECTS; i++ )
		{
		status = cryptEncrypt( handleArray[ i ], "12345678", 8 );
		if( cryptStatusError( status ) )
			printf( "cryptEncrypt() failed at %d with status %d.\n", i, status );
		}
	printf( "." );
	for( i = 0; i < NO_OBJECTS; i++ )
		{
		status = cryptEncrypt( handleArray[ i ], "", 0 );
		if( cryptStatusError( status ) )
			printf( "cryptEncrypt() failed at %d with status %d.\n", i,
					status );
		}
	printf( "." );
	for( i = 0; i < NO_OBJECTS; i++ )
		{
		status = cryptGetAttributeString( handleArray[ i ],
								CRYPT_CTXINFO_HASHVALUE, hash, &length );
		if( cryptStatusError( status ) )
			printf( "cryptEncrypt() failed at %d with status %d.\n", i,
					status );
		}
	printf( "." );
	for( i = 0; i < NO_OBJECTS; i++ )
		{
		status = cryptDestroyContext( handleArray[ i ] );
		if( cryptStatusError( status ) )
			printf( "cryptEncrypt() failed at %d with status %d.\n", i,
					status );
		}
	free( handleArray );
	puts( "." );
	}
Ejemplo n.º 7
0
static void smokeTestAttributes( const CRYPT_HANDLE cryptHandle )
	{
	int attribute;

	printf( "." );
	for( attribute = CRYPT_ATTRIBUTE_NONE; attribute < 8000; attribute++ )
		{
		char buffer[ 1024 ];
		int value;

		cryptGetAttribute( cryptHandle, attribute, &value );
		cryptGetAttributeString( cryptHandle, attribute, buffer, &value );
		}
	cryptDestroyObject( cryptHandle );
	}
Ejemplo n.º 8
0
static int testKeysetWrite( const CRYPT_KEYSET_TYPE keysetType,
							const C_STR keysetName )
	{
	CRYPT_KEYSET cryptKeyset;
	CRYPT_CERTIFICATE cryptCert;
	CRYPT_CONTEXT pubKeyContext, privKeyContext;
	C_CHR filenameBuffer[ FILENAME_BUFFER_SIZE ];
	C_CHR name[ CRYPT_MAX_TEXTSIZE + 1 ];
	int length, status;

	/* Import the certificate from a file - this is easier than creating one
	   from scratch.  We use one of the later certs in the test set, since
	   this contains an email address, which the earlier ones don't */
	status = importCertFromTemplate( &cryptCert, CERT_FILE_TEMPLATE, 
									 EMAILADDR_CERT_NO );
	if( cryptStatusError( status ) )
		{
		printf( "Couldn't read certificate from file, status %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}

	/* Make sure that the certificate does actually contain an email 
	   address */
	status = cryptGetAttributeString( cryptCert, CRYPT_CERTINFO_EMAIL,
									  name, &length );
	if( cryptStatusError( status ) )
		{
		printf( "Certificate doesn't contain an email address and can't be "
				"used for testing,\n  line %d.\n", __LINE__ );
		return( FALSE );
		}

	/* Create the database keyset with a check to make sure this access
	   method exists so we can return an appropriate error message.  If the
	   database table already exists, this will return a duplicate data
	   error so we retry the open with no flags to open the existing database
	   keyset for write access */
	status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, keysetType,
							  keysetName, CRYPT_KEYOPT_CREATE );
	if( cryptStatusOK( status ) )
		printf( "Created new certificate database '%s'.\n", keysetName );
	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 */
		cryptDestroyCert( cryptCert );
		return( CRYPT_ERROR_NOTAVAIL );
		}
	if( status == CRYPT_ERROR_DUPLICATE )
		status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, keysetType,
								  keysetName, 0 );
	if( cryptStatusError( status ) )
		{
		cryptDestroyCert( cryptCert );
		printf( "cryptKeysetOpen() failed with error code %d, line %d.\n",
				status, __LINE__ );
		if( status == CRYPT_ERROR_OPEN )
			return( CRYPT_ERROR_FAILED );
		return( FALSE );
		}

	/* Write the key to the database */
	puts( "Adding certificate." );
	status = cryptAddPublicKey( cryptKeyset, cryptCert );
	if( status == CRYPT_ERROR_DUPLICATE )
		{
		/* The key is already present, delete it and retry the write */
		status = cryptGetAttributeString( cryptCert,
								CRYPT_CERTINFO_COMMONNAME, name, &length );
		if( cryptStatusOK( status ) )
			{
#ifdef UNICODE_STRINGS
			length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
			name[ length ] = TEXT( '\0' );
			status = cryptDeleteKey( cryptKeyset, CRYPT_KEYID_NAME, name );
			}
		if( cryptStatusError( status ) )
			return( extErrorExit( cryptKeyset, "cryptDeleteKey()", status,
								  __LINE__ ) );
		status = cryptAddPublicKey( cryptKeyset, cryptCert );
		}
	if( cryptStatusError( status ) )
		{
		printExtError( cryptKeyset, "cryptAddPublicKey()", status, __LINE__ );

		/* LDAP writes can fail due to the chosen directory not supporting the
		   schema du jour, so we're a bit more careful about cleaning up since
		   we'll skip the error and continue processing */
		cryptDestroyCert( cryptCert );
		cryptKeysetClose( cryptKeyset );
		return( FALSE );
		}
	cryptDestroyCert( cryptCert );

	/* Add a second certificate with C=US so that we've got enough certs to 
	   properly exercise the query code.  This certificate is highly unusual 
	   in that it doesn't have a DN, so we have to move up the DN looking 
	   for higher-up values, in this case the OU */
	if( keysetType != CRYPT_KEYSET_LDAP )
		{
		status = importCertFromTemplate( &cryptCert, CERT_FILE_TEMPLATE, 2 );
		if( cryptStatusError( status ) )
			{
			printf( "Couldn't read certificate from file, status %d, "
					"line %d.\n", status, __LINE__ );
			return( FALSE );
			}
		status = cryptAddPublicKey( cryptKeyset, cryptCert );
		if( status == CRYPT_ERROR_DUPLICATE )
			{
			status = cryptGetAttributeString( cryptCert,
							CRYPT_CERTINFO_COMMONNAME, name, &length );
			if( cryptStatusError( status ) )
				status = cryptGetAttributeString( cryptCert,
							CRYPT_CERTINFO_ORGANIZATIONALUNITNAME, name, &length );
			if( cryptStatusOK( status ) )
				{
#ifdef UNICODE_STRINGS
				length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
				name[ length ] = TEXT( '\0' );
				status = cryptDeleteKey( cryptKeyset, CRYPT_KEYID_NAME, name );
				}
			if( cryptStatusOK( status ) )
				status = cryptAddPublicKey( cryptKeyset, cryptCert );
			}
		if( cryptStatusError( status ) )
			return( extErrorExit( cryptKeyset, "cryptAddPublicKey()",
								  status, __LINE__ ) );
		cryptDestroyCert( cryptCert );
		}

	/* Add a third certificate with a DN that'll cause problems for some 
	   storage technologies */
	if( !loadRSAContexts( CRYPT_UNUSED, &pubKeyContext, &privKeyContext ) )
		return( FALSE );
	status = cryptCreateCert( &cryptCert, CRYPT_UNUSED,
							  CRYPT_CERTTYPE_CERTIFICATE );
	if( cryptStatusError( status ) )
		{
		printf( "cryptCreateCert() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	status = cryptSetAttribute( cryptCert,
					CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, pubKeyContext );
	if( cryptStatusError( status ) )
		return( attrErrorExit( cryptCert, "cryptSetAttribute()", status,
							   __LINE__ ) );
	if( !addCertFields( cryptCert, sqlCertData, __LINE__ ) )
		return( FALSE );
	status = cryptSignCert( cryptCert, privKeyContext );
	if( cryptStatusError( status ) )
		return( attrErrorExit( cryptCert, "cryptSignCert()", status,
							   __LINE__ ) );
	destroyContexts( CRYPT_UNUSED, pubKeyContext, privKeyContext );
	status = cryptAddPublicKey( cryptKeyset, cryptCert );
	if( cryptStatusError( status ) )
		{
		/* The key is already present, delete it and retry the write */
		status = cryptGetAttributeString( cryptCert,
								CRYPT_CERTINFO_COMMONNAME, name, &length );
		if( cryptStatusOK( status ) )
			{
#ifdef UNICODE_STRINGS
			length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
			name[ length ] = TEXT( '\0' );
			status = cryptDeleteKey( cryptKeyset, CRYPT_KEYID_NAME, name );
			}
		if( cryptStatusError( status ) )
			return( extErrorExit( cryptKeyset, "cryptDeleteKey()", status,
								  __LINE__ ) );
		status = cryptAddPublicKey( cryptKeyset, cryptCert );
		}
	if( cryptStatusError( status ) )
		{
		return( extErrorExit( cryptKeyset, "cryptAddPublicKey()",
							  status, __LINE__ ) );
		}
	cryptDestroyCert( cryptCert );

	/* Now try the same thing with a CRL.  This code also tests the
	   duplicate-detection mechanism, if we don't get a duplicate error
	   there's a problem */
	puts( "Adding CRL." );
	status = importCertFromTemplate( &cryptCert, CRL_FILE_TEMPLATE, 1 );
	if( cryptStatusError( status ) )
		{
		printf( "Couldn't read CRL from file, status %d, line %d.\n", 
				status, __LINE__ );
		return( TRUE );
		}
	status = cryptAddPublicKey( cryptKeyset, cryptCert );
	if( cryptStatusError( status ) && status != CRYPT_ERROR_DUPLICATE )
		return( extErrorExit( cryptKeyset, "cryptAddPublicKey()", status,
							  __LINE__ ) );
	status = cryptAddPublicKey( cryptKeyset, cryptCert );
	if( status != CRYPT_ERROR_DUPLICATE )
		{
		printf( "Addition of duplicate item to keyset failed to produce "
			    "CRYPT_ERROR_DUPLICATE, status %d, line %d.\n", status,
				__LINE__ );
		return( FALSE );
		}
	cryptDestroyCert( cryptCert );

	/* Finally, try it with a certificate chain */
	puts( "Adding certificate chain." );
	filenameParamFromTemplate( filenameBuffer, CERTCHAIN_FILE_TEMPLATE, 
							   CERT_CHAIN_NO );
	status = importCertFile( &cryptCert, filenameBuffer );
	if( cryptStatusError( status ) )
		{
		printf( "Couldn't read certificate chain from file, status %d, "
				"line %d.\n", status, __LINE__ );
		return( FALSE );
		}
	status = cryptAddPublicKey( cryptKeyset, cryptCert );
	if( cryptStatusError( status ) && status != CRYPT_ERROR_DUPLICATE )
		return( extErrorExit( cryptKeyset, "cryptAddPublicKey()", status,
							  __LINE__ ) );
	cryptDestroyCert( cryptCert );

	/* In addition to the other certs we also add the generic user 
	   certificate, which is used later in other tests.  Since it may have 
	   been added earlier we try and delete it first (we can't use the 
	   existing version since the issuerAndSerialNumber won't match the one 
	   in the private-key keyset) */
	status = getPublicKey( &cryptCert, USER_PRIVKEY_FILE,
						   USER_PRIVKEY_LABEL );
	if( cryptStatusError( status ) )
		{
		printf( "Couldn't read user certificate from file, status %d, line "
				"%d.\n", status, __LINE__ );
		return( FALSE );
		}
	status = cryptGetAttributeString( cryptCert, CRYPT_CERTINFO_COMMONNAME,
									  name, &length );
	if( cryptStatusError( status ) )
		return( FALSE );
#ifdef UNICODE_STRINGS
	length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
	name[ length ] = TEXT( '\0' );
	do
		status = cryptDeleteKey( cryptKeyset, CRYPT_KEYID_NAME, name );
	while( cryptStatusOK( status ) );
	status = cryptAddPublicKey( cryptKeyset, cryptCert );
	if( status == CRYPT_ERROR_NOTFOUND )
		{
		/* This can occur if a database keyset is defined but hasn't been
		   initialised yet so the necessary tables don't exist, it can be
		   opened but an attempt to add a key will return a not found error
		   since it's the table itself rather than any item within it that
		   isn't being found */
		status = CRYPT_OK;
		}
	if( cryptStatusError( status ) )
		return( extErrorExit( cryptKeyset, "cryptAddPublicKey()", status,
							  __LINE__ ) );
	cryptDestroyCert( cryptCert );

	/* Finally, if ECC is enabled we also add ECC certificates that are used
	   later in other tests */
	if( cryptStatusOK( cryptQueryCapability( CRYPT_ALGO_ECDSA, NULL ) ) )
		{
#ifdef UNICODE_STRINGS
		wchar_t wcBuffer[ FILENAME_BUFFER_SIZE ];
#endif /* UNICODE_STRINGS */
		void *fileNamePtr = filenameBuffer;

		/* Add the P256 certificate */
		filenameFromTemplate( filenameBuffer, 
							  SERVER_ECPRIVKEY_FILE_TEMPLATE, 256 );
#ifdef UNICODE_STRINGS
		mbstowcs( wcBuffer, filenameBuffer, strlen( filenameBuffer ) + 1 );
		fileNamePtr = wcBuffer;
#endif /* UNICODE_STRINGS */
		status = getPublicKey( &cryptCert, fileNamePtr,
							   USER_PRIVKEY_LABEL );
		if( cryptStatusError( status ) )
			{
			printf( "Couldn't read user certificate from file, status %d, "
					"line %d.\n", status, __LINE__ );
			return( FALSE );
			}
		status = cryptAddPublicKey( cryptKeyset, cryptCert );
		if( cryptStatusError( status ) && status != CRYPT_ERROR_DUPLICATE )
			return( extErrorExit( cryptKeyset, "cryptAddPublicKey()", status,
								  __LINE__ ) );
		cryptDestroyCert( cryptCert );

		/* Add the P384 certificate */
		filenameFromTemplate( filenameBuffer, 
							  SERVER_ECPRIVKEY_FILE_TEMPLATE, 384 );
#ifdef UNICODE_STRINGS
		mbstowcs( wcBuffer, filenameBuffer, strlen( filenameBuffer ) + 1 );
		fileNamePtr = wcBuffer;
#endif /* UNICODE_STRINGS */
		status = getPublicKey( &cryptCert, fileNamePtr,
							   USER_PRIVKEY_LABEL );
		if( cryptStatusError( status ) )
			{
			printf( "Couldn't read user certificate from file, status %d, "
					"line %d.\n", status, __LINE__ );
			return( FALSE );
			}
		status = cryptAddPublicKey( cryptKeyset, cryptCert );
		if( cryptStatusError( status ) && status != CRYPT_ERROR_DUPLICATE )
			return( extErrorExit( cryptKeyset, "cryptAddPublicKey()", status,
								  __LINE__ ) );
		cryptDestroyCert( cryptCert );
		}

	/* Make sure the deletion code works properly.  This is an artifact of
	   the way RDBMS' work, the delete query can execute successfully but
	   not delete anything so we make sure the glue code correctly
	   translates this into a CRYPT_DATA_NOTFOUND */
	status = cryptDeleteKey( cryptKeyset, CRYPT_KEYID_NAME,
							 TEXT( "Mr.Not Appearing in this Keyset" ) );
	if( status != CRYPT_ERROR_NOTFOUND )
		{
		puts( "Attempt to delete a nonexistant key reports success, the "
			  "database backend glue\ncode needs to be fixed to handle this "
			  "correctly." );
		return( FALSE );
		}

	/* Close the keyset */
	status = cryptKeysetClose( cryptKeyset );
	if( cryptStatusError( status ) )
		{
		printf( "cryptKeysetClose() failed with error code %d, line %d.\n",
				status, __LINE__ );
		}

	return( TRUE );
	}
Ejemplo n.º 9
0
static int testProcessing( const CRYPT_ALGO_TYPE cryptAlgo,
						   const CRYPT_MODE_TYPE cryptMode,
						   const CRYPT_QUERY_INFO cryptQueryInfo )
	{
	BYTE buffer1[ DATABUFFER_SIZE ], buffer2[ DATABUFFER_SIZE ];
	BYTE hash1[ CRYPT_MAX_HASHSIZE ], hash2[ CRYPT_MAX_HASHSIZE ];
	const int blockSize = ( cryptMode == CRYPT_MODE_ECB || \
							cryptMode == CRYPT_MODE_CBC ) ? \
						  cryptQueryInfo.blockSize : 1;
	int length1, length2, i;

	/* Initialise the buffers with a known data pattern */
	memset( buffer1, '*', DATABUFFER_SIZE );
	memcpy( buffer1, "12345678", 8 );
	memcpy( buffer2, buffer1, DATABUFFER_SIZE );

	/* Process the data using various block sizes */
	printf( "Testing algorithm %d, mode %d, for %d-byte buffer with\n  block "
			"count ", cryptAlgo, ( cryptMode == CRYPT_UNUSED ) ? 0 : cryptMode,
			DATABUFFER_SIZE );
	for( i = 1; i <= MAX_BLOCKS; i++ )
		{
		CRYPT_CONTEXT cryptContext;
		int status;

		memcpy( buffer1, buffer2, DATABUFFER_SIZE );
		printf( "%d%s ", i, ( i == MAX_BLOCKS ) ? "." : "," );

		/* Encrypt the data with random block sizes */
		status = cryptCreateContext( &cryptContext, CRYPT_UNUSED, cryptAlgo );
		if( cryptStatusError( status ) )
			return( status );
		if( cryptMode != CRYPT_UNUSED )
			{
			status = cryptSetAttribute( cryptContext, CRYPT_CTXINFO_MODE,
										cryptMode );
			if( cryptStatusError( status ) )
				return( status );
			if( cryptMode != CRYPT_MODE_ECB && cryptAlgo != CRYPT_ALGO_RC4 )
				{
				status = cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_IV,
								"1234567887654321", cryptQueryInfo.blockSize );
				if( cryptStatusError( status ) )
					return( status );
				}
			}
		if( cryptQueryInfo.keySize )
			{
			status = cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEY,
								"12345678876543211234567887654321",
								cryptQueryInfo.keySize );
			if( cryptStatusError( status ) )
				return( status );
			}
		status = processData( cryptContext, buffer1, i, blockSize,
							  cryptEncrypt );
		if( cryptStatusError( status ) )
			return( status );
		if( cryptAlgo >= CRYPT_ALGO_FIRST_HASH )
			{
			status = cryptGetAttributeString( cryptContext,
								CRYPT_CTXINFO_HASHVALUE, hash1, &length1 );
			if( cryptStatusError( status ) )
				return( status );
			}
		status = cryptDestroyContext( cryptContext );
		if( cryptStatusError( status ) )
			return( status );

		/* Decrypt the data again with random block sizes */
		status = cryptCreateContext( &cryptContext, CRYPT_UNUSED, cryptAlgo );
		if( cryptStatusError( status ) )
			return( status );
		if( cryptMode != CRYPT_UNUSED )
			{
			status = cryptSetAttribute( cryptContext, CRYPT_CTXINFO_MODE,
										cryptMode );
			if( cryptStatusError( status ) )
				return( status );
			if( cryptMode != CRYPT_MODE_ECB && cryptAlgo != CRYPT_ALGO_RC4 )
				{
				status = cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_IV,
								"1234567887654321", cryptQueryInfo.blockSize );
				if( cryptStatusError( status ) )
					return( status );
				}
			}
		if( cryptQueryInfo.keySize )
			{
			status = cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEY,
								"12345678876543211234567887654321",
								cryptQueryInfo.keySize );
			if( cryptStatusError( status ) )
				return( status );
			}
		status = processData( cryptContext, buffer1, i, blockSize,
							  cryptDecrypt );
		if( cryptStatusError( status ) )
			return( status );
		if( cryptAlgo >= CRYPT_ALGO_FIRST_HASH )
			{
			status = cryptGetAttributeString( cryptContext,
								CRYPT_CTXINFO_HASHVALUE, hash2, &length2 );
			if( cryptStatusError( status ) )
				return( status );
			}
		status = cryptDestroyContext( cryptContext );
		if( cryptStatusError( status ) )
			return( status );

		/* Make sure the values match */
		if( cryptAlgo >= CRYPT_ALGO_FIRST_HASH )
			{
			if( ( length1 != length2 ) || memcmp( hash1, hash2, length1 ) )
				{
				puts( "Error: Hash value of identical buffers differs." );
				return( -1234 );
				}
			}
		else
			if( memcmp( buffer1, buffer2, DATABUFFER_SIZE ) )
				{
				printf( "Decrypted data != encrypted data for algorithm %d.\n",
						cryptAlgo );
				return( -1234 );
				}
		}
	printf( "\n" );

	return( CRYPT_OK );
	}
Ejemplo n.º 10
0
int main(int argc, char const *argv[])
{ 
  
  struct passwd *pws;       /* info for input user */
  char   *pwname;       /* username */
  char   *pwdir;        /* home directory */

  char *encFile;
  char *encKey;
  int encKeyFd;    //file state
  char *encKeyPtr;           /* Pointer to encrypted data */
  int encKeySize;           /* Buffer bytes availble for decrypt */

  struct stat fileStat;     /* Struce for checking file attributes */

  char          *keyFile;        /* GPG key ring file name */
  char *gpgPrivateKeyPtr;

  int  ret;            /* Return code */
  int  i;              /* Loop iterator */
  int  bytesCopied;    /* Bytes output by cryptlib enc/dec ops */
  int  reqAttrib;      /* Crypt required attributed */

  CRYPT_ENVELOPE dataEnv;    /* Envelope for enc/dec */
  CRYPT_KEYSET   keyset;     /* GPG keyset */
  CRYPT_CONTEXT   symContext; /* Key context */
  char label[100];           /* Private key label */
  int  labelLength;          /* Length of label */
  char passbuf[1024];        /* Buffer for GPG key passphrase */
  struct termios ts, ots;    /* Strutures for saving/modifying term attribs */

  char        *encDataPtr;       /* Pointer to encrypted data */
  int         encDataSize;       /* Size of encrypted data */
  struct passwd *userInfo;       /* Password info for input user */


  int encFileFd;          /* Destination (Encrypted) File Descriptor */
  int encFileSize;        /* Bytes of encrypted data */ 
  char * encFilePtr;      /* Pointer to enc text */
  char *clrFilePtr;     /* Pointer to clear text */
  int clrFileSize;        /* Bytes of clear text */
  char *clrKeyPtr;
  int clrKeySize;


  struct stat encFileInfo;

  uid = getuid();
  pws = getpwuid(uid);
  pwname = pws->pw_name;//get the user login name;
  pwdir = pws->pw_dir;//get the user dir path

  //Check arguments number 
  if (argc!=2) {
        printf("slient exit\n");
        exit (1);
  }


  //Get encrepted file
  encFile = malloc(strlen(argv[1]) + 4);
  strcpy(encFile, argv[1]);
  strcat(encFile, ".enc");
 

  //Get gpg encrepted key name
  encKey = malloc(strlen(encFile) + strlen(pwname) +5 );
  strcpy(encKey,encFile);
  strcat(encKey, ".");
  strcat(encKey, pwname);
  strcat(encKey, ".key");


  //Open gpg encrepted key
  encKeyFd=open(encKey, O_RDONLY);
  if (encKeyFd<=0){perror("(2) open encKeyFd2");exit(encKeyFd);}
  ret=fstat(encKeyFd,&fileStat);
  if (ret!=0){perror("fstat encKeyFd");exit(ret);}
  encKeySize=fileStat.st_size;
  encKeyPtr=malloc(encKeySize);
  if (encKeyPtr==NULL){perror("malloc encData");exit(__LINE__);}
  ret=read(encKeyFd,encKeyPtr,encKeySize);
  if (ret!=encKeySize){perror("read encData");exit(ret);}
  close(encKeyFd);
 
   

  //Get the private key name
  gpgPrivateKeyPtr=malloc(strlen(pwdir)
               + strlen("/.gnupg/secring.gpg") + 1);
  getPrivateKeyName(gpgPrivateKeyPtr,uid);


  //Decrypt key
  cryptInit();
  ret=cryptAddRandom( NULL , CRYPT_RANDOM_SLOWPOLL);
  checkCryptNormal(ret,"cryptAddRandom",__LINE__);
  ret=cryptKeysetOpen(&keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, gpgPrivateKeyPtr, CRYPT_KEYOPT_READONLY);
  free(gpgPrivateKeyPtr);
  checkCryptNormal(ret,"cryptKeysetOpen",__LINE__);
  ret=cryptCreateEnvelope(&dataEnv, CRYPT_UNUSED, CRYPT_FORMAT_AUTO);
  checkCryptNormal(ret,"cryptCreateEnvelope",__LINE__);
  ret=cryptSetAttribute(dataEnv, CRYPT_ENVINFO_KEYSET_DECRYPT, keyset);
  checkCryptNormal(ret,"cryptSetAttribute",__LINE__);
  ret=cryptPushData(dataEnv,encKeyPtr,encKeySize,&bytesCopied);
  /*  Expect non-zero return -- indicates need private key */
  ret=cryptGetAttribute(dataEnv, CRYPT_ATTRIBUTE_CURRENT, &reqAttrib); 
  if (reqAttrib != CRYPT_ENVINFO_PRIVATEKEY) 
     {printf("Decrypt error\n");exit(ret);}
  ret=cryptGetAttributeString(dataEnv, CRYPT_ENVINFO_PRIVATEKEY_LABEL, label, &labelLength);
  label[labelLength]='\0';
  checkCryptNormal(ret,"cryptGetAttributeString",__LINE__); 

  
  /*===============================================
    Get the passphrase
    ===============================================
  */

  tcgetattr(STDIN_FILENO, &ts);
  ots = ts;


  ts.c_lflag &= ~ECHO;
  ts.c_lflag |= ECHONL;
  tcsetattr(STDIN_FILENO, TCSAFLUSH, &ts);


  tcgetattr(STDIN_FILENO, &ts);
  if (ts.c_lflag & ECHO) {
    fprintf(stderr, "Failed to turn off echo\n");
    tcsetattr(STDIN_FILENO, TCSANOW, &ots);
    exit(1);
  }

  printf("Enter password for <%s>: ",label);
  fflush(stdout);
  fgets(passbuf, 1024, stdin);

  tcsetattr(STDIN_FILENO, TCSANOW, &ots);   

  ret=cryptSetAttributeString(dataEnv, CRYPT_ENVINFO_PASSWORD,
                             passbuf, strlen(passbuf)-1);
  if (ret != CRYPT_OK) {
    if (ret=CRYPT_ERROR_WRONGKEY) {
      printf("Wrong Key\n");
      exit(ret);
    }else{ 
      printf("cryptSetAttributeString line %d returned <%d>\n",__LINE__,ret);
      exit(ret);
    }
  }



  ret=cryptFlushData(dataEnv);
  checkCryptNormal(ret,"cryptFlushData",__LINE__);

  clrKeySize=KEYSIZE;
  clrKeyPtr=malloc(clrKeySize);
  if (clrKeyPtr==NULL){perror("malloc");exit(__LINE__);}
  bzero(clrKeyPtr,clrKeySize);

  ret=cryptPopData(dataEnv,clrKeyPtr,clrKeySize,&bytesCopied);
  checkCryptNormal(ret,"cryptPopData",__LINE__);

  ret=cryptDestroyEnvelope(dataEnv);  
  checkCryptNormal(ret,"cryptDestroyEnvelope",__LINE__);
  cryptKeysetClose(keyset);
  checkCryptNormal(ret,"cryptKeysetClose",__LINE__);

  printf("Bytes decrypted <%d>\n",bytesCopied);
  // for (i=0;i<bytesCopied;i++){printf("%c",clrKeyPtr[i]);}
  ret=cryptEnd();
  checkCryptNormal(ret,"cryptEnd",__LINE__);
 


  //read enc file
  encFileFd=open(encFile, O_RDONLY);
  if (encFileFd<=0){perror("(2) open encFileFd1");exit(encFileFd);}
  ret=fstat(encFileFd,&encFileInfo);
  if (ret!=0){perror("fstat encFileFd");exit(ret);}
  encFileSize=encFileInfo.st_size;
  encFilePtr=malloc(encFileSize);
  if (encFilePtr==NULL){perror("malloc encData");exit(__LINE__);}
  ret=read(encFileFd,encFilePtr,encFileSize);
  if (ret!=encFileSize){perror("read encData");exit(ret);}
  close(encFileFd);


  //Decrypt and get the content of decrepted file
  cryptInit();
  ret=cryptAddRandom( NULL , CRYPT_RANDOM_SLOWPOLL);
  checkCryptNormal(ret,"cryptAddRandom",__LINE__);

  cryptCreateEnvelope(&dataEnv, CRYPT_UNUSED, CRYPT_FORMAT_AUTO);
  checkCryptNormal(ret,"cryptCreateEnvelope",__LINE__);
  cryptPushData(dataEnv,encFilePtr,encFileSize,&bytesCopied);
 
  checkCryptNormal(ret,"cryptPushData",__LINE__);
  cryptCreateContext(&symContext,CRYPT_UNUSED,SYMMETRIC_ALG);
  checkCryptNormal(ret,"cryptCreateContext",__LINE__);
 
  cryptSetAttributeString(symContext, CRYPT_CTXINFO_KEY,clrKeyPtr,clrKeySize);
  checkCryptNormal(ret,"cryptSetAttributeString",__LINE__);
  cryptSetAttribute(dataEnv,CRYPT_ENVINFO_SESSIONKEY,symContext);
  checkCryptNormal(ret,"cryptSetAttribute",__LINE__);

  ret=cryptDestroyContext(symContext);
  checkCryptNormal(ret,"cryptDestroyContext",__LINE__);

  cryptFlushData(dataEnv);

  clrFileSize=KEYSIZE+1028;
  clrFilePtr=malloc(encDataSize);
  ret=cryptPopData(dataEnv,clrFilePtr,clrFileSize,&bytesCopied);
  checkCryptNormal(ret,"cryptPopData",__LINE__);

  ret=cryptDestroyEnvelope(dataEnv);
  checkCryptNormal(ret,"cryptDestroyEnvelope",__LINE__);

  printf("<%d> bytes of decrypted data\n",bytesCopied);
  for (i=0;i<bytesCopied;i++){printf("%c",clrFilePtr[i]);}
  printf("\n");
  fflush(stdout);
  
  ret=cryptEnd();
  checkCryptNormal(ret,"cryptEnd",__LINE__);


  return 0;
}
Ejemplo n.º 11
0
bool sbbs_t::answer()
{
	char	str[MAX_PATH+1],str2[MAX_PATH+1],c;
	char 	tmp[(MAX_PATH > CRYPT_MAX_TEXTSIZE ? MAX_PATH:CRYPT_MAX_TEXTSIZE)+1];
	char 	tmpname[CRYPT_MAX_TEXTSIZE+1];
	char 	path[MAX_PATH+1];
	int		i,l,in;
	struct tm tm;

	useron.number=0;
	answertime=logontime=starttime=now=time(NULL);
	/* Caller ID is IP address */
	SAFECOPY(cid,client_ipaddr);

	memset(&tm,0,sizeof(tm));
    localtime_r(&now,&tm); 

	safe_snprintf(str,sizeof(str),"%s  %s %s %02d %u            Node %3u"
		,hhmmtostr(&cfg,&tm,str2)
		,wday[tm.tm_wday]
        ,mon[tm.tm_mon],tm.tm_mday,tm.tm_year+1900,cfg.node_num);
	logline("@ ",str);

	safe_snprintf(str,sizeof(str),"%s  %s [%s]", connection, client_name, cid);
	logline("@+:",str);

	if(client_ident[0]) {
		safe_snprintf(str,sizeof(str),"Identity: %s",client_ident);
		logline("@*",str);
	}

	online=ON_REMOTE;

	if(sys_status&SS_RLOGIN) {
		if(incom(1000)==0) {
			for(i=0;i<(int)sizeof(str)-1;i++) {
				in=incom(1000);
				if(in==0 || in==NOINP)
					break;
				str[i]=in;
			}
			str[i]=0;
			for(i=0;i<(int)sizeof(str2)-1;i++) {
				in=incom(1000);
				if(in==0 || in==NOINP)
					break;
				str2[i]=in;
			}
			str2[i]=0;
			for(i=0;i<(int)sizeof(terminal)-1;i++) {
				in=incom(1000);
				if(in==0 || in==NOINP)
					break;
				terminal[i]=in;
			}
			terminal[i]=0;
			lprintf(LOG_DEBUG,"Node %d RLogin: '******' / '%.*s' / '%s'"
				,cfg.node_num
				,LEN_ALIAS*2,str
				,LEN_ALIAS*2,str2
				,terminal);
			SAFECOPY(rlogin_term, terminal);
			SAFECOPY(rlogin_name, str2);
			SAFECOPY(rlogin_pass, str);
			/* Truncate terminal speed (e.g. "/57600") from terminal-type string 
			   (but keep full terminal type/speed string in rlogin_term): */
			truncstr(terminal,"/");	
			useron.number=userdatdupe(0, U_ALIAS, LEN_ALIAS, rlogin_name);
			if(useron.number) {
				getuserdat(&cfg,&useron);
				useron.misc&=~TERM_FLAGS;
				SAFEPRINTF(path,"%srlogin.cfg",cfg.ctrl_dir);
				if(!findstr(client.addr,path)) {
					SAFECOPY(tmp, rlogin_pass);
					for(i=0;i<3;i++) {
						if(stricmp(tmp,useron.pass)) {
							badlogin(useron.alias, tmp);
							rioctl(IOFI);       /* flush input buffer */
							bputs(text[InvalidLogon]);
							if(cfg.sys_misc&SM_ECHO_PW)
								safe_snprintf(str,sizeof(str),"(%04u)  %-25s  FAILED Password attempt: '%s'"
									,0,useron.alias,tmp);
							else
								safe_snprintf(str,sizeof(str),"(%04u)  %-25s  FAILED Password attempt"
									,0,useron.alias);
							logline(LOG_NOTICE,"+!",str);
							bputs(text[PasswordPrompt]);
							console|=CON_R_ECHOX;
							getstr(tmp,LEN_PASS*2,K_UPPER|K_LOWPRIO|K_TAB);
							console&=~(CON_R_ECHOX|CON_L_ECHOX);
						}
						else {
							if(REALSYSOP) {
								rioctl(IOFI);       /* flush input buffer */
								if(!chksyspass())
									bputs(text[InvalidLogon]);
								else {
									i=0;
									break;
								}
							}
							else
								break;
						}
					}
					if(i) {
						if(stricmp(tmp,useron.pass)) {
							badlogin(useron.alias, tmp);
							bputs(text[InvalidLogon]);
							if(cfg.sys_misc&SM_ECHO_PW)
								safe_snprintf(str,sizeof(str),"(%04u)  %-25s  FAILED Password attempt: '%s'"
									,0,useron.alias,tmp);
							else
								safe_snprintf(str,sizeof(str),"(%04u)  %-25s  FAILED Password attempt"
									,0,useron.alias);
							logline(LOG_NOTICE,"+!",str);
						}
						lprintf(LOG_WARNING,"Node %d !CLIENT IP NOT LISTED in %s"
							,cfg.node_num,path);
						useron.number=0;
						hangup();
					}
				}
			}
			else
				lprintf(LOG_INFO,"Node %d RLogin: Unknown user: %s",cfg.node_num,rlogin_name);
		}
		if(rlogin_name[0]==0) {
			lprintf(LOG_NOTICE,"Node %d !RLogin: No user name received",cfg.node_num);
			sys_status&=~SS_RLOGIN;
		}
	}

	if(!(telnet_mode&TELNET_MODE_OFF)) {
		/* Disable Telnet Terminal Echo */
		request_telnet_opt(TELNET_WILL,TELNET_ECHO);
		/* Will suppress Go Ahead */
		request_telnet_opt(TELNET_WILL,TELNET_SUP_GA);
		/* Retrieve terminal type and speed from telnet client --RS */
		request_telnet_opt(TELNET_DO,TELNET_TERM_TYPE);
		request_telnet_opt(TELNET_DO,TELNET_TERM_SPEED);
		request_telnet_opt(TELNET_DO,TELNET_SEND_LOCATION);
		request_telnet_opt(TELNET_DO,TELNET_NEGOTIATE_WINDOW_SIZE);
		request_telnet_opt(TELNET_DO,TELNET_NEW_ENVIRON);
	}
#ifdef USE_CRYPTLIB
	if(sys_status&SS_SSH) {
		pthread_mutex_lock(&ssh_mutex);
		cryptGetAttributeString(ssh_session, CRYPT_SESSINFO_USERNAME, tmpname, &i);
		tmpname[i]=0;
		SAFECOPY(rlogin_name, tmpname);
		cryptGetAttributeString(ssh_session, CRYPT_SESSINFO_PASSWORD, tmp, &i);
		tmp[i]=0;
		SAFECOPY(rlogin_pass, tmp);
		pthread_mutex_unlock(&ssh_mutex);
		lprintf(LOG_DEBUG,"Node %d SSH login: '******'"
			,cfg.node_num, tmpname);
		useron.number=userdatdupe(0, U_ALIAS, LEN_ALIAS, tmpname);
		if(useron.number) {
			getuserdat(&cfg,&useron);
			useron.misc&=~TERM_FLAGS;
			for(i=0;i<3;i++) {
				if(stricmp(tmp,useron.pass)) {
					badlogin(useron.alias, tmp);
					rioctl(IOFI);       /* flush input buffer */
					bputs(text[InvalidLogon]);
					if(cfg.sys_misc&SM_ECHO_PW)
						safe_snprintf(str,sizeof(str),"(%04u)  %-25s  FAILED Password attempt: '%s'"
							,0,useron.alias,tmp);
					else
						safe_snprintf(str,sizeof(str),"(%04u)  %-25s  FAILED Password attempt"
							,0,useron.alias);
					/* crash here Sept-12-2010
					   str	0x06b3fc4c "(0000)  Guest                      FAILED Password attempt: '*****@*****.**'"

					   and Oct-6-2010
					   str	0x070ffc4c "(0000)  Woot903                    FAILED Password attempt: 'p67890pppsdsjhsdfhhfhnhnfhfhfdhjksdjkfdskw3902391=`'"	char [261]
					*/
					logline(LOG_NOTICE,"+!",str);
					bputs(text[PasswordPrompt]);
					console|=CON_R_ECHOX;
					getstr(tmp,LEN_PASS*2,K_UPPER|K_LOWPRIO|K_TAB);
					console&=~(CON_R_ECHOX|CON_L_ECHOX);
				}
				else {
					if(REALSYSOP) {
						rioctl(IOFI);       /* flush input buffer */
						if(!chksyspass())
							bputs(text[InvalidLogon]);
						else {
							i=0;
							break;
						}
					}
					else
						break;
				}
			}
			if(i) {
				if(stricmp(tmp,useron.pass)) {
					badlogin(useron.alias, tmp);
					bputs(text[InvalidLogon]);
					if(cfg.sys_misc&SM_ECHO_PW)
						safe_snprintf(str,sizeof(str),"(%04u)  %-25s  FAILED Password attempt: '%s'"
							,0,useron.alias,tmp);
					else
						safe_snprintf(str,sizeof(str),"(%04u)  %-25s  FAILED Password attempt"
							,0,useron.alias);
					logline(LOG_NOTICE,"+!",str);
				}
				useron.number=0;
				hangup();
			}
		}
		else
			lprintf(LOG_INFO,"Node %d SSH: Unknown user: %s",cfg.node_num,rlogin_name);
	}
#endif

	/* Detect terminal type */
    mswait(200);
	rioctl(IOFI);		/* flush input buffer */
	putcom( "\r\n"		/* locate cursor at column 1 */
			"\x1b[s"	/* save cursor position (necessary for HyperTerm auto-ANSI) */
    		"\x1b[255B"	/* locate cursor as far down as possible */
			"\x1b[255C"	/* locate cursor as far right as possible */
			"\b_"		/* need a printable at this location to actually move cursor */
			"\x1b[6n"	/* Get cursor position */
			"\x1b[u"	/* restore cursor position */
			"\x1b[!_"	/* RIP? */
			"\x1b[30;40m\xc2\x9f""Zuul.connection.write('\\x1b""Are you the gatekeeper?')\xc2\x9c"	/* ZuulTerm? */
			"\x1b[0m_"	/* "Normal" colors */
			"\x1b[2J"	/* clear screen */
			"\x1b[H"	/* home cursor */
			"\xC"		/* clear screen (in case not ANSI) */
			"\r"		/* Move cursor left (in case previous char printed) */
			);
	i=l=0;
	tos=1;
	lncntr=0;
	safe_snprintf(str, sizeof(str), "%s  %s", VERSION_NOTICE, COPYRIGHT_NOTICE);
	strip_ctrl(str, str);
	center(str);

	while(i++<50 && l<(int)sizeof(str)-1) { 	/* wait up to 5 seconds for response */
		c=incom(100)&0x7f;
		if(c==0)
			continue;
		i=0;
		if(l==0 && c!=ESC)	// response must begin with escape char
			continue;
		str[l++]=c;
		if(c=='R') {   /* break immediately if ANSI response */
			mswait(500);
			break; 
		}
	}

	while((c=(incom(100)&0x7f))!=0 && l<(int)sizeof(str)-1)
		str[l++]=c;
	str[l]=0;

    if(l) {
		c_escape_str(str,tmp,sizeof(tmp),TRUE);
		lprintf(LOG_DEBUG,"Node %d received terminal auto-detection response: '%s'"
			,cfg.node_num,tmp);
        if(str[0]==ESC && str[1]=='[' && str[l-1]=='R') {
			int	x,y;

			if(terminal[0]==0)
				SAFECOPY(terminal,"ANSI");
			autoterm|=(ANSI|COLOR);
			if(sscanf(str+2,"%u;%u",&y,&x)==2) {
				lprintf(LOG_DEBUG,"Node %d received ANSI cursor position report: %ux%u"
					,cfg.node_num, x, y);
				/* Sanity check the coordinates in the response: */
				if(x>=40 && x<=255) cols=x; 
				if(y>=10 && y<=255) rows=y;
			}
		}
		truncsp(str);
		if(strstr(str,"RIPSCRIP")) {
			if(terminal[0]==0)
				SAFECOPY(terminal,"RIP");
			logline("@R",strstr(str,"RIPSCRIP"));
			autoterm|=(RIP|COLOR|ANSI); }
		else if(strstr(str,"Are you the gatekeeper?"))  {
			if(terminal[0]==0)
				SAFECOPY(terminal,"HTML");
			logline("@H",strstr(str,"Are you the gatekeeper?"));
			autoterm|=HTML;
		} 
	}
	else if(terminal[0]==0)
		SAFECOPY(terminal,"DUMB");

	rioctl(IOFI); /* flush left-over or late response chars */

	if(!autoterm && str[0]) {
		c_escape_str(str,tmp,sizeof(tmp),TRUE);
		lprintf(LOG_NOTICE,"Node %d terminal auto-detection failed, response: '%s'"
			,cfg.node_num, tmp);
	}

	/* AutoLogon via IP or Caller ID here */
	if(!useron.number && !(sys_status&SS_RLOGIN)
		&& (startup->options&BBS_OPT_AUTO_LOGON) && cid[0]) {
		useron.number=userdatdupe(0, U_NOTE, LEN_NOTE, cid);
		if(useron.number) {
			getuserdat(&cfg, &useron);
			if(!(useron.misc&AUTOLOGON) || !(useron.exempt&FLAG('V')))
				useron.number=0;
		}
	}

	if(!online) 
		return(false); 

	if(stricmp(terminal,"sexpots")==0) {	/* dial-up connection (via SexPOTS) */
		SAFEPRINTF2(str,"%s connection detected at %lu bps", terminal, cur_rate);
		logline("@S",str);
		node_connection = (ushort)cur_rate;
		SAFEPRINTF(connection,"%lu",cur_rate);
		SAFECOPY(cid,"Unknown");
		SAFECOPY(client_name,"Unknown");
		if(telnet_location[0]) {			/* Caller-ID info provided */
			SAFEPRINTF(str, "CID: %s", telnet_location);
			logline("@*",str);
			SAFECOPY(cid,telnet_location);
			truncstr(cid," ");				/* Only include phone number in CID */
			char* p=telnet_location;
			FIND_WHITESPACE(p);
			SKIP_WHITESPACE(p);
			if(*p) {
				SAFECOPY(client_name,p);	/* CID name, if provided (maybe 'P' or 'O' if private or out-of-area) */
			}
		}
		SAFECOPY(client.addr,cid);
		SAFECOPY(client.host,client_name);
		client_on(client_socket,&client,TRUE /* update */);
	} else {
		if(telnet_location[0]) {			/* Telnet Location info provided */
			SAFEPRINTF(str, "Telnet Location: %s", telnet_location);
			logline("@*",str);
		}
	}


	useron.misc&=~TERM_FLAGS;
	useron.misc|=autoterm;
	SAFECOPY(useron.comp,client_name);

	if(!useron.number && rlogin_name[0]!=0 && !(cfg.sys_misc&SM_CLOSED) && !matchuser(&cfg, rlogin_name, /* Sysop alias: */FALSE)) {
		lprintf(LOG_INFO,"Node %d UNKNOWN %s-specified USERNAME: %s, starting new user signup",cfg.node_num,client.protocol,rlogin_name);
		bprintf("%s: %s\r\n", text[UNKNOWN_USER], rlogin_name);
		newuser();
	}

	if(!useron.number) {	/* manual/regular logon */

		/* Display ANSWER screen */
		rioctl(IOSM|PAUSE);
		sys_status|=SS_PAUSEON;
		SAFEPRINTF(str,"%sanswer",cfg.text_dir);
		SAFEPRINTF(path,"%s.rip",str);
		if((autoterm&RIP) && fexistcase(path))
			printfile(path,P_NOABORT);
		else {
			SAFEPRINTF(path,"%s.html",str);
			if((autoterm&HTML) && fexistcase(path))
				printfile(path,P_NOABORT);
			else {
				SAFEPRINTF(path,"%s.ans",str);
				if((autoterm&ANSI) && fexistcase(path))
					printfile(path,P_NOABORT);
				else {
					SAFEPRINTF(path,"%s.asc",str);
					if(fexistcase(path))
						printfile(path, P_NOABORT);
				}
			}
		}
		sys_status&=~SS_PAUSEON;
		exec_bin(cfg.login_mod,&main_csi);
	} else	/* auto logon here */
		if(logon()==false)
			return(false);


	if(!useron.number)
		hangup();

	/* Save the IP to the user's note */
	if(cid[0]) {
		SAFECOPY(useron.note,cid);
		putuserrec(&cfg,useron.number,U_NOTE,LEN_NOTE,useron.note);
	}

	/* Save host name to the user's computer description */
	if(client_name[0]) {
		SAFECOPY(useron.comp,client_name);
		putuserrec(&cfg,useron.number,U_COMP,LEN_COMP,useron.comp);
	}

	if(!online) 
		return(false); 

	if(!(sys_status&SS_USERON)) {
		errormsg(WHERE,ERR_CHK,"User not logged on",0);
		hangup();
		return(false); 
	}

	if(useron.pass[0])
		loginSuccess(startup->login_attempt_list, &client_addr);

	return(true);
}
Ejemplo n.º 12
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 );
	}
Ejemplo n.º 13
0
int testReadCertLDAP( void )
	{
	CRYPT_KEYSET cryptKeyset;
	static const char FAR_BSS *ldapErrorString = \
		"LDAP directory read failed, probably because the standard being "
		"used by the\ndirectory server differs from the one used by the "
		"LDAP client software (pick\na standard, any standard).  If you "
		"know how the directory being used is\nconfigured, you can try "
		"changing the CRYPT_OPTION_KEYS_LDAP_xxx settings to\nmatch those "
		"used by the server.  Processing will continue without treating\n"
		"this as a fatal error.\n";
	const C_STR ldapKeysetName = ldapUrlInfo[ LDAP_SERVER_NO ].url;
	char ldapAttribute1[ CRYPT_MAX_TEXTSIZE + 1 ];
	char ldapAttribute2[ CRYPT_MAX_TEXTSIZE + 1 ];
	char certName[ CRYPT_MAX_TEXTSIZE ], caCertName[ CRYPT_MAX_TEXTSIZE ];
	char crlName[ CRYPT_MAX_TEXTSIZE ];
	int length, status;

	/* LDAP directories come and go, check to see which one is currently
	   around */
	puts( "Testing LDAP directory availability..." );
	status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_LDAP,
							  ldapKeysetName, CRYPT_KEYOPT_READONLY );
	if( status == CRYPT_ERROR_PARAM3 )
		{
		/* LDAP keyset access not available */
		return( CRYPT_ERROR_NOTAVAIL );
		}
	if( status == CRYPT_ERROR_OPEN )
		{
		printf( "%s not available for some odd reason,\n  trying "
				"alternative directory instead...\n", 
				ldapUrlInfo[ LDAP_SERVER_NO ].asciiURL );
		ldapKeysetName = ldapUrlInfo[ LDAP_ALT_SERVER_NO ].url;
		status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED,
								  CRYPT_KEYSET_LDAP, ldapKeysetName,
								  CRYPT_KEYOPT_READONLY );
		}
	if( status == CRYPT_ERROR_OPEN )
		{
		printf( "%s not available either.\n",
				ldapUrlInfo[ LDAP_ALT_SERVER_NO ].asciiURL );
		puts( "None of the test LDAP directories are available.  If you need "
			  "to test the\nLDAP capabilities, you need to set up an LDAP "
			  "directory that can be used\nfor the certificate store.  You "
			  "can configure the LDAP directory using the\nLDAP_KEYSET_xxx "
			  "settings in test/test.h.  Alternatively, if this message\n"
			  "took a long time to appear you may be behind a firewall that "
			  "blocks LDAP\ntraffic.\n" );
		return( FALSE );
		}
	if( cryptStatusError( status ) )
		{
		printf( "cryptKeysetOpen() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	status = cryptGetAttributeString( CRYPT_UNUSED,
									  CRYPT_OPTION_KEYS_LDAP_OBJECTCLASS,
									  ldapAttribute1, &length );
	if( cryptStatusOK( status ) )
		{
#ifdef UNICODE_STRINGS
		length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
		ldapAttribute1[ length ] = TEXT( '\0' );
		status = cryptGetAttributeString( cryptKeyset,
										  CRYPT_OPTION_KEYS_LDAP_OBJECTCLASS,
										  ldapAttribute2, &length );
		}
	if( cryptStatusOK( status ) )
		{
#ifdef UNICODE_STRINGS
		length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
		ldapAttribute2[ length ] = TEXT( '\0' );
		}
	if( cryptStatusError( status ) || \
		strcmp( ldapAttribute1, ldapAttribute2 ) )
		{
		printf( "Failed to get/set keyset attribute via equivalent global "
				"attribute, error\ncode %d, value '%s', should be\n'%s', "
				"line %d.\n", status, ldapAttribute2, ldapAttribute1,
				__LINE__ );
		return( FALSE );
		}
	cryptKeysetClose( cryptKeyset );
	printf( "  LDAP directory %s seems to be up, using that for read test.\n",
			ldapKeysetName );

	/* Now it gets tricky, we have to jump through all sorts of hoops to
	   run the tests in an automated manner since the innate incompatibility
	   of LDAP directory setups means that even though cryptlib's LDAP access
	   code retries failed queries with various options, we still need to
	   manually override some settings here.  The simplest option is a direct
	   read with no special-case handling */
	if( !paramStrcmp( ldapKeysetName, ldapUrlInfo[ LDAP_SERVER_NO ].url ) )
		{
		puts( "Testing LDAP certificate read..." );
		status = testKeysetRead( CRYPT_KEYSET_LDAP, ldapKeysetName,
								 CRYPT_KEYID_NAME,
								 ldapUrlInfo[ LDAP_SERVER_NO ].certName,
								 CRYPT_CERTTYPE_CERTIFICATE,
								 READ_OPTION_NORMAL );
		if( !status )
			{
			/* Since we can never be sure about the LDAP schema du jour, we
			   don't treat a failure as a fatal error */
			puts( ldapErrorString );
			return( FALSE );
			}

		/* This directory doesn't contain CRLs (or at least not at any known
		   location) so we skip the CRL read test */
		puts( "LDAP certificate read succeeded (CRL read skipped).\n" );
		return( TRUE );
		}

	/* The secondary LDAP directory that we're using for these tests doesn't
	   recognise the ';binary' modifier which is required by LDAP servers in
	   order to get them to work properly, we have to change the attribute
	   name around the read calls to the format expected by the server.

	   In addition because the magic formula for fetching a CRL doesn't seem
	   to work for certificates, the CRL read is done first */
	puts( "Testing LDAP CRL read..." );
	status = cryptGetAttributeString( CRYPT_UNUSED, 
									  CRYPT_OPTION_KEYS_LDAP_CRLNAME,
									  crlName, &length );
	if( cryptStatusError( status ) )
		return( FALSE );
#ifdef UNICODE_STRINGS
	length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
	certName[ length ] = TEXT( '\0' );
	cryptSetAttributeString( CRYPT_UNUSED, CRYPT_OPTION_KEYS_LDAP_CRLNAME,
							 "certificateRevocationList", 25 );
	status = testKeysetRead( CRYPT_KEYSET_LDAP, ldapKeysetName,
							 CRYPT_KEYID_NAME,
							 ldapUrlInfo[ LDAP_ALT_SERVER_NO ].crlName,
							 CRYPT_CERTTYPE_CRL, READ_OPTION_NORMAL );
	cryptSetAttributeString( CRYPT_UNUSED, CRYPT_OPTION_KEYS_LDAP_CRLNAME,
							 crlName, strlen( crlName ) );
	if( !status )
		{
		/* Since we can never be sure about the LDAP schema du jour, we
		   don't treat a failure as a fatal error */
		puts( ldapErrorString );
		return( FALSE );
		}

	puts( "Testing LDAP certificate read..." );
	status = cryptGetAttributeString( CRYPT_UNUSED, 
									  CRYPT_OPTION_KEYS_LDAP_CERTNAME,
									  certName, &length );
	if( cryptStatusError( status ) )
		return( FALSE );
#ifdef UNICODE_STRINGS
	length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
	certName[ length ] = TEXT( '\0' );
	cryptSetAttributeString( CRYPT_UNUSED, CRYPT_OPTION_KEYS_LDAP_CERTNAME,
							 "userCertificate", 15 );
	status = cryptGetAttributeString( CRYPT_UNUSED, 
									  CRYPT_OPTION_KEYS_LDAP_CACERTNAME,
									  caCertName, &length );
	if( cryptStatusError( status ) )
		return( FALSE );
#ifdef UNICODE_STRINGS
	length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
	certName[ length ] = TEXT( '\0' );
	cryptSetAttributeString( CRYPT_UNUSED, CRYPT_OPTION_KEYS_LDAP_CACERTNAME,
							 "cACertificate", 13 );
	status = testKeysetRead( CRYPT_KEYSET_LDAP, ldapKeysetName,
							 CRYPT_KEYID_NAME,
							 ldapUrlInfo[ LDAP_ALT_SERVER_NO ].certName,
							 CRYPT_CERTTYPE_CERTIFICATE, READ_OPTION_NORMAL );
	cryptSetAttributeString( CRYPT_UNUSED, CRYPT_OPTION_KEYS_LDAP_CERTNAME,
							 certName, strlen( certName ) );
	cryptSetAttributeString( CRYPT_UNUSED, CRYPT_OPTION_KEYS_LDAP_CACERTNAME,
							 caCertName, strlen( caCertName ) );
	if( !status )
		{
		/* Since we can never be sure about the LDAP schema du jour, we
		   don't treat a failure as a fatal error */
		puts( "LDAP directory read failed, probably due to the magic "
			  "incantatation to fetch\na certificate from this server not "
			  "matching the one used to fetch a CRL.\nProcessing will "
			  "continue without treating this as a fatal error.\n" );
		return( FALSE );
		}
	puts( "LDAP certificate/CRL read succeeded.\n" );

	return( TRUE );
	}
Ejemplo n.º 14
0
const char *signCMSBlob(
    struct CMSBlob *cms,
    const char *keyfilename)
{
    bool sigKeyContext_initialized = false;
    CRYPT_CONTEXT sigKeyContext;
    CRYPT_KEYSET cryptKeyset;
    bool hashContext_initialized = false;
    CRYPT_CONTEXT hashContext;
    int tbs_lth;                /* to-be-signed length */
    unsigned char *tbsp = NULL; /* to-be-signed pointer */
    unsigned char *hash[40];    /* stores sha256 message digest */
    int signatureLength;        /* RSA signature length */
    unsigned char *signature = NULL;    /* RSA signature bytes */
    const char *errmsg = NULL;

    struct SignerInfo *signerInfop =
        (struct SignerInfo *)member_casn(&cms->content.signedData.signerInfos.
                                         self, 0);
    struct BlobEncapsulatedContentInfo *encapContentInfop =
        &cms->content.signedData.encapContentInfo;

    if (vsize_casn(&signerInfop->signedAttrs.self) == 0)
    {
        if ((tbs_lth = vsize_casn(&encapContentInfop->eContent)) < 0)
        {
            errmsg = "sizing eContent";
            return errmsg;
        }
        tbsp = (unsigned char *)calloc(1, tbs_lth);
        if (!tbsp)
        {
            errmsg = "out of memory";
            return errmsg;
        }

        tbs_lth = read_casn(&encapContentInfop->eContent, tbsp);
    }
    else
    {
        // get the size of signed attributes and allocate space for them
        if ((tbs_lth = size_casn(&signerInfop->signedAttrs.self)) < 0)
        {
            errmsg = "sizing SignerInfo";
            return errmsg;
        }
        tbsp = (unsigned char *)calloc(1, tbs_lth);
        if (!tbsp)
        {
            errmsg = "out of memory";
            return errmsg;
        }

        // DER-encode signedAttrs
        tbs_lth = encode_casn(&signerInfop->signedAttrs.self, tbsp);
        *tbsp = ASN_SET;        /* replace ASN.1 identifier octet with ASN_SET
                                 * (0x31) */
    }

    // compute SHA-256 of signedAttrs
    if (cryptCreateContext(&hashContext, CRYPT_UNUSED, CRYPT_ALGO_SHA2) < 0 ||
        !(hashContext_initialized = true))
        errmsg = "creating hash context";
    else if (cryptEncrypt(hashContext, tbsp, tbs_lth) < 0 ||
             cryptEncrypt(hashContext, tbsp, 0) < 0)
        errmsg = "hashing attrs";
    else if (cryptGetAttributeString(hashContext, CRYPT_CTXINFO_HASHVALUE,
                                     hash, &signatureLength) < 0)
        errmsg = "getting attr hash";

    // get the key and sign it
    else if (cryptKeysetOpen(&cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE,
                             keyfilename, CRYPT_KEYOPT_READONLY) < 0)
        errmsg = "opening key set";
    else if (cryptCreateContext(&sigKeyContext, CRYPT_UNUSED,
                                CRYPT_ALGO_RSA) < 0 ||
             !(sigKeyContext_initialized = true))
        errmsg = "creating RSA context";
    else if (cryptGetPrivateKey(cryptKeyset, &sigKeyContext, CRYPT_KEYID_NAME,
                                "label", "password") < 0)
        errmsg = "getting key";
    else if (cryptCreateSignature(NULL, 0, &signatureLength, sigKeyContext,
                                  hashContext) < 0)
        errmsg = "signing";

    // compute signature
    else if ((signature =
              (unsigned char *)calloc(1, signatureLength + 20)) == 0)
        errmsg = "out of memory";
    // second parameter is signatureMaxLength, so we allow a little more
    else if (cryptCreateSignature
             (signature, signatureLength + 20, &signatureLength, sigKeyContext,
              hashContext) < 0)
        errmsg = "signing";
    // verify that the signature is right
    else if (cryptCheckSignature(signature, signatureLength, sigKeyContext,
                                 hashContext) < 0)
        errmsg = "verifying";

    if (hashContext_initialized)
    {
        cryptDestroyContext(hashContext);
        hashContext_initialized = false;
    }
    if (sigKeyContext_initialized)
    {
        cryptDestroyContext(sigKeyContext);
        sigKeyContext_initialized = false;
    }

    if (!errmsg)
    {
        struct SignerInfo sigInfo;
        SignerInfo(&sigInfo, (ushort) 0);
        decode_casn(&sigInfo.self, signature);
        // copy the signature into the object
        copy_casn(&signerInfop->signature, &sigInfo.signature);
        delete_casn(&sigInfo.self);
    }

    if (signature)
        free(signature);
    if (tbsp)
        free(tbsp);

    return errmsg;
}
Ejemplo n.º 15
0
main(int argc, char **argv){
 
  int  ret;            /* Return code */
  int  i;              /* Loop iterator */
  int  bytesCopied;    /* Bytes output by cryptlib enc/dec ops */
  int  reqAttrib;      /* Crypt required attributed */

  CRYPT_ENVELOPE dataEnv;    /* Envelope for enc/dec */
  CRYPT_KEYSET   keyset;     /* GPG keyset */
  CRYPT_CONTEXT   symContext;        /* Key context */
  char            *keyPtr;           /* Pointer to key */
  
  char label[100];           /* Private key label */
  int  labelLength;          /* Length of label */
  char passbuf[1024];        /* Buffer for GPG key passphrase */
  struct termios ts, ots;    /* Strutures for saving/modifying term attribs */

  char        *clrDataPtr;       /* Pointer to clear text */
  int         clrDataSize;       /* Size of clear text */
  int         clrDataFd;             /* Pointer to clear text file */
  char        *encDataPtr;       /* Pointer to encrypted data */
  int         encDataSize;       /* Size of encrypted data */
  int         encDataFd;             /* Pointer to encrypted text file */
  struct stat encDataFileInfo;       /* fstat return for encrypted data file */
  struct passwd *userInfo;       /* Password info for input user */
  char          *keyFile;        /* GPG key ring file name */
  
  uid_t ownerID = getuid();
  struct passwd *owner_pws = getpwuid(ownerID);
  char* owner_pwname = owner_pws->pw_name;//get the user login name;
  char* owner_pwdir = owner_pws->pw_dir;
  char          *fileKeyName;
  *fileKeyName = malloc(strlen(owner_pwname)+strlen(argv[2]+10));

  strcpy(fileKeyName,argv[2]);
  strcat(fileKeyName,".enc.");
  strcat(fileKeyName,owner_pwname);
  strcat(fileKeyName,".key");
  printf("%s\n",fileKeyName);
  
  
  char          *outputFileKeyName = malloc(strlen(argv[1])+strlen(argv[2])+20);
  
  strcpy(outputFileKeyName,argv[2]);
  strcat(outputFileKeyName,".enc.");
  strcat(outputFileKeyName,argv[1]);
  strcat(outputFileKeyName,".key");
  printf("%s\n",outputFileKeyName);
  
 /*==============================================
     Check Check Check Check Check Check
    ==============================================
   */
  if (argc!=3) {printf("Wrong number of arguments\n");exit(1);}
  char *fileName = malloc(strlen(argv[2])+5);
  strcpy(fileName,argv[2]);
  strcat(fileName,".enc");
  
  fileChecker(fileName);
  
  
  
  
 /*=============================================
    Open DATAFILE and get data
    =============================================
 */
  encDataFd=open(fileKeyName,O_RDONLY);
  if (encDataFd<=0){perror("open encData1");exit(encDataFd);}
  ret=fstat(encDataFd,&encDataFileInfo);
  if (ret!=0){perror("fstat encDataFd");exit(ret);}
  encDataSize=encDataFileInfo.st_size;
  encDataPtr=malloc(encDataFileInfo.st_size);
  if (encDataPtr==NULL){perror("malloc encData");exit(__LINE__);}
  ret=read(encDataFd,encDataPtr,encDataSize);
  if (ret!=encDataSize){perror("read encData");exit(ret);}
  close(encDataFd);
   /*==============================================
     Cryptlib initialization
    ==============================================
   */
  //cryptInit();
  //ret=cryptAddRandom( NULL , CRYPT_RANDOM_SLOWPOLL);
  //checkCryptNormal(ret,"cryptAddRandom",__LINE__);
  
 /*=================================================
    Decrypt the key
    =================================================
  */
   
  keyFile=malloc(  strlen(owner_pwdir )
                 + strlen("/.gnupg/secring.gpg") + 1);
  if (keyFile==NULL){perror("malloc");exit(__LINE__);}
  strcpy(keyFile,owner_pwdir);
  strcat(keyFile,"/.gnupg/secring.gpg");
  printf("Getting secret key from <%s>\n",keyFile);

 //Decrypt key
  cryptInit();
  ret=cryptAddRandom( NULL , CRYPT_RANDOM_SLOWPOLL);
  checkCryptNormal(ret,"cryptAddRandom",__LINE__);
  ret=cryptKeysetOpen(&keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, keyFile, CRYPT_KEYOPT_READONLY);
  free(keyFile);
  checkCryptNormal(ret,"cryptKeysetOpen",__LINE__);
  ret=cryptCreateEnvelope(&dataEnv, CRYPT_UNUSED, CRYPT_FORMAT_AUTO);
  checkCryptNormal(ret,"cryptCreateEnvelope",__LINE__);
  ret=cryptSetAttribute(dataEnv, CRYPT_ENVINFO_KEYSET_DECRYPT, keyset);
  checkCryptNormal(ret,"cryptSetAttribute",__LINE__);
  ret=cryptPushData(dataEnv,encDataPtr,encDataSize,&bytesCopied);
  /*  Expect non-zero return -- indicates need private key */
  ret=cryptGetAttribute(dataEnv, CRYPT_ATTRIBUTE_CURRENT, &reqAttrib); 
  if (reqAttrib != CRYPT_ENVINFO_PRIVATEKEY) 
     {printf("Decrypt error\n");exit(ret);}
  ret=cryptGetAttributeString(dataEnv, CRYPT_ENVINFO_PRIVATEKEY_LABEL, label, &labelLength);
  label[labelLength]='\0';
  checkCryptNormal(ret,"cryptGetAttributeString",__LINE__); 

  
  /*===============================================
    Get the passphrase
    ===============================================
  */

  tcgetattr(STDIN_FILENO, &ts);
  ots = ts;


  ts.c_lflag &= ~ECHO;
  ts.c_lflag |= ECHONL;
  tcsetattr(STDIN_FILENO, TCSAFLUSH, &ts);


  tcgetattr(STDIN_FILENO, &ts);
  if (ts.c_lflag & ECHO) {
    fprintf(stderr, "Failed to turn off echo\n");
    tcsetattr(STDIN_FILENO, TCSANOW, &ots);
    exit(1);
  }

  printf("Enter password for <%s>: ",label);
  fflush(stdout);
  fgets(passbuf, 1024, stdin);

  tcsetattr(STDIN_FILENO, TCSANOW, &ots);   

  ret=cryptSetAttributeString(dataEnv, CRYPT_ENVINFO_PASSWORD,
                             passbuf, strlen(passbuf)-1);
  if (ret != CRYPT_OK) {
    if (ret=CRYPT_ERROR_WRONGKEY) {
      printf("Wrong Key\n");
      exit(ret);
    }else{ 
      printf("cryptSetAttributeString line %d returned <%d>\n",__LINE__,ret);
      exit(ret);
    }
  }



  ret=cryptFlushData(dataEnv);
  checkCryptNormal(ret,"cryptFlushData",__LINE__);

  clrDataSize=KEYSIZE;
  clrDataPtr=malloc(clrDataSize);
  if (clrDataPtr==NULL){perror("malloc");exit(__LINE__);}
  bzero(clrDataPtr,clrDataSize);

  ret=cryptPopData(dataEnv,clrDataPtr,clrDataSize,&bytesCopied);
  checkCryptNormal(ret,"cryptPopData",__LINE__);

  ret=cryptDestroyEnvelope(dataEnv);  
  checkCryptNormal(ret,"cryptDestroyEnvelope",__LINE__);
  cryptKeysetClose(keyset);
  checkCryptNormal(ret,"cryptKeysetClose",__LINE__);

  printf("Bytes decrypted <%d>\n",bytesCopied);
   for (i=0;i<bytesCopied;i++){printf("%c",clrDataPtr[i]);}
  ret=cryptEnd();
  checkCryptNormal(ret,"cryptEnd",__LINE__);
  
  /*====================================================
    Part2 Encrypt the key with user's private key 
    ====================================================
  */
  
    /*==============================================
     Cryptlib initialization
    ==============================================
   */
  cryptInit();
  ret=cryptAddRandom( NULL , CRYPT_RANDOM_SLOWPOLL);
  checkCryptNormal(ret,"cryptAddRandom",__LINE__);
  /*====================================================
    Get key file name 
    ====================================================
  */
  keyFile=malloc(  strlen(owner_pwdir )
                 + strlen("/.gnupg/pubring.gpg") + 1);
  if (keyFile==NULL){perror("malloc");exit(__LINE__);}
  strcpy(keyFile,owner_pwdir);
  strcat(keyFile,"/.gnupg/pubring.gpg");
  printf("Getting secret key from <%s>\n",keyFile);

  /*====================================================
    Encrypt key with GPG public key
    Email address is for recipient
    ===================================================
  */

  
  ret=cryptKeysetOpen(&keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, keyFile, CRYPT_KEYOPT_READONLY);
  free(keyFile);
  checkCryptNormal(ret,"cryptKeysetOpen",__LINE__);
  ret=cryptCreateEnvelope(&dataEnv, CRYPT_UNUSED, CRYPT_FORMAT_PGP);
  checkCryptNormal(ret,"cryptCreateEnvelope",__LINE__);
  ret=cryptSetAttribute(dataEnv, CRYPT_ENVINFO_KEYSET_ENCRYPT, keyset);
  checkCryptNormal(ret,"cryptSetAttribute",__LINE__);
  ret=cryptSetAttributeString(dataEnv, CRYPT_ENVINFO_RECIPIENT, 
                              argv[1],strlen(argv[1]));
  checkCryptNormal(ret,"cryptSetAttributeString",__LINE__);
  ret=cryptSetAttribute(dataEnv, CRYPT_ENVINFO_DATASIZE, KEYSIZE);

  ret=cryptPushData(dataEnv,clrDataPtr,KEYSIZE,&bytesCopied);
  checkCryptNormal(ret,"cryptPushData",__LINE__);
  ret=cryptFlushData(dataEnv);
  checkCryptNormal(ret,"cryptFlushData",__LINE__);

  encDataSize=strlen(clrDataPtr)+1+1028;
  encDataPtr=malloc(encDataSize);
  if (encDataPtr==NULL){perror("malloc");exit(__LINE__);}
  ret=cryptPopData(dataEnv,encDataPtr,encDataSize,&bytesCopied);
  printf("cryptPopData returned <%d> bytes of encrypted data\n",bytesCopied);
  encDataSize=bytesCopied;

  ret=cryptDestroyEnvelope(dataEnv);  
  checkCryptNormal(ret,"cryptDestroyEnvelope",__LINE__);
  cryptKeysetClose(keyset);
  checkCryptNormal(ret,"cryptKeysetClose",__LINE__);
  
  /*==============================================
     
        write it to output file.
    ==============================================
  */

  
  printf("%s\n",outputFileKeyName);
  encDataFd=open(outputFileKeyName,O_RDWR|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
  if (encDataFd<=0){perror("open encDataFd");exit(encDataFd);}
  ret=write(encDataFd,encDataPtr,bytesCopied);
  if (ret!=bytesCopied){perror("write encData");exit(ret);}
  close(encDataFd);
  int chmodStat = chmod (outputFileKeyName, S_IWRITE| S_IREAD| S_IRGRP | S_IWGRP);
  if(chmodStat<0){
	  perror("failed to chmod");
	  exit(-1);
  }
  free(encDataPtr);

  }
Ejemplo n.º 16
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 );
	}
Ejemplo n.º 17
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;
}
Ejemplo n.º 18
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;
}
Ejemplo n.º 19
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 );
	}
Ejemplo n.º 20
0
int testReadCert( void )
	{
	CRYPT_CERTIFICATE cryptCert;
	C_CHR name[ CRYPT_MAX_TEXTSIZE + 1 ], email[ CRYPT_MAX_TEXTSIZE + 1 ];
	C_CHR filenameBuffer[ FILENAME_BUFFER_SIZE ];
	int length, status;

	/* Get the DN from one of the test certs (the one that we wrote to the
	   keyset earlier with testKeysetWrite() */
	status = importCertFromTemplate( &cryptCert, CERT_FILE_TEMPLATE, 
									 EMAILADDR_CERT_NO );
	if( cryptStatusError( status ) )
		{
		printf( "Couldn't read certificate from file, status %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	status = cryptGetAttributeString( cryptCert, CRYPT_CERTINFO_COMMONNAME,
									  name, &length );
	if( cryptStatusOK( status ) )
		{
#ifdef UNICODE_STRINGS
		length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
		name[ length ] = TEXT( '\0' );
		status = cryptGetAttributeString( cryptCert, CRYPT_CERTINFO_EMAIL,
										  email, &length );
		}
	if( cryptStatusOK( status ) )
		{
		int i;

#ifdef UNICODE_STRINGS
		length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
		email[ length ] = TEXT( '\0' );

		/* Mess up the case to make sure that case-insensitive matching is
		   working */
		for( i = 0; i < length; i++ )
			{
			if( i & 1 )
				email[ i ] = toupper( email[ i ] );
			else
				email[ i ] = tolower( email[ i ] );
			}
		}
	else
		{
		return( extErrorExit( cryptCert, "cryptGetAttributeString()", status,
							  __LINE__ ) );
		}
	cryptDestroyCert( cryptCert );

	puts( "Testing certificate database read..." );
	status = testKeysetRead( DATABASE_KEYSET_TYPE, DATABASE_KEYSET_NAME,
	 						 CRYPT_KEYID_NAME, name,
							 CRYPT_CERTTYPE_CERTIFICATE,
							 READ_OPTION_NORMAL );
	if( status == CRYPT_ERROR_NOTAVAIL )
		{
		/* Database keyset access not available */
		return( CRYPT_ERROR_NOTAVAIL );
		}
	if( status == CRYPT_ERROR_FAILED )
		{
		puts( "This is probably because you haven't set up a database or "
			  "data source for use\nas a key database.  For this test to "
			  "work, you need to set up a database/data\nsource with the "
			  "name '" DATABASE_KEYSET_NAME_ASCII "'.\n" );
		return( TRUE );
		}
	if( !status )
		return( FALSE );
	puts( "Reading certs using cached query." );
	status = testKeysetRead( DATABASE_KEYSET_TYPE, DATABASE_KEYSET_NAME,
	 						 CRYPT_KEYID_EMAIL, email,
							 CRYPT_CERTTYPE_CERTIFICATE,
							 READ_OPTION_MULTIPLE );
	if( !status )
		return( FALSE );

	/* Get the DN from one of the test certificate chains */
	filenameParamFromTemplate( filenameBuffer, CERTCHAIN_FILE_TEMPLATE, 
							   CERT_CHAIN_NO );
	status = importCertFile( &cryptCert, filenameBuffer );
	if( cryptStatusError( status ) )
		{
		printf( "Couldn't read certificate chain from file, status %d, "
				"line %d.\n", status, __LINE__ );
		return( FALSE );
		}
	status = cryptGetAttributeString( cryptCert, CRYPT_CERTINFO_COMMONNAME,
									  name, &length );
	if( cryptStatusOK( status ) )
		{
#ifdef UNICODE_STRINGS
		length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
		name[ length ] = TEXT( '\0' );
		}
	cryptDestroyCert( cryptCert );

	/* Now read the complete certificate chain */
	puts( "Reading complete certificate chain." );
	status = testKeysetRead( DATABASE_KEYSET_TYPE, DATABASE_KEYSET_NAME,
	 						 CRYPT_KEYID_NAME, name,
							 CRYPT_CERTTYPE_CERTCHAIN, READ_OPTION_NORMAL );
	if( !status )
		return( FALSE );
	puts( "Certificate database read succeeded.\n" );
	return( TRUE );
	}
Ejemplo n.º 21
0
const char *signCMS(
    struct CMS *cms,
    const char *keyfilename,
    bool bad)
{
    bool hashContext_initialized = false;
    CRYPT_CONTEXT hashContext;
    bool sigKeyContext_initialized = false;
    CRYPT_CONTEXT sigKeyContext;
    CRYPT_KEYSET cryptKeyset;
    int signatureLength;
    int tbs_lth;
    char *msg = (char *)0;
    uchar *tbsp;
    uchar *signature = NULL;
    uchar hash[40];
    struct casn *sidp;
    struct Attribute *attrp;
    struct AttrTableDefined *attrtdp;
    struct SignerInfo *sigInfop;

    // signer info
    // firat clear out any old stuff in signerInfos that may have been put
    // there by old code
    while (num_items(&cms->content.signedData.signerInfos.self) > 0)
        eject_casn(&cms->content.signedData.signerInfos.self, 0);
    sigInfop =
        (struct SignerInfo *)
        inject_casn(&(cms->content.signedData.signerInfos.self), 0);

    // write the signature version (3) to the signer info
    write_casn_num(&sigInfop->version.self, 3);

    // find the SID
    if ((sidp = findSID(cms)) == NULL)
        return "finding SID";

    // copy the CMS's SID over to the signature's SID
    copy_casn(&sigInfop->sid.subjectKeyIdentifier, sidp);

    // use sha256 as the algorithm
    write_objid(&sigInfop->digestAlgorithm.algorithm, id_sha256);

    // no parameters to sha256
    write_casn(&sigInfop->digestAlgorithm.parameters.sha256, (uchar *) "", 0);

    // first attribute: content type
    attrp = (struct Attribute *)inject_casn(&sigInfop->signedAttrs.self, 0);
    write_objid(&attrp->attrType, id_contentTypeAttr);
    attrtdp =
        (struct AttrTableDefined *)inject_casn(&attrp->attrValues.self, 0);
    copy_casn(&attrtdp->contentType,
              &cms->content.signedData.encapContentInfo.eContentType);

    // second attribute: message digest
    attrp = (struct Attribute *)inject_casn(&sigInfop->signedAttrs.self, 1);
    write_objid(&attrp->attrType, id_messageDigestAttr);

    // create the hash for the content

    // first pull out the content
    if ((tbs_lth =
         readvsize_casn(&cms->content.signedData.encapContentInfo.eContent.
                        self, &tbsp)) < 0)
        return "getting content";

    // set up the context, initialize crypt
    memset(hash, 0, 40);
    if (cryptInit_wrapper() != CRYPT_OK)
        return "initializing cryptlib";

    // the following calls function f, and if f doesn't return 0 sets
    // msg to m, then breaks out of the loop. Used immediately below.
#define CALL(f,m) if (f != 0) { msg = m; break; }

    // use a "do { ... } while (0)" loop to bracket this code, so we can
    // bail out on failure. (Note that this construct isn't really a
    // loop; it's a way to use break as a more clean version of goto.)
    do
    {
        // first sign the body of the message

        // create the context
        CALL(cryptCreateContext(&hashContext, CRYPT_UNUSED, CRYPT_ALGO_SHA2),
             "creating context");
        hashContext_initialized = true;

        // generate the hash
        CALL(cryptEncrypt(hashContext, tbsp, tbs_lth), "hashing");
        CALL(cryptEncrypt(hashContext, tbsp, 0), "hashing");

        // get the hash value. then we're done, so destroy it
        CALL(cryptGetAttributeString
             (hashContext, CRYPT_CTXINFO_HASHVALUE, hash, &signatureLength),
             "getting first hash");
        CALL(cryptDestroyContext(hashContext),
             "destroying intermediate context");

        // insert the hash as the first attribute
        attrtdp =
            (struct AttrTableDefined *)inject_casn(&attrp->attrValues.self, 0);
        write_casn(&attrtdp->messageDigest, hash, signatureLength);

        // create signing time attribute; mark the signing time as now
        if (getenv("RPKI_NO_SIGNING_TIME") == NULL)
        {
            attrp =
                (struct Attribute *)inject_casn(&sigInfop->signedAttrs.self, 2);
            write_objid(&attrp->attrType, id_signingTimeAttr);
            attrtdp =
                (struct AttrTableDefined *)inject_casn(&attrp->attrValues.self, 0);
            write_casn_time(&attrtdp->signingTime.utcTime, time((time_t *) 0));
        }

        // we are all done with the content
        free(tbsp);

        // now sign the attributes

        // get the size of signed attributes and allocate space for them
        if ((tbs_lth = size_casn(&sigInfop->signedAttrs.self)) < 0)
        {
            msg = "sizing SignerInfo";
            break;
        }
        tbsp = (uchar *) calloc(1, tbs_lth);
        encode_casn(&sigInfop->signedAttrs.self, tbsp);
        *tbsp = ASN_SET;

        // create a new, fresh hash context for hashing the attrs, and hash
        // them
        CALL(cryptCreateContext(&hashContext, CRYPT_UNUSED, CRYPT_ALGO_SHA2),
             "creating hash context");
        CALL(cryptEncrypt(hashContext, tbsp, tbs_lth), "hashing attrs");
        CALL(cryptEncrypt(hashContext, tbsp, 0), "hashing attrs");

        // get the hash value
        CALL(cryptGetAttributeString
             (hashContext, CRYPT_CTXINFO_HASHVALUE, hash, &signatureLength),
             "getting attr hash");

        // get the key and sign it
        CALL(cryptKeysetOpen
             (&cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, keyfilename,
              CRYPT_KEYOPT_READONLY), "opening key set");
        CALL(cryptCreateContext(&sigKeyContext, CRYPT_UNUSED, CRYPT_ALGO_RSA),
             "creating RSA context");
        sigKeyContext_initialized = true;
        CALL(cryptGetPrivateKey
             (cryptKeyset, &sigKeyContext, CRYPT_KEYID_NAME, "label",
              "password"), "getting key");
        CALL(cryptCreateSignature
             (NULL, 0, &signatureLength, sigKeyContext, hashContext),
             "signing");

        // check the signature to make sure it's right
        signature = (uchar *) calloc(1, signatureLength + 20);

        // second parameter is signatureMaxLength, so we allow a little more
        CALL(cryptCreateSignature
             (signature, signatureLength + 20, &signatureLength, sigKeyContext,
              hashContext), "signing");

        // verify that the signature is right
        CALL(cryptCheckSignature
             (signature, signatureLength, sigKeyContext, hashContext),
             "verifying");

        // end of protected block
    } while (0);

    // done with cryptlib, shut it down
    if (hashContext_initialized)
    {
        cryptDestroyContext(hashContext);
        hashContext_initialized = false;
    }
    if (sigKeyContext_initialized)
    {
        cryptDestroyContext(sigKeyContext);
        sigKeyContext_initialized = false;
    }

    // did we have any trouble above? if so, bail
    if (msg != 0)
    {
        return msg;
    }

    // ok, write the signature back to the object
    struct SignerInfo sigInfo;
    SignerInfo(&sigInfo, (ushort) 0);
    decode_casn(&sigInfo.self, signature);

    // were we supposed to make a bad signature? if so, make it bad
    if (bad)
    {
        uchar *sig;
        int siz = readvsize_casn(&sigInfo.signature, &sig);
        sig[0]++;
        write_casn(&sigInfo.signature, sig, siz);
        free(sig);
    }

    // copy the signature into the object
    copy_casn(&sigInfop->signature, &sigInfo.signature);
    delete_casn(&sigInfo.self);

    // all done with it now
    free(signature);

    // Mark it as encrypted with rsa, no params.
    // See http://www.ietf.org/mail-archive/web/sidr/current/msg04813.html for
    // why we use id_rsadsi_rsaEncryption instead of id_sha_256WithRSAEncryption
    // here.
    write_objid(&sigInfop->signatureAlgorithm.algorithm,
                id_rsadsi_rsaEncryption);
    write_casn(&sigInfop->signatureAlgorithm.parameters.self, (uchar *) "", 0);

    // no errors, we return NULL
    return NULL;
}
Ejemplo n.º 22
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;

}