OVMS3/OVMS.V3/components/wolfssl/wrapper/CSharp/wolfSSL_CSharp/X509.cs

203 lines
6.9 KiB
C#

using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
namespace wolfSSL.CSharp
{
public class X509
{
private const string wolfssl_dll = "wolfssl.dll";
[DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
private extern static int wolfSSL_X509_get_pubkey_buffer(IntPtr x509, IntPtr buf, IntPtr bufSz);
[DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
private extern static IntPtr wolfSSL_X509_get_der(IntPtr x509, IntPtr bufSz);
[DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
private extern static void wolfSSL_X509_free(IntPtr x509);
[DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
private extern static int wc_DerToPem(IntPtr der, int derSz, IntPtr pem, int pemSz, int type);
[DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
private extern static IntPtr wolfSSL_X509_get_name_oneline(IntPtr x509Name, IntPtr buf, int bufSz);
[DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
private extern static IntPtr wolfSSL_X509_get_subject_name(IntPtr x509);
[DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
private extern static IntPtr wolfSSL_X509_get_issuer_name(IntPtr x509);
private IntPtr x509;
private int type;
private bool isDynamic;
/* public properties */
public string Issuer;
public string Subject;
/* enum from wolfssl */
private readonly int CERT_TYPE = 0;
/// <summary>
/// Creates a new X509 class
/// </summary>
/// <param name="x509">Pointer to wolfSSL structure</param>
/// <param name="isDynamic">Should the lower level x509 be free'd? </param>
public X509(IntPtr x509, bool isDynamic)
{
IntPtr ret;
this.type = wolfssl.SSL_FILETYPE_PEM;
this.x509 = x509;
ret = wolfSSL_X509_get_name_oneline(
wolfSSL_X509_get_issuer_name(this.x509), IntPtr.Zero, 0);
this.Issuer = Marshal.PtrToStringAnsi(ret);
ret = wolfSSL_X509_get_name_oneline(
wolfSSL_X509_get_subject_name(this.x509), IntPtr.Zero, 0);
this.Subject = Marshal.PtrToStringAnsi(ret);
this.isDynamic = isDynamic;
}
/// <summary>
/// Free up the C level WOLFSSL_X509 struct if needed
/// </summary>
~X509()
{
if (this.isDynamic)
{
wolfSSL_X509_free(this.x509);
}
}
/// <summary>
/// Used for getting the public key buffer
/// </summary>
/// <returns>DER public key on success</returns>
public byte[] GetPublicKey()
{
if (this.x509 == IntPtr.Zero)
{
return null;
}
try
{
IntPtr bufSz;
IntPtr buf;
int keySz = 0;
int ret;
byte[] key = null;
bufSz = Marshal.AllocHGlobal(4); /* pointer to 4 bytes */
ret = wolfSSL_X509_get_pubkey_buffer(this.x509, IntPtr.Zero, bufSz);
if (ret == wolfssl.SUCCESS)
{
keySz = Marshal.ReadInt32(bufSz, 0);
buf = Marshal.AllocHGlobal(keySz);
ret = wolfSSL_X509_get_pubkey_buffer(this.x509, buf, bufSz);
if (ret == wolfssl.SUCCESS)
{
key = new byte[keySz];
Marshal.Copy(buf, key, 0, keySz);
}
Marshal.FreeHGlobal(buf);
}
Marshal.FreeHGlobal(bufSz);
return key;
}
catch (Exception e)
{
wolfssl.log(wolfssl.ERROR_LOG, "error getting public key" + e.ToString());
return null;
}
}
/// <summary>
/// Gets the X509 buffer
/// </summary>
/// <returns>X509 buffer on success</returns>
public byte[] Export(int type)
{
if (this.x509 == IntPtr.Zero)
return null;
try
{
IntPtr bufSz;
IntPtr buf;
byte[] ret = null;
bufSz = Marshal.AllocHGlobal(4); /* pointer to 4 bytes */
buf = wolfSSL_X509_get_der(this.x509, bufSz);
if (buf != IntPtr.Zero)
{
int derSz = Marshal.ReadInt32(bufSz, 0);
if (type == wolfssl.SSL_FILETYPE_ASN1)
{
ret = new byte[derSz];
Marshal.Copy(buf, ret, 0, derSz);
}
else if (type == wolfssl.SSL_FILETYPE_PEM)
{
int pemSz;
pemSz = wc_DerToPem(buf, derSz, IntPtr.Zero, 0, CERT_TYPE);
if (pemSz > 0)
{
IntPtr pem = Marshal.AllocHGlobal(pemSz);
pemSz = wc_DerToPem(buf, derSz, pem, pemSz, CERT_TYPE);
ret = new byte[pemSz];
Marshal.Copy(pem, ret, 0, pemSz);
Marshal.FreeHGlobal(pem);
}
}
else
{
wolfssl.log(wolfssl.ERROR_LOG, "unsupported export type");
}
Marshal.FreeHGlobal(bufSz);
return ret;
}
{
wolfssl.log(wolfssl.ERROR_LOG, "unable to get buffer");
}
Marshal.FreeHGlobal(bufSz);
return ret;
}
catch (Exception e)
{
wolfssl.log(wolfssl.ERROR_LOG, "error getting x509 DER" + e.ToString());
return null;
}
}
/// <summary>
/// Gets the X509 buffer using this.type set (default PEM)
/// </summary>
/// <returns>X509 buffer on success</returns>
public byte[] Export()
{
return Export(this.type);
}
/// <summary>
/// Gets the X509 format
/// </summary>
/// <returns>X509 format on success</returns>
public string GetFormat()
{
if (this.type == wolfssl.SSL_FILETYPE_PEM)
{
return "PEM";
}
if (this.type == wolfssl.SSL_FILETYPE_ASN1)
{
return "DER";
}
return "Unknown";
}
}
}