diff --git a/examples/DigiDocCSharp/DigiDocCSharp.csproj b/examples/DigiDocCSharp/DigiDocCSharp.csproj
index 8fb78a012..95123b394 100644
--- a/examples/DigiDocCSharp/DigiDocCSharp.csproj
+++ b/examples/DigiDocCSharp/DigiDocCSharp.csproj
@@ -2,9 +2,8 @@
net472
Exe
- true
- 0.4.0.0
- 0.4.0.0
+ 0.5.0.0
+ 0.5.0.0
Copyright © 2015
diff --git a/examples/DigiDocCSharp/Program.cs b/examples/DigiDocCSharp/Program.cs
index ed3accb6b..c5f25cfa4 100644
--- a/examples/DigiDocCSharp/Program.cs
+++ b/examples/DigiDocCSharp/Program.cs
@@ -154,8 +154,7 @@ private static void Websign(string[] args)
b.addDataFile(args[i], "application/octet-stream");
}
- X509Certificate cert = new X509Certificate();
- cert.Import(args[args.Length - 2]);
+ var cert = new X509Certificate(args[args.Length - 2]);
Signature c = b.prepareWebSignature(cert.Export(X509ContentType.Cert), "time-stamp");
Console.WriteLine("Signature method: " + c.signatureMethod());
Console.WriteLine("Digest to sign: " + BitConverter.ToString(c.dataToSign()).Replace("-", string.Empty));
@@ -207,7 +206,8 @@ private static void Verify(string file)
Console.WriteLine();
Console.WriteLine("Time: " + s.trustedSigningTime());
- Console.WriteLine("Cert: " + new X509Certificate2(s.signingCertificateDer()).Subject);
+ Console.WriteLine("Cert: " + s.signingCertificate().Subject);
+ Console.WriteLine("TimeStamp: " + s.TimeStampCertificate().Subject);
s.validate();
Console.WriteLine("Signature is valid");
diff --git a/examples/java/src/main/java/ee/ria/libdigidocpp/libdigidocpp.java b/examples/java/src/main/java/ee/ria/libdigidocpp/libdigidocpp.java
index bbe59f2bc..bf6050226 100644
--- a/examples/java/src/main/java/ee/ria/libdigidocpp/libdigidocpp.java
+++ b/examples/java/src/main/java/ee/ria/libdigidocpp/libdigidocpp.java
@@ -149,7 +149,8 @@ static void verify(String file) {
System.out.println();
System.out.println("Time: " + signature.trustedSigningTime());
- System.out.println("Cert: " + toX509(signature.signingCertificateDer()).getSubjectDN().toString());
+ System.out.println("Cert: " + signature.signingCertificate().getSubjectDN().toString());
+ System.out.println("TimeStamp Cert: " + signature.TimeStampCertificate().getSubjectDN().toString());
try
{
@@ -171,7 +172,7 @@ static void verify(String file) {
}
static void version() {
- System.out.println("DigiDocJAVA 0.3 libdigidocpp " + digidoc.version());
+ System.out.println("DigiDocJAVA 0.4 libdigidocpp " + digidoc.version());
}
static X509Certificate toX509(byte[] der) throws CertificateException {
diff --git a/libdigidocpp.i b/libdigidocpp.i
index f64ba3ee0..ef2e5884f 100644
--- a/libdigidocpp.i
+++ b/libdigidocpp.i
@@ -60,6 +60,9 @@ extern "C"
SWIGEXPORT int SWIGSTDCALL ByteVector_size(void *ptr) {
return static_cast*>(ptr)->size();
}
+ SWIGEXPORT void SWIGSTDCALL ByteVector_free(void *ptr) {
+ delete static_cast*>(ptr);
+ }
SWIGEXPORT void* SWIGSTDCALL ByteVector_to(unsigned char *data, int size) {
return new std::vector(data, data + size);
}
@@ -72,112 +75,93 @@ extern "C"
public static extern global::System.IntPtr ByteVector_data(global::System.IntPtr data);
[global::System.Runtime.InteropServices.DllImport("$dllimport", EntryPoint="ByteVector_size")]
public static extern int ByteVector_size(global::System.IntPtr data);
+ [global::System.Runtime.InteropServices.DllImport("$dllimport", EntryPoint="ByteVector_free")]
+ public static extern void ByteVector_free(global::System.IntPtr data);
[global::System.Runtime.InteropServices.DllImport("$dllimport", EntryPoint="ByteVector_to")]
public static extern global::System.IntPtr ByteVector_to(
- [global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPArray)]byte[] data, int size);
-
- public class UTF8Marshaler : global::System.Runtime.InteropServices.ICustomMarshaler {
- static UTF8Marshaler static_instance = new UTF8Marshaler();
-
- public global::System.IntPtr MarshalManagedToNative(object managedObj) {
- if (managedObj == null)
- return global::System.IntPtr.Zero;
- if (!(managedObj is string))
- throw new global::System.Runtime.InteropServices.MarshalDirectiveException(
- "UTF8Marshaler must be used on a string.");
-
- // not null terminated
- byte[] strbuf = global::System.Text.Encoding.UTF8.GetBytes((string)managedObj);
- global::System.IntPtr buffer = global::System.Runtime.InteropServices.Marshal.AllocHGlobal(strbuf.Length + 1);
- global::System.Runtime.InteropServices.Marshal.Copy(strbuf, 0, buffer, strbuf.Length);
-
- // write the terminating null
- global::System.Runtime.InteropServices.Marshal.WriteByte(buffer + strbuf.Length, 0);
- return buffer;
- }
-
- public unsafe object MarshalNativeToManaged(global::System.IntPtr pNativeData) {
- byte* walk = (byte*)pNativeData;
-
- // find the end of the string
- while (*walk != 0) {
- walk++;
- }
- int length = (int)(walk - (byte*)pNativeData);
-
- // should not be null terminated
- byte[] strbuf = new byte[length];
- // skip the trailing null
- global::System.Runtime.InteropServices.Marshal.Copy((global::System.IntPtr)pNativeData, strbuf, 0, length);
- return global::System.Text.Encoding.UTF8.GetString(strbuf);
- }
-
- public void CleanUpNativeData(global::System.IntPtr pNativeData) {
- global::System.Runtime.InteropServices.Marshal.FreeHGlobal(pNativeData);
- }
-
- public void CleanUpManagedData(object managedObj) {
- }
-
- public int GetNativeDataSize() {
- return -1;
- }
-
- public static global::System.Runtime.InteropServices.ICustomMarshaler GetInstance(string cookie) {
- return static_instance;
- }
- }
+ [global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPArray)]byte[] data, int size);
%}
#ifdef SWIGJAVA
-%typemap(in) std::vector %{
- jbyte *$input_ptr = jenv->GetByteArrayElements($input, NULL);
- jsize $input_size = jenv->GetArrayLength($input);
- std::vector $1_data($input_ptr, $input_ptr+$input_size);
- $1 = &$1_data;
- jenv->ReleaseByteArrayElements($input, $input_ptr, JNI_ABORT);
-%}
-%typemap(out) std::vector %{
- jresult = jenv->NewByteArray((&result)->size());
- jenv->SetByteArrayRegion(jresult, 0, (&result)->size(), (const jbyte*)(&result)->data());
-%}
-%typemap(jtype) std::vector "byte[]"
+%fragment("SWIG_VectorUnsignedCharToJavaArray", "header") {
+static jbyteArray SWIG_VectorUnsignedCharToJavaArray(JNIEnv *jenv, const std::vector &data) {
+ jbyteArray jresult = JCALL1(NewByteArray, jenv, data.size());
+ if (!jresult)
+ return nullptr;
+ JCALL4(SetByteArrayRegion, jenv, jresult, 0, data.size(), (const jbyte*)data.data());
+ return jresult;
+}}
+%fragment("SWIG_JavaArrayToVectorUnsignedChar", "header") {
+static std::vector* SWIG_JavaArrayToVectorUnsignedChar(JNIEnv *jenv, jbyteArray data) {
+ std::vector *result = new std::vector(JCALL1(GetArrayLength, jenv, data));
+ JCALL4(GetByteArrayRegion, jenv, data, 0, result->size(), (jbyte*)result->data());
+ return result;
+}}
+%typemap(in, fragment="SWIG_JavaArrayToVectorUnsignedChar") std::vector
+%{ $1 = SWIG_JavaArrayToVectorUnsignedChar(jenv, $input); %}
+%typemap(out, fragment="SWIG_VectorUnsignedCharToJavaArray") std::vector, digidoc::X509Cert
+%{ $result = SWIG_VectorUnsignedCharToJavaArray(jenv, $1); %}
+%typemap(jtype) std::vector, digidoc::X509Cert "byte[]"
%typemap(jstype) std::vector "byte[]"
-%typemap(jni) std::vector "jbyteArray"
-%typemap(javain) std::vector "$javainput"
+%typemap(jstype) digidoc::X509Cert "java.security.cert.X509Certificate"
+%typemap(jni) std::vector, digidoc::X509Cert "jbyteArray"
+%typemap(javain) std::vector, digidoc::X509Cert "$javainput"
%typemap(javaout) std::vector {
return $jnicall;
}
+%typemap(javaout, throws="java.security.cert.CertificateException, java.io.IOException") digidoc::X509Cert {
+ byte[] der = $jnicall;
+ java.security.cert.CertificateFactory cf = java.security.cert.CertificateFactory.getInstance("X509");
+ try (java.io.ByteArrayInputStream is = new java.io.ByteArrayInputStream(der)) {
+ return (java.security.cert.X509Certificate) cf.generateCertificate(is);
+ }
+ }
+
#elif defined(SWIGCSHARP)
%typemap(cstype) std::vector "byte[]"
-%typemap(csin,
- pre= " global::System.IntPtr cPtr$csinput = digidocPINVOKE.ByteVector_to($csinput, $csinput.Length);
- global::System.Runtime.InteropServices.HandleRef handleRef$csinput = new global::System.Runtime.InteropServices.HandleRef(this, cPtr$csinput);"
+%typemap(cstype) digidoc::X509Cert "System.Security.Cryptography.X509Certificates.X509Certificate2"
+%typemap(csin, pre= " global::System.IntPtr cPtr$csinput = digidocPINVOKE.ByteVector_to($csinput, $csinput.Length);
+ var handleRef$csinput = new global::System.Runtime.InteropServices.HandleRef(this, cPtr$csinput);"
) std::vector "handleRef$csinput"
%typemap(csout, excode=SWIGEXCODE) std::vector {
- global::System.IntPtr data = $imcall;$excode
- byte[] result = new byte[$modulePINVOKE.ByteVector_size(data)];
- global::System.Runtime.InteropServices.Marshal.Copy($modulePINVOKE.ByteVector_data(data), result, 0, result.Length);
- return result;
-}
-#elif defined(SWIGPYTHON)
- %typemap(in) std::vector %{
- if (PyBytes_Check($input)) {
- const char *data = PyBytes_AsString($input);
- $1 = new std::vector(data, data + PyBytes_Size($input));
- } else if (PyString_Check($input)) {
- const char *data = PyString_AsString($input);
- $1 = new std::vector(data, data + PyString_Size($input));
- } else {
- PyErr_SetString(PyExc_TypeError, "not a bytes");
- SWIG_fail;
+ global::System.IntPtr cPtr = $imcall;$excode
+ byte[] result = new byte[$modulePINVOKE.ByteVector_size(cPtr)];
+ global::System.Runtime.InteropServices.Marshal.Copy($modulePINVOKE.ByteVector_data(cPtr), result, 0, result.Length);
+ $modulePINVOKE.ByteVector_free(cPtr);
+ return result;
+ }
+%typemap(csout, excode=SWIGEXCODE) digidoc::X509Cert {
+ global::System.IntPtr cPtr = $imcall;$excode
+ byte[] der = new byte[$modulePINVOKE.ByteVector_size(cPtr)];
+ global::System.Runtime.InteropServices.Marshal.Copy($modulePINVOKE.ByteVector_data(cPtr), der, 0, der.Length);
+ $modulePINVOKE.ByteVector_free(cPtr);
+ return new System.Security.Cryptography.X509Certificates.X509Certificate2(der);
}
- %}
+%typemap(out) std::vector %{ $result = new std::vector(std::move($1)); %}
+%typemap(out) digidoc::X509Cert %{ $result = new std::vector($1); %}
+
+#elif defined(SWIGPYTHON)
+%typemap(in) std::vector %{
+ if (PyBytes_Check($input)) {
+ const char *data = PyBytes_AsString($input);
+ $1 = new std::vector(data, data + PyBytes_Size($input));
+ } else if (PyString_Check($input)) {
+ const char *data = PyString_AsString($input);
+ $1 = new std::vector(data, data + PyString_Size($input));
+ } else {
+ PyErr_SetString(PyExc_TypeError, "not a bytes");
+ SWIG_fail;
+ }
+%}
%typemap(out) std::vector
%{ $result = PyBytes_FromStringAndSize((const char*)(&result)->data(), (&result)->size()); %}
+%typemap(out) digidoc::X509Cert {
+ std::vector temp = $1;
+ $result = PyBytes_FromStringAndSize((const char*)temp.data(), temp.size());
+}
+#endif
%typemap(freearg) std::vector
%{ delete $1; %}
-#endif
%apply std::vector { std::vector const & };
%exception %{
@@ -208,11 +192,6 @@ extern "C"
%ignore digidoc::ConfV2::verifyServiceCert;
%ignore digidoc::ConfV4::verifyServiceCerts;
%ignore digidoc::ConfV5::TSCerts;
-%ignore digidoc::Signer::cert;
-%ignore digidoc::Signature::signingCertificate;
-%ignore digidoc::Signature::OCSPCertificate;
-%ignore digidoc::Signature::TimeStampCertificate;
-%ignore digidoc::Signature::ArchiveTimeStampCertificate;
// hide stream methods, swig cannot generate usable wrappers
%ignore digidoc::DataFile::saveAs(std::ostream &os) const;
%ignore digidoc::Container::addAdESSignature(std::istream &signature);
@@ -260,15 +239,10 @@ def transfer(self):
%include "std_vector.i"
%include "std_map.i"
#ifdef SWIGCSHARP
-namespace std {
- %typemap(imtype,
- inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]",
- outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]")
- string "string"
- %typemap(imtype,
- inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]",
- outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]") const string & "string"
-}
+%typemap(imtype,
+ inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPUTF8Str)]",
+ outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPUTF8Str)]")
+ std::string, const std::string & "string"
#endif
// Handle DigiDoc Export declarations
@@ -294,31 +268,6 @@ namespace std {
%template(DataFiles) std::vector;
%template(Signatures) std::vector;
-// override X509Cert methods to return byte array
-%extend digidoc::Signer {
- std::vector cert() const
- {
- return $self->cert();
- }
-}
-%extend digidoc::Signature {
- std::vector signingCertificateDer() const
- {
- return $self->signingCertificate();
- }
- std::vector OCSPCertificateDer() const
- {
- return $self->OCSPCertificate();
- }
- std::vector TimeStampCertificateDer() const
- {
- return $self->TimeStampCertificate();
- }
- std::vector ArchiveTimeStampCertificateDer() const
- {
- return $self->ArchiveTimeStampCertificate();
- }
-}
%extend digidoc::Container {
static digidoc::Container* open(const std::string &path, digidoc::ContainerOpenCB *cb)
{
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c4363e0cb..01317a3d8 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -202,7 +202,7 @@ if(SWIG_FOUND)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/digidoc.py DESTINATION ${Python3_SITELIB})
endif()
- set(CMAKE_SWIG_FLAGS -dllimport digidoc_csharp -namespace digidoc)
+ set(CMAKE_SWIG_FLAGS -namespace digidoc)
set(CMAKE_SWIG_OUTDIR ${CMAKE_CURRENT_BINARY_DIR}/csharp)
swig_add_library(digidoc_csharp LANGUAGE csharp SOURCES ../libdigidocpp.i)
target_compile_definitions(digidoc_csharp PRIVATE TARGET_NAME="$")