-static void sk_free_parameters(struct sk_cred *skc)
-{
- if (skc->sc_params)
- DH_free(skc->sc_params);
- if (skc->sc_p.value)
- free(skc->sc_p.value);
- if (skc->sc_pub_key.value)
- free(skc->sc_pub_key.value);
-
- skc->sc_p.value = NULL;
- skc->sc_p.length = 0;
- skc->sc_pub_key.value = NULL;
- skc->sc_pub_key.length = 0;
-}
-
-/**
- * Generates shared key Diffie Hellman parameters used for the DH key exchange
- * between host and peer if privacy mode is enabled
- *
- * \param[in,out] skc Shared key credentials structure to populate
- * with DH parameters
- *
- * \retval GSS_S_COMPLETE success
- * \retval GSS_S_FAILURE failure
- */
-static uint32_t sk_gen_initiator_params(struct sk_cred *skc)
-{
- gss_buffer_desc *iv = &skc->sc_kctx.skc_iv;
- int rc;
-
- /* The credential could be used so free existing parameters */
- sk_free_parameters(skc);
-
- /* Pseudo random should be sufficient here because the IV will be used
- * with a key that is used only once. This also should ensure we have
- * unqiue tokens that are sent to the remote server which is important
- * because the token is hashed for the sunrpc cache lookups and a
- * failure there would cause connection attempts to fail indefinitely
- * due to the large timeout value on the server side sunrpc cache
- * (INT_MAX) */
- iv->length = SK_IV_SIZE;
- iv->value = malloc(iv->length);
- if (!iv->value) {
- printerr(0, "Failed to allocate memory for IV\n");
- return GSS_S_FAILURE;
- }
- memset(iv->value, 0, iv->length);
- if (RAND_bytes(iv->value, iv->length) != 1) {
- printerr(0, "Failed to get data for IV\n");
- return GSS_S_FAILURE;
- }
-
- /* Only privacy mode needs the rest of the parameter generation
- * but we use IV in other modes as well so tokens should be
- * unique */
- if ((skc->sc_flags & LGSS_SVC_PRIV) == 0)
- return GSS_S_COMPLETE;
-
- skc->sc_params = DH_generate_parameters(skc->sc_session_keylen * 8,
- SK_GENERATOR, NULL, NULL);
- if (skc->sc_params == NULL) {
- printerr(0, "Failed to generate diffie-hellman parameters: %s",
- ERR_error_string(ERR_get_error(), NULL));
- return GSS_S_FAILURE;
- }
-
- if (DH_check(skc->sc_params, &rc) != 1) {
- printerr(0, "DH_check() failed: %d\n", rc);
- return GSS_S_FAILURE;
- } else if (rc) {
- printerr(0, "DH_check() returned error codes: 0x%x\n", rc);
- return GSS_S_FAILURE;
- }
-
- if (DH_generate_key(skc->sc_params) != 1) {
- printerr(0, "Failed to generate public DH key: %s\n",
- ERR_error_string(ERR_get_error(), NULL));
- return GSS_S_FAILURE;
- }
-
- skc->sc_p.length = BN_num_bytes(skc->sc_params->p);
- skc->sc_pub_key.length = BN_num_bytes(skc->sc_params->pub_key);
- skc->sc_p.value = malloc(skc->sc_p.length);
- skc->sc_pub_key.value = malloc(skc->sc_pub_key.length);
- if (!skc->sc_p.value || !skc->sc_pub_key.value) {
- printerr(0, "Failed to allocate memory for params\n");
- return GSS_S_FAILURE;
- }
-
- BN_bn2bin(skc->sc_params->pub_key, skc->sc_pub_key.value);
- BN_bn2bin(skc->sc_params->p, skc->sc_p.value);
-
- return GSS_S_COMPLETE;
-}
-
-/**
- * Generates or populates the DH parameters depending on whether the system is
- * the initiator or responder for the connection
- *
- * \param[in,out] skc Shared key credentials structure to
- * populate with DH parameters
- * \param[in] initiator Boolean whether to initiate parameters
- *
- * \retval GSS_S_COMPLETE success
- * \retval GSS_S_FAILURE failure
- */
-uint32_t sk_gen_params(struct sk_cred *skc, const bool initiator)
-{
- if (initiator)
- return sk_gen_initiator_params(skc);
-
- return sk_gen_responder_params(skc);
-}
-