|
apparently these temp values are scrubbed by openssl. i would definitely verify because there could be some implementation bug that stops their scrubbing. so what nginx does is: handle_request:
do_decryption
scrub_temporaries
write_to_client
handle_another_request:
..
because nginx is single threaded there shouldn't be any requests handled between do_decryption and scrub_temporaries. but this is a problem on other servers. static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
...
if (ctx != NULL)
{
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
if (buf != NULL)
{
OPENSSL_cleanse(buf,num);
OPENSSL_free(buf);
}
return(r);
void BN_CTX_free(BN_CTX *ctx)
{
if (ctx == NULL)
return;
#ifdef BN_CTX_DEBUG
{
BN_POOL_ITEM *pool = ctx->pool.head;
fprintf(stderr,"BN_CTX_free, stack-size=%d, pool-bignums=%d\n",
ctx->stack.size, ctx->pool.size);
fprintf(stderr,"dmaxs: ");
while(pool) {
unsigned loop = 0;
while(loop < BN_CTX_POOL_SIZE)
fprintf(stderr,"%02x ", pool->vals[loop++].dmax);
pool = pool->next;
}
fprintf(stderr,"\n");
}
#endif
BN_STACK_finish(&ctx->stack);
BN_POOL_finish(&ctx->pool);
OPENSSL_free(ctx);
}
static void BN_POOL_finish(BN_POOL *p)
{
while(p->head)
{
unsigned int loop = 0;
BIGNUM *bn = p->head->vals;
while(loop++ < BN_CTX_POOL_SIZE)
{
if(bn->d) BN_clear_free(bn);
bn++;
}
p->current = p->head->next;
OPENSSL_free(p->head);
p->head = p->current;
}
}
void BN_clear_free(BIGNUM *a)
{
int i;
if (a == NULL) return;
bn_check_top(a);
if (a->d != NULL)
{
OPENSSL_cleanse(a->d,a->dmax*sizeof(a->d[0]));
if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
OPENSSL_free(a->d);
}
i=BN_get_flags(a,BN_FLG_MALLOCED);
OPENSSL_cleanse(a,sizeof(BIGNUM));
if (i)
OPENSSL_free(a);
}
void OPENSSL_cleanse(void *ptr, size_t len)
{
unsigned char *p = ptr;
size_t loop = len, ctr = cleanse_ctr;
while(loop--)
{
*(p++) = (unsigned char)ctr;
ctr += (17 + ((size_t)p & 0xF));
}
p=memchr(ptr, (unsigned char)ctr, len);
if(p)
ctr += (63 + (size_t)p);
cleanse_ctr = (unsigned char)ctr;
}
|