Skip to content

Commit 8a35146

Browse files
committed
Add C# web signing support
IB-4339
1 parent 9f44695 commit 8a35146

File tree

2 files changed

+89
-21
lines changed

2 files changed

+89
-21
lines changed

examples/DigiDocCSharp/Program.cs

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.IO;
6+
using System.Linq;
67
using System.Security.Cryptography.X509Certificates;
78
using digidoc;
89

@@ -23,6 +24,7 @@ static void Main(string[] args)
2324
{
2425
case "extract": extract(Convert.ToInt32(args[1]), args[2]); return;
2526
case "sign": sign(args); return;
27+
case "websign": websign(args); return;
2628
case "verify": verify(args[1]); return;
2729
case "version": version(); return;
2830
case "help":
@@ -36,7 +38,7 @@ static void extract(int index, string file)
3638
try
3739
{
3840
Console.WriteLine("Opening file: " + file);
39-
Container b = new Container(file);
41+
Container b = Container.open(file);
4042
DataFile d = b.dataFiles()[index];
4143
string dest = Path.Combine(Directory.GetCurrentDirectory(), d.fileName());
4244
Console.WriteLine("Extracting file {0} to {1}", d.fileName(), dest);
@@ -59,13 +61,19 @@ static void extract(int index, string file)
5961

6062
static void help()
6163
{
62-
Console.WriteLine("DigiDocCSharpt command");
64+
Console.WriteLine("DigiDocCSharp command [params]");
6365
Console.WriteLine("Command:");
6466
Console.WriteLine(" extract\tExtracts files from document");
6567
Console.WriteLine(" num");
6668
Console.WriteLine(" file");
6769
Console.WriteLine(" help\t\tPrints utility commands");
6870
Console.WriteLine(" sign\t\tSigns file");
71+
Console.WriteLine(" datafile1 datafile2 ...");
72+
Console.WriteLine(" file");
73+
Console.WriteLine(" websign\t\tSigns file");
74+
Console.WriteLine(" datafile1 datafile2 ...");
75+
Console.WriteLine(" cert");
76+
Console.WriteLine(" file");
6977
Console.WriteLine(" verify\t\tVerifies document signature and shows info");
7078
Console.WriteLine(" file");
7179
Console.WriteLine(" version\tPrints utility version");
@@ -78,11 +86,46 @@ static void sign(string[] args)
7886
try
7987
{
8088
Console.WriteLine("Creating file: " + args[args.Length-1]);
81-
Container b = new Container(Container.DocumentType.BDocType);
89+
Container b = Container.create(args[args.Length - 1]);
8290
for (int i = 1; i < args.Length - 1; ++i)
83-
b.addDataFile(args[i], "");
84-
b.sign("", "", "", "", new StringVector { }, "");
85-
b.save(args[args.Length - 1]);
91+
b.addDataFile(args[i], "application/octet-stream");
92+
using (WinSigner signer = new WinSigner())
93+
b.sign(signer);
94+
b.save();
95+
}
96+
catch (Exception e)
97+
{
98+
Console.WriteLine(e.Message);
99+
}
100+
digidoc.digidoc.terminate();
101+
}
102+
103+
static void websign(string[] args)
104+
{
105+
digidoc.digidoc.initialize();
106+
try
107+
{
108+
Console.WriteLine("Creating file: " + args[args.Length - 1]);
109+
Container b = Container.create(args[args.Length - 1]);
110+
for (int i = 1; i < args.Length - 2; ++i)
111+
b.addDataFile(args[i], "application/octet-stream");
112+
113+
X509Certificate cert = new X509Certificate();
114+
cert.Import(args[args.Length - 2]);
115+
Signature c = b.prepareWebSignature(cert.Export(X509ContentType.Cert), "BES/time-stamp");
116+
Console.WriteLine("Signature method: " + c.signatureMethod());
117+
Console.WriteLine("Digest to sign: " + BitConverter.ToString(c.dataToSign()).Replace("-", string.Empty));
118+
Console.WriteLine("Please enter signed digest in hex: ");
119+
120+
byte[] inputBuffer = new byte[1024];
121+
Stream inputStream = Console.OpenStandardInput(inputBuffer.Length);
122+
Console.SetIn(new StreamReader(inputStream, Console.InputEncoding, false, inputBuffer.Length));
123+
String hex = Console.ReadLine();
124+
125+
byte[] signature = Enumerable.Range(0, hex.Length / 2).Select(x => Convert.ToByte(hex.Substring(x * 2, 2), 16)).ToArray();
126+
c.setSignatureValue(signature);
127+
c.extendSignatureProfile("BES/time-stamp");
128+
b.save();
86129
}
87130
catch (Exception e)
88131
{
@@ -97,7 +140,7 @@ static void verify(string file)
97140
try
98141
{
99142
Console.WriteLine("Opening file: " + file);
100-
Container b = new Container(file);
143+
Container b = Container.open(file);
101144

102145
Console.WriteLine("Files:");
103146
foreach (DataFile d in b.dataFiles())
@@ -114,13 +157,8 @@ static void verify(string file)
114157
Console.Write(" " + role);
115158
Console.WriteLine();
116159

117-
Console.WriteLine("Time: " + s.signingTime());
118-
X509Certificate2 c = new X509Certificate2(s.signingCert());
119-
Console.WriteLine("Cert: " + c.Subject);
120-
121-
Console.WriteLine("ProducedAt: " + s.producedAt());
122-
c = new X509Certificate2(s.OCSPCert());
123-
Console.WriteLine("OCSP Cert: " + c.Subject);
160+
Console.WriteLine("Time: " + s.trustedSigningTime());
161+
Console.WriteLine("Cert: " + new X509Certificate2(s.signingCertificateDer()).Subject);
124162

125163
s.validate();
126164
Console.WriteLine("Signature is valid");
@@ -136,7 +174,7 @@ static void verify(string file)
136174

137175
static void version()
138176
{
139-
Console.WriteLine("DigiDocCSharp 0.1 libdigidocpp " + digidoc.digidoc.version());
177+
Console.WriteLine("DigiDocCSharp 0.2 libdigidocpp " + digidoc.digidoc.version());
140178
}
141179
}
142180
}

src/digidoc.i

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,33 @@
3636
#include "Container.h"
3737
#include "DataFile.h"
3838
#include "Exception.h"
39+
#include "log.h"
3940
#include "Signature.h"
4041
#include "XmlConf.h"
4142
#include "crypto/PKCS11Signer.h"
4243
#include "crypto/PKCS12Signer.h"
4344
#include "crypto/X509Cert.h"
44-
#ifdef SWIGWIN
45+
#ifdef _WIN32
4546
#include "crypto/WinSigner.h"
4647
#endif
4748

4849
#include <vector>
4950

51+
class WebSignerPrivate: public digidoc::Signer
52+
{
53+
public:
54+
WebSignerPrivate(const digidoc::X509Cert &cert): _cert(cert) {}
55+
56+
private:
57+
digidoc::X509Cert cert() const override { return _cert; }
58+
std::vector<unsigned char> sign(const std::string &, const std::vector<unsigned char> &) const override
59+
{
60+
THROW("Not implemented");
61+
}
62+
63+
digidoc::X509Cert _cert;
64+
};
65+
5066
static std::string parseException(const digidoc::Exception &e) {
5167
std::string msg = e.msg();
5268
for(const digidoc::Exception &ex: e.causes())
@@ -203,9 +219,9 @@ SWIGEXPORT void JNICALL Java_ee_ria_libdigidocpp_digidocJNI_initJava(JNIEnv *jen
203219
%include "crypto/Signer.h"
204220
%include "crypto/PKCS12Signer.h"
205221
%include "crypto/PKCS11Signer.h"
206-
#ifdef SWIGWIN
222+
//#ifdef SWIGWIN
207223
%include "crypto/WinSigner.h"
208-
#endif
224+
//#endif
209225

210226
%template(StringVector) std::vector<std::string>;
211227
%template(DataFiles) std::vector<digidoc::DataFile*>;
@@ -223,20 +239,34 @@ SWIGEXPORT void JNICALL Java_ee_ria_libdigidocpp_digidocJNI_initJava(JNIEnv *jen
223239
{
224240
return $self->signingCertificate();
225241
}
226-
std::vector<unsigned char> OCSPCertificate() const
242+
std::vector<unsigned char> OCSPCertificateDer() const
227243
{
228244
return $self->OCSPCertificate();
229245
}
230-
std::vector<unsigned char> TimeStampCertificate() const
246+
std::vector<unsigned char> TimeStampCertificateDer() const
231247
{
232248
return $self->TimeStampCertificate();
233249
}
234-
std::vector<unsigned char> ArchiveTimeStampCertificate() const
250+
std::vector<unsigned char> ArchiveTimeStampCertificateDer() const
235251
{
236252
return $self->ArchiveTimeStampCertificate();
237253
}
238254
}
239255

256+
%extend digidoc::Container {
257+
Signature* prepareWebSignature(const std::vector<unsigned char> &cert, const std::string &profile = "",
258+
const std::vector<std::string> &roles = std::vector<std::string>(),
259+
const std::string &city = "", const std::string &state = "",
260+
const std::string &postalCode = "", const std::string &country = "")
261+
{
262+
WebSignerPrivate signer(X509Cert(cert, X509Cert::Der));
263+
signer.setProfile(profile);
264+
signer.setSignatureProductionPlace(city, state, postalCode, country);
265+
signer.setSignerRoles(roles);
266+
return $self->prepareSignature(&signer);
267+
}
268+
}
269+
240270
// Target language specific functions
241271
#ifdef SWIGPHP
242272
%minit %{ %}

0 commit comments

Comments
 (0)