/* * This function is called when an SSL connection is closed. */ void Curl_nss_close(struct connectdata *conn, int sockindex) { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; if(connssl->handle) { PR_Close(connssl->handle); /* NSS closes the socket we previously handed to it, so we must mark it as closed to avoid double close */ fake_sclose(conn->sock[sockindex]); conn->sock[sockindex] = CURL_SOCKET_BAD; if(connssl->client_nickname != NULL) { free(connssl->client_nickname); connssl->client_nickname = NULL; } #ifdef HAVE_PK11_CREATEGENERICOBJECT if(connssl->key) (void)PK11_DestroyGenericObject(connssl->key); if(connssl->cacert[1]) (void)PK11_DestroyGenericObject(connssl->cacert[1]); if(connssl->cacert[0]) (void)PK11_DestroyGenericObject(connssl->cacert[0]); #endif connssl->handle = NULL; } }
static void free_PK11_ctx(struct PK11_ctx *ctx) { if(!ctx) return; if(ctx->list) CERT_DestroyCertList(ctx->list); if(ctx->obj) PK11_DestroyGenericObject(ctx->obj); if(ctx->slot) PK11_FreeSlot(ctx->slot); }
/* * This function is called when an SSL connection is closed. */ void Curl_nss_close(struct connectdata *conn, int sockindex) { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; if(connssl->handle) { PR_Close(connssl->handle); if(connssl->client_nickname != NULL) { free(connssl->client_nickname); connssl->client_nickname = NULL; } if(connssl->client_cert) CERT_DestroyCertificate(connssl->client_cert); if(connssl->key) (void)PK11_DestroyGenericObject(connssl->key); if(connssl->cacert[1]) (void)PK11_DestroyGenericObject(connssl->cacert[1]); if(connssl->cacert[0]) (void)PK11_DestroyGenericObject(connssl->cacert[0]); connssl->handle = NULL; } }
/* Call PK11_CreateGenericObject() with the given obj_class and filename. If * the call succeeds, append the object handle to the list of objects so that * the object can be destroyed in Curl_nss_close(). */ static CURLcode nss_create_object(struct ssl_connect_data *ssl, CK_OBJECT_CLASS obj_class, const char *filename, bool cacert) { PK11SlotInfo *slot; PK11GenericObject *obj; CK_BBOOL cktrue = CK_TRUE; CK_BBOOL ckfalse = CK_FALSE; CK_ATTRIBUTE attrs[/* max count of attributes */ 4]; int attr_cnt = 0; CURLcode err = (cacert) ? CURLE_SSL_CACERT_BADFILE : CURLE_SSL_CERTPROBLEM; const int slot_id = (cacert) ? 0 : 1; char *slot_name = aprintf("PEM Token #%d", slot_id); if(!slot_name) return CURLE_OUT_OF_MEMORY; slot = PK11_FindSlotByName(slot_name); free(slot_name); if(!slot) return err; PK11_SETATTRS(attrs, attr_cnt, CKA_CLASS, &obj_class, sizeof(obj_class)); PK11_SETATTRS(attrs, attr_cnt, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL)); PK11_SETATTRS(attrs, attr_cnt, CKA_LABEL, (unsigned char *)filename, strlen(filename) + 1); if(CKO_CERTIFICATE == obj_class) { CK_BBOOL *pval = (cacert) ? (&cktrue) : (&ckfalse); PK11_SETATTRS(attrs, attr_cnt, CKA_TRUST, pval, sizeof(*pval)); } obj = PK11_CreateGenericObject(slot, attrs, attr_cnt, PR_FALSE); PK11_FreeSlot(slot); if(!obj) return err; if(!Curl_llist_insert_next(ssl->obj_list, ssl->obj_list->tail, obj)) { PK11_DestroyGenericObject(obj); return CURLE_OUT_OF_MEMORY; } if(!cacert && CKO_CERTIFICATE == obj_class) /* store reference to a client certificate */ ssl->obj_clicert = obj; return CURLE_OK; }
/* Destroy the NSS object whose handle is given by ptr. This function is * a callback of Curl_llist_alloc() used by Curl_llist_destroy() to destroy * NSS objects in Curl_nss_close() */ static void nss_destroy_object(void *user, void *ptr) { PK11GenericObject *obj = (PK11GenericObject *)ptr; (void) user; PK11_DestroyGenericObject(obj); }