From 1fbd5563430a4a0854054806f67d460a5f015d7a Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Mon, 27 Sep 2010 22:52:52 -0400 Subject: [PATCH 010/150] - start on cert iteration --- src/plugins/preauth/pkinit/pkinit_crypto_nss.c | 112 ++++++++++++++++++++---- 1 files changed, 96 insertions(+), 16 deletions(-) diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c index d737192..1dc4674 100644 --- a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c +++ b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c @@ -56,7 +56,6 @@ struct _pkinit_plg_crypto_context { struct _pkinit_req_crypto_context { PLArenaPool *pool; - CERTCertificate *cert; SECKEYPrivateKey *client_seckey; }; @@ -76,8 +75,9 @@ struct _pkinit_cert_info { /* aka _pkinit_cert_handle */ }; struct _pkinit_cert_iter_info { /* aka _pkinit_cert_iter_handle */ - struct _pkinit_identity_crypto_context *id_cryptoctx; + PLArenaPool *pool; CERTCertListNode *node; + struct _pkinit_identity_crypto_context *id_cryptoctx; }; /* Protocol elements. */ @@ -309,9 +309,6 @@ pkinit_init_req_crypto(pkinit_req_crypto_context *req_cryptoctx) void pkinit_fini_req_crypto(pkinit_req_crypto_context req_cryptoctx) { - if (req_cryptoctx->cert != NULL) { - CERT_DestroyCertificate(req_cryptoctx->cert); - } if (req_cryptoctx->client_seckey != NULL) { SECKEY_DestroyPrivateKey(req_cryptoctx->client_seckey); } @@ -948,6 +945,7 @@ create_krb5_trustedCertifiers(krb5_context context, return 0; } +/* Load up a certificate and associated key. */ krb5_error_code crypto_load_certs(krb5_context context, pkinit_plg_crypto_context plg_cryptoctx, @@ -956,9 +954,29 @@ crypto_load_certs(krb5_context context, pkinit_identity_crypto_context id_cryptoctx, krb5_principal princ) { - return ENOSYS; + switch (idopts->idtype) { + case IDTYPE_FILE: + return ENOSYS; + break; + case IDTYPE_DIR: + return ENOSYS; + break; + case IDTYPE_PKCS11: + return ENOSYS; + break; + case IDTYPE_ENVVAR: + return ENOSYS; + break; + case IDTYPE_PKCS12: + return ENOSYS; + break; + default: + return ENOSYS; + break; + } } +/* Drop "self" certificate and keys that we didn't select. */ krb5_error_code crypto_free_cert_info(krb5_context context, pkinit_plg_crypto_context plg_cryptoctx, @@ -968,6 +986,7 @@ crypto_free_cert_info(krb5_context context, return ENOSYS; } +/* Count how many "self" certificates and keys we have. */ krb5_error_code crypto_cert_get_count(krb5_context context, pkinit_plg_crypto_context plg_cryptoctx, @@ -975,9 +994,19 @@ crypto_cert_get_count(krb5_context context, pkinit_identity_crypto_context id_cryptoctx, int *cert_count) { - return ENOSYS; + CERTCertListNode *node; + *cert_count = 0; + if (!CERT_LIST_EMPTY(id_cryptoctx->id_certs)) { + for (node = CERT_LIST_HEAD(id_cryptoctx->id_certs); + (node != NULL) && (node->cert != NULL); + node = CERT_LIST_NEXT(node)) { + (*cert_count)++; + } + } + return 0; } +/* Start walking the list of "self" certificates and keys. */ krb5_error_code crypto_cert_iteration_begin(krb5_context context, pkinit_plg_crypto_context plg_cryptoctx, @@ -985,39 +1014,85 @@ crypto_cert_iteration_begin(krb5_context context, pkinit_identity_crypto_context id_cryptoctx, pkinit_cert_iter_handle *iter_handle) { - return ENOSYS; + PLArenaPool *pool; + struct _pkinit_cert_iter_info *info; + if (CERT_LIST_EMPTY(id_cryptoctx->id_certs)) { + return ENOENT; + } + pool = PORT_NewArena(sizeof(double)); + if (pool == NULL) { + return ENOMEM; + } + info = PORT_ArenaZAlloc(pool, sizeof(*info)); + if (info == NULL) { + PORT_FreeArena(pool, PR_TRUE); + return ENOMEM; + } + info->pool = pool; + info->id_cryptoctx = id_cryptoctx; + info->node = CERT_LIST_HEAD(info->id_cryptoctx->id_certs); + *iter_handle = info; + return 0; } +/* Stop walking the list of "self" certificates and keys. */ krb5_error_code crypto_cert_iteration_end(krb5_context context, pkinit_cert_iter_handle iter_handle) { - return ENOSYS; + struct _pkinit_cert_iter_info *info; + info = iter_handle; + PORT_FreeArena(info->pool, PR_TRUE); + return 0; } +/* Walk to the next "self" certificate and key. */ krb5_error_code crypto_cert_iteration_next(krb5_context context, pkinit_cert_iter_handle iter_handle, pkinit_cert_handle *cert_handle) { - return ENOSYS; + CERTCertListNode *node; + struct _pkinit_cert_iter_info *info; + struct _pkinit_cert_info *cert; + info = iter_handle; + /* Find the next node. */ + node = CERT_LIST_NEXT(info->node); + if (CERT_LIST_END(node, info->id_cryptoctx->id_certs)) { + *cert_handle = NULL; + return ENOENT; + } + /* Try to store cert info. */ + cert = PORT_ArenaZAlloc(info->pool, sizeof(*cert)); + if (cert == NULL) { + return ENOMEM; + } + /* Record that we iterated. */ + info->node = node; + cert->id_cryptoctx = info->id_cryptoctx; + cert->cert = node->cert; + *cert_handle = cert; + return 0; } +/* Read names, key usage, and extended key usage from the cert. */ krb5_error_code -crypto_cert_release(krb5_context context, - pkinit_cert_handle cert_handle) +crypto_cert_get_matching_data(krb5_context context, + pkinit_cert_handle cert_handle, + pkinit_cert_matching_data **ret_data) { return ENOSYS; } +/* Free up "this" "self" certificate and key. */ krb5_error_code -crypto_cert_get_matching_data(krb5_context context, - pkinit_cert_handle cert_handle, - pkinit_cert_matching_data **ret_data) +crypto_cert_release(krb5_context context, pkinit_cert_handle cert_handle) { return ENOSYS; } +/* Free names, key usage, and extended key usage from the cert matching data + * structure -- everything except the cert_handle it contains, anyway. */ krb5_error_code crypto_cert_free_matching_data(krb5_context context, pkinit_cert_matching_data *data) @@ -1025,6 +1100,8 @@ crypto_cert_free_matching_data(krb5_context context, return ENOSYS; } +/* Mark the cert tracked in the matching data structure as the one we're going + * to use. */ krb5_error_code crypto_cert_select(krb5_context context, pkinit_cert_matching_data *data) @@ -1032,6 +1109,7 @@ crypto_cert_select(krb5_context context, return ENOSYS; } +/* Try to select the "default" cert. */ krb5_error_code crypto_cert_select_default(krb5_context context, pkinit_plg_crypto_context plg_cryptoctx, @@ -1054,6 +1132,7 @@ crypto_load_cas_and_crls(krb5_context context, return ENOSYS; } +/* Retrieve the client's copy of the KDC's certificate. */ krb5_error_code pkinit_get_kdc_cert(krb5_context context, pkinit_plg_crypto_context plg_cryptoctx, @@ -1061,7 +1140,8 @@ pkinit_get_kdc_cert(krb5_context context, pkinit_identity_crypto_context id_cryptoctx, krb5_principal princ) { - return ENOSYS; + /* Nothing to do. */ + return 0; } krb5_error_code -- 1.7.6.4