From 2455bce79328560f7a41b885db0e5c4cc346af96 Mon Sep 17 00:00:00 2001 From: cxl Date: Fri, 21 Oct 2016 10:47:46 +0000 Subject: [PATCH] Core, Core/SSL: GetP7Signature git-svn-id: svn://ultimatepp.org/upp/trunk@10340 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Core/SSL/P7S.icpp | 44 ++++++++++++++++++++++++++++++ uppsrc/Core/SSL/SSL.upp | 3 +- uppsrc/Core/SSL/init | 3 ++ uppsrc/Core/Util.cpp | 14 ++++++++++ uppsrc/Core/Util.h | 3 ++ uppsrc/Core/src.tpp/Util$en-us.tpp | 18 +++++++++++- 6 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 uppsrc/Core/SSL/P7S.icpp diff --git a/uppsrc/Core/SSL/P7S.icpp b/uppsrc/Core/SSL/P7S.icpp new file mode 100644 index 000000000..fca7c989b --- /dev/null +++ b/uppsrc/Core/SSL/P7S.icpp @@ -0,0 +1,44 @@ +#include "SSL.h" + +namespace Upp { + +String GetP7Signature_imp(const void *data, int length, const String& cert_pem, const String& pkey_pem) +{ + SslCertificate x509; + SslKey pkey; + if(!x509.Load(cert_pem)) + return Null; + if(!pkey.Load(pkey_pem)) + return Null; + + SslStream in; + in.OpenBuffer((const char *)data, length); + + PKCS7 *p7 = PKCS7_sign(x509, pkey, NULL, in, PKCS7_DETACHED|PKCS7_STREAM|PKCS7_BINARY); + + if (!p7) + return Null; + + SslStream out; + out.CreateBuffer(); + + String r; + if (SMIME_write_PKCS7(out, p7, in, PKCS7_DETACHED|PKCS7_STREAM|PKCS7_BINARY)) { + SslStream out1; + out1.CreateBuffer(); + i2d_PKCS7_bio(out1, p7); + r = out1.GetResult(); + } + + PKCS7_free(p7); + + return r; +} + +extern String (*GetP7Signature__)(const void *data, int length, const String& cert_pem, const String& pkey_pem); + +INITBLOCK { + GetP7Signature__ = GetP7Signature_imp; +} + +} diff --git a/uppsrc/Core/SSL/SSL.upp b/uppsrc/Core/SSL/SSL.upp index a837bee10..954bf0a1d 100644 --- a/uppsrc/Core/SSL/SSL.upp +++ b/uppsrc/Core/SSL/SSL.upp @@ -20,5 +20,6 @@ file SSL.h, Util.cpp, InitExit.icpp, - Socket.icpp; + Socket.icpp, + P7S.icpp; diff --git a/uppsrc/Core/SSL/init b/uppsrc/Core/SSL/init index 001ca4731..1d87a814e 100644 --- a/uppsrc/Core/SSL/init +++ b/uppsrc/Core/SSL/init @@ -6,4 +6,7 @@ #define BLITZ_INDEX__ F20fd197ce515f45c6284ecc270cf38ca #include "Socket.icpp" #undef BLITZ_INDEX__ +#define BLITZ_INDEX__ F2102a4fa3eba4dcfabd989be82ccd052 +#include "P7S.icpp" +#undef BLITZ_INDEX__ #endif diff --git a/uppsrc/Core/Util.cpp b/uppsrc/Core/Util.cpp index 423065013..1e07ffef5 100644 --- a/uppsrc/Core/Util.cpp +++ b/uppsrc/Core/Util.cpp @@ -874,4 +874,18 @@ WString Replace(const WString& s, const VectorMap& fr) return Replace__(s, fr.GetKeys(), fr.GetValues()); } + +String (*GetP7Signature__)(const void *data, int length, const String& cert_pem, const String& pkey_pem); + +String GetP7Signature(const void *data, int length, const String& cert_pem, const String& pkey_pem) +{ + ASSERT_(GetP7Signature__, "Missing SSL support (Core/SSL)"); + return (*GetP7Signature__)(data, length, cert_pem, pkey_pem); +} + +String GetP7Signature(const String& data, const String& cert_pem, const String& pkey_pem) +{ + return GetP7Signature(data, data.GetLength(), cert_pem, pkey_pem); +} + } diff --git a/uppsrc/Core/Util.h b/uppsrc/Core/Util.h index 970eae766..fd8a89a9f 100644 --- a/uppsrc/Core/Util.h +++ b/uppsrc/Core/Util.h @@ -487,3 +487,6 @@ String Replace(const String& s, const Vector& find, const Vector& fr); WString Replace(const WString& s, const Vector& find, const Vector& replace); WString Replace(const WString& s, const VectorMap& fr); + +String GetP7Signature(const void *data, int length, const String& cert_pem, const String& pkey_pem); +String GetP7Signature(const String& data, const String& cert_pem, const String& pkey_pem); diff --git a/uppsrc/Core/src.tpp/Util$en-us.tpp b/uppsrc/Core/src.tpp/Util$en-us.tpp index 3394f3cc5..470b9e318 100644 --- a/uppsrc/Core/src.tpp/Util$en-us.tpp +++ b/uppsrc/Core/src.tpp/Util$en-us.tpp @@ -49,4 +49,20 @@ pattern is always used (if patterns:replases are `"hell`":`"hello`" and `"hello`":`"hell`", then replacing within `"hell hello`" produces `"hello hell`").&] [s3;%% &] -[s0;%% ]] \ No newline at end of file +[s4; &] +[s5;:Upp`:`:GetP7Signature`(const void`*`,int`,const Upp`:`:String`&`,const Upp`:`:String`&`): [_^Upp`:`:String^ S +tring]_[* GetP7Signature]([@(0.0.255) const]_[@(0.0.255) void]_`*[*@3 data], +[@(0.0.255) int]_[*@3 length], [@(0.0.255) const]_[_^Upp`:`:String^ String][@(0.0.255) `&]_ +[*@3 cert`_pem], [@(0.0.255) const]_[_^Upp`:`:String^ String][@(0.0.255) `&]_[*@3 pkey`_pem +])&] +[s5;:Upp`:`:GetP7Signature`(const Upp`:`:String`&`,const Upp`:`:String`&`,const Upp`:`:String`&`): [_^Upp`:`:String^ S +tring]_[* GetP7Signature]([@(0.0.255) const]_[_^Upp`:`:String^ String][@(0.0.255) `&]_[*@3 d +ata], [@(0.0.255) const]_[_^Upp`:`:String^ String][@(0.0.255) `&]_[*@3 cert`_pem], +[@(0.0.255) const]_[_^Upp`:`:String^ String][@(0.0.255) `&]_[*@3 pkey`_pem])&] +[s2;%% Computes P7S signature in binary format of [%-*@3 data] bytes. +[%-*@3 cert`_pem] (X509 public key) and [%-*@3 pkey`_pem] (X509 private +key) should be in [^https`:`/`/en`.wikipedia`.org`/wiki`/Privacy`-enhanced`_Electronic`_Mail`.^ P +EM] format. Requires Core/SSL. Returns signature in binary format +(e.g. needs to be base64 encoded for SMIME emails). Returns Null +in case of error.&] +[s3;%% ]] \ No newline at end of file