Пищу следующий код (C#):
Сводка
public class AlgList
{
internal const string dllName = “libcrypto.so”;
private class Names
{
public Names(int type, bool isSorted)
{
if (isSorted) OBJ_NAME_do_all_sorted(type, new ObjectNameHandler(OnObjectName), IntPtr.Zero);
else OBJ_NAME_do_all(type, new ObjectNameHandler(OnObjectName), IntPtr.Zero);
}
private void OnObjectName(IntPtr ptr, IntPtr arg)
{
Console.WriteLine(PtrToStringAnsi(((ObjName)Marshal.PtrToStructure(ptr, typeof(ObjName))).name, false));
}
private struct ObjName
{
public int type;
public int alias;
public IntPtr name;
public IntPtr data;
}
public static string PtrToStringAnsi(IntPtr ptr, bool hasOwnership)
{
int ofs = 0;
int length = 0;
while (ofs < 1024 && Marshal.ReadByte(ptr, ofs) != 0)
{
++ofs;
++length;
}
if (length == 1024) return "Invalid string";
byte[] numArray = new byte[length];
Marshal.Copy(ptr, numArray, 0, length);
if (hasOwnership) CRYPTO_free(ptr);
return Encoding.ASCII.GetString(numArray, 0, length);
}
}
static AlgList()
{
OPENSSL_add_all_algorithms_noconf();
ERR_load_crypto_strings();
ENGINE_load_openssl();
ENGINE_load_builtin_engines();
}
public static void RunTest()
{
Console.WriteLine("------------- Ciphers -------------");
new Names(2, true);
Console.WriteLine();
Console.WriteLine("------------- MessageDigests -------------");
new Names(1, true);
}
[DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
private static extern void OPENSSL_add_all_algorithms_noconf();
[DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
private static extern void ERR_load_crypto_strings();
[DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
private static extern void ENGINE_load_openssl();
[DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
private static extern void ENGINE_load_builtin_engines();
[DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
private static extern void CRYPTO_free(IntPtr p);
[DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
private static extern void OBJ_NAME_do_all(int type, ObjectNameHandler fn, IntPtr arg);
[DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
private static extern void OBJ_NAME_do_all_sorted(int type, ObjectNameHandler fn, IntPtr arg);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void ObjectNameHandler(IntPtr name, IntPtr arg);
}
В Windows возвращается список алгоритмов (библиотека libeay64.dll) и в том числе GOST
------------- Ciphers -------------
GOST 28147-89
gost89
gost89-cnt
------------- MessageDigests -------------
GOST 28147-89 MAC
GOST 34.311-95
GOST Old 34.311-95
GOST R 34.11-94
gost-mac
В Linux эти алгоритмы отсутствуют. Как инициализировать эти алгоритмы под Linux?
В Windows-библиотеке есть метод ENGINE_load_gost(), в Linux-библиотеке его нет.