Example #1
0
bool
pkcs11_management_id_get(
    const int index,
    char **id,
    char **base64
    ) {
    pkcs11h_certificate_id_list_t id_list = NULL;
    pkcs11h_certificate_id_list_t entry = NULL;
#if 0 /* certificate_id seems to be unused -- JY */
    pkcs11h_certificate_id_t certificate_id = NULL;
#endif
    pkcs11h_certificate_t certificate = NULL;
    CK_RV rv = CKR_OK;
    unsigned char *certificate_blob = NULL;
    size_t certificate_blob_size = 0;
    size_t max;
    char *internal_id = NULL;
    char *internal_base64 = NULL;
    int count = 0;
    bool success = false;

    ASSERT(id!=NULL);
    ASSERT(base64!=NULL);

    dmsg(
        D_PKCS11_DEBUG,
        "PKCS#11: pkcs11_management_id_get - entered index=%d",
        index
        );

    *id = NULL;
    *base64 = NULL;

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

    entry = id_list;
    count = 0;
    while (entry != NULL && count != index) {
        count++;
        entry = entry->next;
    }

    if (entry == NULL)
    {
        dmsg(
            D_PKCS11_DEBUG,
            "PKCS#11: pkcs11_management_id_get - no certificate at index=%d",
            index
            );
        goto cleanup;
    }

    if (
        (rv = pkcs11h_certificate_serializeCertificateId(
             NULL,
             &max,
             entry->certificate_id
             )) != CKR_OK
        )
    {
        msg(M_WARN, "PKCS#11: Cannot serialize certificate id %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if ((internal_id = (char *)malloc(max)) == NULL)
    {
        msg(M_FATAL, "PKCS#11: Cannot allocate memory");
        goto cleanup;
    }

    if (
        (rv = pkcs11h_certificate_serializeCertificateId(
             internal_id,
             &max,
             entry->certificate_id
             )) != CKR_OK
        )
    {
        msg(M_WARN, "PKCS#11: Cannot serialize certificate id %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if (
        (rv = pkcs11h_certificate_create(
             entry->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 (
        (rv = pkcs11h_certificate_getCertificateBlob(
             certificate,
             NULL,
             &certificate_blob_size
             )) != CKR_OK
        )
    {
        msg(M_WARN, "PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if ((certificate_blob = (unsigned char *)malloc(certificate_blob_size)) == NULL)
    {
        msg(M_FATAL, "PKCS#11: Cannot allocate memory");
        goto cleanup;
    }

    if (
        (rv = pkcs11h_certificate_getCertificateBlob(
             certificate,
             certificate_blob,
             &certificate_blob_size
             )) != CKR_OK
        )
    {
        msg(M_WARN, "PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if (openvpn_base64_encode(certificate_blob, certificate_blob_size, &internal_base64) == -1)
    {
        msg(M_WARN, "PKCS#11: Cannot encode certificate");
        goto cleanup;
    }

    *id = internal_id;
    internal_id = NULL;
    *base64 = internal_base64;
    internal_base64 = NULL;
    success = true;

cleanup:

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

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

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

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

    dmsg(
        D_PKCS11_DEBUG,
        "PKCS#11: pkcs11_management_id_get - return success=%d, id='%s'",
        success ? 1 : 0,
        *id
        );

    return success;
}
Example #2
0
void
show_pkcs11_ids(
    const char *const provider,
    bool cert_private
    ) {
    struct gc_arena gc = gc_new();
    pkcs11h_certificate_id_list_t user_certificates = NULL;
    pkcs11h_certificate_id_list_t current = NULL;
    CK_RV rv = CKR_FUNCTION_FAILED;

    if ((rv = pkcs11h_initialize()) != CKR_OK)
    {
        msg(M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if ((rv = pkcs11h_setLogHook(_pkcs11_openvpn_log, NULL)) != CKR_OK)
    {
        msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    pkcs11h_setLogLevel(_pkcs11_msg_openvpn2pkcs11(get_debug_level()));

    if ((rv = pkcs11h_setProtectedAuthentication(TRUE)) != CKR_OK)
    {
        msg(M_FATAL, "PKCS#11: Cannot set protected authentication %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_show_pkcs11_ids_pin_prompt, NULL)) != CKR_OK)
    {
        msg(M_FATAL, "PKCS#11: Cannot set PIN hook %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if (
        (rv = pkcs11h_addProvider(
             provider,
             provider,
             TRUE,
             0,
             FALSE,
             0,
             cert_private ? TRUE : FALSE
             )) != CKR_OK
        )
    {
        msg(M_FATAL, "PKCS#11: Cannot add provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if (
        (rv = pkcs11h_certificate_enumCertificateIds(
             PKCS11H_ENUM_METHOD_CACHE_EXIST,
             NULL,
             PKCS11H_PROMPT_MASK_ALLOW_ALL,
             NULL,
             &user_certificates
             )) != CKR_OK
        )
    {
        msg(M_FATAL, "PKCS#11: Cannot enumerate certificates %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    msg(
        M_INFO|M_NOPREFIX|M_NOLF,
        (
            "\n"
            "The following objects are available for use.\n"
            "Each object shown below may be used as parameter to\n"
            "--pkcs11-id option please remember to use single quote mark.\n"
        )
        );
    for (current = user_certificates; current != NULL; current = current->next) {
        pkcs11h_certificate_t certificate = NULL;
        char *dn = NULL;
        char serial[1024] = {0};
        char *ser = NULL;
        size_t ser_len = 0;

        if (
            (rv = pkcs11h_certificate_serializeCertificateId(
                 NULL,
                 &ser_len,
                 current->certificate_id
                 )) != CKR_OK
            )
        {
            msg(M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
            goto cleanup1;
        }

        if (
            rv == CKR_OK
            && (ser = (char *)malloc(ser_len)) == NULL
            )
        {
            msg(M_FATAL, "PKCS#11: Cannot allocate memory");
            goto cleanup1;
        }

        if (
            (rv = pkcs11h_certificate_serializeCertificateId(
                 ser,
                 &ser_len,
                 current->certificate_id
                 )) != CKR_OK
            )
        {
            msg(M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
            goto cleanup1;
        }

        if (
            (rv = pkcs11h_certificate_create(
                 current->certificate_id,
                 NULL,
                 PKCS11H_PROMPT_MASK_ALLOW_ALL,
                 PKCS11H_PIN_CACHE_INFINITE,
                 &certificate
                 ))
            )
        {
            msg(M_FATAL, "PKCS#11: Cannot create certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
            goto cleanup1;
        }

        if (
            (dn = pkcs11_certificate_dn(
                 certificate,
                 &gc
                 )) == NULL
            )
        {
            goto cleanup1;
        }

        if (
            (pkcs11_certificate_serial(
                 certificate,
                 serial,
                 sizeof(serial)
                 ))
            )
        {
            goto cleanup1;
        }

        msg(
            M_INFO|M_NOPREFIX|M_NOLF,
            (
                "\n"
                "Certificate\n"
                "       DN:             %s\n"
                "       Serial:         %s\n"
                "       Serialized id:  %s\n"
            ),
            dn,
            serial,
            ser
            );

cleanup1:

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

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

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

    pkcs11h_terminate();
    gc_free(&gc);
}
Example #3
0
/**
   Send status lines in the format

   S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id>
   S CERTINFO <certtype> <hexstring_with_id>

   If certificate is issuer, we set type to 102 (useful); otherwise it is
   assumed that we're in posession of private key, so the type is set to 101
   (trusted).  The certificate ID is percent-plus escaped displayName.
*/
static
int
send_certificate_list (
	assuan_context_t ctx,
	pkcs11h_certificate_id_list_t head,	/* list head */
	int is_issuer				/* true if issuer certificate */
) {
	cmd_data_t *data = (cmd_data_t *)assuan_get_pointer (ctx);
	gpg_err_code_t error = GPG_ERR_GENERAL;
	pkcs11h_certificate_id_list_t curr_cert;

	for (
		curr_cert = head;
		curr_cert != NULL;
		curr_cert = curr_cert->next
	) {
		char *certid = NULL;
		char *key_hexgrip = NULL;
		char *keypairinfo = NULL;
		char *gpginfo = NULL;
		char *info_cert = NULL;
		gcry_sexp_t sexp = NULL;
		size_t ser_len;
		char *key_prefix = NULL;
		char *nameinfo = NULL;

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

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

		if (
			(error = common_map_pkcs11_error (
				pkcs11h_certificate_serializeCertificateId (
					NULL,
					&ser_len,
					curr_cert->certificate_id
				)
			)) != GPG_ERR_NO_ERROR
		) {
			goto retry;
		}

		if ((certid = (char *)malloc (ser_len)) == NULL	) {
			error = GPG_ERR_ENOMEM;
			goto retry;
		}

		if (
			(error = common_map_pkcs11_error (
				pkcs11h_certificate_serializeCertificateId (
					certid,
					&ser_len,
					curr_cert->certificate_id
				)
			)) != GPG_ERR_NO_ERROR
		) {
			goto retry;
		}

		if ((info_cert = strdup (is_issuer ? "102 " : "101 ")) == NULL) {
			error = GPG_ERR_ENOMEM;
			goto retry;
		}

		if (!encoding_strappend (&info_cert, certid)) {
			error = GPG_ERR_ENOMEM;
			goto retry;
		}

		if (
			data->config->openpgp_sign != NULL &&
			!strcmp (data->config->openpgp_sign, key_hexgrip)
		) {
			key_prefix = M2S(OPENPGP_SIGN) " ";
		}
		else if (
			data->config->openpgp_encr != NULL &&
			!strcmp (data->config->openpgp_encr, key_hexgrip)
		) {
			key_prefix = M2S(OPENPGP_ENCR) " ";
		}
		else if (
			data->config->openpgp_auth != NULL &&
			!strcmp (data->config->openpgp_auth, key_hexgrip)
		) {
			key_prefix = M2S(OPENPGP_AUTH) " ";
		}

		if (
			(nameinfo = strdup (key_hexgrip)) == NULL ||
			!encoding_strappend (&nameinfo, " ") ||
			!encoding_strappend (&nameinfo, curr_cert->certificate_id->displayName)
		) {
			error = GPG_ERR_ENOMEM;
			goto retry;
		}

		if (
			(error = assuan_write_status (
				ctx,
				"KEY-FRIEDNLY",
				nameinfo
			)) != GPG_ERR_NO_ERROR
		) {
			goto retry;
		}

		if (key_prefix != NULL) {
			if (
				(gpginfo = strdup (key_prefix)) == NULL ||
				!encoding_strappend (&gpginfo, key_hexgrip)
			) {
				error = GPG_ERR_ENOMEM;
				goto retry;
			}


			if (
				(error = assuan_write_status (
					ctx,
					"KEY-FPR",
					gpginfo
				)) != GPG_ERR_NO_ERROR
			) {
				goto retry;
			}

		}
		if (
			(error = assuan_write_status (
				ctx,
				"CERTINFO",
				info_cert
			)) != GPG_ERR_NO_ERROR
		) {
			goto retry;
		}

		/* send keypairinfo if not issuer certificate */
		if(!is_issuer) {
			if (
				(keypairinfo = strdup (key_hexgrip)) == NULL ||
				!encoding_strappend (&keypairinfo, " ") ||
				!encoding_strappend (&keypairinfo, certid)
			) {
				error = GPG_ERR_ENOMEM;
				goto retry;
			}

			if (
				(error = assuan_write_status (
					ctx,
					"KEYPAIRINFO",
					keypairinfo
				)) != GPG_ERR_NO_ERROR
			) {
				goto retry;
			}
		}

		error = GPG_ERR_NO_ERROR;

	retry:

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

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

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

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

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

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

		if (error != GPG_ERR_NO_ERROR) {
			goto cleanup;
		}
	}

	error = GPG_ERR_NO_ERROR;

cleanup:

	return error;
}