Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9bbbf02

Browse files
committed
Fix pgcrypto compilation with OpenSSL 1.1.0.
Was broken by the switch to using OpenSSL's EVP interface for ciphers, incommit5ff4a67.Reported by Andres Freund. Fix by Michael Paquier with some kibitzing by me.Discussion:https://www.postgresql.org/message-id/20161201014826.ic72tfkahmevpwz7@alap3.anarazel.de
1 parent41493ba commit9bbbf02

File tree

2 files changed

+141
-49
lines changed

2 files changed

+141
-49
lines changed

‎contrib/pgcrypto/openssl.c

Lines changed: 139 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ typedef struct OSSLDigest
6666
}OSSLDigest;
6767

6868
staticOSSLDigest*open_digests=NULL;
69-
staticboolresowner_callback_registered= false;
69+
staticbooldigest_resowner_callback_registered= false;
7070

7171
staticvoid
72-
free_openssldigest(OSSLDigest*digest)
72+
free_openssl_digest(OSSLDigest*digest)
7373
{
7474
EVP_MD_CTX_destroy(digest->ctx);
7575
if (digest->prev)
@@ -106,7 +106,7 @@ digest_free_callback(ResourceReleasePhase phase,
106106
{
107107
if (isCommit)
108108
elog(WARNING,"pgcrypto digest reference leak: digest %p still referenced",curr);
109-
free_openssldigest(curr);
109+
free_openssl_digest(curr);
110110
}
111111
}
112112
}
@@ -156,7 +156,7 @@ digest_free(PX_MD *h)
156156
{
157157
OSSLDigest*digest= (OSSLDigest*)h->p.ptr;
158158

159-
free_openssldigest(digest);
159+
free_openssl_digest(digest);
160160
px_free(h);
161161
}
162162

@@ -178,10 +178,10 @@ px_find_digest(const char *name, PX_MD **res)
178178
OpenSSL_add_all_algorithms();
179179
}
180180

181-
if (!resowner_callback_registered)
181+
if (!digest_resowner_callback_registered)
182182
{
183183
RegisterResourceReleaseCallback(digest_free_callback,NULL);
184-
resowner_callback_registered= true;
184+
digest_resowner_callback_registered= true;
185185
}
186186

187187
md=EVP_get_digestbyname(name);
@@ -240,6 +240,9 @@ px_find_digest(const char *name, PX_MD **res)
240240
*/
241241
typedefconstEVP_CIPHER*(*ossl_EVP_cipher_func)(void);
242242

243+
/*
244+
* ossl_cipher contains the static information about each cipher.
245+
*/
243246
structossl_cipher
244247
{
245248
int(*init) (PX_Cipher*c,constuint8*key,unsignedklen,constuint8*iv);
@@ -248,31 +251,89 @@ struct ossl_cipher
248251
intmax_key_size;
249252
};
250253

251-
typedefstruct
254+
/*
255+
* OSSLCipher contains the state for using a cipher. A separate OSSLCipher
256+
* object is allocated in each px_find_cipher() call.
257+
*
258+
* To make sure we don't leak OpenSSL handles on abort, we keep OSSLCipher
259+
* objects in a linked list, allocated in TopMemoryContext. We use the
260+
* ResourceOwner mechanism to free them on abort.
261+
*/
262+
typedefstructOSSLCipher
252263
{
253-
EVP_CIPHER_CTXevp_ctx;
264+
EVP_CIPHER_CTX*evp_ctx;
254265
constEVP_CIPHER*evp_ciph;
255266
uint8key[MAX_KEY];
256267
uint8iv[MAX_IV];
257268
unsignedklen;
258269
unsignedinit;
259270
conststructossl_cipher*ciph;
260-
}ossldata;
271+
272+
ResourceOwnerowner;
273+
structOSSLCipher*next;
274+
structOSSLCipher*prev;
275+
}OSSLCipher;
276+
277+
staticOSSLCipher*open_ciphers=NULL;
278+
staticboolcipher_resowner_callback_registered= false;
279+
280+
staticvoid
281+
free_openssl_cipher(OSSLCipher*od)
282+
{
283+
EVP_CIPHER_CTX_free(od->evp_ctx);
284+
if (od->prev)
285+
od->prev->next=od->next;
286+
else
287+
open_ciphers=od->next;
288+
if (od->next)
289+
od->next->prev=od->prev;
290+
pfree(od);
291+
}
292+
293+
/*
294+
* Close any open OpenSSL cipher handles on abort.
295+
*/
296+
staticvoid
297+
cipher_free_callback(ResourceReleasePhasephase,
298+
boolisCommit,
299+
boolisTopLevel,
300+
void*arg)
301+
{
302+
OSSLCipher*curr;
303+
OSSLCipher*next;
304+
305+
if (phase!=RESOURCE_RELEASE_AFTER_LOCKS)
306+
return;
307+
308+
next=open_ciphers;
309+
while (next)
310+
{
311+
curr=next;
312+
next=curr->next;
313+
314+
if (curr->owner==CurrentResourceOwner)
315+
{
316+
if (isCommit)
317+
elog(WARNING,"pgcrypto cipher reference leak: cipher %p still referenced",curr);
318+
free_openssl_cipher(curr);
319+
}
320+
}
321+
}
261322

262323
/* Common routines for all algorithms */
263324

264325
staticunsigned
265326
gen_ossl_block_size(PX_Cipher*c)
266327
{
267-
ossldata*od= (ossldata*)c->ptr;
328+
OSSLCipher*od= (OSSLCipher*)c->ptr;
268329

269330
returnod->ciph->block_size;
270331
}
271332

272333
staticunsigned
273334
gen_ossl_key_size(PX_Cipher*c)
274335
{
275-
ossldata*od= (ossldata*)c->ptr;
336+
OSSLCipher*od= (OSSLCipher*)c->ptr;
276337

277338
returnod->ciph->max_key_size;
278339
}
@@ -281,7 +342,7 @@ static unsigned
281342
gen_ossl_iv_size(PX_Cipher*c)
282343
{
283344
unsignedivlen;
284-
ossldata*od= (ossldata*)c->ptr;
345+
OSSLCipher*od= (OSSLCipher*)c->ptr;
285346

286347
ivlen=od->ciph->block_size;
287348
returnivlen;
@@ -290,34 +351,31 @@ gen_ossl_iv_size(PX_Cipher *c)
290351
staticvoid
291352
gen_ossl_free(PX_Cipher*c)
292353
{
293-
ossldata*od= (ossldata*)c->ptr;
354+
OSSLCipher*od= (OSSLCipher*)c->ptr;
294355

295-
EVP_CIPHER_CTX_cleanup(&od->evp_ctx);
296-
px_memset(od,0,sizeof(*od));
297-
px_free(od);
356+
free_openssl_cipher(od);
298357
px_free(c);
299358
}
300359

301360
staticint
302361
gen_ossl_decrypt(PX_Cipher*c,constuint8*data,unsigneddlen,
303362
uint8*res)
304363
{
305-
ossldata*od=c->ptr;
364+
OSSLCipher*od=c->ptr;
306365
intoutlen;
307366

308367
if (!od->init)
309368
{
310-
EVP_CIPHER_CTX_init(&od->evp_ctx);
311-
if (!EVP_DecryptInit_ex(&od->evp_ctx,od->evp_ciph,NULL,NULL,NULL))
369+
if (!EVP_DecryptInit_ex(od->evp_ctx,od->evp_ciph,NULL,NULL,NULL))
312370
returnPXE_CIPHER_INIT;
313-
if (!EVP_CIPHER_CTX_set_key_length(&od->evp_ctx,od->klen))
371+
if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx,od->klen))
314372
returnPXE_CIPHER_INIT;
315-
if (!EVP_DecryptInit_ex(&od->evp_ctx,NULL,NULL,od->key,od->iv))
373+
if (!EVP_DecryptInit_ex(od->evp_ctx,NULL,NULL,od->key,od->iv))
316374
returnPXE_CIPHER_INIT;
317375
od->init= true;
318376
}
319377

320-
if (!EVP_DecryptUpdate(&od->evp_ctx,res,&outlen,data,dlen))
378+
if (!EVP_DecryptUpdate(od->evp_ctx,res,&outlen,data,dlen))
321379
returnPXE_DECRYPT_FAILED;
322380

323381
return0;
@@ -327,22 +385,21 @@ static int
327385
gen_ossl_encrypt(PX_Cipher*c,constuint8*data,unsigneddlen,
328386
uint8*res)
329387
{
330-
ossldata*od=c->ptr;
388+
OSSLCipher*od=c->ptr;
331389
intoutlen;
332390

333391
if (!od->init)
334392
{
335-
EVP_CIPHER_CTX_init(&od->evp_ctx);
336-
if (!EVP_EncryptInit_ex(&od->evp_ctx,od->evp_ciph,NULL,NULL,NULL))
393+
if (!EVP_EncryptInit_ex(od->evp_ctx,od->evp_ciph,NULL,NULL,NULL))
337394
returnPXE_CIPHER_INIT;
338-
if (!EVP_CIPHER_CTX_set_key_length(&od->evp_ctx,od->klen))
395+
if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx,od->klen))
339396
returnPXE_CIPHER_INIT;
340-
if (!EVP_EncryptInit_ex(&od->evp_ctx,NULL,NULL,od->key,od->iv))
397+
if (!EVP_EncryptInit_ex(od->evp_ctx,NULL,NULL,od->key,od->iv))
341398
returnPXE_CIPHER_INIT;
342399
od->init= true;
343400
}
344401

345-
if (!EVP_EncryptUpdate(&od->evp_ctx,res,&outlen,data,dlen))
402+
if (!EVP_EncryptUpdate(od->evp_ctx,res,&outlen,data,dlen))
346403
returnPXE_ERR_GENERIC;
347404

348405
return0;
@@ -370,31 +427,38 @@ bf_check_supported_key_len(void)
370427
staticconstuint8data[8]= {0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
371428
staticconstuint8res[8]= {0xc0,0x45,0x04,0x01,0x2e,0x4e,0x1f,0x53};
372429
uint8out[8];
373-
EVP_CIPHER_CTXevp_ctx;
430+
EVP_CIPHER_CTX*evp_ctx;
374431
intoutlen;
432+
intstatus=0;
375433

376434
/* encrypt with 448bits key and verify output */
377-
EVP_CIPHER_CTX_init(&evp_ctx);
378-
if (!EVP_EncryptInit_ex(&evp_ctx,EVP_bf_ecb(),NULL,NULL,NULL))
379-
return0;
380-
if (!EVP_CIPHER_CTX_set_key_length(&evp_ctx,56))
381-
return0;
382-
if (!EVP_EncryptInit_ex(&evp_ctx,NULL,NULL,key,NULL))
435+
evp_ctx=EVP_CIPHER_CTX_new();
436+
if (!evp_ctx)
383437
return0;
438+
if (!EVP_EncryptInit_ex(evp_ctx,EVP_bf_ecb(),NULL,NULL,NULL))
439+
gotoleave;
440+
if (!EVP_CIPHER_CTX_set_key_length(evp_ctx,56))
441+
gotoleave;
442+
if (!EVP_EncryptInit_ex(evp_ctx,NULL,NULL,key,NULL))
443+
gotoleave;
384444

385-
if (!EVP_EncryptUpdate(&evp_ctx,out,&outlen,data,8))
386-
return0;
445+
if (!EVP_EncryptUpdate(evp_ctx,out,&outlen,data,8))
446+
gotoleave;
387447

388448
if (memcmp(out,res,8)!=0)
389-
return0;/* Output does not match -> strong cipher is
449+
gotoleave;/* Output does not match -> strong cipher is
390450
* not supported */
391-
return1;
451+
status=1;
452+
453+
leave:
454+
EVP_CIPHER_CTX_free(evp_ctx);
455+
returnstatus;
392456
}
393457

394458
staticint
395459
bf_init(PX_Cipher*c,constuint8*key,unsignedklen,constuint8*iv)
396460
{
397-
ossldata*od=c->ptr;
461+
OSSLCipher*od=c->ptr;
398462
unsignedbs=gen_ossl_block_size(c);
399463
staticintbf_is_strong=-1;
400464

@@ -426,7 +490,7 @@ bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
426490
staticint
427491
ossl_des_init(PX_Cipher*c,constuint8*key,unsignedklen,constuint8*iv)
428492
{
429-
ossldata*od=c->ptr;
493+
OSSLCipher*od=c->ptr;
430494
unsignedbs=gen_ossl_block_size(c);
431495

432496
od->klen=8;
@@ -445,7 +509,7 @@ ossl_des_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
445509
staticint
446510
ossl_des3_init(PX_Cipher*c,constuint8*key,unsignedklen,constuint8*iv)
447511
{
448-
ossldata*od=c->ptr;
512+
OSSLCipher*od=c->ptr;
449513
unsignedbs=gen_ossl_block_size(c);
450514

451515
od->klen=24;
@@ -464,7 +528,7 @@ ossl_des3_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
464528
staticint
465529
ossl_cast_init(PX_Cipher*c,constuint8*key,unsignedklen,constuint8*iv)
466530
{
467-
ossldata*od=c->ptr;
531+
OSSLCipher*od=c->ptr;
468532
unsignedbs=gen_ossl_block_size(c);
469533

470534
od->klen=klen;
@@ -482,7 +546,7 @@ ossl_cast_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
482546
staticint
483547
ossl_aes_init(PX_Cipher*c,constuint8*key,unsignedklen,constuint8*iv)
484548
{
485-
ossldata*od=c->ptr;
549+
OSSLCipher*od=c->ptr;
486550
unsignedbs=gen_ossl_block_size(c);
487551

488552
if (klen <=128 /8)
@@ -507,7 +571,7 @@ ossl_aes_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
507571
staticint
508572
ossl_aes_ecb_init(PX_Cipher*c,constuint8*key,unsignedklen,constuint8*iv)
509573
{
510-
ossldata*od=c->ptr;
574+
OSSLCipher*od=c->ptr;
511575
interr;
512576

513577
err=ossl_aes_init(c,key,klen,iv);
@@ -537,7 +601,7 @@ ossl_aes_ecb_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv
537601
staticint
538602
ossl_aes_cbc_init(PX_Cipher*c,constuint8*key,unsignedklen,constuint8*iv)
539603
{
540-
ossldata*od=c->ptr;
604+
OSSLCipher*od=c->ptr;
541605
interr;
542606

543607
err=ossl_aes_init(c,key,klen,iv);
@@ -683,7 +747,8 @@ px_find_cipher(const char *name, PX_Cipher **res)
683747
{
684748
conststructossl_cipher_lookup*i;
685749
PX_Cipher*c=NULL;
686-
ossldata*od;
750+
EVP_CIPHER_CTX*ctx;
751+
OSSLCipher*od;
687752

688753
name=px_resolve_alias(ossl_aliases,name);
689754
for (i=ossl_cipher_types;i->name;i++)
@@ -692,13 +757,38 @@ px_find_cipher(const char *name, PX_Cipher **res)
692757
if (i->name==NULL)
693758
returnPXE_NO_CIPHER;
694759

695-
od=px_alloc(sizeof(*od));
696-
memset(od,0,sizeof(*od));
760+
if (!cipher_resowner_callback_registered)
761+
{
762+
RegisterResourceReleaseCallback(cipher_free_callback,NULL);
763+
cipher_resowner_callback_registered= true;
764+
}
765+
766+
/*
767+
* Create an OSSLCipher object, an EVP_CIPHER_CTX object and a PX_Cipher.
768+
* The order is crucial, to make sure we don't leak anything on
769+
* out-of-memory or other error.
770+
*/
771+
od=MemoryContextAllocZero(TopMemoryContext,sizeof(*od));
697772
od->ciph=i->ciph;
698773

774+
/* Allocate an EVP_CIPHER_CTX object. */
775+
ctx=EVP_CIPHER_CTX_new();
776+
if (!ctx)
777+
{
778+
pfree(od);
779+
returnPXE_CIPHER_INIT;
780+
}
781+
782+
od->evp_ctx=ctx;
783+
od->owner=CurrentResourceOwner;
784+
od->next=open_ciphers;
785+
od->prev=NULL;
786+
open_ciphers=od;
787+
699788
if (i->ciph->cipher_func)
700789
od->evp_ciph=i->ciph->cipher_func();
701790

791+
/* The PX_Cipher is allocated in current memory context */
702792
c=px_alloc(sizeof(*c));
703793
c->block_size=gen_ossl_block_size;
704794
c->key_size=gen_ossl_key_size;

‎contrib/pgcrypto/pgp-encrypt.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,8 @@ encrypt_free(void *priv)
219219
{
220220
structEncStat*st=priv;
221221

222+
if (st->ciph)
223+
pgp_cfb_free(st->ciph);
222224
px_memset(st,0,sizeof(*st));
223225
px_free(st);
224226
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp