From 68f89ad571f4ef40ec3c61d1069ee43794c35c24 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Wed, 29 Sep 2010 16:59:28 -0400 Subject: [PATCH 025/150] - allow a cert handle to live longer than the iteration handle we used to initialize it --- src/plugins/preauth/pkinit/pkinit_crypto_nss.c | 24 ++++++++++++++++-------- 1 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c index fa38c66..908cf5e 100644 --- a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c +++ b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c @@ -82,14 +82,15 @@ struct _pkinit_identity_crypto_context { }; struct _pkinit_cert_info { /* aka _pkinit_cert_handle */ + PLArenaPool *pool; struct _pkinit_identity_crypto_context *id_cryptoctx; CERTCertificate *cert; }; struct _pkinit_cert_iter_info { /* aka _pkinit_cert_iter_handle */ PLArenaPool *pool; - CERTCertListNode *node; struct _pkinit_identity_crypto_context *id_cryptoctx; + CERTCertListNode *node; }; /* Protocol elements. */ @@ -1075,12 +1076,15 @@ crypto_cert_iteration_end(krb5_context context, return 0; } -/* Walk to the first/next "self" certificate and key. */ +/* Walk to the first/next "self" certificate and key. The cert_handle we + * produce here has to be useful beyond the life of the iteration handle, so it + * can't be allocated from the iteration handle's memory pool. */ krb5_error_code crypto_cert_iteration_next(krb5_context context, pkinit_cert_iter_handle iter_handle, pkinit_cert_handle *cert_handle) { + PLArenaPool *pool; CERTCertListNode *node; node = iter_handle->node; /* Check if we're at the last node. */ @@ -1089,12 +1093,17 @@ crypto_cert_iteration_next(krb5_context context, *cert_handle = NULL; return PKINIT_ITER_NO_MORE; } - /* Try to store cert info. */ - *cert_handle = PORT_ArenaZAlloc(iter_handle->pool, - sizeof(**cert_handle)); + /* Create a pool to hold info about this certificate. */ + pool = PORT_NewArena(sizeof(double)); + if (pool == NULL) { + return ENOMEM; + } + *cert_handle = PORT_ArenaZAlloc(pool, sizeof(**cert_handle)); if (*cert_handle == NULL) { + PORT_FreeArena(pool, PR_TRUE); return ENOMEM; } + (*cert_handle)->pool = pool; /* Return a copy of the certificate in this node, and then move on to * the next one. */ (*cert_handle)->id_cryptoctx = iter_handle->id_cryptoctx; @@ -1332,13 +1341,12 @@ crypto_cert_get_matching_data(krb5_context context, return 0; } -/* Free up "this" certificate. */ +/* Free up the data for this certificate. */ krb5_error_code crypto_cert_release(krb5_context context, pkinit_cert_handle cert_handle) { - /* Free the contents, but not the handle itself. That's part of a - * pool. */ CERT_DestroyCertificate(cert_handle->cert); + PORT_FreeArena(cert_handle->pool, PR_TRUE); return 0; } -- 1.7.6.4