Index: openssl.c
===================================================================
RCS file: /projects/cvsroot/pgsql/contrib/pgcrypto/openssl.c,v
retrieving revision 1.30
diff -c -r1.30 openssl.c
*** openssl.c	4 Oct 2006 00:29:46 -0000	1.30
--- openssl.c	24 Jul 2007 11:20:02 -0000
***************
*** 380,385 ****
--- 380,399 ----
  {
  	ossldata   *od = c->ptr;
  
+ 	/* Test if key len is supported. BF_set_key silently cut large keys and it could be
+ 	 be a problem when user transfer crypted data from one server to another. */
+ 	EVP_CIPHER_CTX ctx;
+ 	EVP_CIPHER_CTX_init(&ctx);
+ 	EVP_EncryptInit_ex(&ctx, EVP_bf_cbc(), NULL, NULL, NULL);
+ 	EVP_CIPHER_CTX_set_key_length(&ctx,klen);
+ 	if( !EVP_EncryptInit_ex(&ctx,NULL, NULL, key, NULL) )
+ 	{
+ 		EVP_CIPHER_CTX_cleanup(&ctx);
+ 		return PXE_KEY_TOO_BIG;
+ 	}
+ 	EVP_CIPHER_CTX_cleanup(&ctx);
+ 
+ 	/* Key len is supported. We can use it. */
  	BF_set_key(&od->u.bf.key, klen, key);
  	if (iv)
  		memcpy(od->iv, iv, BF_BLOCK);
***************
*** 692,705 ****
  	return 0;
  }
  
! static void
  ossl_aes_key_init(ossldata * od, int type)
  {
  	if (type == AES_ENCRYPT)
! 		AES_set_encrypt_key(od->key, od->klen * 8, &od->u.aes_key);
  	else
! 		AES_set_decrypt_key(od->key, od->klen * 8, &od->u.aes_key);
! 	od->init = 1;
  }
  
  static int
--- 706,728 ----
  	return 0;
  }
  
! static int
  ossl_aes_key_init(ossldata * od, int type)
  {
+ 	int err;
+ 	/* Strong key support could miss on some openssl installation, we must
+ 		check return value, from set key function.
+ 	*/ 
  	if (type == AES_ENCRYPT)
! 	    err = AES_set_encrypt_key(od->key, od->klen * 8, &od->u.aes_key);
  	else
! 		err = AES_set_decrypt_key(od->key, od->klen * 8, &od->u.aes_key);
! 
! 	if (err == 0)
! 		od->init = 1;
! 	else 
! 		od->init = 0;
! 	return err;
  }
  
  static int
***************
*** 711,717 ****
  	const uint8 *end = data + dlen - bs;
  
  	if (!od->init)
! 		ossl_aes_key_init(od, AES_ENCRYPT);
  
  	for (; data <= end; data += bs, res += bs)
  		AES_ecb_encrypt(data, res, &od->u.aes_key, AES_ENCRYPT);
--- 734,741 ----
  	const uint8 *end = data + dlen - bs;
  
  	if (!od->init)
! 		if( ossl_aes_key_init(od, AES_ENCRYPT) )
! 			return PXE_KEY_TOO_BIG;
  
  	for (; data <= end; data += bs, res += bs)
  		AES_ecb_encrypt(data, res, &od->u.aes_key, AES_ENCRYPT);
***************
*** 727,733 ****
  	const uint8 *end = data + dlen - bs;
  
  	if (!od->init)
! 		ossl_aes_key_init(od, AES_DECRYPT);
  
  	for (; data <= end; data += bs, res += bs)
  		AES_ecb_encrypt(data, res, &od->u.aes_key, AES_DECRYPT);
--- 751,758 ----
  	const uint8 *end = data + dlen - bs;
  
  	if (!od->init)
! 		if( ossl_aes_key_init(od, AES_DECRYPT) )
! 			return PXE_KEY_TOO_BIG;
  
  	for (; data <= end; data += bs, res += bs)
  		AES_ecb_encrypt(data, res, &od->u.aes_key, AES_DECRYPT);
***************
*** 741,748 ****
  	ossldata   *od = c->ptr;
  
  	if (!od->init)
! 		ossl_aes_key_init(od, AES_ENCRYPT);
! 
  	AES_cbc_encrypt(data, res, dlen, &od->u.aes_key, od->iv, AES_ENCRYPT);
  	return 0;
  }
--- 766,774 ----
  	ossldata   *od = c->ptr;
  
  	if (!od->init)
! 		if( ossl_aes_key_init(od, AES_ENCRYPT) )
! 			return PXE_KEY_TOO_BIG;
! 	
  	AES_cbc_encrypt(data, res, dlen, &od->u.aes_key, od->iv, AES_ENCRYPT);
  	return 0;
  }
***************
*** 754,760 ****
  	ossldata   *od = c->ptr;
  
  	if (!od->init)
! 		ossl_aes_key_init(od, AES_DECRYPT);
  
  	AES_cbc_encrypt(data, res, dlen, &od->u.aes_key, od->iv, AES_DECRYPT);
  	return 0;
--- 780,787 ----
  	ossldata   *od = c->ptr;
  
  	if (!od->init)
! 		if( ossl_aes_key_init(od, AES_DECRYPT) )
! 			return PXE_KEY_TOO_BIG;
  
  	AES_cbc_encrypt(data, res, dlen, &od->u.aes_key, od->iv, AES_DECRYPT);
  	return 0;
