Example #1
0
int
tls_ctx_use_pkcs11(
    struct tls_root_ctx *const ssl_ctx,
    bool pkcs11_id_management,
    const char *const pkcs11_id
    ) {
    pkcs11h_certificate_id_t certificate_id = NULL;
    pkcs11h_certificate_t certificate = NULL;
    CK_RV rv = CKR_OK;

    bool ok = false;

    ASSERT(ssl_ctx!=NULL);
    ASSERT(pkcs11_id_management || pkcs11_id!=NULL);

    dmsg(
        D_PKCS11_DEBUG,
        "PKCS#11: tls_ctx_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id_management=%d, pkcs11_id='%s'",
        (void *)ssl_ctx,
        pkcs11_id_management ? 1 : 0,
        pkcs11_id
        );

    if (pkcs11_id_management)
    {
        struct user_pass id_resp;

        CLEAR(id_resp);

        id_resp.defined = false;
        id_resp.nocache = true;
        openvpn_snprintf(
            id_resp.username,
            sizeof(id_resp.username),
            "Please specify PKCS#11 id to use"
            );

        if (
            !get_user_pass(
                &id_resp,
                NULL,
                "pkcs11-id-request",
                GET_USER_PASS_MANAGEMENT|GET_USER_PASS_NEED_STR|GET_USER_PASS_NOFATAL
                )
            )
        {
            goto cleanup;
        }

        if (
            (rv = pkcs11h_certificate_deserializeCertificateId(
                 &certificate_id,
                 id_resp.password
                 )) != CKR_OK
            )
        {
            msg(M_WARN, "PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage(rv));
            goto cleanup;
        }
    }
    else
    {
        if (
            (rv = pkcs11h_certificate_deserializeCertificateId(
                 &certificate_id,
                 pkcs11_id
                 )) != CKR_OK
            )
        {
            msg(M_WARN, "PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage(rv));
            goto cleanup;
        }
    }

    if (
        (rv = pkcs11h_certificate_create(
             certificate_id,
             NULL,
             PKCS11H_PROMPT_MASK_ALLOW_ALL,
             PKCS11H_PIN_CACHE_INFINITE,
             &certificate
             )) != CKR_OK
        )
    {
        msg(M_WARN, "PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if (
        (pkcs11_init_tls_session(
             certificate,
             ssl_ctx
             ))
        )
    {
        /* Handled by SSL context free */
        certificate = NULL;
        goto cleanup;
    }

    /* Handled by SSL context free */
    certificate = NULL;
    ok = true;

cleanup:
    if (certificate != NULL)
    {
        pkcs11h_certificate_freeCertificate(certificate);
        certificate = NULL;
    }

    if (certificate_id != NULL)
    {
        pkcs11h_certificate_freeCertificateId(certificate_id);
        certificate_id = NULL;
    }

    dmsg(
        D_PKCS11_DEBUG,
        "PKCS#11: tls_ctx_use_pkcs11 - return ok=%d, rv=%ld",
        ok ? 1 : 0,
        rv
        );

    return ok ? 1 : 0;
}
Example #2
0
int _get_certificate_by_name (assuan_context_t ctx, char *name, int typehint, pkcs11h_certificate_id_t *p_cert_id, char **p_key) {
	cmd_data_t *data = (cmd_data_t *)assuan_get_pointer (ctx);
	gpg_err_code_t error = GPG_ERR_BAD_KEY;
	pkcs11h_certificate_id_list_t user_certificates = NULL;
	pkcs11h_certificate_id_list_t curr_cert;
	pkcs11h_certificate_id_t cert_id = NULL;
	char *key_hexgrip = NULL;
	gcry_sexp_t sexp = NULL;
	char *key = NULL;
	int type;

	*p_cert_id = NULL;
	if (p_key != NULL) {
		*p_key = NULL;
	}

	if (name == NULL) {
		type = typehint;
	}
	else if (	/* gnupg-2.0 mode */
		data->config->openpgp_sign != NULL ||
		data->config->openpgp_encr != NULL ||
		data->config->openpgp_auth != NULL
	) {
		type = typehint;
	}
	else if (strncmp (name, OPENPGP_KEY_NAME_PREFIX, strlen (OPENPGP_KEY_NAME_PREFIX))) {
		return common_map_pkcs11_error (
			pkcs11h_certificate_deserializeCertificateId (p_cert_id, name)
		);
	}
	else {
		type = atoi(name + strlen (OPENPGP_KEY_NAME_PREFIX));
	}

	switch (type) {
		case OPENPGP_SIGN:
			key = data->config->openpgp_sign;
		break;
		case OPENPGP_ENCR:
			key = data->config->openpgp_encr;
		break;
		case OPENPGP_AUTH:
			key = data->config->openpgp_auth;
		break;
		default:
			error = GPG_ERR_BAD_KEY;
			goto cleanup;
	}

	if (key == NULL) {
		error = GPG_ERR_BAD_KEY;
		goto cleanup;
	}

	if (
		(error = common_map_pkcs11_error (
			pkcs11h_certificate_enumCertificateIds (
				PKCS11H_ENUM_METHOD_CACHE_EXIST,
				ctx,
				PKCS11H_PROMPT_MASK_ALLOW_ALL,
				NULL,
				&user_certificates
			)
		)) != GPG_ERR_NO_ERROR
	) {
		goto cleanup;
	}

	for (
		curr_cert = user_certificates;
		curr_cert != NULL && cert_id == NULL;
		curr_cert = curr_cert->next
	) {

		if ((error = get_cert_sexp (ctx, curr_cert->certificate_id, &sexp)) != GPG_ERR_NO_ERROR) {
			goto cleanup;
		}

		if ((key_hexgrip = keyutil_get_cert_hexgrip (sexp)) == NULL) {
			error = GPG_ERR_ENOMEM;
			goto cleanup;
		}

		if (!strcmp (key_hexgrip, key)) {
			if (
				(error = common_map_pkcs11_error (
					pkcs11h_certificate_duplicateCertificateId (
						&cert_id,
						curr_cert->certificate_id
					)
				)) != GPG_ERR_NO_ERROR
			) {
				goto cleanup;
			}
		}
	}

	if (cert_id == NULL) {
		error = GPG_ERR_BAD_KEY;
		goto cleanup;
	}

	*p_cert_id = cert_id;
	cert_id = NULL;
	if (p_key != NULL) {
		*p_key = key;
	}
	error = GPG_ERR_NO_ERROR;

cleanup:

	if (sexp != NULL) {
		gcry_sexp_release(sexp);
		sexp = NULL;
	}

	if (key_hexgrip != NULL) {
		free (key_hexgrip);
		key_hexgrip = NULL;
	}

	if (user_certificates != NULL) {
		pkcs11h_certificate_freeCertificateIdList (user_certificates);
		user_certificates = NULL;
	}

	if (cert_id != NULL) {
		pkcs11h_certificate_freeCertificateId (cert_id);
		cert_id = NULL;
	}

	return error;
}