[Библиотека GnuTLS в проекте C#] - PullRequest
0 голосов
/ 27 января 2020

Я пытаюсь импортировать библиотеку GnuTLS в мой проект C# и использовать ее API. К сожалению, я не могу найти способ, как это сделать с помощью библиотеки GnuTLS на основе C.

Кто-нибудь знает, как использовать библиотеку GnuTLS в проекте C# или даже как использовать сборку Windows библиотеки GnuTLS, доступную на их сайте https://www.gnutls.org/download.html, чтобы я мог запустить ее с помощью компилятора C и использовать P / Invoke в C# для доступа к необходимым API.

(В C# я пытался импортировать библиотеки как справочные, используя MSVS2010, но там говорится, что это не допустимая сборка NET или компонент COM) (также пробовал Windows сборка этой библиотеки с использованием простого C кода, который вызывает функцию, но не выполняет компиляцию из-за ошибки «... неопределенная ссылка на ...». Я помещаю заголовочные файлы в каталог MinGW, а также в DLL и EXE файлы).

1 Ответ

0 голосов
/ 25 апреля 2020

Вы можете использовать gnutls через P \ Invoke. Так что он работает на unix платформах. Пример на linux:

namespace GnuTlsExample
{
   internal static class NativeMethodsLinux {
        internal enum GNUTLS_X509_FMT
        {
            GNUTLS_X509_FMT_DER = 0,
            GNUTLS_X509_FMT_PEM = 1
        }

        [DllImport("libgnutls.so.30")]
        internal static extern int gnutls_x509_crt_list_import(IntPtr certs, ref int cert_max, IntPtr data, GNUTLS_X509_FMT format, uint flags);

        [DllImport("libgnutls.so.30")]
        internal static extern int gnutls_x509_privkey_init(ref IntPtr key);

        [DllImport("libgnutls.so.30")]
        internal static extern int gnutls_x509_privkey_import(IntPtr key,  IntPtr data, GNUTLS_X509_FMT format);

        [DllImport("libgnutls.so.30")]
        internal static extern int gnutls_certificate_set_x509_key(IntPtr cred, IntPtr certs, int max, IntPtr key);

        [StructLayout(LayoutKind.Sequential)]
        internal class gnutls_datum_t
        {
            public IntPtr data = IntPtr.Zero;
            public int size = 0;
        }
  }

    class Program
    {
        static void Main(string[] args)
        {
            var buf = ByteArrayToGnuTlsDatum(File.ReadAllBytes(certificateFilePath));
            var certs = Marshal.AllocHGlobal(IntPtr.Size);
            var max = 6;
            var tlsCtx = IntPtr.Zero;
            var isServer = 0;           

            var key = IntPtr.Zero;
            var bufKey = MarshalUtils.ByteArrayToGnuTlsDatum(File.ReadAllBytes(keyFilePath));
            var res = NativeMethodsLinux.gnutls_x509_privkey_init(ref key);

            res = NativeMethodsLinux.gnutls_x509_privkey_import(key, bufKey,
                NativeMethodsLinux.GNUTLS_X509_FMT.GNUTLS_X509_FMT_PEM);

            res = NativeMethodsLinux.gnutls_x509_crt_list_import(certs, ref max, buf,
                NativeMethodsLinux.GNUTLS_X509_FMT.GNUTLS_X509_FMT_PEM, 0);

            var cred = Marshal.AllocHGlobal(IntPtr.Size);
            res = NativeMethodsLinux.gnutls_certificate_set_x509_key(cred, certs, max, key);
        }
        internal static IntPtr ByteArrayToGnuTlsDatum(byte[] bytes)
        {
            var berPtr = Marshal.AllocHGlobal(Marshal.SizeOf<NativeMethodsLinux.gnutls_datum_t>());
            var valPtr = Marshal.AllocHGlobal(bytes.Length);
            Marshal.Copy(bytes,0,valPtr,bytes.Length);
            Marshal.StructureToPtr(new NativeMethodsLinux.gnutls_datum_t
            {
                data = valPtr,
                size = bytes.Length
            }, berPtr, true);
            return berPtr;
        }
     }

}


...