unsigned __stdcall envelopeDataThread( void *arg )
#endif /* Different threading models */
	{
	static const char *envData = "qwertyuiopasdfghjklzxcvbnm";
	BYTE fileBuffer[ BUFFER_SIZE ];
	const unsigned uThread = ( unsigned ) arg;
	const time_t startTime = time( NULL );
	int count, status;

	printf( "Thread %d started.\n", uThread );
	fflush( stdout );

	filenameFromTemplate( fileBuffer, CERT_FILE_TEMPLATE, 13 );

	for( count = 0; count < 150; count++ )
		{
		CRYPT_ENVELOPE cryptEnvelope;
		CRYPT_CERTIFICATE cryptCert;
		BYTE envBuffer[ BUFFER_SIZE ];
		int bytesCopied;

		/* Create the cert and envelope and add the cert to the envelope */
		status = importCertFile( &cryptCert, fileBuffer );
		if( cryptStatusOK( status ) )
			status = cryptCreateEnvelope( &cryptEnvelope, CRYPT_UNUSED,
										  CRYPT_FORMAT_CRYPTLIB );
		if( cryptStatusOK( status ) )
			status = cryptSetAttribute( cryptEnvelope,
										CRYPT_ENVINFO_PUBLICKEY, cryptCert );
		if( cryptStatusError( status ) )
			break;

		/* Envelope data and destroy the envelope */
		status = cryptPushData( cryptEnvelope, envData, strlen( envData ),
								&bytesCopied );
		if( cryptStatusOK( status ) )
			status = cryptPushData( cryptEnvelope, NULL, 0, NULL );
		if( cryptStatusOK( status ) )
			status = cryptPopData( cryptEnvelope, envBuffer, BUFFER_SIZE,
									&bytesCopied );
		if( cryptStatusOK( status ) )
			status = cryptDestroyEnvelope( cryptEnvelope );
		if( cryptStatusError( status ) )
			break;
		printf( "%c", uThread + '0' );
		}

	printf( "Thread %u exited after %d seconds.\n", uThread,
			time( NULL ) - startTime );
	fflush( stdout );
#ifdef UNIX_THREADS
	pthread_exit( NULL );
#else
	_endthreadex( 0 );
#endif /* Different threading models */
	return( 0 );
	}
unsigned __stdcall encTest( void *arg ) 
	{
	CRYPT_ENVELOPE cryptEnvelope;
	CRYPT_CERTIFICATE cryptCert;
	BYTE buffer[ 1024 ];
	const int count = *( ( int * ) arg );
	int bytesCopied, i, status;

	printf( "EncTest %d.\n", count );

	for( i = 0; i < count; i++ ) 
		{
		FILE *filePtr;
		int certSize;

		if( ( filePtr = fopen( "testdata/cert5.der", "rb" ) ) != NULL ) 
			{
			certSize = fread( buffer, 1, 1024, filePtr );
			fclose( filePtr );
			}

		status = cryptImportCert( buffer, certSize, CRYPT_UNUSED, 
								  &certificate );
		if( cryptStatusOK( status ) )
			status = cryptCreateEnvelope( &cryptEnvelope, CRYPT_UNUSED, 
										  CRYPT_FORMAT_CMS );
		if( cryptStatusOK( status ) )
			status = cryptSetAttribute( cryptEnvelope, 
										CRYPT_ENVINFO_PUBLICKEY, cryptCert );
		if( cryptStatusOK( status ) )
			status = cryptPushData( cryptEnvelope, buffer, 200, 
									&bytesCopied );
		if( cryptStatusOK( status ) )
			status = cryptFlushData( cryptEnvelope );
		if( cryptStatusOK( status ) )
			status = cryptPopData( cryptEnvelope, buffer, 1024, 
								   &bytesCopied );
		if( cryptStatusOK( status ) )
			status = cryptDestroyCert( cryptCert );
		if( cryptStatusOK( status ) )
			status = cryptDestroyEnvelope( cryptEnvelope );
		if( cryptStatusError( status ) )
			{
			_endthreadex( status );
			return( 0 );
			}
		}

	_endthreadex( 0 );
	return( 0 );
	}
unsigned __stdcall signTest( void *arg ) 
	{
	CRYPT_KEYSET cryptKeyset;
	CRYPT_CONTEXT privateKeyContext;
	CRYPT_ENVELOPE cryptEnvelope;
	BYTE buffer[ 1024 ];
	const int count = *( ( int * ) arg );
	int bytesCopied, i, status;

	printf( "SignTest %d.\n", count );

	for( i = 0; i < count; i++ ) 
		{
		status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, 
								  CRYPT_KEYSET_FILE, TEST_PRIVKEY_FILE, 
								  CRYPT_KEYOPT_READONLY);
		if( cryptStatusOK( status ) )
			status = cryptGetPrivateKey( cryptKeyset, &privateKeyContext, 
										 CRYPT_KEYID_NAME, RSA_PRIVKEY_LABEL, 
										 TEST_PRIVKEY_PASSWORD );
		if( cryptStatusOK( status ) )
			status = cryptCreateEnvelope( &cryptEnvelope, CRYPT_UNUSED, 
										  CRYPT_FORMAT_CMS );
		if( cryptStatusOK( status ) )
			status = cryptSetAttribute( cryptEnvelope, 
										CRYPT_ENVINFO_SIGNATURE, 
										privateKeyContext );
		if( cryptStatusOK( status ) )
			status = cryptPushData( cryptEnvelope, "message", 7, 
									&bytesCopied );
		if( cryptStatusOK( status ) )
			status = cryptFlushData( cryptEnvelope );
		if( cryptStatusOK( status ) )
			status = cryptPopData( cryptEnvelope, buffer, 1024, 
									&bytesCopied );
		if( cryptStatusOK( status ) )
			status = cryptDestroyContext( privateKeyContext );
		if( cryptStatusOK( status ) )
			status = cryptKeysetClose( cryptKeyset );
		if( cryptStatusOK( status ) )
			status = cryptDestroyEnvelope( cryptEnvelope );
		if( cryptStatusError( status ) )
			{
			_endthreadex( status );
			return( 0 );
			}
		}

	_endthreadex( 0 );
	return( 0 );
	}
Exemple #4
0
static int testTSP( const CRYPT_SESSION cryptSession,
					const BOOLEAN isServer,
					const BOOLEAN isRecycledConnection,
					const BOOLEAN useAltHash,
					const BOOLEAN localSession )
	{
	int status;

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

	/* If we're the client, create a message imprint to timestamp */
	if( !isServer )
		{
		CRYPT_CONTEXT hashContext;

		/* Create the hash value to add to the TSP request */
		status = cryptCreateContext( &hashContext, CRYPT_UNUSED, 
									 useAltHash ? CRYPT_ALGO_SHA256 : \
												  CRYPT_ALGO_SHA1 );
		if( cryptStatusError( status ) )
			return( FALSE );
		cryptEncrypt( hashContext, "12345678", 8 );
		cryptEncrypt( hashContext, "", 0 );
		if( isRecycledConnection )
			{
			/* If we're moving further data over an existing connection, 
			   delete the message imprint from the previous run */
			status = cryptDeleteAttribute( cryptSession,
										   CRYPT_SESSINFO_TSP_MSGIMPRINT );
			if( cryptStatusError( status ) )
				{
				printf( "cryptDeleteAttribute() failed with error code %d, "
						"line %d.\n", status, __LINE__ );
				return( FALSE );
				}
			}
		status = cryptSetAttribute( cryptSession,
									CRYPT_SESSINFO_TSP_MSGIMPRINT,
									hashContext );
		if( cryptStatusError( status ) )
			{
			printf( "cryptSetAttribute() failed with error code %d, line "
					"%d.\n", status, __LINE__ );
			return( FALSE );
			}
		cryptDestroyContext( hashContext );

		/* If it's a local session, 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 );
			}		
		}
	else
		{
		/* We're the server, if this is the first connect tell the client 
		   that we're ready to go */
		if( localSession && !isRecycledConnection )
			releaseMutex();
		}

	/* Activate the session and timestamp the message */
#if TSP_SERVER_NO == 11
	cryptSetAttribute( cryptSession, CRYPT_OPTION_NET_READTIMEOUT, 30 );
#endif /* Very slow TSP */
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
	if( isServer )
		printConnectInfo( cryptSession );
	if( cryptStatusError( status ) )
		{
		printExtError( cryptSession, isServer ? \
					   "SVR: Attempt to activate TSP server session" : \
					   "Attempt to activate TSP client session", status,
					   __LINE__ );
		if( !isServer && isServerDown( cryptSession, status ) )
			{
			puts( "  (Server could be down, faking it and continuing...)\n" );
			cryptDestroySession( cryptSession );
			return( CRYPT_ERROR_FAILED );
			}
		cryptDestroySession( cryptSession );
		return( FALSE );
		}

	/* There's not much more we can do in the client at this point since the 
	   TSP data is only used internally by cryptlib, OTOH if we get to here 
	   then we've received a valid response from the TSA so all is OK */
	if( !isServer )
		{
		CRYPT_ENVELOPE cryptEnvelope;
		BYTE buffer[ BUFFER_SIZE ];
		int bytesCopied;

		status = cryptGetAttribute( cryptSession, CRYPT_SESSINFO_RESPONSE,
									&cryptEnvelope );
		if( cryptStatusError( status ) )
			{
			printExtError( cryptSession, "Attempt to process returned "
						   "timestamp", status, __LINE__ );
			return( FALSE );
			}
		status = cryptPopData( cryptEnvelope, buffer, BUFFER_SIZE,
							   &bytesCopied );
		if( cryptStatusError( status ) )
			{
			printf( "cryptPopData() failed with error code %d, line %d.\n",
					status, __LINE__ );
			return( FALSE );
			}
		printf( "Timestamp data size = %d bytes.\n", bytesCopied );
		debugDump( "tstinfo", buffer, bytesCopied );
		cryptDestroyEnvelope( cryptEnvelope );
		}

	return( TRUE );
	}
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);

  }
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;
}
main(int argc, char **argv){


  int  i;                            /* Loop iterator */
  int  ret;                          /* Return value */
  int  total;                        /* Total key bytes */
  int  bytesCopied;                  /* Bytes output by cryptlib enc/dec ops */
  int  urandFd;                      /* Pointer to /dev/urandom */
  char            *keyPtr;           /* Pointer to key */
  CRYPT_ENVELOPE  dataEnv;           /* Envelope for encrypt/decrypt */
  CRYPT_CONTEXT   symContext;        /* Key context */
  char        *clrDataPtr;           /* Pointer to clear text */
  int         clrDataSize;           /* Bytes of clear text */
  int         clrDataFd;             /* Pointer to clear text file */
  struct stat clrDataFileInfo;       /* fstat return for clear text file */
  int         encDataFd;             /* Pointer to encrypted text file */
  char        *encDataPtr;           /* Pointer to encrypted data */
  int         encDataSize;           /* Buffer bytes availble for decrypt */
  struct stat encDataFileInfo;       /* fstat return for encrypted data file */


  if (argc!=3) {printf("Wrong number of arguments\n");exit(__LINE__);}


  /*==============================================
     Cryptlib initialization
    ==============================================
   */
  cryptInit();
  ret=cryptAddRandom( NULL , CRYPT_RANDOM_SLOWPOLL);
  checkCryptNormal(ret,"cryptAddRandom",__LINE__);

  /*=============================================
    Open DATAFILE and get data
    =============================================
  */
  clrDataFd=open(argv[1],O_RDONLY);
  if (clrDataFd<=0){perror("open clrData");exit(clrDataFd);}
  ret=fstat(clrDataFd,&clrDataFileInfo);
  if (ret!=0){perror("fstat clrDataFd");exit(ret);}
  clrDataSize=clrDataFileInfo.st_size;
  clrDataPtr=malloc(clrDataFileInfo.st_size);
  if (clrDataPtr==NULL){perror("malloc clrData");exit(__LINE__);}
  ret=read(clrDataFd,clrDataPtr,clrDataSize);
  if (ret!=clrDataSize){perror("read clrData");exit(ret);}
  close(clrDataFd);

  /*==============================================
    (1) Generate the key
    ==============================================
  */

  keyPtr=malloc(KEYSIZE);
  if (keyPtr==NULL){perror("malloc keyPtr");exit(__LINE__);}
  urandFd=open("/dev/urandom",O_RDONLY);
  if (urandFd<=0){perror("open urandFd");exit(urandFd);}
  total=0;ret=0;
  while (total<KEYSIZE){
    ret=read(urandFd,&keyPtr[total],KEYSIZE-total);total+=ret;
    if (ret < 0){perror("read urand");exit(ret);}
  }
  close(urandFd);


  /*==============================================
    (2) Encrypt data from file with the key and 
        write it to output file.
    ==============================================
  */

  ret=cryptCreateEnvelope(&dataEnv, CRYPT_UNUSED, CRYPT_FORMAT_CRYPTLIB);
  checkCryptNormal(ret,"cryptCreateEnvelope",__LINE__);

  ret=cryptCreateContext(&symContext, CRYPT_UNUSED, SYMMETRIC_ALG);
  checkCryptNormal(ret,"cryptCreateContext",__LINE__);

  ret=cryptSetAttributeString(symContext, CRYPT_CTXINFO_KEY,keyPtr,KEYSIZE);
  checkCryptNormal(ret,"cryptSetAttributeString",__LINE__);

  ret=cryptSetAttribute(dataEnv, CRYPT_ENVINFO_SESSIONKEY, symContext);
  checkCryptNormal(ret,"cryptSetAttribute",__LINE__);

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

  ret=cryptSetAttribute(dataEnv, CRYPT_ENVINFO_DATASIZE, 
                        clrDataSize);
  checkCryptNormal(ret,"cryptSetAttribute",__LINE__);

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

  cryptFlushData(dataEnv);

  encDataSize=clrDataFileInfo.st_size+2048;
  encDataPtr=malloc(encDataSize);
  if (encDataPtr==NULL){perror("malloc encData");exit(__LINE__);}

  ret=cryptPopData(dataEnv,encDataPtr,encDataSize,&bytesCopied);
  checkCryptNormal(ret,"cryptPopData",__LINE__);
  printf("<%d> bytes of encrypted data\n",bytesCopied); 
  ret=cryptDestroyEnvelope(dataEnv);
  checkCryptNormal(ret,"cryptDestroyEnvelope",__LINE__);

  encDataFd=open(argv[2],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);
  free(encDataPtr);

  /*======================================================
    Get decrypted data from file and write to stdout
    ======================================================
  */
  encDataFd=open(argv[2],O_RDONLY);
  if (encDataFd<=0){perror("(2) open encDataFd");exit(encDataFd);}
  ret=fstat(encDataFd,&encDataFileInfo);
  if (ret!=0){perror("fstat encDataFd");exit(ret);}
  encDataSize=encDataFileInfo.st_size;
  encDataPtr=malloc(encDataSize);
  if (encDataPtr==NULL){perror("malloc encData");exit(__LINE__);}

  ret=read(encDataFd,encDataPtr,encDataSize);
  if (ret!=encDataSize){perror("read encData");exit(ret);}
  close(encDataFd);
  
  cryptCreateEnvelope(&dataEnv, CRYPT_UNUSED, CRYPT_FORMAT_AUTO);
  checkCryptNormal(ret,"cryptCreateEnvelope",__LINE__);
  cryptPushData(dataEnv,encDataPtr,encDataSize,&bytesCopied);
  checkCryptNormal(ret,"cryptPushData",__LINE__);
  cryptCreateContext(&symContext,CRYPT_UNUSED,SYMMETRIC_ALG);
  checkCryptNormal(ret,"cryptCreateContext",__LINE__);
  cryptSetAttributeString(symContext, CRYPT_CTXINFO_KEY,keyPtr,KEYSIZE);
  checkCryptNormal(ret,"cryptSetAttributeString",__LINE__);
  cryptSetAttribute(dataEnv,CRYPT_ENVINFO_SESSIONKEY,symContext);
  checkCryptNormal(ret,"cryptSetAttribute",__LINE__);

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

  cryptFlushData(dataEnv);
  ret=cryptPopData(dataEnv,clrDataPtr,clrDataSize,&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",clrDataPtr[i]);}
  printf("\n");
  fflush(stdout);
  
  ret=cryptEnd();
  checkCryptNormal(ret,"cryptEnd",__LINE__);
  }
Exemple #8
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 );
	}