Agregar archivos de proyecto.
This commit is contained in:
24
TSpdf.tests/TSpdf.sign.tests/Properties/AssemblyInfo.cs
Normal file
24
TSpdf.tests/TSpdf.sign.tests/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("TSpdf.Sign.Tests")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("TSpdf")]
|
||||
[assembly: AssemblyProduct("TSpdf")]
|
||||
[assembly: AssemblyCopyright("Copyright (c) 1987-2023 TSpdf")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
[assembly: Guid("be15bdf3-b184-4e2f-8459-ebee3160e19d")]
|
||||
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyInformationalVersion("1.0.0.0")]
|
||||
|
||||
#if !NETSTANDARD2_0
|
||||
[assembly: NUnit.Framework.Timeout(300000)]
|
||||
#endif
|
||||
60
TSpdf.tests/TSpdf.sign.tests/TSpdf.sign.tests.csproj
Normal file
60
TSpdf.tests/TSpdf.sign.tests/TSpdf.sign.tests.csproj
Normal file
@@ -0,0 +1,60 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
|
||||
<PropertyGroup Label="Globals">
|
||||
<SccProjectName>SAK</SccProjectName>
|
||||
<SccProvider>SAK</SccProvider>
|
||||
<SccAuxPath>SAK</SccAuxPath>
|
||||
<SccLocalPath>SAK</SccLocalPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<SignAssembly>True</SignAssembly>
|
||||
<DelaySign>False</DelaySign>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp3.1;net461;net48</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(TargetFramework)' == 'net461' ">
|
||||
<OutputType>library</OutputType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">
|
||||
<OutputType>Library</OutputType>
|
||||
<DefineConstants>NETSTANDARD2_0</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AssemblyOriginatorKeyFile>TSpdf.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<ApplicationIcon />
|
||||
<OutputTypeEx>library</OutputTypeEx>
|
||||
<StartupObject />
|
||||
<RootNamespace />
|
||||
<AssemblyName>TSpdf.sign.tests</AssemblyName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<NoWarn>1701;1702;1591;1570;1572;1573;1574;1580;1584;1658</NoWarn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net461' ">
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="TeamCity.VSTest.TestAdapter" Version="1.0.0" />
|
||||
<PackageReference Include="NUnit" Version="3.7.1" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\TSpdf\TSpdf.forms\TSpdf.forms.csproj" />
|
||||
<ProjectReference Include="..\..\TSpdf\TSpdf.io\TSpdf.io.csproj" />
|
||||
<ProjectReference Include="..\..\TSpdf\TSpdf.kernel\TSpdf.kernel.csproj" />
|
||||
<ProjectReference Include="..\..\TSpdf\TSpdf.sign\TSpdf.sign.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk">
|
||||
<Version>15.0.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Runtime.InteropServices.RuntimeInformation">
|
||||
<Version>4.3.0</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
BIN
TSpdf.tests/TSpdf.sign.tests/TSpdf.snk
Normal file
BIN
TSpdf.tests/TSpdf.sign.tests/TSpdf.snk
Normal file
Binary file not shown.
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Kernel.Exceptions;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
[NUnit.Framework.Category("BouncyCastleUnitTest")]
|
||||
public class CertificateInfoTest : ExtendedTSpdfTest {
|
||||
private static readonly IBouncyCastleFactory FACTORY = BouncyCastleFactoryCreator.GetFactory();
|
||||
|
||||
private static readonly String EXPECTED_EXCEPTION_MESSAGE = FACTORY.GetBouncyCastleFactoryTestUtil().GetCertificateInfoTestConst
|
||||
();
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void X500InvalidDirectoryConstructorTest() {
|
||||
NUnit.Framework.Assert.Catch(typeof(ArgumentException), () => new CertificateInfo.X500Name("some_dir"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void X500ValidDirectoryConstructorTest() {
|
||||
CertificateInfo.X500Name name = new CertificateInfo.X500Name("some=dir,another=dir,some=value");
|
||||
IDictionary<String, IList<String>> values = name.GetFields();
|
||||
NUnit.Framework.Assert.AreEqual(2, values.Count);
|
||||
NUnit.Framework.Assert.AreEqual(JavaUtil.ArraysAsList("dir", "value"), values.Get("SOME"));
|
||||
NUnit.Framework.Assert.AreEqual(JavaCollectionsUtil.SingletonList("dir"), values.Get("ANOTHER"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void X500GetFieldTest() {
|
||||
CertificateInfo.X500Name name = new CertificateInfo.X500Name("some=value,another=dir,some=dir");
|
||||
NUnit.Framework.Assert.AreEqual("value", name.GetField("SOME"));
|
||||
NUnit.Framework.Assert.AreEqual("dir", name.GetField("ANOTHER"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void X500GetFieldArrayTest() {
|
||||
CertificateInfo.X500Name name = new CertificateInfo.X500Name("some=value,another=dir,some=dir");
|
||||
NUnit.Framework.Assert.AreEqual(JavaUtil.ArraysAsList("value", "dir"), name.GetFieldArray("SOME"));
|
||||
NUnit.Framework.Assert.AreEqual(JavaCollectionsUtil.SingletonList("dir"), name.GetFieldArray("ANOTHER"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void X509NameTokenizerNextTokenComplicatedTest() {
|
||||
CertificateInfo.X509NameTokenizer tokenizer = new CertificateInfo.X509NameTokenizer("quoted\",\"comma=escaped\\,comma_escaped\\\"quote"
|
||||
);
|
||||
String token = tokenizer.NextToken();
|
||||
NUnit.Framework.Assert.AreEqual("quoted,comma=escaped,comma_escaped\"quote", token);
|
||||
NUnit.Framework.Assert.IsNull(tokenizer.NextToken());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetIssuerFieldsExceptionTest() {
|
||||
Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfException), () => CertificateInfo.GetIssuer(new
|
||||
byte[] { 4, 8, 15, 16, 23, 42 }));
|
||||
NUnit.Framework.Assert.AreEqual(EXPECTED_EXCEPTION_MESSAGE, exception.InnerException.Message);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetSubjectExceptionTest() {
|
||||
Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfException), () => CertificateInfo.GetSubject(
|
||||
new byte[] { 4, 8, 15, 16, 23, 42 }));
|
||||
NUnit.Framework.Assert.AreEqual(EXPECTED_EXCEPTION_MESSAGE, exception.InnerException.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using TSpdf.Test;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace TSpdf.Signatures
|
||||
{
|
||||
class CertificateSupportedCriticalExtensionsTest : ExtendedTSpdfTest
|
||||
{
|
||||
[Test]
|
||||
public void SupportedCriticalOIDsTest()
|
||||
{
|
||||
X509MockCertificate cert = new X509MockCertificate();
|
||||
|
||||
ISet<string> criticalExtensions = new HashSet<string>();
|
||||
|
||||
criticalExtensions.Add(OID.X509Extensions.KEY_USAGE);
|
||||
criticalExtensions.Add(OID.X509Extensions.BASIC_CONSTRAINTS);
|
||||
|
||||
cert.SetCriticalExtensions(criticalExtensions);
|
||||
|
||||
cert.KeyUsage = new bool[] { true, true };
|
||||
|
||||
Assert.False(SignUtils.HasUnsupportedCriticalExtension(cert));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BasicConstraintsSupportedTest()
|
||||
{
|
||||
X509MockCertificate cert = new X509MockCertificate();
|
||||
|
||||
ISet<string> criticalExtensions = new HashSet<string>();
|
||||
|
||||
criticalExtensions.Add(OID.X509Extensions.BASIC_CONSTRAINTS);
|
||||
|
||||
cert.SetCriticalExtensions(criticalExtensions);
|
||||
|
||||
Assert.False(SignUtils.HasUnsupportedCriticalExtension(cert));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtendedKeyUsageWithIdKpTimestampingTest()
|
||||
{
|
||||
X509MockCertificate cert = new X509MockCertificate();
|
||||
|
||||
ISet<string> criticalExtensions = new HashSet<string>();
|
||||
|
||||
criticalExtensions.Add(OID.X509Extensions.EXTENDED_KEY_USAGE);
|
||||
|
||||
cert.SetCriticalExtensions(criticalExtensions);
|
||||
|
||||
IList extendedKeyUsage = new List<string>();
|
||||
extendedKeyUsage.Add(OID.X509Extensions.ID_KP_TIMESTAMPING);
|
||||
|
||||
cert.SetExtendedKeyUsage(extendedKeyUsage);
|
||||
|
||||
Assert.False(SignUtils.HasUnsupportedCriticalExtension(cert));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtendedKeyUsageWithoutIdKpTimestampingTest()
|
||||
{
|
||||
X509MockCertificate cert = new X509MockCertificate();
|
||||
|
||||
ISet<string> criticalExtensions = new HashSet<string>();
|
||||
|
||||
criticalExtensions.Add(OID.X509Extensions.EXTENDED_KEY_USAGE);
|
||||
|
||||
cert.SetCriticalExtensions(criticalExtensions);
|
||||
|
||||
IList extendedKeyUsage = new List<string>();
|
||||
extendedKeyUsage.Add("Not ID KP TIMESTAMPING");
|
||||
|
||||
cert.SetExtendedKeyUsage(extendedKeyUsage);
|
||||
|
||||
Assert.False(SignUtils.HasUnsupportedCriticalExtension(cert));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IdKpTimestampingWithoutExtendedKeyUsageTest()
|
||||
{
|
||||
X509MockCertificate cert = new X509MockCertificate();
|
||||
|
||||
IList extendedKeyUsage = new List<string>();
|
||||
extendedKeyUsage.Add(OID.X509Extensions.ID_KP_TIMESTAMPING);
|
||||
|
||||
cert.SetExtendedKeyUsage(extendedKeyUsage);
|
||||
|
||||
Assert.False(SignUtils.HasUnsupportedCriticalExtension(cert));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NotSupportedOIDTest()
|
||||
{
|
||||
X509MockCertificate cert = new X509MockCertificate();
|
||||
|
||||
ISet<string> criticalExtensions = new HashSet<string>();
|
||||
|
||||
criticalExtensions.Add("Totally not supported OID");
|
||||
|
||||
cert.SetCriticalExtensions(criticalExtensions);
|
||||
|
||||
Assert.True(SignUtils.HasUnsupportedCriticalExtension(cert));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CertificateIsNullTest()
|
||||
{
|
||||
Assert.Catch(typeof(ArgumentException), () => SignUtils.HasUnsupportedCriticalExtension(null));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CertificateHasNoExtensionsTest()
|
||||
{
|
||||
X509MockCertificate cert = new X509MockCertificate();
|
||||
|
||||
cert.SetCriticalExtensions(null);
|
||||
|
||||
Assert.False(SignUtils.HasUnsupportedCriticalExtension(cert));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
[NUnit.Framework.Category("BouncyCastleUnitTest")]
|
||||
public class CertificateUtilTest : ExtendedTSpdfTest {
|
||||
private static readonly String CERTS_SRC = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/";
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetTSAURLAdobeExtensionTest() {
|
||||
IX509Certificate tsaCert = (IX509Certificate)PemFileHelper.ReadFirstChain(CERTS_SRC + "adobeExtensionCert.pem"
|
||||
)[0];
|
||||
String url = CertificateUtil.GetTSAURL(tsaCert);
|
||||
NUnit.Framework.Assert.AreEqual("https://TSpdfpdf.com/en", url);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetTSAURLUsualTimestampCertificateTest() {
|
||||
IX509Certificate tsaCert = (IX509Certificate)PemFileHelper.ReadFirstChain(CERTS_SRC + "tsCertRsa.pem")[0];
|
||||
String url = CertificateUtil.GetTSAURL(tsaCert);
|
||||
NUnit.Framework.Assert.IsNull(url);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetTSAURLAdobeExtensionNotTaggedTest() {
|
||||
IX509Certificate tsaCert = (IX509Certificate)PemFileHelper.ReadFirstChain(CERTS_SRC + "adobeExtensionCertWithoutTag.pem"
|
||||
)[0];
|
||||
NUnit.Framework.Assert.Catch(typeof(NullReferenceException), () => CertificateUtil.GetTSAURL(tsaCert));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetCRLFromStringNullTest() {
|
||||
NUnit.Framework.Assert.IsNull(CertificateUtil.GetCRL((String)null));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetCRLFromCertificateWithoutCRLTest() {
|
||||
IX509Certificate tsaCert = (IX509Certificate)PemFileHelper.ReadFirstChain(CERTS_SRC + "rootRsa.pem")[0];
|
||||
IX509Crl crl = CertificateUtil.GetCRL(tsaCert);
|
||||
NUnit.Framework.Assert.IsNull(crl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Kernel.Exceptions;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
[NUnit.Framework.Category("UnitTest")]
|
||||
public class CrlClientOfflineTest : ExtendedTSpdfTest {
|
||||
private static readonly String SOURCE_FOLDER = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/CrlClientOfflineTest/";
|
||||
|
||||
private const String CRL_DISTRIBUTION_POINT = "http://www.example.com/";
|
||||
|
||||
private static ICollection<byte[]> listOfByteArrays;
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void CheckUnknownPdfExceptionWhenCrlIsNull() {
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(PdfException), () => listOfByteArrays = new CrlClientOffline
|
||||
(BouncyCastleFactoryCreator.GetFactory().CreateNullCrl()).GetEncoded(null, ""));
|
||||
NUnit.Framework.Assert.AreEqual(KernelExceptionMessageConstant.UNKNOWN_PDF_EXCEPTION, e.Message);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetEncodedFromCrlEmptyByteArrayRealArgsTest() {
|
||||
ValidateCrlBytes(null, CRL_DISTRIBUTION_POINT);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetEncodedFromCrlEmptyByteArrayWithoutArgsTest() {
|
||||
ValidateCrlBytes(null, "");
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetEncodedFromCrlEmptyByteArrayUrlIsEmptyTest() {
|
||||
ValidateCrlBytes(null, "");
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetEncodedFromCrlEmptyByteArrayNonExistingUrlTest() {
|
||||
ValidateCrlBytes(null, "http://nonexistingurl.com");
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetEncodedFromCrlEmptyByteArrayCertIsNullNonExistingUrlTest() {
|
||||
ValidateCrlBytes(null, "http://nonexistingurl.com");
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetEncodedFromCrlEmptyByteArrayCertIsNullUrlIsRealTest() {
|
||||
ValidateCrlBytes(null, CRL_DISTRIBUTION_POINT);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetEncodedFromCrlObjectRealArgsTest() {
|
||||
String fileName = SOURCE_FOLDER + "pdfWithCrl.pdf";
|
||||
byte[] testBytes = ObtainCrlFromPdf(fileName);
|
||||
ValidateCrlBytes(testBytes, CRL_DISTRIBUTION_POINT);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetEncodedFromCrlObjectWithoutCertAndUrlTest() {
|
||||
String fileName = SOURCE_FOLDER + "pdfWithCrl.pdf";
|
||||
byte[] testBytes = ObtainCrlFromPdf(fileName);
|
||||
ValidateCrlBytes(testBytes, "");
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetEncodedFromCrlObjectUrlIsEmptyTest() {
|
||||
String fileName = SOURCE_FOLDER + "pdfWithCrl.pdf";
|
||||
byte[] testBytes = ObtainCrlFromPdf(fileName);
|
||||
ValidateCrlBytes(testBytes, "");
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetEncodedFromCrlObjectNonExistingUrlTest() {
|
||||
String fileName = SOURCE_FOLDER + "pdfWithCrl.pdf";
|
||||
byte[] testBytes = ObtainCrlFromPdf(fileName);
|
||||
ValidateCrlBytes(testBytes, "http://nonexistingurl.com");
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetEncodedFromCrlObjectCertIsNullNonExistingUrlTest() {
|
||||
String fileName = SOURCE_FOLDER + "pdfWithCrl.pdf";
|
||||
byte[] testBytes = ObtainCrlFromPdf(fileName);
|
||||
ValidateCrlBytes(testBytes, "http://nonexistingurl.com");
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetEncodedFromCrlObjectCertIsNullUrlIsRealTest() {
|
||||
String fileName = SOURCE_FOLDER + "pdfWithCrl.pdf";
|
||||
byte[] testBytes = ObtainCrlFromPdf(fileName);
|
||||
ValidateCrlBytes(testBytes, CRL_DISTRIBUTION_POINT);
|
||||
}
|
||||
|
||||
//Get CRL from PDF. We expect the PDF to contain an array of CRLs from which we only take the first
|
||||
private static byte[] ObtainCrlFromPdf(String fileName) {
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(fileName));
|
||||
PdfDictionary pdfDictionary = pdfDocument.GetCatalog().GetPdfObject().GetAsDictionary(PdfName.DSS);
|
||||
PdfArray crlArray = pdfDictionary.GetAsArray(PdfName.CRLs);
|
||||
PdfStream stream = crlArray.GetAsStream(0);
|
||||
return stream.GetBytes();
|
||||
}
|
||||
|
||||
private static void ValidateCrlBytes(byte[] testBytes, String crlDistPoint) {
|
||||
CrlClientOffline crlClientOffline = new CrlClientOffline(testBytes);
|
||||
IX509Certificate checkCert = (IX509Certificate)PemFileHelper.ReadFirstChain(SOURCE_FOLDER + "crlDistPoint.pem"
|
||||
)[0];
|
||||
listOfByteArrays = crlClientOffline.GetEncoded(checkCert, crlDistPoint);
|
||||
//These checks are enough, because there is exactly one element in the collection,
|
||||
//and these are the same test bytes
|
||||
NUnit.Framework.Assert.AreEqual(1, listOfByteArrays.Count);
|
||||
NUnit.Framework.Assert.IsTrue(listOfByteArrays.Contains(testBytes));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures
|
||||
{
|
||||
public class DigestAlgorithmsManualTest : ExtendedTSpdfTest
|
||||
{
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void DigestSHA1SunPKCS11Test()
|
||||
{
|
||||
Stream data = new MemoryStream(new byte[] {13, 16, 20, 0, 10});
|
||||
byte[] hash = DigestAlgorithms.Digest(data, DigestAlgorithms.SHA1);
|
||||
byte[] expected = {15, 20, 1, 9, 150, 49, 219, 191, 211, 193, 53, 186, 76, 185, 102, 188, 78, 205, 156, 50};
|
||||
NUnit.Framework.Assert.AreEqual(expected, hash);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void DigestSHA256SUNTest()
|
||||
{
|
||||
Stream data = new MemoryStream(new byte[] {13, 16, 20, 0, 10});
|
||||
byte[] hash = DigestAlgorithms.Digest(data, DigestAlgorithms.SHA256);
|
||||
foreach (byte b in hash)
|
||||
{
|
||||
Console.Out.Write(b + ", ");
|
||||
}
|
||||
|
||||
byte[] expected =
|
||||
{
|
||||
19, 172, 172, 211, 220, 121, 241, 238, 167, 97, 239, 51, 81, 119, 214, 197, 225, 121, 169, 174, 211,
|
||||
119, 61, 92, 110, 157, 105, 4, 97, 12, 127, 194
|
||||
};
|
||||
NUnit.Framework.Assert.AreEqual(expected, hash);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
[NUnit.Framework.Category("UnitTest")]
|
||||
public class DigestAlgorithmsTest : ExtendedTSpdfTest {
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void EmptyStringOidGetDigestTest() {
|
||||
String oid = "";
|
||||
NUnit.Framework.Assert.AreEqual(oid, DigestAlgorithms.GetDigest(oid));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void NonExistingOidGetDigestTest() {
|
||||
String oid = "non_existing_oid";
|
||||
NUnit.Framework.Assert.AreEqual(oid, DigestAlgorithms.GetDigest(oid));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void EmptyStringNameGetAllowedDigestTest() {
|
||||
NUnit.Framework.Assert.IsNull(DigestAlgorithms.GetAllowedDigest(""));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void NonExistingNameGetAllowedDigestTest() {
|
||||
NUnit.Framework.Assert.IsNull(DigestAlgorithms.GetAllowedDigest("non_existing_oid"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void NullNameGetAllowedDigestTest() {
|
||||
NUnit.Framework.Assert.Catch(typeof(ArgumentException), () => DigestAlgorithms.GetAllowedDigest(null));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System.IO;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
[NUnit.Framework.Category("UnitTest")]
|
||||
public class ExternalBlankSignatureContainerUnitTest : ExtendedTSpdfTest {
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void CreateBlankSignTest() {
|
||||
IExternalSignatureContainer container = new ExternalBlankSignatureContainer(new PdfDictionary());
|
||||
byte[] blankSign = container.Sign(new MemoryStream(new byte[] { 1, 0, 32, 5 }));
|
||||
NUnit.Framework.Assert.AreEqual(0, blankSign.Length);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ModifySigningDictionarySignTest() {
|
||||
PdfDictionary initDict = new PdfDictionary();
|
||||
initDict.Put(new PdfName("test_key"), new PdfName("test_value"));
|
||||
IExternalSignatureContainer container = new ExternalBlankSignatureContainer(initDict);
|
||||
PdfDictionary addDict = new PdfDictionary();
|
||||
addDict.Put(new PdfName("add_key"), new PdfName("add_value"));
|
||||
container.ModifySigningDictionary(addDict);
|
||||
byte[] blankSign = container.Sign(new MemoryStream(new byte[] { 1, 0, 32, 5 }));
|
||||
NUnit.Framework.Assert.AreEqual(0, blankSign.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,471 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Signatures.Exceptions;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Signatures.Testutils.Client;
|
||||
using TSpdf.Test;
|
||||
using TSpdf.Test.Attributes;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
[NUnit.Framework.Category("BouncyCastleUnitTest")]
|
||||
public class LtvVerificationTest : ExtendedTSpdfTest {
|
||||
private static readonly String SOURCE_FOLDER = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/LtvVerificationTest/";
|
||||
|
||||
private static readonly String SRC_PDF = SOURCE_FOLDER + "pdfWithDssDictionary.pdf";
|
||||
|
||||
private const String SIG_FIELD_NAME = "Signature1";
|
||||
|
||||
private const String CRL_DISTRIBUTION_POINT = "http://example.com";
|
||||
|
||||
private static readonly String CERT_FOLDER_PATH = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/";
|
||||
|
||||
private static readonly char[] PASSWORD = "testpassphrase".ToCharArray();
|
||||
|
||||
private static LtvVerification TEST_VERIFICATION;
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC_PDF));
|
||||
TEST_VERIFICATION = new LtvVerification(pdfDoc);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Adding verification for TestSignature", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Certificate: C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestRsaCert01", LogLevel = LogLevelConstants
|
||||
.INFO)]
|
||||
[LogMessage("CRL added", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Certificate: C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestRoot", LogLevel = LogLevelConstants.INFO
|
||||
)]
|
||||
public virtual void AddVerificationToDocumentWithAlreadyExistedDss() {
|
||||
String input = SOURCE_FOLDER + "signingCertHasChainWithOcspOnlyForChildCert.pdf";
|
||||
String signatureHash = "C5CC1458AAA9B8BAB0677F9EA409983B577178A3";
|
||||
using (PdfDocument pdfDocument = new PdfDocument(new PdfReader(input))) {
|
||||
PdfDictionary dss = pdfDocument.GetCatalog().GetPdfObject().GetAsDictionary(PdfName.DSS);
|
||||
NUnit.Framework.Assert.IsNull(dss.Get(PdfName.CRLs));
|
||||
PdfArray ocsps = dss.GetAsArray(PdfName.OCSPs);
|
||||
NUnit.Framework.Assert.AreEqual(1, ocsps.Size());
|
||||
PdfIndirectReference pir = ocsps.Get(0).GetIndirectReference();
|
||||
PdfDictionary vri = dss.GetAsDictionary(PdfName.VRI);
|
||||
NUnit.Framework.Assert.AreEqual(1, vri.EntrySet().Count);
|
||||
PdfDictionary vriElem = vri.GetAsDictionary(new PdfName(signatureHash));
|
||||
NUnit.Framework.Assert.AreEqual(1, vriElem.EntrySet().Count);
|
||||
PdfArray vriOcsp = vriElem.GetAsArray(PdfName.OCSP);
|
||||
NUnit.Framework.Assert.AreEqual(1, vriOcsp.Size());
|
||||
NUnit.Framework.Assert.AreEqual(pir, vriOcsp.Get(0).GetIndirectReference());
|
||||
}
|
||||
MemoryStream baos = new MemoryStream();
|
||||
using (PdfDocument pdfDocument_1 = new PdfDocument(new PdfReader(input), new PdfWriter(baos), new StampingProperties
|
||||
().UseAppendMode())) {
|
||||
LtvVerification verification = new LtvVerification(pdfDocument_1);
|
||||
String rootCertPath = CERT_FOLDER_PATH + "rootRsa.pem";
|
||||
IX509Certificate caCert = (IX509Certificate)PemFileHelper.ReadFirstChain(rootCertPath)[0];
|
||||
IPrivateKey caPrivateKey = PemFileHelper.ReadFirstKey(rootCertPath, PASSWORD);
|
||||
verification.AddVerification("TestSignature", null, new TestCrlClient().AddBuilderForCertIssuer(caCert, caPrivateKey
|
||||
), LtvVerification.CertificateOption.SIGNING_CERTIFICATE, LtvVerification.Level.CRL, LtvVerification.CertificateInclusion
|
||||
.NO);
|
||||
verification.Merge();
|
||||
}
|
||||
using (PdfDocument pdfDocument_2 = new PdfDocument(new PdfReader(new MemoryStream(baos.ToArray())))) {
|
||||
PdfDictionary dss = pdfDocument_2.GetCatalog().GetPdfObject().GetAsDictionary(PdfName.DSS);
|
||||
NUnit.Framework.Assert.IsNull(dss.Get(PdfName.OCSPs));
|
||||
PdfArray crls = dss.GetAsArray(PdfName.CRLs);
|
||||
NUnit.Framework.Assert.AreEqual(1, crls.Size());
|
||||
PdfIndirectReference pir = crls.Get(0).GetIndirectReference();
|
||||
PdfDictionary vri = dss.GetAsDictionary(PdfName.VRI);
|
||||
NUnit.Framework.Assert.AreEqual(1, vri.EntrySet().Count);
|
||||
PdfDictionary vriElem = vri.GetAsDictionary(new PdfName(signatureHash));
|
||||
NUnit.Framework.Assert.AreEqual(1, vriElem.EntrySet().Count);
|
||||
PdfArray vriCrl = vriElem.GetAsArray(PdfName.CRL);
|
||||
NUnit.Framework.Assert.AreEqual(1, vriCrl.Size());
|
||||
NUnit.Framework.Assert.AreEqual(pir, vriCrl.Get(0).GetIndirectReference());
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ValidateSigNameWithEmptyByteArrayCrlOcspCertTest() {
|
||||
IList<byte[]> crls = new List<byte[]>();
|
||||
crls.Add(new byte[0]);
|
||||
IList<byte[]> ocsps = new List<byte[]>();
|
||||
ocsps.Add(new byte[0]);
|
||||
IList<byte[]> certs = new List<byte[]>();
|
||||
certs.Add(new byte[0]);
|
||||
NUnit.Framework.Assert.IsTrue(TEST_VERIFICATION.AddVerification(SIG_FIELD_NAME, ocsps, crls, certs));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TryAddVerificationAfterMerge() {
|
||||
IList<byte[]> crls = new List<byte[]>();
|
||||
crls.Add(new byte[0]);
|
||||
IList<byte[]> ocsps = new List<byte[]>();
|
||||
ocsps.Add(new byte[0]);
|
||||
IList<byte[]> certs = new List<byte[]>();
|
||||
certs.Add(new byte[0]);
|
||||
using (PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC_PDF), new PdfWriter(new MemoryStream()))) {
|
||||
LtvVerification verificationWithWriter = new LtvVerification(pdfDoc);
|
||||
verificationWithWriter.Merge();
|
||||
verificationWithWriter.AddVerification(SIG_FIELD_NAME, ocsps, crls, certs);
|
||||
verificationWithWriter.Merge();
|
||||
Exception exception1 = NUnit.Framework.Assert.Catch(typeof(InvalidOperationException), () => verificationWithWriter
|
||||
.AddVerification(SIG_FIELD_NAME, ocsps, crls, certs));
|
||||
NUnit.Framework.Assert.AreEqual(SignExceptionMessageConstant.VERIFICATION_ALREADY_OUTPUT, exception1.Message
|
||||
);
|
||||
verificationWithWriter.Merge();
|
||||
Exception exception2 = NUnit.Framework.Assert.Catch(typeof(InvalidOperationException), () => verificationWithWriter
|
||||
.AddVerification(null, null, null, LtvVerification.CertificateOption.SIGNING_CERTIFICATE, LtvVerification.Level
|
||||
.CRL, LtvVerification.CertificateInclusion.YES));
|
||||
NUnit.Framework.Assert.AreEqual(SignExceptionMessageConstant.VERIFICATION_ALREADY_OUTPUT, exception2.Message
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ValidateSigNameWithNullCrlOcspCertTest() {
|
||||
NUnit.Framework.Assert.IsTrue(TEST_VERIFICATION.AddVerification(SIG_FIELD_NAME, null, null, null));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ExceptionWhenValidateNonExistentSigNameTest() {
|
||||
//TODO DEVSIX-5696 Sign: NPE is thrown because no such a signature
|
||||
NUnit.Framework.Assert.Catch(typeof(NullReferenceException), () => TEST_VERIFICATION.AddVerification("nonExistentSigName"
|
||||
, null, null, null));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ExceptionWhenValidateParticularNonExistentSigNameTest() {
|
||||
//TODO DEVSIX-5696 Sign: NPE is thrown because no such a signature
|
||||
NUnit.Framework.Assert.Catch(typeof(NullReferenceException), () => TEST_VERIFICATION.AddVerification("nonExistentSigName"
|
||||
, null, null, LtvVerification.CertificateOption.SIGNING_CERTIFICATE, LtvVerification.Level.OCSP_CRL, LtvVerification.CertificateInclusion
|
||||
.YES));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Looking for CRL for certificate C=BY,L=Minsk,O=TSpdf,OU=test," + "CN=TSpdfTestRsaCert01", LogLevel
|
||||
= LogLevelConstants.INFO)]
|
||||
[LogMessage("Skipped CRL url: Passed url can not be null", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameWithoutCrlAndOcspSigningOcspCrlYesTest() {
|
||||
ValidateOptionLevelInclusion(null, LtvVerification.CertificateOption.SIGNING_CERTIFICATE, LtvVerification.Level
|
||||
.OCSP_CRL, LtvVerification.CertificateInclusion.YES, false);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ValidateSigNameWithoutCrlAndOcspSigningOcspYesTest() {
|
||||
ValidateOptionLevelInclusion(null, LtvVerification.CertificateOption.SIGNING_CERTIFICATE, LtvVerification.Level
|
||||
.OCSP, LtvVerification.CertificateInclusion.YES, false);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Looking for CRL for certificate C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestRsaCert01", LogLevel
|
||||
= LogLevelConstants.INFO)]
|
||||
[LogMessage("Skipped CRL url: Passed url can not be null.", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameWithoutCrlAndOcspSigningCrlYesTest() {
|
||||
ValidateOptionLevelInclusion(null, LtvVerification.CertificateOption.SIGNING_CERTIFICATE, LtvVerification.Level
|
||||
.CRL, LtvVerification.CertificateInclusion.YES, false);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Looking for CRL for certificate C=BY,L=Minsk,O=TSpdf,OU=test," + "CN=TSpdfTestRsaCert01", LogLevel
|
||||
= LogLevelConstants.INFO)]
|
||||
[LogMessage("Skipped CRL url: Passed url can not be null.", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameWithoutCrlAndOcspSigningOcspOptCrlYesTest() {
|
||||
ValidateOptionLevelInclusion(null, LtvVerification.CertificateOption.SIGNING_CERTIFICATE, LtvVerification.Level
|
||||
.OCSP_OPTIONAL_CRL, LtvVerification.CertificateInclusion.YES, false);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ValidateSigNameWithoutCrlAndOcspWholeChainOcspYesTest() {
|
||||
ValidateOptionLevelInclusion(null, LtvVerification.CertificateOption.WHOLE_CHAIN, LtvVerification.Level.OCSP
|
||||
, LtvVerification.CertificateInclusion.YES, false);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Looking for CRL for certificate C=BY,L=Minsk,O=TSpdf,OU=test," + "CN=TSpdfTestRsaCert01", LogLevel
|
||||
= LogLevelConstants.INFO)]
|
||||
[LogMessage("Skipped CRL url: Passed url can not be null.", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("Looking for CRL for certificate C=BY,L=Minsk,O=TSpdf,OU=test," + "CN=TSpdfTestRoot", LogLevel
|
||||
= LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameWithoutCrlAndOcspWholeChainCrlYesTest() {
|
||||
ValidateOptionLevelInclusion(null, LtvVerification.CertificateOption.WHOLE_CHAIN, LtvVerification.Level.CRL
|
||||
, LtvVerification.CertificateInclusion.YES, false);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Looking for CRL for certificate C=BY,L=Minsk,O=TSpdf,OU=test," + "CN=TSpdfTestRsaCert01", LogLevel
|
||||
= LogLevelConstants.INFO)]
|
||||
[LogMessage("Skipped CRL url: Passed url can not be null.", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("Looking for CRL for certificate C=BY,L=Minsk,O=TSpdf,OU=test," + "CN=TSpdfTestRoot", LogLevel
|
||||
= LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameWithoutCrlAndOcspWholeChainOptCrlYesTest() {
|
||||
ValidateOptionLevelInclusion(null, LtvVerification.CertificateOption.WHOLE_CHAIN, LtvVerification.Level.OCSP_OPTIONAL_CRL
|
||||
, LtvVerification.CertificateInclusion.YES, false);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Looking for CRL for certificate C=BY,L=Minsk,O=TSpdf,OU=test," + "CN=TSpdfTestRsaCert01", LogLevel
|
||||
= LogLevelConstants.INFO)]
|
||||
[LogMessage("Skipped CRL url: Passed url can not be null.", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("Looking for CRL for certificate C=BY,L=Minsk,O=TSpdf,OU=test," + "CN=TSpdfTestRoot", LogLevel
|
||||
= LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameWithoutCrlAndOcspWholeChainOcspCrlYesTest() {
|
||||
ValidateOptionLevelInclusion(null, LtvVerification.CertificateOption.WHOLE_CHAIN, LtvVerification.Level.OCSP_CRL
|
||||
, LtvVerification.CertificateInclusion.YES, false);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Looking for CRL for certificate C=BY,L=Minsk,O=TSpdf,OU=test," + "CN=TSpdfTestRsaCert01", LogLevel
|
||||
= LogLevelConstants.INFO)]
|
||||
[LogMessage("Skipped CRL url: Passed url can not be null", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameWithoutCrlAndOcspSigningOcspCrlNoTest() {
|
||||
ValidateOptionLevelInclusion(null, LtvVerification.CertificateOption.SIGNING_CERTIFICATE, LtvVerification.Level
|
||||
.OCSP_CRL, LtvVerification.CertificateInclusion.NO, false);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ValidateSigNameWithoutCrlAndOcspSigningOcspNoTest() {
|
||||
ValidateOptionLevelInclusion(null, LtvVerification.CertificateOption.SIGNING_CERTIFICATE, LtvVerification.Level
|
||||
.OCSP, LtvVerification.CertificateInclusion.NO, false);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Looking for CRL for certificate C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestRsaCert01", LogLevel
|
||||
= LogLevelConstants.INFO)]
|
||||
[LogMessage("Skipped CRL url: Passed url can not be null.", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameWithoutCrlAndOcspSigningCrlNoTest() {
|
||||
ValidateOptionLevelInclusion(null, LtvVerification.CertificateOption.SIGNING_CERTIFICATE, LtvVerification.Level
|
||||
.CRL, LtvVerification.CertificateInclusion.NO, false);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Looking for CRL for certificate C=BY,L=Minsk,O=TSpdf,OU=test," + "CN=TSpdfTestRsaCert01", LogLevel
|
||||
= LogLevelConstants.INFO)]
|
||||
[LogMessage("Skipped CRL url: Passed url can not be null.", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameWithoutCrlAndOcspSigningOcspOptCrlNoTest() {
|
||||
ValidateOptionLevelInclusion(null, LtvVerification.CertificateOption.SIGNING_CERTIFICATE, LtvVerification.Level
|
||||
.OCSP_OPTIONAL_CRL, LtvVerification.CertificateInclusion.NO, false);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ValidateSigNameWithoutCrlAndOcspWholeChainOcspNoTest() {
|
||||
ValidateOptionLevelInclusion(null, LtvVerification.CertificateOption.WHOLE_CHAIN, LtvVerification.Level.OCSP
|
||||
, LtvVerification.CertificateInclusion.NO, false);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Looking for CRL for certificate C=BY,L=Minsk,O=TSpdf,OU=test," + "CN=TSpdfTestRsaCert01", LogLevel
|
||||
= LogLevelConstants.INFO)]
|
||||
[LogMessage("Skipped CRL url: Passed url can not be null.", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("Looking for CRL for certificate C=BY,L=Minsk,O=TSpdf,OU=test," + "CN=TSpdfTestRoot", LogLevel
|
||||
= LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameWithoutCrlAndOcspWholeChainCrlNoTest() {
|
||||
ValidateOptionLevelInclusion(null, LtvVerification.CertificateOption.WHOLE_CHAIN, LtvVerification.Level.CRL
|
||||
, LtvVerification.CertificateInclusion.NO, false);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Looking for CRL for certificate C=BY,L=Minsk,O=TSpdf,OU=test," + "CN=TSpdfTestRsaCert01", LogLevel
|
||||
= LogLevelConstants.INFO)]
|
||||
[LogMessage("Skipped CRL url: Passed url can not be null.", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("Looking for CRL for certificate C=BY,L=Minsk,O=TSpdf,OU=test," + "CN=TSpdfTestRoot", LogLevel
|
||||
= LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameWithoutCrlAndOcspWholeChainOptCrlNoTest() {
|
||||
ValidateOptionLevelInclusion(null, LtvVerification.CertificateOption.WHOLE_CHAIN, LtvVerification.Level.OCSP_OPTIONAL_CRL
|
||||
, LtvVerification.CertificateInclusion.NO, false);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Looking for CRL for certificate C=BY,L=Minsk,O=TSpdf,OU=test," + "CN=TSpdfTestRsaCert01", LogLevel
|
||||
= LogLevelConstants.INFO)]
|
||||
[LogMessage("Skipped CRL url: Passed url can not be null.", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("Looking for CRL for certificate C=BY,L=Minsk,O=TSpdf,OU=test," + "CN=TSpdfTestRoot", LogLevel
|
||||
= LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameWithoutCrlAndOcspWholeChainOcspCrlNoTest() {
|
||||
ValidateOptionLevelInclusion(null, LtvVerification.CertificateOption.WHOLE_CHAIN, LtvVerification.Level.OCSP_CRL
|
||||
, LtvVerification.CertificateInclusion.NO, false);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Added CRL url: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Checking CRL: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Added CRL found at: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameSigningOcspCrlYesTest() {
|
||||
ValidateOptionLevelInclusion(CRL_DISTRIBUTION_POINT, LtvVerification.CertificateOption.SIGNING_CERTIFICATE
|
||||
, LtvVerification.Level.OCSP_CRL, LtvVerification.CertificateInclusion.YES, true);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Added CRL url: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameSigningOcspYesTest() {
|
||||
ValidateOptionLevelInclusion(CRL_DISTRIBUTION_POINT, LtvVerification.CertificateOption.SIGNING_CERTIFICATE
|
||||
, LtvVerification.Level.OCSP, LtvVerification.CertificateInclusion.YES, false);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Added CRL url: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Checking CRL: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Added CRL found at: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameSigningCrlYesTest() {
|
||||
ValidateOptionLevelInclusion(CRL_DISTRIBUTION_POINT, LtvVerification.CertificateOption.SIGNING_CERTIFICATE
|
||||
, LtvVerification.Level.CRL, LtvVerification.CertificateInclusion.YES, true);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Added CRL url: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Checking CRL: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Added CRL found at: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameSigningOcspOptionalCrlYesTest() {
|
||||
ValidateOptionLevelInclusion(CRL_DISTRIBUTION_POINT, LtvVerification.CertificateOption.SIGNING_CERTIFICATE
|
||||
, LtvVerification.Level.OCSP_OPTIONAL_CRL, LtvVerification.CertificateInclusion.YES, true);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Added CRL url: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Checking CRL: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Added CRL found at: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameSigningOcspCrlNoTest() {
|
||||
ValidateOptionLevelInclusion(CRL_DISTRIBUTION_POINT, LtvVerification.CertificateOption.SIGNING_CERTIFICATE
|
||||
, LtvVerification.Level.OCSP_CRL, LtvVerification.CertificateInclusion.NO, true);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Added CRL url: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameSigningOcspNoTest() {
|
||||
ValidateOptionLevelInclusion(CRL_DISTRIBUTION_POINT, LtvVerification.CertificateOption.SIGNING_CERTIFICATE
|
||||
, LtvVerification.Level.OCSP, LtvVerification.CertificateInclusion.NO, false);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Added CRL url: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Checking CRL: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Added CRL found at: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameSigningCrlNoTest() {
|
||||
ValidateOptionLevelInclusion(CRL_DISTRIBUTION_POINT, LtvVerification.CertificateOption.SIGNING_CERTIFICATE
|
||||
, LtvVerification.Level.CRL, LtvVerification.CertificateInclusion.NO, true);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Added CRL url: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Checking CRL: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Added CRL found at: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameSigningOcspOptionalCrlNoTest() {
|
||||
ValidateOptionLevelInclusion(CRL_DISTRIBUTION_POINT, LtvVerification.CertificateOption.SIGNING_CERTIFICATE
|
||||
, LtvVerification.Level.OCSP_OPTIONAL_CRL, LtvVerification.CertificateInclusion.NO, true);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Added CRL url: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Checking CRL: http://example.com", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("Added CRL found at: http://example.com", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
public virtual void ValidateSigNameWholeChainOcspCrlYesTest() {
|
||||
ValidateOptionLevelInclusion(CRL_DISTRIBUTION_POINT, LtvVerification.CertificateOption.WHOLE_CHAIN, LtvVerification.Level
|
||||
.OCSP_CRL, LtvVerification.CertificateInclusion.YES, true);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Added CRL url: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Checking CRL: http://example.com", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("Added CRL found at: http://example.com", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
public virtual void ValidateSigNameWholeChainOcspOptionalCrlYesTest() {
|
||||
ValidateOptionLevelInclusion(CRL_DISTRIBUTION_POINT, LtvVerification.CertificateOption.WHOLE_CHAIN, LtvVerification.Level
|
||||
.OCSP_OPTIONAL_CRL, LtvVerification.CertificateInclusion.YES, true);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Added CRL url: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameWholeChainOcspYesTest() {
|
||||
ValidateOptionLevelInclusion(CRL_DISTRIBUTION_POINT, LtvVerification.CertificateOption.WHOLE_CHAIN, LtvVerification.Level
|
||||
.OCSP, LtvVerification.CertificateInclusion.YES, false);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Added CRL url: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Checking CRL: http://example.com", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("Added CRL found at: http://example.com", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
public virtual void ValidateSigNameWholeChainCrlYesTest() {
|
||||
ValidateOptionLevelInclusion(CRL_DISTRIBUTION_POINT, LtvVerification.CertificateOption.WHOLE_CHAIN, LtvVerification.Level
|
||||
.CRL, LtvVerification.CertificateInclusion.YES, true);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Added CRL url: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Checking CRL: http://example.com", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("Added CRL found at: http://example.com", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
public virtual void ValidateSigNameWholeChainOcspCrlNoTest() {
|
||||
ValidateOptionLevelInclusion(CRL_DISTRIBUTION_POINT, LtvVerification.CertificateOption.WHOLE_CHAIN, LtvVerification.Level
|
||||
.OCSP_CRL, LtvVerification.CertificateInclusion.NO, true);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Added CRL url: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Checking CRL: http://example.com", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("Added CRL found at: http://example.com", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
public virtual void ValidateSigNameWholeChainOcspOptionalCrlNoTest() {
|
||||
ValidateOptionLevelInclusion(CRL_DISTRIBUTION_POINT, LtvVerification.CertificateOption.WHOLE_CHAIN, LtvVerification.Level
|
||||
.OCSP_OPTIONAL_CRL, LtvVerification.CertificateInclusion.NO, true);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Added CRL url: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void ValidateSigNameWholeChainOcspNoTest() {
|
||||
ValidateOptionLevelInclusion(CRL_DISTRIBUTION_POINT, LtvVerification.CertificateOption.WHOLE_CHAIN, LtvVerification.Level
|
||||
.OCSP, LtvVerification.CertificateInclusion.NO, false);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Added CRL url: http://example.com", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Checking CRL: http://example.com", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("Added CRL found at: http://example.com", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
public virtual void ValidateSigNameWholeChainCrlNoTest() {
|
||||
ValidateOptionLevelInclusion(CRL_DISTRIBUTION_POINT, LtvVerification.CertificateOption.WHOLE_CHAIN, LtvVerification.Level
|
||||
.CRL, LtvVerification.CertificateInclusion.NO, true);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetParentWithoutCertsTest() {
|
||||
using (PdfDocument document = new PdfDocument(new PdfWriter(new MemoryStream()))) {
|
||||
LtvVerification verification = new LtvVerification(document);
|
||||
NUnit.Framework.Assert.IsNull(verification.GetParent(null, new IX509Certificate[0]));
|
||||
}
|
||||
}
|
||||
|
||||
private static void ValidateOptionLevelInclusion(String crlUrl, LtvVerification.CertificateOption certificateOption
|
||||
, LtvVerification.Level level, LtvVerification.CertificateInclusion inclusion, bool expectedResult) {
|
||||
IOcspClient ocsp = new OcspClientBouncyCastle(null);
|
||||
ICrlClient crl = null;
|
||||
if (null == crlUrl) {
|
||||
crl = new CrlClientOnline();
|
||||
}
|
||||
else {
|
||||
crl = new CrlClientOnline(crlUrl);
|
||||
}
|
||||
NUnit.Framework.Assert.AreEqual(expectedResult, TEST_VERIFICATION.AddVerification(SIG_FIELD_NAME, ocsp, crl
|
||||
, certificateOption, level, inclusion));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Test;
|
||||
using TSpdf.Test.Attributes;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
[NUnit.Framework.Category("BouncyCastleIntegrationTest")]
|
||||
public class LtvVerifierIntegrationTest : ExtendedTSpdfTest {
|
||||
private static readonly String SOURCE_FOLDER = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/LtvVerifierIntegrationTest/";
|
||||
|
||||
private static readonly IBouncyCastleFactory BOUNCY_CASTLE_FACTORY = BouncyCastleFactoryCreator.GetFactory
|
||||
();
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("The timestamp covers whole document.", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("The signed document has not been modified.", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Checking signature TestSignature", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Verifying signature.", LogLevel = LogLevelConstants.INFO)]
|
||||
// Checking of "All certificates are valid on ..." message is impossible because current time is used in message
|
||||
[LogMessage("C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestRoot", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Valid OCSPs found: 0", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Valid CRLs found: 0", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Switching to previous revision.", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("No signatures in revision", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void VerifySigningCertIsSelfSignedWithoutRevocationDataTest() {
|
||||
String src = SOURCE_FOLDER + "signingCertIsSelfSignedWithoutRevocationData.pdf";
|
||||
using (PdfDocument pdfDocument = new PdfDocument(new PdfReader(src))) {
|
||||
LtvVerifier verifier = new LtvVerifier(pdfDocument);
|
||||
verifier.SetVerifyRootCertificate(false);
|
||||
IList<VerificationOK> verificationOKList = verifier.VerifySignature();
|
||||
NUnit.Framework.Assert.IsTrue(verificationOKList.IsEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("The timestamp covers whole document.", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("The signed document has not been modified.", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Checking signature TestSignature", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Verifying signature.", LogLevel = LogLevelConstants.INFO)]
|
||||
// Checking of "All certificates are valid on ..." message is impossible because current time is used in message
|
||||
[LogMessage("C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestRsaCert01", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Valid OCSPs found: 0", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Valid CRLs found: 0", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void VerifySigningCertHasChainWithoutRevocationDataTest() {
|
||||
String src = SOURCE_FOLDER + "signingCertHasChainWithoutRevocationData.pdf";
|
||||
using (PdfDocument pdfDocument = new PdfDocument(new PdfReader(src))) {
|
||||
LtvVerifier verifier = new LtvVerifier(pdfDocument);
|
||||
verifier.SetVerifyRootCertificate(false);
|
||||
Exception ex = NUnit.Framework.Assert.Catch(typeof(VerificationException), () => verifier.VerifySignature(
|
||||
));
|
||||
NUnit.Framework.Assert.AreEqual("Certificate C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestRsaCert01 failed: "
|
||||
+ "Couldn't verify with CRL or OCSP or trusted anchor", ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("The timestamp covers whole document.", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("The signed document has not been modified.", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("Checking document-level timestamp signature TestTimestamp", LogLevel = LogLevelConstants.INFO
|
||||
)]
|
||||
[LogMessage("Switching to previous revision.", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("Checking signature TestSignature", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Verifying signature.", LogLevel = LogLevelConstants.INFO)]
|
||||
// Checking of "All certificates are valid on ..." message is impossible because current time is used in message
|
||||
[LogMessage("C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestRsaCert01", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Valid OCSPs found: 1", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Valid CRLs found: 0", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestRoot", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Valid OCSPs found: 0", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("No signatures in revision", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void VerifySigningCertHasChainWithOcspOnlyForChildCertNotVerifyRootTest() {
|
||||
String src = SOURCE_FOLDER + "signingCertHasChainWithOcspOnlyForChildCert.pdf";
|
||||
using (PdfDocument pdfDocument = new PdfDocument(new PdfReader(src))) {
|
||||
LtvVerifier verifier = new LtvVerifier(pdfDocument);
|
||||
verifier.SetCertificateOption(LtvVerification.CertificateOption.WHOLE_CHAIN);
|
||||
verifier.SetVerifyRootCertificate(false);
|
||||
// TSpdf doesn't allow adding\processing DSS with one revision in document, so document
|
||||
// "signingCertHasChainWithOcspOnlyForChildCert.pdf" contains 2 revision. The first is
|
||||
// dummy revision (signing cert of first revision has a chain without any revocation data).
|
||||
// The second is main revision which verifying we want to test.
|
||||
verifier.SwitchToPreviousRevision();
|
||||
IList<VerificationOK> verificationOKList = verifier.VerifySignature();
|
||||
NUnit.Framework.Assert.AreEqual(2, verificationOKList.Count);
|
||||
VerificationOK verificationOK = verificationOKList[0];
|
||||
NUnit.Framework.Assert.AreEqual("C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestRsaCert01", BOUNCY_CASTLE_FACTORY
|
||||
.CreateX500Name(verificationOK.certificate).ToString());
|
||||
NUnit.Framework.Assert.AreEqual("Valid OCSPs Found: 1", verificationOK.message);
|
||||
verificationOK = verificationOKList[1];
|
||||
NUnit.Framework.Assert.AreEqual("C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestRoot", BOUNCY_CASTLE_FACTORY.CreateX500Name
|
||||
(verificationOK.certificate).ToString());
|
||||
NUnit.Framework.Assert.AreEqual("Root certificate passed without checking", verificationOK.message);
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("The timestamp covers whole document.", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("The signed document has not been modified.", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("Checking document-level timestamp signature TestTimestamp", LogLevel = LogLevelConstants.INFO
|
||||
)]
|
||||
[LogMessage("Switching to previous revision.", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Checking signature TestSignature", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Verifying signature.", LogLevel = LogLevelConstants.INFO)]
|
||||
// Checking of "All certificates are valid on ..." message is impossible because current time is used in message
|
||||
[LogMessage("C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestRsaCert01", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Valid OCSPs found: 1", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Valid CRLs found: 0", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestRoot", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Valid OCSPs found: 0", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void VerifySigningCertHasChainWithOcspOnlyForChildCertVerifyRootTest() {
|
||||
String src = SOURCE_FOLDER + "signingCertHasChainWithOcspOnlyForChildCert.pdf";
|
||||
using (PdfDocument pdfDocument = new PdfDocument(new PdfReader(src))) {
|
||||
LtvVerifier verifier = new LtvVerifier(pdfDocument);
|
||||
verifier.SetCertificateOption(LtvVerification.CertificateOption.WHOLE_CHAIN);
|
||||
verifier.SetVerifyRootCertificate(true);
|
||||
// TSpdf doesn't allow adding\processing DSS with one revision in document, so document
|
||||
// "signingCertHasChainWithOcspOnlyForChildCert.pdf" contains 2 revision. The first is
|
||||
// dummy revision (signing cert of first revision has a chain without any revocation data).
|
||||
// The second is main revision which verifying we want to test.
|
||||
verifier.SwitchToPreviousRevision();
|
||||
Exception ex = NUnit.Framework.Assert.Catch(typeof(VerificationException), () => verifier.VerifySignature(
|
||||
));
|
||||
NUnit.Framework.Assert.AreEqual("Certificate C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestRoot failed: " + "Couldn't verify with CRL or OCSP or trusted anchor"
|
||||
, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("The timestamp covers whole document.", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("The signed document has not been modified.", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("Checking document-level timestamp signature TestTimestamp", LogLevel = LogLevelConstants.INFO
|
||||
)]
|
||||
[LogMessage("Switching to previous revision.", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Checking signature TestSignature", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Verifying signature.", LogLevel = LogLevelConstants.INFO)]
|
||||
// Checking of "All certificates are valid on ..." message is impossible because current time is used in message
|
||||
[LogMessage("C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestRsaCertWithChain", LogLevel = LogLevelConstants.INFO
|
||||
)]
|
||||
[LogMessage("Valid OCSPs found: 1", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Valid CRLs found: 0", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestIntermediateRsa01", LogLevel = LogLevelConstants.INFO
|
||||
)]
|
||||
[LogMessage("Valid OCSPs found: 0", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void VerifySigningCertHas3ChainWithOcspOnlyForChildCertVerifyRootTest() {
|
||||
String src = SOURCE_FOLDER + "signingCertHas3ChainWithOcspOnlyForChildCert.pdf";
|
||||
using (PdfDocument pdfDocument = new PdfDocument(new PdfReader(src))) {
|
||||
LtvVerifier verifier = new LtvVerifier(pdfDocument);
|
||||
verifier.SetCertificateOption(LtvVerification.CertificateOption.WHOLE_CHAIN);
|
||||
verifier.SetVerifyRootCertificate(true);
|
||||
// TSpdf doesn't allow adding\processing DSS with one revision in document, so document
|
||||
// "signingCertHas3ChainWithOcspOnlyForChildCert.pdf" contains 2 revision. The first is
|
||||
// dummy revision (signing cert of first revision has a chain without any revocation data).
|
||||
// The second is main revision which verifying we want to test.
|
||||
verifier.SwitchToPreviousRevision();
|
||||
Exception ex = NUnit.Framework.Assert.Catch(typeof(VerificationException), () => verifier.VerifySignature(
|
||||
));
|
||||
NUnit.Framework.Assert.AreEqual("Certificate C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestIntermediateRsa01 failed: "
|
||||
+ "Couldn't verify with CRL or OCSP or trusted anchor", ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("The timestamp covers whole document.", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("The signed document has not been modified.", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("Checking document-level timestamp signature TestTimestamp", LogLevel = LogLevelConstants.INFO
|
||||
)]
|
||||
[LogMessage("Switching to previous revision.", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("Checking signature TestSignature", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Verifying signature.", LogLevel = LogLevelConstants.INFO)]
|
||||
// Checking of "All certificates are valid on ..." message is impossible because current time is used in message
|
||||
[LogMessage("C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestRsaCert01", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Valid OCSPs found: 1", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Valid CRLs found: 0", LogLevel = LogLevelConstants.INFO, Count = 2)]
|
||||
[LogMessage("C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestRoot", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Valid OCSPs found: 0", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("No signatures in revision", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void NotTrustedRootCertificateInLatestRevisionTest() {
|
||||
String src = SOURCE_FOLDER + "signingCertHasChainWithOcspOnlyForChildCert.pdf";
|
||||
using (PdfDocument pdfDocument = new PdfDocument(new PdfReader(src))) {
|
||||
LtvVerifier verifier = new LtvVerifier(pdfDocument);
|
||||
verifier.SetCertificateOption(LtvVerification.CertificateOption.WHOLE_CHAIN);
|
||||
verifier.SetVerifyRootCertificate(true);
|
||||
// TSpdf doesn't allow adding\processing DSS with one revision in document, so document
|
||||
// "signingCertHasChainWithOcspOnlyForChildCert.pdf" contains 2 revision. The first is
|
||||
// dummy revision (signing cert of first revision has a chain without any revocation data).
|
||||
// The second is main revision which verifying we want to test.
|
||||
verifier.SwitchToPreviousRevision();
|
||||
// TODO after implementing DEVSIX-6233, 1- pass local CRL for child certificate to LtvVerifier
|
||||
// 2- don't manually change latestRevision field 3- don't use first signature and DSS in test PDF document
|
||||
verifier.latestRevision = true;
|
||||
IList<VerificationOK> verificationOKList = verifier.VerifySignature();
|
||||
NUnit.Framework.Assert.AreEqual(3, verificationOKList.Count);
|
||||
VerificationOK verificationOK = verificationOKList[0];
|
||||
NUnit.Framework.Assert.AreEqual("C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestRsaCert01", BOUNCY_CASTLE_FACTORY
|
||||
.CreateX500Name(verificationOK.certificate).ToString());
|
||||
NUnit.Framework.Assert.AreEqual("Valid OCSPs Found: 1", verificationOK.message);
|
||||
verificationOK = verificationOKList[1];
|
||||
NUnit.Framework.Assert.AreEqual("C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestRoot", BOUNCY_CASTLE_FACTORY.CreateX500Name
|
||||
(verificationOK.certificate).ToString());
|
||||
NUnit.Framework.Assert.AreEqual("Root certificate in final revision", verificationOK.message);
|
||||
verificationOK = verificationOKList[2];
|
||||
NUnit.Framework.Assert.AreEqual("C=BY,L=Minsk,O=TSpdf,OU=test,CN=TSpdfTestRoot", BOUNCY_CASTLE_FACTORY.CreateX500Name
|
||||
(verificationOK.certificate).ToString());
|
||||
NUnit.Framework.Assert.AreEqual("Root certificate passed without checking", verificationOK.message);
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SwitchBetweenSeveralRevisionsTest() {
|
||||
String testInput = SOURCE_FOLDER + "severalConsequentSignatures.pdf";
|
||||
using (PdfReader pdfReader = new PdfReader(testInput)) {
|
||||
using (PdfDocument pdfDoc = new PdfDocument(pdfReader)) {
|
||||
LtvVerifier ltvVerifier = new LtvVerifier(pdfDoc);
|
||||
NUnit.Framework.Assert.AreEqual("timestampSig2", ltvVerifier.signatureName);
|
||||
ltvVerifier.SwitchToPreviousRevision();
|
||||
NUnit.Framework.Assert.AreEqual("Signature2", ltvVerifier.signatureName);
|
||||
ltvVerifier.SwitchToPreviousRevision();
|
||||
NUnit.Framework.Assert.AreEqual("timestampSig1", ltvVerifier.signatureName);
|
||||
ltvVerifier.SwitchToPreviousRevision();
|
||||
NUnit.Framework.Assert.AreEqual("Signature1", ltvVerifier.signatureName);
|
||||
ltvVerifier.SwitchToPreviousRevision();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
[NUnit.Framework.Category("BouncyCastleUnitTest")]
|
||||
public class LtvVerifierUnitTest : ExtendedTSpdfTest {
|
||||
private static readonly String SOURCE_FOLDER = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/LtvVerifierUnitTest/";
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SetVerifierTest() {
|
||||
LtvVerifier verifier1 = new LtvVerifier(new PdfDocument(new PdfReader(new FileStream(SOURCE_FOLDER + "ltvDoc.pdf"
|
||||
, FileMode.Open, FileAccess.Read))));
|
||||
LtvVerifier verifier2 = new LtvVerifier(new PdfDocument(new PdfReader(new FileStream(SOURCE_FOLDER + "ltvDoc.pdf"
|
||||
, FileMode.Open, FileAccess.Read))));
|
||||
verifier1.SetVerifier(verifier2);
|
||||
NUnit.Framework.Assert.AreSame(verifier2, verifier1.verifier);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SetVerifyRootCertificateTest() {
|
||||
LtvVerifier verifier = new LtvVerifier(new PdfDocument(new PdfReader(new FileStream(SOURCE_FOLDER + "ltvDoc.pdf"
|
||||
, FileMode.Open, FileAccess.Read))));
|
||||
verifier.SetVerifyRootCertificate(true);
|
||||
NUnit.Framework.Assert.IsTrue(verifier.verifyRootCertificate);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void VerifyNotNullTest() {
|
||||
LtvVerifier verifier = new LtvVerifier(new PdfDocument(new PdfReader(new FileStream(SOURCE_FOLDER + "ltvDoc.pdf"
|
||||
, FileMode.Open, FileAccess.Read))));
|
||||
verifier.pkcs7 = null;
|
||||
IList<VerificationOK> list = JavaCollectionsUtil.EmptyList<VerificationOK>();
|
||||
NUnit.Framework.Assert.AreSame(list, verifier.Verify(list));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetCRLsFromDSSCRLsNullTest() {
|
||||
LtvVerifier verifier = new LtvVerifier(new PdfDocument(new PdfReader(new FileStream(SOURCE_FOLDER + "ltvDoc.pdf"
|
||||
, FileMode.Open, FileAccess.Read))));
|
||||
verifier.dss = new PdfDictionary();
|
||||
NUnit.Framework.Assert.AreEqual(new List<Object>(), verifier.GetCRLsFromDSS());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetOCSPResponsesFromDSSOCSPsNullTest() {
|
||||
LtvVerifier verifier = new LtvVerifier(new PdfDocument(new PdfReader(new FileStream(SOURCE_FOLDER + "ltvDoc.pdf"
|
||||
, FileMode.Open, FileAccess.Read))));
|
||||
verifier.dss = new PdfDictionary();
|
||||
NUnit.Framework.Assert.AreEqual(new List<Object>(), verifier.GetOCSPResponsesFromDSS());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.Net;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1.Ocsp;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Cert.Ocsp;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Signatures.Testutils.Builder;
|
||||
using TSpdf.Test;
|
||||
using TSpdf.Test.Attributes;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
[NUnit.Framework.Category("BouncyCastleUnitTest")]
|
||||
public class OcspClientBouncyCastleTest : ExtendedTSpdfTest {
|
||||
private static readonly String ocspCertsSrc = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/OcspClientBouncyCastleTest/";
|
||||
|
||||
private static readonly String rootOcspCert = ocspCertsSrc + "ocspRootRsa.pem";
|
||||
|
||||
private static readonly String signOcspCert = ocspCertsSrc + "ocspSignRsa.pem";
|
||||
|
||||
private static readonly char[] password = "testpassphrase".ToCharArray();
|
||||
|
||||
private const String ocspServiceUrl = "http://localhost:9000/demo/ocsp/ocsp-service";
|
||||
|
||||
private static readonly IBouncyCastleFactory BOUNCY_CASTLE_FACTORY = BouncyCastleFactoryCreator.GetFactory
|
||||
();
|
||||
|
||||
private static IX509Certificate checkCert;
|
||||
|
||||
private static IX509Certificate rootCert;
|
||||
|
||||
private static TestOcspResponseBuilder builder;
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
}
|
||||
|
||||
[NUnit.Framework.SetUp]
|
||||
public virtual void SetUp() {
|
||||
builder = CreateBuilder(BOUNCY_CASTLE_FACTORY.CreateCertificateStatus().GetGood());
|
||||
checkCert = (IX509Certificate)PemFileHelper.ReadFirstChain(signOcspCert)[0];
|
||||
rootCert = builder.GetIssuerCert();
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetOcspResponseWhenCheckCertIsNullTest() {
|
||||
OcspClientBouncyCastle castle = new OcspClientBouncyCastle(null);
|
||||
NUnit.Framework.Assert.IsNull(castle.GetOcspResponse(null, rootCert, ocspServiceUrl));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetOcspResponseWhenRootCertIsNullTest() {
|
||||
OcspClientBouncyCastle castle = new OcspClientBouncyCastle(null);
|
||||
NUnit.Framework.Assert.IsNull(castle.GetOcspResponse(checkCert, null, ocspServiceUrl));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetOcspResponseWhenRootAndCheckCertIsNullTest() {
|
||||
OcspClientBouncyCastle castle = new OcspClientBouncyCastle(null);
|
||||
NUnit.Framework.Assert.IsNull(castle.GetOcspResponse(null, null, ocspServiceUrl));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetOcspResponseWhenUrlCertIsNullTest() {
|
||||
OcspClientBouncyCastle castle = new OcspClientBouncyCastle(null);
|
||||
NUnit.Framework.Assert.Catch(typeof(WebException), () => castle.GetOcspResponse(checkCert, rootCert, null)
|
||||
);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Getting OCSP from http://asd", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void IncorrectUrlTest() {
|
||||
OcspClientBouncyCastle castle = new OcspClientBouncyCastle(null);
|
||||
NUnit.Framework.Assert.Catch(typeof(WebException), () => castle.GetOcspResponse(checkCert, rootCert, "http://asd"
|
||||
));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Getting OCSP from", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void MalformedUrlTest() {
|
||||
OcspClientBouncyCastle castle = new OcspClientBouncyCastle(null);
|
||||
NUnit.Framework.Assert.Catch(typeof(UriFormatException), () => castle.GetOcspResponse(checkCert, rootCert,
|
||||
""));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Getting OCSP from http://localhost:9000/demo/ocsp/ocsp-service", LogLevel = LogLevelConstants
|
||||
.INFO)]
|
||||
public virtual void ConnectionRefusedTest() {
|
||||
OcspClientBouncyCastle castle = new OcspClientBouncyCastle(null);
|
||||
NUnit.Framework.Assert.Catch(typeof(WebException), () => castle.GetOcspResponse(checkCert, rootCert, ocspServiceUrl
|
||||
));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetBasicOcspRespTest() {
|
||||
OcspClientBouncyCastle ocspClientBouncyCastle = CreateOcspClient();
|
||||
IBasicOCSPResponse basicOCSPResp = ocspClientBouncyCastle.GetBasicOCSPResp(checkCert, rootCert, ocspServiceUrl
|
||||
);
|
||||
NUnit.Framework.Assert.IsNotNull(basicOCSPResp);
|
||||
NUnit.Framework.Assert.IsTrue(basicOCSPResp.GetResponses().Length > 0);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetBasicOcspRespNullTest() {
|
||||
OcspClientBouncyCastle ocspClientBouncyCastle = new OcspClientBouncyCastle(null);
|
||||
IBasicOCSPResponse basicOCSPResp = ocspClientBouncyCastle.GetBasicOCSPResp(checkCert, null, ocspServiceUrl
|
||||
);
|
||||
NUnit.Framework.Assert.IsNull(basicOCSPResp);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("OCSP response could not be verified")]
|
||||
public virtual void GetBasicOCSPRespLogMessageTest() {
|
||||
OcspClientBouncyCastle ocspClientBouncyCastle = CreateOcspClient();
|
||||
IBasicOCSPResponse basicOCSPResp = ocspClientBouncyCastle.GetBasicOCSPResp(null, null, null);
|
||||
NUnit.Framework.Assert.IsNull(basicOCSPResp);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetEncodedTest() {
|
||||
OcspClientBouncyCastle ocspClientBouncyCastle = CreateOcspClient();
|
||||
byte[] encoded = ocspClientBouncyCastle.GetEncoded(checkCert, rootCert, ocspServiceUrl);
|
||||
NUnit.Framework.Assert.IsNotNull(encoded);
|
||||
NUnit.Framework.Assert.IsTrue(encoded.Length > 0);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage(TSpdf.IO.Logs.IoLogMessageConstant.OCSP_STATUS_IS_REVOKED)]
|
||||
public virtual void OcspStatusIsRevokedTest() {
|
||||
IRevokedStatus status = BOUNCY_CASTLE_FACTORY.CreateRevokedStatus(DateTimeUtil.GetCurrentUtcTime().AddDays
|
||||
(-20), BOUNCY_CASTLE_FACTORY.CreateOCSPResponse().GetSuccessful());
|
||||
TestOcspResponseBuilder responseBuilder = CreateBuilder(status);
|
||||
OcspClientBouncyCastle ocspClientBouncyCastle = CreateTestOcspClient(responseBuilder);
|
||||
byte[] encoded = ocspClientBouncyCastle.GetEncoded(checkCert, rootCert, ocspServiceUrl);
|
||||
NUnit.Framework.Assert.IsNull(encoded);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage(TSpdf.IO.Logs.IoLogMessageConstant.OCSP_STATUS_IS_UNKNOWN)]
|
||||
public virtual void OcspStatusIsUnknownTest() {
|
||||
IUnknownStatus status = BOUNCY_CASTLE_FACTORY.CreateUnknownStatus();
|
||||
TestOcspResponseBuilder responseBuilder = CreateBuilder(status);
|
||||
OcspClientBouncyCastle ocspClientBouncyCastle = CreateTestOcspClient(responseBuilder);
|
||||
byte[] encoded = ocspClientBouncyCastle.GetEncoded(checkCert, rootCert, ocspServiceUrl);
|
||||
NUnit.Framework.Assert.IsNull(encoded);
|
||||
}
|
||||
|
||||
private static OcspClientBouncyCastle CreateOcspClient() {
|
||||
return CreateOcspClient(builder);
|
||||
}
|
||||
|
||||
private static OcspClientBouncyCastle CreateOcspClient(TestOcspResponseBuilder builder) {
|
||||
OCSPVerifier ocspVerifier = new OCSPVerifier(null, null);
|
||||
return new OcspClientBouncyCastleTest.TestOcspClientBouncyCastle(ocspVerifier, builder);
|
||||
}
|
||||
|
||||
private static OcspClientBouncyCastle CreateTestOcspClient(TestOcspResponseBuilder responseBuilder) {
|
||||
return CreateOcspClient(responseBuilder);
|
||||
}
|
||||
|
||||
private static TestOcspResponseBuilder CreateBuilder(ICertificateStatus status) {
|
||||
IX509Certificate caCert = (IX509Certificate)PemFileHelper.ReadFirstChain(rootOcspCert)[0];
|
||||
IPrivateKey caPrivateKey = PemFileHelper.ReadFirstKey(rootOcspCert, password);
|
||||
return new TestOcspResponseBuilder(caCert, caPrivateKey, status);
|
||||
}
|
||||
|
||||
private sealed class TestOcspClientBouncyCastle : OcspClientBouncyCastle {
|
||||
private static TestOcspResponseBuilder testOcspBuilder;
|
||||
|
||||
public TestOcspClientBouncyCastle(OCSPVerifier verifier, TestOcspResponseBuilder testBuilder)
|
||||
: base(verifier) {
|
||||
testOcspBuilder = testBuilder;
|
||||
}
|
||||
|
||||
internal override IOCSPResponse GetOcspResponse(IX509Certificate chCert, IX509Certificate rCert, String url
|
||||
) {
|
||||
try {
|
||||
ICertificateID id = SignTestPortUtil.GenerateCertificateId(rootCert, checkCert.GetSerialNumber(), BOUNCY_CASTLE_FACTORY
|
||||
.CreateCertificateID().GetHashSha1());
|
||||
IBasicOCSPResponse basicOCSPResp = testOcspBuilder.MakeOcspResponseObject(SignTestPortUtil.GenerateOcspRequestWithNonce
|
||||
(id).GetEncoded());
|
||||
return BOUNCY_CASTLE_FACTORY.CreateOCSPResponse(BOUNCY_CASTLE_FACTORY.CreateOCSPResponseStatus().GetSuccessful
|
||||
(), basicOCSPResp);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw BOUNCY_CASTLE_FACTORY.CreateAbstractOCSPException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
[NUnit.Framework.Category("BouncyCastleUnitTest")]
|
||||
public class PdfPKCS7BasicTest : ExtendedTSpdfTest {
|
||||
protected internal static readonly String SOURCE_FOLDER = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/PdfPKCS7Test/";
|
||||
|
||||
protected internal static IX509Certificate[] chain;
|
||||
|
||||
protected internal static IPrivateKey pk;
|
||||
|
||||
protected internal static readonly IBouncyCastleFactory BOUNCY_CASTLE_FACTORY = BouncyCastleFactoryCreator
|
||||
.GetFactory();
|
||||
|
||||
private static readonly String CERTS_SRC = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/";
|
||||
|
||||
private static readonly char[] PASSWORD = "testpassphrase".ToCharArray();
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Init() {
|
||||
pk = PemFileHelper.ReadFirstKey(CERTS_SRC + "signCertRsa01.pem", PASSWORD);
|
||||
chain = PemFileHelper.ReadFirstChain(CERTS_SRC + "signCertRsa01.pem");
|
||||
}
|
||||
|
||||
internal static void VerifyIsoExtensionExample(String expectedSigMechanismName, String fileName) {
|
||||
String infile = SOURCE_FOLDER + "extensions/" + fileName;
|
||||
using (PdfReader r = new PdfReader(infile)) {
|
||||
using (PdfDocument pdfDoc = new PdfDocument(r)) {
|
||||
SignatureUtil u = new SignatureUtil(pdfDoc);
|
||||
/*
|
||||
We specify the security provider explicitly; we're not testing security provider fallback here.
|
||||
|
||||
Also, default providers (in 2022) don't always have the parameters for Brainpool curves,
|
||||
but a curve param mismatch doesn't factor into the algorithm support fallback logic, so
|
||||
it causes a runtime error.
|
||||
*/
|
||||
PdfPKCS7 data = u.ReadSignatureData("Signature");
|
||||
NUnit.Framework.Assert.AreEqual(expectedSigMechanismName, data.GetSignatureMechanismName());
|
||||
NUnit.Framework.Assert.IsTrue(data.VerifySignatureIntegrityAndAuthenticity());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using TSpdf.Kernel.Exceptions;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
// The behavior is different on .NET
|
||||
[NUnit.Framework.Category("BouncyCastleUnitTest")]
|
||||
public class PdfPKCS7ManuallyPortedTest : PdfPKCS7BasicTest {
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void VerifyEd25519SignatureTest() {
|
||||
if ("BCFIPS".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName())) {
|
||||
// ED25519 is not available in FIPS approved mode
|
||||
if (BOUNCY_CASTLE_FACTORY.IsInApprovedOnlyMode()) {
|
||||
NUnit.Framework.Assert.Catch(typeof(PdfException), () => VerifyIsoExtensionExample("Ed25519", "sample-ed25519-sha512.pdf"
|
||||
));
|
||||
} else {
|
||||
// algorithm identifier in key not recognised
|
||||
NUnit.Framework.Assert.Catch(typeof(PdfException), () => VerifyIsoExtensionExample("Ed25519", "sample-ed25519-sha512.pdf"
|
||||
));
|
||||
}
|
||||
} else {
|
||||
VerifyIsoExtensionExample("Ed25519", "sample-ed25519-sha512.pdf");
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void VerifyNistECDSASha3SignatureTest() {
|
||||
if ("BCFIPS".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName())) {
|
||||
VerifyIsoExtensionExample("SHA3-256withECDSA", "sample-nistp256-sha3_256.pdf");
|
||||
} else {
|
||||
// Signer SHA3-256WITHECDSA not recognised in BC mode
|
||||
NUnit.Framework.Assert.Catch(typeof(PdfException), () => VerifyIsoExtensionExample("SHA3-256withECDSA", "sample-nistp256-sha3_256.pdf"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void VerifyBrainpoolSha3SignatureTest() {
|
||||
if ("BCFIPS".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName())) {
|
||||
VerifyIsoExtensionExample("SHA3-384withECDSA", "sample-brainpoolP384r1-sha3_384.pdf");
|
||||
} else {
|
||||
// Signer SHA3-384WITHECDSA not recognised in BC mode
|
||||
NUnit.Framework.Assert.Catch(typeof(PdfException), () => VerifyIsoExtensionExample("SHA3-384withECDSA", "sample-brainpoolP384r1-sha3_384.pdf"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void VerifyRsaSha3SignatureTest() {
|
||||
// VerifySignatureIntegrityAndAuthenticity fails in BCFIPS mode
|
||||
if ("BC".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName())) {
|
||||
VerifyIsoExtensionExample("SHA3-256withRSA", "sample-rsa-sha3_256.pdf");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
300
TSpdf.tests/TSpdf.sign.tests/TSpdf/signatures/PdfPKCS7Test.cs
Normal file
300
TSpdf.tests/TSpdf.sign.tests/TSpdf/signatures/PdfPKCS7Test.cs
Normal file
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1.Tsp;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Kernel.Exceptions;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Signatures.Exceptions;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Signatures.Testutils.Client;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
[NUnit.Framework.Category("BouncyCastleUnitTest")]
|
||||
public class PdfPKCS7Test : PdfPKCS7BasicTest {
|
||||
private const double EPS = 0.001;
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void UnknownHashAlgorithmTest() {
|
||||
// PdfPKCS7 is created here the same way it's done in PdfSigner#signDetached,
|
||||
// only the hash algorithm is altered
|
||||
String hashAlgorithm = "";
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(PdfException), () => new PdfPKCS7(null, chain, hashAlgorithm
|
||||
, false));
|
||||
NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(SignExceptionMessageConstant.UNKNOWN_HASH_ALGORITHM
|
||||
, hashAlgorithm), e.Message);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SimpleCreationTest() {
|
||||
String hashAlgorithm = DigestAlgorithms.SHA256;
|
||||
PdfPKCS7 pkcs7 = new PdfPKCS7(null, chain, hashAlgorithm, false);
|
||||
String expectedOid = DigestAlgorithms.GetAllowedDigest(hashAlgorithm);
|
||||
NUnit.Framework.Assert.AreEqual(expectedOid, pkcs7.GetDigestAlgorithmOid());
|
||||
NUnit.Framework.Assert.AreEqual(chain[0], pkcs7.GetSigningCertificate());
|
||||
NUnit.Framework.Assert.AreEqual(chain, pkcs7.GetCertificates());
|
||||
NUnit.Framework.Assert.IsNull(pkcs7.GetSignatureMechanismOid());
|
||||
// test default fields
|
||||
NUnit.Framework.Assert.AreEqual(1, pkcs7.GetVersion());
|
||||
NUnit.Framework.Assert.AreEqual(1, pkcs7.GetSigningInfoVersion());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SimpleCreationWithPrivateKeyTest() {
|
||||
String hashAlgorithm = DigestAlgorithms.SHA256;
|
||||
PdfPKCS7 pkcs7 = new PdfPKCS7(pk, chain, hashAlgorithm, false);
|
||||
String expectedOid = DigestAlgorithms.GetAllowedDigest(hashAlgorithm);
|
||||
NUnit.Framework.Assert.AreEqual(expectedOid, pkcs7.GetDigestAlgorithmOid());
|
||||
NUnit.Framework.Assert.AreEqual(chain[0], pkcs7.GetSigningCertificate());
|
||||
NUnit.Framework.Assert.AreEqual(chain, pkcs7.GetCertificates());
|
||||
NUnit.Framework.Assert.AreEqual(SecurityIDs.ID_RSA_WITH_SHA256, pkcs7.GetSignatureMechanismOid());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void NotAvailableSignatureTest() {
|
||||
String hashAlgorithm = "GOST3411";
|
||||
// Throws different exceptions on .net and java, bc/bcfips
|
||||
NUnit.Framework.Assert.Catch(typeof(Exception), () => new PdfPKCS7(pk, chain, hashAlgorithm, false));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ReasonSetGetTest() {
|
||||
PdfPKCS7 pkcs7 = CreateSimplePdfPKCS7();
|
||||
NUnit.Framework.Assert.IsNull(pkcs7.GetReason());
|
||||
String testReason = "testReason";
|
||||
pkcs7.SetReason(testReason);
|
||||
NUnit.Framework.Assert.AreEqual(testReason, pkcs7.GetReason());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void LocationSetGetTest() {
|
||||
PdfPKCS7 pkcs7 = CreateSimplePdfPKCS7();
|
||||
NUnit.Framework.Assert.IsNull(pkcs7.GetLocation());
|
||||
String testLocation = "testLocation";
|
||||
pkcs7.SetLocation(testLocation);
|
||||
NUnit.Framework.Assert.AreEqual(testLocation, pkcs7.GetLocation());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignNameSetGetTest() {
|
||||
PdfPKCS7 pkcs7 = CreateSimplePdfPKCS7();
|
||||
NUnit.Framework.Assert.IsNull(pkcs7.GetSignName());
|
||||
String testSignName = "testSignName";
|
||||
pkcs7.SetSignName(testSignName);
|
||||
NUnit.Framework.Assert.AreEqual(testSignName, pkcs7.GetSignName());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignDateSetGetTest() {
|
||||
PdfPKCS7 pkcs7 = CreateSimplePdfPKCS7();
|
||||
NUnit.Framework.Assert.AreEqual(TimestampConstants.UNDEFINED_TIMESTAMP_DATE, pkcs7.GetSignDate());
|
||||
DateTime testSignDate = DateTimeUtil.GetCurrentTime();
|
||||
pkcs7.SetSignDate(testSignDate);
|
||||
NUnit.Framework.Assert.AreEqual(testSignDate, pkcs7.GetSignDate());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void OcspGetTest() {
|
||||
PdfDocument outDocument = new PdfDocument(new PdfReader(SOURCE_FOLDER + "ltvEnabledSingleSignatureTest01.pdf"
|
||||
));
|
||||
SignatureUtil sigUtil = new SignatureUtil(outDocument);
|
||||
PdfPKCS7 pkcs7 = sigUtil.ReadSignatureData("Signature1");
|
||||
NUnit.Framework.Assert.IsNull(pkcs7.GetCRLs());
|
||||
// it's tested here that ocsp and time stamp token were found while
|
||||
// constructing PdfPKCS7 instance
|
||||
ITSTInfo timeStampTokenInfo = pkcs7.GetTimeStampTokenInfo();
|
||||
NUnit.Framework.Assert.IsNotNull(timeStampTokenInfo);
|
||||
// The number corresponds to 3 September, 2021 13:32:33.
|
||||
double expectedMillis = (double)1630675953000L;
|
||||
NUnit.Framework.Assert.AreEqual(TimeTestUtil.GetFullDaysMillis(expectedMillis), TimeTestUtil.GetFullDaysMillis
|
||||
(DateTimeUtil.GetUtcMillisFromEpoch(DateTimeUtil.GetCalendar(timeStampTokenInfo.GetGenTime()))), EPS);
|
||||
NUnit.Framework.Assert.AreEqual(TimeTestUtil.GetFullDaysMillis(expectedMillis), TimeTestUtil.GetFullDaysMillis
|
||||
(DateTimeUtil.GetUtcMillisFromEpoch(DateTimeUtil.GetCalendar(pkcs7.GetOcsp().GetProducedAtDate()))), EPS
|
||||
);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void VerifyTimestampImprintSimpleSignatureTest() {
|
||||
PdfDocument outDocument = new PdfDocument(new PdfReader(SOURCE_FOLDER + "simpleSignature.pdf"));
|
||||
PdfPKCS7 pkcs7 = new SignatureUtil(outDocument).ReadSignatureData("Signature1");
|
||||
NUnit.Framework.Assert.IsFalse(pkcs7.VerifyTimestampImprint());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void VerifyTimestampImprintTimeStampSignatureTest() {
|
||||
PdfDocument outDocument = new PdfDocument(new PdfReader(SOURCE_FOLDER + "timeStampSignature.pdf"));
|
||||
PdfPKCS7 pkcs7 = new SignatureUtil(outDocument).ReadSignatureData("timestampSig1");
|
||||
NUnit.Framework.Assert.IsFalse(pkcs7.VerifyTimestampImprint());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void VerifyTimestampImprintEmbeddedTimeStampSignatureTest() {
|
||||
PdfDocument outDocument = new PdfDocument(new PdfReader(SOURCE_FOLDER + "embeddedTimeStampSignature.pdf"));
|
||||
PdfPKCS7 pkcs7 = new SignatureUtil(outDocument).ReadSignatureData("Signature1");
|
||||
NUnit.Framework.Assert.IsTrue(pkcs7.VerifyTimestampImprint());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void VerifyTimestampImprintCorruptedTimeStampSignatureTest() {
|
||||
PdfDocument outDocument = new PdfDocument(new PdfReader(SOURCE_FOLDER + "embeddedTimeStampCorruptedSignature.pdf"
|
||||
));
|
||||
PdfPKCS7 pkcs7 = new SignatureUtil(outDocument).ReadSignatureData("Signature1");
|
||||
NUnit.Framework.Assert.IsTrue(pkcs7.VerifyTimestampImprint());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void FindCrlIsNotNullTest() {
|
||||
PdfDocument outDocument = new PdfDocument(new PdfReader(SOURCE_FOLDER + "singleSignatureNotEmptyCRL.pdf"));
|
||||
SignatureUtil sigUtil = new SignatureUtil(outDocument);
|
||||
PdfPKCS7 pkcs7 = sigUtil.ReadSignatureData("Signature1");
|
||||
IList<IX509Crl> crls = pkcs7.GetCRLs().Select((crl) => (IX509Crl)crl).ToList();
|
||||
NUnit.Framework.Assert.AreEqual(2, crls.Count);
|
||||
NUnit.Framework.Assert.AreEqual(crls[0].GetEncoded(), File.ReadAllBytes(System.IO.Path.Combine(SOURCE_FOLDER
|
||||
, "firstCrl.bin")));
|
||||
NUnit.Framework.Assert.AreEqual(crls[1].GetEncoded(), File.ReadAllBytes(System.IO.Path.Combine(SOURCE_FOLDER
|
||||
, "secondCrl.bin")));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void FindCrlNullSequenceNoExceptionTest() {
|
||||
PdfPKCS7 pkcs7 = CreateSimplePdfPKCS7();
|
||||
pkcs7.FindCRL(null);
|
||||
NUnit.Framework.Assert.IsTrue(pkcs7.GetCRLs().IsEmpty());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void IsRevocationValidWithInvalidOcspTest() {
|
||||
PdfDocument outDocument = new PdfDocument(new PdfReader(SOURCE_FOLDER + "signatureWithInvalidOcspTest.pdf"
|
||||
));
|
||||
SignatureUtil sigUtil = new SignatureUtil(outDocument);
|
||||
PdfPKCS7 pkcs7 = sigUtil.ReadSignatureData("Signature1");
|
||||
NUnit.Framework.Assert.IsFalse(pkcs7.IsRevocationValid());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void IsRevocationValidWithValidOcspTest() {
|
||||
PdfDocument outDocument = new PdfDocument(new PdfReader(SOURCE_FOLDER + "signatureWithValidOcspTest.pdf"));
|
||||
SignatureUtil sigUtil = new SignatureUtil(outDocument);
|
||||
PdfPKCS7 pkcs7 = sigUtil.ReadSignatureData("Signature1");
|
||||
NUnit.Framework.Assert.IsTrue(pkcs7.IsRevocationValid());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void IsRevocationValidOcspResponseIsNullTest() {
|
||||
PdfPKCS7 pkcs7 = CreateSimplePdfPKCS7();
|
||||
pkcs7.basicResp = null;
|
||||
NUnit.Framework.Assert.IsFalse(pkcs7.IsRevocationValid());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void IsRevocationValidLackOfSignCertsTest() {
|
||||
PdfPKCS7 pkcs7 = CreateSimplePdfPKCS7();
|
||||
pkcs7.basicResp = BOUNCY_CASTLE_FACTORY.CreateBasicOCSPResponse(BOUNCY_CASTLE_FACTORY.CreateASN1InputStream
|
||||
(File.ReadAllBytes(System.IO.Path.Combine(SOURCE_FOLDER, "simpleOCSPResponse.bin"))).ReadObject());
|
||||
pkcs7.signCerts = JavaCollectionsUtil.Singleton(chain[0]);
|
||||
NUnit.Framework.Assert.IsFalse(pkcs7.IsRevocationValid());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void IsRevocationValidExceptionDuringValidationTest() {
|
||||
PdfPKCS7 pkcs7 = CreateSimplePdfPKCS7();
|
||||
pkcs7.basicResp = BOUNCY_CASTLE_FACTORY.CreateBasicOCSPResponse(BOUNCY_CASTLE_FACTORY.CreateASN1InputStream
|
||||
(File.ReadAllBytes(System.IO.Path.Combine(SOURCE_FOLDER, "simpleOCSPResponse.bin"))).ReadObject());
|
||||
pkcs7.signCerts = JavaUtil.ArraysAsList(new IX509Certificate[] { null, null });
|
||||
NUnit.Framework.Assert.IsFalse(pkcs7.IsRevocationValid());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetEncodedPkcs1Test() {
|
||||
String hashAlgorithm = DigestAlgorithms.SHA256;
|
||||
PdfPKCS7 pkcs7 = new PdfPKCS7(pk, chain, hashAlgorithm, true);
|
||||
byte[] bytes = pkcs7.GetEncodedPKCS1();
|
||||
byte[] cmpBytes = File.ReadAllBytes(System.IO.Path.Combine(SOURCE_FOLDER + "cmpBytesPkcs1.txt"));
|
||||
IASN1OctetString outOctetString = BOUNCY_CASTLE_FACTORY.CreateASN1OctetString(bytes);
|
||||
IASN1OctetString cmpOctetString = BOUNCY_CASTLE_FACTORY.CreateASN1OctetString(cmpBytes);
|
||||
NUnit.Framework.Assert.AreEqual(outOctetString, cmpOctetString);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetEncodedPkcs1NullPrivateKeyTest() {
|
||||
String hashAlgorithm = DigestAlgorithms.SHA256;
|
||||
PdfPKCS7 pkcs7 = new PdfPKCS7(null, chain, hashAlgorithm, true);
|
||||
Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfException), () => pkcs7.GetEncodedPKCS1());
|
||||
NUnit.Framework.Assert.AreEqual(KernelExceptionMessageConstant.UNKNOWN_PDF_EXCEPTION, exception.Message);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetEncodedPkcs7UnknownExceptionTest() {
|
||||
String hashAlgorithm = DigestAlgorithms.SHA256;
|
||||
PdfPKCS7 pkcs7 = new PdfPKCS7(pk, chain, hashAlgorithm, true);
|
||||
TestTsaClient testTsa = new TestTsaClient(JavaUtil.ArraysAsList(chain), pk);
|
||||
Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfException), () => pkcs7.GetEncodedPKCS7(null,
|
||||
PdfSigner.CryptoStandard.CMS, testTsa, null, null));
|
||||
NUnit.Framework.Assert.AreEqual(KernelExceptionMessageConstant.UNKNOWN_PDF_EXCEPTION, exception.Message);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetEncodedPkcs7Test() {
|
||||
String hashAlgorithm = DigestAlgorithms.SHA256;
|
||||
PdfPKCS7 pkcs7 = new PdfPKCS7(pk, chain, hashAlgorithm, true);
|
||||
byte[] bytes = pkcs7.GetEncodedPKCS7();
|
||||
byte[] cmpBytes = File.ReadAllBytes(System.IO.Path.Combine(SOURCE_FOLDER + "cmpBytesPkcs7.txt"));
|
||||
IASN1Primitive outStream = BOUNCY_CASTLE_FACTORY.CreateASN1Primitive(bytes);
|
||||
IASN1Primitive cmpStream = BOUNCY_CASTLE_FACTORY.CreateASN1Primitive(cmpBytes);
|
||||
NUnit.Framework.Assert.AreEqual("SHA256withRSA", pkcs7.GetSignatureMechanismName());
|
||||
NUnit.Framework.Assert.AreEqual(outStream, cmpStream);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void VerifyEd448SignatureTest() {
|
||||
// SHAKE256 is not available in BCFIPS
|
||||
if ("BCFIPS".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName())) {
|
||||
NUnit.Framework.Assert.Catch(typeof(PdfException), () => VerifyIsoExtensionExample("Ed448", "sample-ed448-shake256.pdf"
|
||||
));
|
||||
}
|
||||
else {
|
||||
VerifyIsoExtensionExample("Ed448", "sample-ed448-shake256.pdf");
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void VerifyNistECDSASha2SignatureTest() {
|
||||
VerifyIsoExtensionExample("SHA256withECDSA", "sample-nistp256-sha256.pdf");
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void VerifyBrainpoolSha2SignatureTest() {
|
||||
VerifyIsoExtensionExample("SHA384withECDSA", "sample-brainpoolP384r1-sha384.pdf");
|
||||
}
|
||||
|
||||
// PdfPKCS7 is created here the same way it's done in PdfSigner#signDetached
|
||||
private static PdfPKCS7 CreateSimplePdfPKCS7() {
|
||||
return new PdfPKCS7(null, chain, DigestAlgorithms.SHA256, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.IO;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.IO.Image;
|
||||
using TSpdf.Kernel.Colors;
|
||||
using TSpdf.Kernel.Font;
|
||||
using TSpdf.Kernel.Geom;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Kernel.Pdf.Xobject;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
/// <summary>
|
||||
/// The idea of this test is to check the
|
||||
/// <see cref="PdfSignatureAppearance"/>
|
||||
/// 's getters.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The idea of this test is to check the
|
||||
/// <see cref="PdfSignatureAppearance"/>
|
||||
/// 's getters.
|
||||
/// For actual result of setters invocations one should check the integration test for this class.
|
||||
/// </remarks>
|
||||
[NUnit.Framework.Category("BouncyCastleUnitTest")]
|
||||
public class PdfSignatureAppearanceUnitTest : ExtendedTSpdfTest {
|
||||
// The source folder points to the integration test, so that the resources are nor duplicated
|
||||
public static readonly String SOURCE_FOLDER = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/sign/PdfSignatureAppearanceTest/";
|
||||
|
||||
public static readonly String DESTINATION_FOLDER = NUnit.Framework.TestContext.CurrentContext.TestDirectory
|
||||
+ "/test/TSpdf/signatures/sign/PdfSignatureAppearanceUnitTest/";
|
||||
|
||||
public static readonly String KEYSTORE_PATH = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/sign/PdfSignatureAppearanceTest/test.pem";
|
||||
|
||||
public static readonly char[] PASSWORD = "kspass".ToCharArray();
|
||||
|
||||
private static IX509Certificate[] chain;
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
CreateOrClearDestinationFolder(DESTINATION_FOLDER);
|
||||
chain = PemFileHelper.ReadFirstChain(KEYSTORE_PATH);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ReasonCaptionTest() {
|
||||
PdfSignatureAppearance signatureAppearance = GetTestSignatureAppearance();
|
||||
String newReasonCaption = "Hello World";
|
||||
NUnit.Framework.Assert.IsNull(signatureAppearance.GetLayer2Text());
|
||||
String layer2Text = signatureAppearance.GenerateLayer2Text();
|
||||
// There is no text from new reason caption in the default layer 2 text
|
||||
NUnit.Framework.Assert.IsFalse(layer2Text.Contains(newReasonCaption));
|
||||
signatureAppearance.SetReasonCaption(newReasonCaption);
|
||||
layer2Text = signatureAppearance.GenerateLayer2Text();
|
||||
// Now layer 2 text contains text from new reason caption
|
||||
NUnit.Framework.Assert.IsTrue(layer2Text.Contains(newReasonCaption));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void LocationCaptionTest() {
|
||||
PdfSignatureAppearance signatureAppearance = GetTestSignatureAppearance();
|
||||
String newLocationCaption = "Hello World";
|
||||
NUnit.Framework.Assert.IsNull(signatureAppearance.GetLayer2Text());
|
||||
String layer2Text = signatureAppearance.GenerateLayer2Text();
|
||||
// There is no text from new location caption in the default layer 2 text
|
||||
NUnit.Framework.Assert.IsFalse(layer2Text.Contains(newLocationCaption));
|
||||
signatureAppearance.SetLocationCaption(newLocationCaption);
|
||||
layer2Text = signatureAppearance.GenerateLayer2Text();
|
||||
// Now layer 2 text contains text from new location caption
|
||||
NUnit.Framework.Assert.IsTrue(layer2Text.Contains(newLocationCaption));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void RenderingModeSetGetTest() {
|
||||
PdfSignatureAppearance signatureAppearance = GetTestSignatureAppearance();
|
||||
PdfSignatureAppearance.RenderingMode defaultMode = signatureAppearance.GetRenderingMode();
|
||||
NUnit.Framework.Assert.AreEqual(PdfSignatureAppearance.RenderingMode.DESCRIPTION, defaultMode);
|
||||
PdfSignatureAppearance.RenderingMode testRenderingMode = PdfSignatureAppearance.RenderingMode.GRAPHIC_AND_DESCRIPTION;
|
||||
signatureAppearance.SetRenderingMode(testRenderingMode);
|
||||
NUnit.Framework.Assert.AreEqual(testRenderingMode, signatureAppearance.GetRenderingMode());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignatureCreatorSetGetTest() {
|
||||
PdfSignatureAppearance signatureAppearance = GetTestSignatureAppearance();
|
||||
NUnit.Framework.Assert.AreEqual("", signatureAppearance.GetSignatureCreator());
|
||||
String signatureCreator = "Hello World";
|
||||
signatureAppearance.SetSignatureCreator(signatureCreator);
|
||||
NUnit.Framework.Assert.AreEqual(signatureCreator, signatureAppearance.GetSignatureCreator());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ContactSetGetTest() {
|
||||
PdfSignatureAppearance signatureAppearance = GetTestSignatureAppearance();
|
||||
NUnit.Framework.Assert.AreEqual("", signatureAppearance.GetContact());
|
||||
String contact = "Hello World";
|
||||
signatureAppearance.SetContact(contact);
|
||||
NUnit.Framework.Assert.AreEqual(contact, signatureAppearance.GetContact());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void CertificateSetGetTest() {
|
||||
PdfSignatureAppearance signatureAppearance = GetTestSignatureAppearance();
|
||||
NUnit.Framework.Assert.IsNull(signatureAppearance.GetCertificate());
|
||||
IX509Certificate testCertificate = chain[0];
|
||||
signatureAppearance.SetCertificate(testCertificate);
|
||||
NUnit.Framework.Assert.AreEqual(testCertificate, signatureAppearance.GetCertificate());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignatureGraphicSetGetTest() {
|
||||
PdfSignatureAppearance signatureAppearance = GetTestSignatureAppearance();
|
||||
NUnit.Framework.Assert.IsNull(signatureAppearance.GetSignatureGraphic());
|
||||
ImageData testImageData = ImageDataFactory.Create(SOURCE_FOLDER + "TSpdf.png");
|
||||
signatureAppearance.SetSignatureGraphic(testImageData);
|
||||
NUnit.Framework.Assert.AreEqual(testImageData, signatureAppearance.GetSignatureGraphic());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ImageSetGetTest() {
|
||||
PdfSignatureAppearance signatureAppearance = GetTestSignatureAppearance();
|
||||
NUnit.Framework.Assert.IsNull(signatureAppearance.GetImage());
|
||||
ImageData testImageData = ImageDataFactory.Create(SOURCE_FOLDER + "TSpdf.png");
|
||||
signatureAppearance.SetImage(testImageData);
|
||||
NUnit.Framework.Assert.AreEqual(testImageData, signatureAppearance.GetImage());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ImageScalingSetGetTest() {
|
||||
PdfSignatureAppearance signatureAppearance = GetTestSignatureAppearance();
|
||||
NUnit.Framework.Assert.AreEqual(0, signatureAppearance.GetImageScale(), 0.0001);
|
||||
float newScale = 1F;
|
||||
signatureAppearance.SetImageScale(newScale);
|
||||
NUnit.Framework.Assert.AreEqual(newScale, signatureAppearance.GetImageScale(), 0.0001);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void Layer2FontSetGetTest() {
|
||||
PdfSignatureAppearance signatureAppearance = GetTestSignatureAppearance();
|
||||
NUnit.Framework.Assert.IsNull(signatureAppearance.GetLayer2Font());
|
||||
PdfFont newFont = PdfFontFactory.CreateFont();
|
||||
signatureAppearance.SetLayer2Font(newFont);
|
||||
NUnit.Framework.Assert.AreEqual(newFont, signatureAppearance.GetLayer2Font());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void Layer2FontSizeSetGetTest() {
|
||||
PdfSignatureAppearance signatureAppearance = GetTestSignatureAppearance();
|
||||
NUnit.Framework.Assert.AreEqual(0, signatureAppearance.GetLayer2FontSize(), 0.0001);
|
||||
float newSize = 12F;
|
||||
signatureAppearance.SetLayer2FontSize(newSize);
|
||||
NUnit.Framework.Assert.AreEqual(newSize, signatureAppearance.GetLayer2FontSize(), 0.0001);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void Layer2FontColorSetGetTest() {
|
||||
PdfSignatureAppearance signatureAppearance = GetTestSignatureAppearance();
|
||||
NUnit.Framework.Assert.IsNull(signatureAppearance.GetLayer2FontColor());
|
||||
Color newColor = ColorConstants.RED;
|
||||
signatureAppearance.SetLayer2FontColor(newColor);
|
||||
NUnit.Framework.Assert.AreEqual(newColor, signatureAppearance.GetLayer2FontColor());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetAppearanceInvisibleTest() {
|
||||
PdfSignatureAppearance appearance = new PdfSignatureAppearance(null, new Rectangle(0, 100), 1);
|
||||
PdfFormXObject xObject = appearance.GetAppearance();
|
||||
NUnit.Framework.Assert.IsTrue(new Rectangle(0, 0).EqualsWithEpsilon(xObject.GetBBox().ToRectangle()));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetSignDateTest() {
|
||||
PdfSignatureAppearance appearance = new PdfSignatureAppearance(null, new Rectangle(100, 100), 1);
|
||||
DateTime current = DateTimeUtil.GetCurrentTime();
|
||||
appearance.SetSignDate(current);
|
||||
NUnit.Framework.Assert.AreEqual(current, appearance.GetSignDate());
|
||||
}
|
||||
|
||||
private static PdfSignatureAppearance GetTestSignatureAppearance() {
|
||||
String src = SOURCE_FOLDER + "simpleDocument.pdf";
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(src), new MemoryStream(), new StampingProperties());
|
||||
return signer.GetSignatureAppearance();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
[NUnit.Framework.Category("UnitTest")]
|
||||
public class PdfSignatureBuildPropertiesUnitTest : ExtendedTSpdfTest {
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SetSignatureCreatorTest() {
|
||||
PdfSignatureBuildProperties properties = new PdfSignatureBuildProperties();
|
||||
PdfDictionary appPropDic = new PdfDictionary();
|
||||
properties.GetPdfObject().Put(PdfName.App, appPropDic);
|
||||
properties.SetSignatureCreator("sign_creator");
|
||||
PdfObject appDict = properties.GetPdfObject().Get(PdfName.App);
|
||||
NUnit.Framework.Assert.IsTrue(appDict is PdfDictionary);
|
||||
PdfObject name = ((PdfDictionary)appDict).Get(PdfName.Name);
|
||||
NUnit.Framework.Assert.IsTrue(name is PdfName);
|
||||
NUnit.Framework.Assert.AreEqual("sign_creator", ((PdfName)name).GetValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,461 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.IO;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Forms;
|
||||
using TSpdf.Forms.Fields;
|
||||
using TSpdf.IO.Source;
|
||||
using TSpdf.Kernel.Exceptions;
|
||||
using TSpdf.Kernel.Geom;
|
||||
using TSpdf.Kernel.Logs;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Kernel.Pdf.Annot;
|
||||
using TSpdf.Pdfa;
|
||||
using TSpdf.Signatures.Exceptions;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Test;
|
||||
using TSpdf.Test.Attributes;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
[NUnit.Framework.Category("BouncyCastleUnitTest")]
|
||||
public class PdfSignerUnitTest : ExtendedTSpdfTest {
|
||||
private static readonly byte[] OWNER = "owner".GetBytes();
|
||||
|
||||
private static readonly byte[] USER = "user".GetBytes();
|
||||
|
||||
private static readonly String PDFA_RESOURCES = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/pdfa/";
|
||||
|
||||
private static readonly String DESTINATION_FOLDER = NUnit.Framework.TestContext.CurrentContext.TestDirectory
|
||||
+ "/test/TSpdf/signatures/PdfSignerUnitTest/";
|
||||
|
||||
private static readonly String CERTS_SRC = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/";
|
||||
|
||||
private static readonly char[] PASSWORD = "testpassphrase".ToCharArray();
|
||||
|
||||
private IX509Certificate[] chain;
|
||||
|
||||
private IPrivateKey pk;
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
CreateOrClearDestinationFolder(DESTINATION_FOLDER);
|
||||
}
|
||||
|
||||
[NUnit.Framework.SetUp]
|
||||
public virtual void Init() {
|
||||
pk = PemFileHelper.ReadFirstKey(CERTS_SRC + "signCertRsa01.pem", PASSWORD);
|
||||
chain = PemFileHelper.ReadFirstChain(CERTS_SRC + "signCertRsa01.pem");
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage(KernelLogMessageConstant.MD5_IS_NOT_FIPS_COMPLIANT, Ignore = true)]
|
||||
public virtual void CreateNewSignatureFormFieldInvisibleAnnotationTest() {
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(new MemoryStream(CreateEncryptedDocumentWithoutWidgetAnnotation
|
||||
()), new ReaderProperties().SetPassword(OWNER)), new ByteArrayOutputStream(), new StampingProperties()
|
||||
);
|
||||
signer.cryptoDictionary = new PdfSignature();
|
||||
signer.appearance.SetPageRect(new Rectangle(100, 100, 0, 0));
|
||||
PdfAcroForm acroForm = PdfAcroForm.GetAcroForm(signer.document, true);
|
||||
signer.CreateNewSignatureFormField(acroForm, signer.fieldName);
|
||||
PdfFormField formField = acroForm.GetField(signer.fieldName);
|
||||
PdfDictionary formFieldDictionary = formField.GetPdfObject();
|
||||
NUnit.Framework.Assert.IsNotNull(formFieldDictionary);
|
||||
NUnit.Framework.Assert.IsFalse(formFieldDictionary.ContainsKey(PdfName.AP));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage(KernelLogMessageConstant.MD5_IS_NOT_FIPS_COMPLIANT, Ignore = true)]
|
||||
public virtual void CreateNewSignatureFormFieldNotInvisibleAnnotationTest() {
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(new MemoryStream(CreateEncryptedDocumentWithoutWidgetAnnotation
|
||||
()), new ReaderProperties().SetPassword(OWNER)), new ByteArrayOutputStream(), new StampingProperties()
|
||||
);
|
||||
signer.cryptoDictionary = new PdfSignature();
|
||||
signer.appearance.SetPageRect(new Rectangle(100, 100, 10, 10));
|
||||
PdfSigFieldLock fieldLock = new PdfSigFieldLock();
|
||||
signer.fieldLock = fieldLock;
|
||||
PdfAcroForm acroForm = PdfAcroForm.GetAcroForm(signer.document, true);
|
||||
NUnit.Framework.Assert.AreEqual(fieldLock, signer.CreateNewSignatureFormField(acroForm, signer.fieldName));
|
||||
PdfFormField formField = acroForm.GetField(signer.fieldName);
|
||||
PdfDictionary formFieldDictionary = formField.GetPdfObject();
|
||||
NUnit.Framework.Assert.IsNotNull(formFieldDictionary);
|
||||
NUnit.Framework.Assert.IsTrue(formFieldDictionary.ContainsKey(PdfName.AP));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignWithFieldLockNotNullTest() {
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(new MemoryStream(CreateSimpleDocument(PdfVersion.PDF_2_0)))
|
||||
, new ByteArrayOutputStream(), new StampingProperties());
|
||||
signer.cryptoDictionary = new PdfSignature();
|
||||
signer.appearance.SetPageRect(new Rectangle(100, 100, 10, 10));
|
||||
PdfSigFieldLock fieldLock = new PdfSigFieldLock();
|
||||
signer.fieldLock = fieldLock;
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
|
||||
NUnit.Framework.Assert.IsTrue(signer.closed);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignDetachedWhenAlreadySignedIsNotPossibleTest() {
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(new MemoryStream(CreateSimpleDocument())), new ByteArrayOutputStream
|
||||
(), new StampingProperties());
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(PdfException), () => signer.SignDetached(pks, chain, null
|
||||
, null, null, 0, PdfSigner.CryptoStandard.CADES));
|
||||
NUnit.Framework.Assert.AreEqual(SignExceptionMessageConstant.THIS_INSTANCE_OF_PDF_SIGNER_ALREADY_CLOSED, e
|
||||
.Message);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignExternalWhenAlreadySignedIsNotPossibleTest() {
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(new MemoryStream(CreateSimpleDocument())), new ByteArrayOutputStream
|
||||
(), new StampingProperties());
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(PdfException), () => signer.SignExternalContainer(new ExternalBlankSignatureContainer
|
||||
(new PdfDictionary()), 0));
|
||||
NUnit.Framework.Assert.AreEqual(SignExceptionMessageConstant.THIS_INSTANCE_OF_PDF_SIGNER_ALREADY_CLOSED, e
|
||||
.Message);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage(KernelLogMessageConstant.MD5_IS_NOT_FIPS_COMPLIANT, Ignore = true)]
|
||||
public virtual void PopulateExistingSignatureFormFieldInvisibleAnnotationTest() {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
PdfDocument document = new PdfDocument(new PdfWriter(outputStream, new WriterProperties().SetStandardEncryption
|
||||
(USER, OWNER, 0, EncryptionConstants.STANDARD_ENCRYPTION_128)));
|
||||
document.AddNewPage();
|
||||
PdfWidgetAnnotation widgetAnnotation = new PdfWidgetAnnotation(new Rectangle(100, 100, 0, 0));
|
||||
document.GetPage(1).AddAnnotation(widgetAnnotation);
|
||||
document.Close();
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(new MemoryStream(outputStream.ToArray()), new ReaderProperties
|
||||
().SetPassword(OWNER)), new ByteArrayOutputStream(), new StampingProperties());
|
||||
signer.cryptoDictionary = new PdfSignature();
|
||||
signer.appearance.SetPageRect(new Rectangle(100, 100, 0, 0));
|
||||
widgetAnnotation = (PdfWidgetAnnotation)signer.document.GetPage(1).GetAnnotations()[0];
|
||||
PdfAcroForm acroForm = PdfAcroForm.GetAcroForm(signer.document, true);
|
||||
PdfFormField formField = new PdfSignerUnitTest.ExtendedPdfSignatureFormField(widgetAnnotation, signer.document
|
||||
);
|
||||
formField.SetFieldName(signer.fieldName);
|
||||
acroForm.AddField(formField);
|
||||
signer.PopulateExistingSignatureFormField(acroForm);
|
||||
formField = acroForm.GetField(signer.fieldName);
|
||||
PdfDictionary formFieldDictionary = formField.GetPdfObject();
|
||||
NUnit.Framework.Assert.IsNotNull(formFieldDictionary);
|
||||
NUnit.Framework.Assert.IsFalse(formFieldDictionary.ContainsKey(PdfName.AP));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage(KernelLogMessageConstant.MD5_IS_NOT_FIPS_COMPLIANT, Ignore = true)]
|
||||
public virtual void PopulateExistingSignatureFormFieldNotInvisibleAnnotationTest() {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
PdfDocument document = new PdfDocument(new PdfWriter(outputStream, new WriterProperties().SetStandardEncryption
|
||||
(USER, OWNER, 0, EncryptionConstants.STANDARD_ENCRYPTION_128)));
|
||||
document.AddNewPage();
|
||||
PdfWidgetAnnotation widgetAnnotation = new PdfWidgetAnnotation(new Rectangle(100, 100, 0, 0));
|
||||
document.GetPage(1).AddAnnotation(widgetAnnotation);
|
||||
document.Close();
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(new MemoryStream(outputStream.ToArray()), new ReaderProperties
|
||||
().SetPassword(OWNER)), new ByteArrayOutputStream(), new StampingProperties());
|
||||
signer.cryptoDictionary = new PdfSignature();
|
||||
PdfSigFieldLock fieldLock = new PdfSigFieldLock();
|
||||
signer.fieldLock = fieldLock;
|
||||
signer.appearance.SetPageRect(new Rectangle(100, 100, 10, 10));
|
||||
widgetAnnotation = (PdfWidgetAnnotation)signer.document.GetPage(1).GetAnnotations()[0];
|
||||
PdfAcroForm acroForm = PdfAcroForm.GetAcroForm(signer.document, true);
|
||||
PdfFormField formField = new PdfSignerUnitTest.ExtendedPdfSignatureFormField(widgetAnnotation, signer.document
|
||||
);
|
||||
formField.SetFieldName(signer.fieldName);
|
||||
acroForm.AddField(formField);
|
||||
NUnit.Framework.Assert.AreEqual(signer.PopulateExistingSignatureFormField(acroForm), fieldLock);
|
||||
formField = acroForm.GetField(signer.fieldName);
|
||||
PdfDictionary formFieldDictionary = formField.GetPdfObject();
|
||||
NUnit.Framework.Assert.IsNotNull(formFieldDictionary);
|
||||
NUnit.Framework.Assert.IsTrue(formFieldDictionary.ContainsKey(PdfName.AP));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TempFileProvidedTest() {
|
||||
String tempFileName = "tempFile";
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(new MemoryStream(CreateSimpleDocument())), new ByteArrayOutputStream
|
||||
(), DESTINATION_FOLDER + tempFileName, new StampingProperties());
|
||||
NUnit.Framework.Assert.IsNotNull(signer.tempFile);
|
||||
NUnit.Framework.Assert.AreEqual(tempFileName, signer.tempFile.Name);
|
||||
NUnit.Framework.Assert.IsNull(signer.temporaryOS);
|
||||
}
|
||||
|
||||
// Android-Conversion-Skip-Block-Start (TODO DEVSIX-7372 investigate why a few tests related to PdfA in PdfSignerUnitTest were cut)
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void InitPdfaDocumentTest() {
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(new MemoryStream(CreateSimplePdfaDocument())), new ByteArrayOutputStream
|
||||
(), new StampingProperties());
|
||||
NUnit.Framework.Assert.AreEqual(PdfAConformanceLevel.PDF_A_1A, ((PdfAAgnosticPdfDocument)signer.GetDocument
|
||||
()).GetConformanceLevel());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SigningDateSetGetTest() {
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(new MemoryStream(CreateSimplePdfaDocument())), new ByteArrayOutputStream
|
||||
(), new StampingProperties());
|
||||
DateTime testDate = DateTimeUtil.GetCurrentTime();
|
||||
signer.SetSignDate(testDate);
|
||||
NUnit.Framework.Assert.AreEqual(testDate, signer.GetSignDate());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void CertificationLevelSetGetTest() {
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(new MemoryStream(CreateSimplePdfaDocument())), new ByteArrayOutputStream
|
||||
(), new StampingProperties());
|
||||
NUnit.Framework.Assert.AreEqual(PdfSigner.NOT_CERTIFIED, signer.GetCertificationLevel());
|
||||
int testLevel = PdfSigner.CERTIFIED_NO_CHANGES_ALLOWED;
|
||||
signer.SetCertificationLevel(testLevel);
|
||||
NUnit.Framework.Assert.AreEqual(testLevel, signer.GetCertificationLevel());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignatureDictionarySetGetTest() {
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(new MemoryStream(CreateSimplePdfaDocument())), new ByteArrayOutputStream
|
||||
(), new StampingProperties());
|
||||
NUnit.Framework.Assert.IsNull(signer.GetSignatureDictionary());
|
||||
PdfSignature testSignature = new PdfSignature();
|
||||
signer.cryptoDictionary = testSignature;
|
||||
NUnit.Framework.Assert.AreEqual(testSignature, signer.GetSignatureDictionary());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignatureEventSetGetTest() {
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(new MemoryStream(CreateSimplePdfaDocument())), new ByteArrayOutputStream
|
||||
(), new StampingProperties());
|
||||
NUnit.Framework.Assert.IsNull(signer.GetSignatureEvent());
|
||||
PdfSigner.ISignatureEvent testEvent = new PdfSignerUnitTest.DummySignatureEvent(this);
|
||||
signer.SetSignatureEvent(testEvent);
|
||||
NUnit.Framework.Assert.AreEqual(testEvent, signer.GetSignatureEvent());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignatureFieldNameMustNotContainDotTest() {
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(new MemoryStream(CreateSimplePdfaDocument())), new ByteArrayOutputStream
|
||||
(), new StampingProperties());
|
||||
Exception exception = NUnit.Framework.Assert.Catch(typeof(ArgumentException), () => signer.SetFieldName("name.with.dots"
|
||||
));
|
||||
NUnit.Framework.Assert.AreEqual(SignExceptionMessageConstant.FIELD_NAMES_CANNOT_CONTAIN_A_DOT, exception.Message
|
||||
);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void DocumentWithoutReaderCannotBeSetToSignerTest() {
|
||||
PdfReader reader = new PdfReader(new MemoryStream(CreateSimplePdfaDocument()));
|
||||
PdfSigner signer = new PdfSigner(reader, new ByteArrayOutputStream(), new StampingProperties());
|
||||
PdfDocument documentWithoutReader = new PdfDocument(new PdfWriter(new ByteArrayOutputStream()));
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(ArgumentException), () => signer.SetDocument(documentWithoutReader
|
||||
));
|
||||
NUnit.Framework.Assert.AreEqual(SignExceptionMessageConstant.DOCUMENT_MUST_HAVE_READER, e.Message);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void DocumentSetGetTest() {
|
||||
PdfReader reader = new PdfReader(new MemoryStream(CreateSimplePdfaDocument()));
|
||||
PdfSigner signer = new PdfSigner(reader, new ByteArrayOutputStream(), new StampingProperties());
|
||||
PdfDocument document = signer.GetDocument();
|
||||
NUnit.Framework.Assert.AreEqual(reader, document.GetReader());
|
||||
PdfDocument documentWithoutReader = new PdfDocument(new PdfReader(new MemoryStream(CreateSimpleDocument())
|
||||
), new PdfWriter(new ByteArrayOutputStream()));
|
||||
signer.SetDocument(documentWithoutReader);
|
||||
NUnit.Framework.Assert.AreEqual(documentWithoutReader, signer.GetDocument());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void OutputStreamSetGetTest() {
|
||||
PdfReader reader = new PdfReader(new MemoryStream(CreateSimplePdfaDocument()));
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
PdfSigner signer = new PdfSigner(reader, outputStream, new StampingProperties());
|
||||
NUnit.Framework.Assert.AreEqual(outputStream, signer.originalOS);
|
||||
ByteArrayOutputStream anotherStream = new ByteArrayOutputStream();
|
||||
signer.SetOriginalOutputStream(anotherStream);
|
||||
NUnit.Framework.Assert.AreEqual(anotherStream, signer.originalOS);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void FieldLockSetGetTest() {
|
||||
PdfReader reader = new PdfReader(new MemoryStream(CreateSimplePdfaDocument()));
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
PdfSigner signer = new PdfSigner(reader, outputStream, new StampingProperties());
|
||||
NUnit.Framework.Assert.IsNull(signer.GetFieldLockDict());
|
||||
PdfSigFieldLock fieldLock = new PdfSigFieldLock();
|
||||
signer.SetFieldLockDict(fieldLock);
|
||||
NUnit.Framework.Assert.AreEqual(fieldLock, signer.GetFieldLockDict());
|
||||
}
|
||||
|
||||
// Android-Conversion-Skip-Block-End
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SetFieldNameNullForDefaultSignerTest() {
|
||||
PdfReader reader = new PdfReader(new MemoryStream(CreateSimpleDocument()));
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
PdfSigner signer = new PdfSigner(reader, outputStream, new StampingProperties());
|
||||
signer.SetFieldName(null);
|
||||
NUnit.Framework.Assert.AreEqual("Signature1", signer.GetFieldName());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void KeepFieldNameAfterSetToNullTest() {
|
||||
PdfReader reader = new PdfReader(new MemoryStream(CreateSimpleDocument()));
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
PdfSigner signer = new PdfSigner(reader, outputStream, new StampingProperties());
|
||||
String testName = "test_name";
|
||||
signer.SetFieldName(testName);
|
||||
signer.SetFieldName(null);
|
||||
NUnit.Framework.Assert.AreEqual(testName, signer.GetFieldName());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SetFieldNameToFieldWithSameNameAndNoSigTest() {
|
||||
PdfReader reader = new PdfReader(new MemoryStream(CreateDocumentWithEmptyField()));
|
||||
PdfSigner signer = new PdfSigner(reader, new ByteArrayOutputStream(), new StampingProperties());
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(ArgumentException), () => signer.SetFieldName("test_field"
|
||||
));
|
||||
NUnit.Framework.Assert.AreEqual(SignExceptionMessageConstant.FIELD_TYPE_IS_NOT_A_SIGNATURE_FIELD_TYPE, e.Message
|
||||
);
|
||||
reader.Close();
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SetFieldNameToSigFieldWithValueTest() {
|
||||
String fieldName = "test_field";
|
||||
String fieldValue = "test_value";
|
||||
PdfReader reader = new PdfReader(new MemoryStream(CreateDocumentWithSignatureWithTestValueField(fieldName,
|
||||
fieldValue)));
|
||||
PdfSigner signer = new PdfSigner(reader, new ByteArrayOutputStream(), new StampingProperties());
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(ArgumentException), () => signer.SetFieldName(fieldName)
|
||||
);
|
||||
NUnit.Framework.Assert.AreEqual(SignExceptionMessageConstant.FIELD_ALREADY_SIGNED, e.Message);
|
||||
reader.Close();
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SetFieldNameToSigFieldWithoutWidgetsTest() {
|
||||
String fieldName = "test_field";
|
||||
PdfReader reader = new PdfReader(new MemoryStream(CreateDocumentWithSignatureField(fieldName)));
|
||||
PdfSigner signer = new PdfSigner(reader, new ByteArrayOutputStream(), new StampingProperties());
|
||||
signer.SetFieldName(fieldName);
|
||||
NUnit.Framework.Assert.AreEqual(fieldName, signer.GetFieldName());
|
||||
reader.Close();
|
||||
}
|
||||
|
||||
private static byte[] CreateDocumentWithEmptyField() {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outputStream));
|
||||
PdfFormField formField = new NonTerminalFormFieldBuilder(pdfDocument, "test_field").CreateNonTerminalFormField
|
||||
();
|
||||
PdfAcroForm acroForm = PdfAcroForm.GetAcroForm(pdfDocument, true);
|
||||
acroForm.AddField(formField);
|
||||
pdfDocument.Close();
|
||||
return outputStream.ToArray();
|
||||
}
|
||||
|
||||
private static byte[] CreateDocumentWithSignatureWithTestValueField(String fieldName, String fieldValue) {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outputStream));
|
||||
PdfFormField formField = new SignatureFormFieldBuilder(pdfDocument, fieldName).CreateSignature().SetValue(
|
||||
fieldValue);
|
||||
PdfAcroForm acroForm = PdfAcroForm.GetAcroForm(pdfDocument, true);
|
||||
acroForm.AddField(formField);
|
||||
pdfDocument.Close();
|
||||
return outputStream.ToArray();
|
||||
}
|
||||
|
||||
private static byte[] CreateDocumentWithSignatureField(String fieldName) {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outputStream));
|
||||
PdfFormField formField = new SignatureFormFieldBuilder(pdfDocument, fieldName).CreateSignature();
|
||||
PdfAcroForm acroForm = PdfAcroForm.GetAcroForm(pdfDocument, true);
|
||||
acroForm.AddField(formField);
|
||||
pdfDocument.Close();
|
||||
return outputStream.ToArray();
|
||||
}
|
||||
|
||||
private static byte[] CreateEncryptedDocumentWithoutWidgetAnnotation() {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
PdfDocument document = new PdfDocument(new PdfWriter(outputStream, new WriterProperties().SetStandardEncryption
|
||||
(USER, OWNER, 0, EncryptionConstants.STANDARD_ENCRYPTION_128)));
|
||||
document.AddNewPage();
|
||||
document.Close();
|
||||
return outputStream.ToArray();
|
||||
}
|
||||
|
||||
private static byte[] CreateSimpleDocument() {
|
||||
return CreateSimpleDocument(PdfVersion.PDF_1_7);
|
||||
}
|
||||
|
||||
private static byte[] CreateSimpleDocument(PdfVersion version) {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
WriterProperties writerProperties = new WriterProperties();
|
||||
if (null != version) {
|
||||
writerProperties.SetPdfVersion(version);
|
||||
}
|
||||
PdfDocument document = new PdfDocument(new PdfWriter(outputStream, writerProperties));
|
||||
document.AddNewPage();
|
||||
document.Close();
|
||||
return outputStream.ToArray();
|
||||
}
|
||||
|
||||
// Android-Conversion-Skip-Block-Start (TODO DEVSIX-7372 investigate why a few tests related to PdfA in PdfSignerUnitTest were cut)
|
||||
private static byte[] CreateSimplePdfaDocument() {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
PdfWriter writer = new PdfWriter(outputStream);
|
||||
Stream @is = new FileStream(PDFA_RESOURCES + "sRGB Color Space Profile.icm", FileMode.Open, FileAccess.Read
|
||||
);
|
||||
PdfOutputIntent outputIntent = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1"
|
||||
, @is);
|
||||
PdfDocument document = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_1A, outputIntent);
|
||||
document.SetTagged();
|
||||
document.GetCatalog().SetLang(new PdfString("en-US"));
|
||||
document.AddNewPage();
|
||||
document.Close();
|
||||
return outputStream.ToArray();
|
||||
}
|
||||
|
||||
// Android-Conversion-Skip-Block-End
|
||||
internal class ExtendedPdfSignatureFormField : PdfSignatureFormField {
|
||||
public ExtendedPdfSignatureFormField(PdfWidgetAnnotation widgetAnnotation, PdfDocument document)
|
||||
: base(widgetAnnotation, document) {
|
||||
}
|
||||
}
|
||||
|
||||
internal class DummySignatureEvent : PdfSigner.ISignatureEvent {
|
||||
public virtual void GetSignatureDictionary(PdfSignature sig) {
|
||||
}
|
||||
|
||||
internal DummySignatureEvent(PdfSignerUnitTest _enclosing) {
|
||||
this._enclosing = _enclosing;
|
||||
}
|
||||
|
||||
private readonly PdfSignerUnitTest _enclosing;
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
[NUnit.Framework.Category("UnitTest")]
|
||||
public class SignUtilsUnitTest : ExtendedTSpdfTest {
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void Add180SecTest() {
|
||||
// use int value in month for porting compatibility
|
||||
NUnit.Framework.Assert.AreEqual(new DateTime(2021, 8, 19, 0, 3, 20), SignUtils.Add180Sec(new DateTime(2021
|
||||
, 8, 19, 0, 0, 20)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures
|
||||
{
|
||||
public class SignatureMechanismsManualTest : ExtendedTSpdfTest
|
||||
{
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetAlgorithmNullTest()
|
||||
{
|
||||
NUnit.Framework.Assert.Catch(typeof(ArgumentNullException),
|
||||
() => SignatureMechanisms.GetAlgorithm(null));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
[NUnit.Framework.Category("UnitTest")]
|
||||
public class SignatureMechanismsTest : ExtendedTSpdfTest {
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetAlgorithmRSATest() {
|
||||
NUnit.Framework.Assert.AreEqual("RSA", SignatureMechanisms.GetAlgorithm("1.2.840.113549.1.1.1"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetAlgorithmECDSATest() {
|
||||
NUnit.Framework.Assert.AreEqual("ECDSA", SignatureMechanisms.GetAlgorithm("1.2.840.10045.2.1"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetAlgorithmEmptyTest() {
|
||||
NUnit.Framework.Assert.AreEqual("", SignatureMechanisms.GetAlgorithm(""));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetAlgorithmEmptySpaceTest() {
|
||||
NUnit.Framework.Assert.AreEqual(" ", SignatureMechanisms.GetAlgorithm(" "));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetAlgorithmUndefinedTest() {
|
||||
NUnit.Framework.Assert.AreEqual("undefined", SignatureMechanisms.GetAlgorithm("undefined"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
[NUnit.Framework.Category("UnitTest")]
|
||||
public class SignaturePermissionsTest : ExtendedTSpdfTest {
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void DefaultValuesTest() {
|
||||
SignaturePermissions permissions = new SignaturePermissions(new PdfDictionary(), null);
|
||||
NUnit.Framework.Assert.AreEqual(new List<Object>(), permissions.GetFieldLocks());
|
||||
NUnit.Framework.Assert.IsTrue(permissions.IsAnnotationsAllowed());
|
||||
NUnit.Framework.Assert.IsFalse(permissions.IsCertification());
|
||||
NUnit.Framework.Assert.IsTrue(permissions.IsFillInAllowed());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TransformedMethodDocMDPIsPresentedTest() {
|
||||
PdfDictionary dict = new PdfDictionary();
|
||||
PdfArray references = new PdfArray();
|
||||
PdfDictionary dictWithDocMDP = new PdfDictionary();
|
||||
dictWithDocMDP.Put(PdfName.TransformMethod, PdfName.DocMDP);
|
||||
dictWithDocMDP.Put(PdfName.TransformParams, new PdfDictionary());
|
||||
references.Add(dictWithDocMDP);
|
||||
dict.Put(PdfName.Reference, references);
|
||||
SignaturePermissions permissions = new SignaturePermissions(dict, null);
|
||||
NUnit.Framework.Assert.IsTrue(permissions.IsCertification());
|
||||
NUnit.Framework.Assert.AreEqual(new List<Object>(), permissions.GetFieldLocks());
|
||||
NUnit.Framework.Assert.IsTrue(permissions.IsAnnotationsAllowed());
|
||||
NUnit.Framework.Assert.IsTrue(permissions.IsFillInAllowed());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ActionIsPresentedTest() {
|
||||
PdfDictionary dict = new PdfDictionary();
|
||||
PdfArray references = new PdfArray();
|
||||
PdfDictionary dictWithAction = new PdfDictionary();
|
||||
PdfDictionary @params = new PdfDictionary();
|
||||
PdfName action = new PdfName("Name");
|
||||
PdfArray fields = new PdfArray();
|
||||
fields.Add(new PdfString("Value1"));
|
||||
fields.Add(new PdfString("Value2"));
|
||||
@params.Put(PdfName.Action, action);
|
||||
@params.Put(PdfName.Fields, fields);
|
||||
dictWithAction.Put(PdfName.TransformParams, @params);
|
||||
references.Add(dictWithAction);
|
||||
dict.Put(PdfName.Reference, references);
|
||||
SignaturePermissions permissions = new SignaturePermissions(dict, null);
|
||||
NUnit.Framework.Assert.AreEqual(1, permissions.GetFieldLocks().Count);
|
||||
SignaturePermissions.FieldLock fieldLock = permissions.GetFieldLocks()[0];
|
||||
NUnit.Framework.Assert.AreEqual(action, fieldLock.GetAction());
|
||||
NUnit.Framework.Assert.AreEqual(fields, fieldLock.GetFields());
|
||||
NUnit.Framework.Assert.IsTrue(permissions.IsAnnotationsAllowed());
|
||||
NUnit.Framework.Assert.IsFalse(permissions.IsCertification());
|
||||
NUnit.Framework.Assert.IsTrue(permissions.IsFillInAllowed());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void MultipleActionsArePresentedTest() {
|
||||
PdfDictionary dict = new PdfDictionary();
|
||||
PdfArray references = new PdfArray();
|
||||
PdfDictionary dictWithAction = new PdfDictionary();
|
||||
PdfDictionary @params = new PdfDictionary();
|
||||
PdfName action = new PdfName("Name");
|
||||
PdfArray fields = new PdfArray();
|
||||
fields.Add(new PdfString("Value1"));
|
||||
fields.Add(new PdfString("Value2"));
|
||||
@params.Put(PdfName.Action, action);
|
||||
@params.Put(PdfName.Fields, fields);
|
||||
dictWithAction.Put(PdfName.TransformParams, @params);
|
||||
references.Add(dictWithAction);
|
||||
references.Add(dictWithAction);
|
||||
references.Add(dictWithAction);
|
||||
dict.Put(PdfName.Reference, references);
|
||||
SignaturePermissions permissions = new SignaturePermissions(dict, null);
|
||||
NUnit.Framework.Assert.AreEqual(3, permissions.GetFieldLocks().Count);
|
||||
foreach (SignaturePermissions.FieldLock fieldLock in permissions.GetFieldLocks()) {
|
||||
NUnit.Framework.Assert.AreEqual(action, fieldLock.GetAction());
|
||||
NUnit.Framework.Assert.AreEqual(fields, fieldLock.GetFields());
|
||||
}
|
||||
NUnit.Framework.Assert.IsTrue(permissions.IsAnnotationsAllowed());
|
||||
NUnit.Framework.Assert.IsFalse(permissions.IsCertification());
|
||||
NUnit.Framework.Assert.IsTrue(permissions.IsFillInAllowed());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void PParamEqualsTo1Test() {
|
||||
PdfDictionary dict = new PdfDictionary();
|
||||
PdfArray references = new PdfArray();
|
||||
PdfDictionary dictWithAction = new PdfDictionary();
|
||||
PdfDictionary @params = new PdfDictionary();
|
||||
@params.Put(PdfName.P, new PdfNumber(1));
|
||||
dictWithAction.Put(PdfName.TransformParams, @params);
|
||||
references.Add(dictWithAction);
|
||||
dict.Put(PdfName.Reference, references);
|
||||
SignaturePermissions permissions = new SignaturePermissions(dict, null);
|
||||
NUnit.Framework.Assert.IsFalse(permissions.IsFillInAllowed());
|
||||
NUnit.Framework.Assert.IsFalse(permissions.IsAnnotationsAllowed());
|
||||
NUnit.Framework.Assert.AreEqual(new List<Object>(), permissions.GetFieldLocks());
|
||||
NUnit.Framework.Assert.IsFalse(permissions.IsCertification());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void PParamEqualsTo2Test() {
|
||||
PdfDictionary dict = new PdfDictionary();
|
||||
PdfArray references = new PdfArray();
|
||||
PdfDictionary dictWithAction = new PdfDictionary();
|
||||
PdfDictionary @params = new PdfDictionary();
|
||||
@params.Put(PdfName.P, new PdfNumber(2));
|
||||
dictWithAction.Put(PdfName.TransformParams, @params);
|
||||
references.Add(dictWithAction);
|
||||
dict.Put(PdfName.Reference, references);
|
||||
SignaturePermissions permissions = new SignaturePermissions(dict, null);
|
||||
NUnit.Framework.Assert.IsFalse(permissions.IsAnnotationsAllowed());
|
||||
NUnit.Framework.Assert.AreEqual(new List<Object>(), permissions.GetFieldLocks());
|
||||
NUnit.Framework.Assert.IsTrue(permissions.IsFillInAllowed());
|
||||
NUnit.Framework.Assert.IsFalse(permissions.IsCertification());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void PreviousIsSetTest() {
|
||||
PdfDictionary previousDict = new PdfDictionary();
|
||||
PdfArray references = new PdfArray();
|
||||
PdfDictionary dictWithAction = new PdfDictionary();
|
||||
PdfDictionary @params = new PdfDictionary();
|
||||
@params.Put(PdfName.P, new PdfNumber(1));
|
||||
PdfName action = new PdfName("Name");
|
||||
PdfArray fields = new PdfArray();
|
||||
fields.Add(new PdfString("Value1"));
|
||||
fields.Add(new PdfString("Value2"));
|
||||
@params.Put(PdfName.Action, action);
|
||||
@params.Put(PdfName.Fields, fields);
|
||||
dictWithAction.Put(PdfName.TransformParams, @params);
|
||||
references.Add(dictWithAction);
|
||||
previousDict.Put(PdfName.Reference, references);
|
||||
SignaturePermissions previousPermissions = new SignaturePermissions(previousDict, null);
|
||||
SignaturePermissions permissions = new SignaturePermissions(new PdfDictionary(), previousPermissions);
|
||||
NUnit.Framework.Assert.AreEqual(1, permissions.GetFieldLocks().Count);
|
||||
SignaturePermissions.FieldLock fieldLock = permissions.GetFieldLocks()[0];
|
||||
NUnit.Framework.Assert.AreEqual(action, fieldLock.GetAction());
|
||||
NUnit.Framework.Assert.AreEqual(fields, fieldLock.GetFields());
|
||||
NUnit.Framework.Assert.IsFalse(permissions.IsAnnotationsAllowed());
|
||||
NUnit.Framework.Assert.IsFalse(permissions.IsCertification());
|
||||
NUnit.Framework.Assert.IsFalse(permissions.IsFillInAllowed());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1.Esf;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1.X509;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
[NUnit.Framework.Category("BouncyCastleUnitTest")]
|
||||
public class SignaturePolicyInfoTest : ExtendedTSpdfTest {
|
||||
private static readonly IBouncyCastleFactory BOUNCY_CASTLE_FACTORY = BouncyCastleFactoryCreator.GetFactory
|
||||
();
|
||||
|
||||
private const String POLICY_IDENTIFIER = "2.16.724.1.3.1.1.2.1.9";
|
||||
|
||||
private const String POLICY_HASH_BASE64 = "G7roucf600+f03r/o0bAOQ6WAs0=";
|
||||
|
||||
private static readonly byte[] POLICY_HASH = Convert.FromBase64String(POLICY_HASH_BASE64);
|
||||
|
||||
private const String POLICY_DIGEST_ALGORITHM = "SHA-256";
|
||||
|
||||
private const String POLICY_URI = "https://sede.060.gob.es/politica_de_firma_anexo_1.pdf";
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void CheckConstructorTest() {
|
||||
SignaturePolicyInfo info = new SignaturePolicyInfo(POLICY_IDENTIFIER, POLICY_HASH, POLICY_DIGEST_ALGORITHM
|
||||
, POLICY_URI);
|
||||
NUnit.Framework.Assert.AreEqual(POLICY_IDENTIFIER, info.GetPolicyIdentifier());
|
||||
NUnit.Framework.Assert.AreEqual(POLICY_HASH, info.GetPolicyHash());
|
||||
NUnit.Framework.Assert.AreEqual(POLICY_DIGEST_ALGORITHM, info.GetPolicyDigestAlgorithm());
|
||||
NUnit.Framework.Assert.AreEqual(POLICY_URI, info.GetPolicyUri());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void CheckConstructorWithEncodedHashTest() {
|
||||
SignaturePolicyInfo info = new SignaturePolicyInfo(POLICY_IDENTIFIER, POLICY_HASH_BASE64, POLICY_DIGEST_ALGORITHM
|
||||
, POLICY_URI);
|
||||
NUnit.Framework.Assert.AreEqual(POLICY_IDENTIFIER, info.GetPolicyIdentifier());
|
||||
NUnit.Framework.Assert.AreEqual(POLICY_HASH, info.GetPolicyHash());
|
||||
NUnit.Framework.Assert.AreEqual(POLICY_DIGEST_ALGORITHM, info.GetPolicyDigestAlgorithm());
|
||||
NUnit.Framework.Assert.AreEqual(POLICY_URI, info.GetPolicyUri());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void NullIdentifierIsNotAllowedTest() {
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(ArgumentException), () => new SignaturePolicyInfo(null,
|
||||
POLICY_HASH, POLICY_DIGEST_ALGORITHM, POLICY_URI));
|
||||
NUnit.Framework.Assert.AreEqual("Policy identifier cannot be null", e.Message);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void EmptyIdentifierIsNotAllowedTest() {
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(ArgumentException), () => new SignaturePolicyInfo("", POLICY_HASH
|
||||
, POLICY_DIGEST_ALGORITHM, POLICY_URI));
|
||||
NUnit.Framework.Assert.AreEqual("Policy identifier cannot be null", e.Message);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void NullPolicyHashIsNotAllowedTest() {
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(ArgumentException), () => new SignaturePolicyInfo(POLICY_IDENTIFIER
|
||||
, (byte[])null, POLICY_DIGEST_ALGORITHM, POLICY_URI));
|
||||
NUnit.Framework.Assert.AreEqual("Policy hash cannot be null", e.Message);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void NullEncodedPolicyHashIsNotAllowedTest() {
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(ArgumentException), () => new SignaturePolicyInfo(POLICY_IDENTIFIER
|
||||
, (String)null, POLICY_DIGEST_ALGORITHM, POLICY_URI));
|
||||
NUnit.Framework.Assert.AreEqual("Policy hash cannot be null", e.Message);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void NullDigestAlgorithmIsNotAllowedTest() {
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(ArgumentException), () => new SignaturePolicyInfo(POLICY_IDENTIFIER
|
||||
, POLICY_HASH, null, POLICY_URI));
|
||||
NUnit.Framework.Assert.AreEqual("Policy digest algorithm cannot be null", e.Message);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void EmptyDigestAlgorithmIsNotAllowedTest() {
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(ArgumentException), () => new SignaturePolicyInfo(POLICY_IDENTIFIER
|
||||
, POLICY_HASH, "", POLICY_URI));
|
||||
NUnit.Framework.Assert.AreEqual("Policy digest algorithm cannot be null", e.Message);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ToSignaturePolicyIdentifierTest() {
|
||||
ISignaturePolicyIdentifier actual = new SignaturePolicyInfo(POLICY_IDENTIFIER, POLICY_HASH, POLICY_DIGEST_ALGORITHM
|
||||
, POLICY_URI).ToSignaturePolicyIdentifier();
|
||||
IDERIA5String deria5String = BOUNCY_CASTLE_FACTORY.CreateDERIA5String(POLICY_URI);
|
||||
ISigPolicyQualifierInfo sigPolicyQualifierInfo = BOUNCY_CASTLE_FACTORY.CreateSigPolicyQualifierInfo(BOUNCY_CASTLE_FACTORY
|
||||
.CreatePKCSObjectIdentifiers().GetIdSpqEtsUri(), deria5String);
|
||||
IDEROctetString derOctetString = BOUNCY_CASTLE_FACTORY.CreateDEROctetString(POLICY_HASH);
|
||||
String algId = DigestAlgorithms.GetAllowedDigest(POLICY_DIGEST_ALGORITHM);
|
||||
IASN1ObjectIdentifier asn1ObjectIdentifier = BOUNCY_CASTLE_FACTORY.CreateASN1ObjectIdentifier(algId);
|
||||
IAlgorithmIdentifier algorithmIdentifier = BOUNCY_CASTLE_FACTORY.CreateAlgorithmIdentifier(asn1ObjectIdentifier
|
||||
);
|
||||
IOtherHashAlgAndValue otherHashAlgAndValue = BOUNCY_CASTLE_FACTORY.CreateOtherHashAlgAndValue(algorithmIdentifier
|
||||
, derOctetString);
|
||||
IASN1ObjectIdentifier objectIdentifier = BOUNCY_CASTLE_FACTORY.CreateASN1ObjectIdentifier(POLICY_IDENTIFIER
|
||||
);
|
||||
IASN1ObjectIdentifier objectIdentifierInstance = BOUNCY_CASTLE_FACTORY.CreateASN1ObjectIdentifier(objectIdentifier
|
||||
);
|
||||
ISignaturePolicyId signaturePolicyId = BOUNCY_CASTLE_FACTORY.CreateSignaturePolicyId(objectIdentifierInstance
|
||||
, otherHashAlgAndValue, sigPolicyQualifierInfo);
|
||||
ISignaturePolicyIdentifier expected = BOUNCY_CASTLE_FACTORY.CreateSignaturePolicyIdentifier(signaturePolicyId
|
||||
);
|
||||
NUnit.Framework.Assert.AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ToSignaturePolicyIdentifierUnexpectedAlgorithmTest() {
|
||||
SignaturePolicyInfo info = new SignaturePolicyInfo(POLICY_IDENTIFIER, POLICY_HASH, "SHA-12345", POLICY_URI
|
||||
);
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(ArgumentException), () => info.ToSignaturePolicyIdentifier
|
||||
());
|
||||
NUnit.Framework.Assert.AreEqual("Invalid policy hash algorithm", e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Kernel.Exceptions;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
[NUnit.Framework.Category("BouncyCastleIntegrationTest")]
|
||||
public class SignatureUtilTest : ExtendedTSpdfTest {
|
||||
private static readonly String sourceFolder = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/SignatureUtilTest/";
|
||||
|
||||
private const double EPS = 0.001;
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetSignaturesTest01() {
|
||||
String inPdf = sourceFolder + "simpleSignature.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
IList<String> signatureNames = signatureUtil.GetSignatureNames();
|
||||
NUnit.Framework.Assert.AreEqual(1, signatureNames.Count);
|
||||
NUnit.Framework.Assert.AreEqual("Signature1", signatureNames[0]);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetSignaturesTest02() {
|
||||
String inPdf = sourceFolder + "simpleDocument.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
IList<String> signatureNames = signatureUtil.GetSignatureNames();
|
||||
NUnit.Framework.Assert.AreEqual(0, signatureNames.Count);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void FirstBytesNotCoveredTest01() {
|
||||
String inPdf = sourceFolder + "firstBytesNotCoveredTest01.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
NUnit.Framework.Assert.IsFalse(signatureUtil.SignatureCoversWholeDocument("Signature1"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void LastBytesNotCoveredTest01() {
|
||||
String inPdf = sourceFolder + "lastBytesNotCoveredTest01.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
NUnit.Framework.Assert.IsFalse(signatureUtil.SignatureCoversWholeDocument("Signature1"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void LastBytesNotCoveredTest02() {
|
||||
String inPdf = sourceFolder + "lastBytesNotCoveredTest02.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
NUnit.Framework.Assert.IsFalse(signatureUtil.SignatureCoversWholeDocument("Signature1"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void BytesAreNotCoveredTest01() {
|
||||
String inPdf = sourceFolder + "bytesAreNotCoveredTest01.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
NUnit.Framework.Assert.IsFalse(signatureUtil.SignatureCoversWholeDocument("Signature1"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void BytesAreCoveredTest01() {
|
||||
String inPdf = sourceFolder + "bytesAreCoveredTest01.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
NUnit.Framework.Assert.IsTrue(signatureUtil.SignatureCoversWholeDocument("Signature1"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void BytesAreCoveredTest02() {
|
||||
String inPdf = sourceFolder + "bytesAreCoveredTest02.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
NUnit.Framework.Assert.IsTrue(signatureUtil.SignatureCoversWholeDocument("sig"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TwoContentsTest01() {
|
||||
String inPdf = sourceFolder + "twoContentsTest01.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
NUnit.Framework.Assert.IsTrue(signatureUtil.SignatureCoversWholeDocument("Signature1"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SpacesBeforeContentsTest01() {
|
||||
String inPdf = sourceFolder + "spacesBeforeContentsTest01.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
NUnit.Framework.Assert.IsFalse(signatureUtil.SignatureCoversWholeDocument("Signature1"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SpacesBeforeContentsTest02() {
|
||||
String inPdf = sourceFolder + "spacesBeforeContentsTest02.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
NUnit.Framework.Assert.IsTrue(signatureUtil.SignatureCoversWholeDocument("Signature1"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void NotIndirectSigDictionaryTest() {
|
||||
String inPdf = sourceFolder + "notIndirectSigDictionaryTest.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
NUnit.Framework.Assert.IsTrue(signatureUtil.SignatureCoversWholeDocument("Signature1"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void EmptySignatureReadSignatureDataTest() {
|
||||
String inPdf = sourceFolder + "emptySignature.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
NUnit.Framework.Assert.IsNull(signatureUtil.ReadSignatureData("Signature1"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ReadSignatureDataTest() {
|
||||
String inPdf = sourceFolder + "simpleSignature.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
PdfPKCS7 pkcs7 = signatureUtil.ReadSignatureData("Signature1");
|
||||
NUnit.Framework.Assert.IsNotNull(pkcs7);
|
||||
NUnit.Framework.Assert.AreEqual("Test 1", pkcs7.GetReason());
|
||||
NUnit.Framework.Assert.IsNull(pkcs7.GetSignName());
|
||||
NUnit.Framework.Assert.AreEqual("TestCity", pkcs7.GetLocation());
|
||||
// The number corresponds to 18 May, 2021 17:23:59.
|
||||
double expectedMillis = (double)1621347839000L;
|
||||
NUnit.Framework.Assert.AreEqual(TimeTestUtil.GetFullDaysMillis(expectedMillis), TimeTestUtil.GetFullDaysMillis
|
||||
(DateTimeUtil.GetUtcMillisFromEpoch(pkcs7.GetSignDate())), EPS);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ReadSignatureDataWithSpecialSubFilterTest() {
|
||||
String inPdf = sourceFolder + "adbe.x509.rsa_sha1_signature.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
PdfPKCS7 pkcs7 = signatureUtil.ReadSignatureData("Signature1");
|
||||
NUnit.Framework.Assert.IsNotNull(pkcs7);
|
||||
NUnit.Framework.Assert.IsNotNull(pkcs7);
|
||||
NUnit.Framework.Assert.AreEqual("Test", pkcs7.GetReason());
|
||||
NUnit.Framework.Assert.IsNull(pkcs7.GetSignName());
|
||||
NUnit.Framework.Assert.AreEqual("TestCity", pkcs7.GetLocation());
|
||||
// The number corresponds to 18 May, 2021 11:28:40.
|
||||
double expectedMillis = (double)1621326520000L;
|
||||
NUnit.Framework.Assert.AreEqual(TimeTestUtil.GetFullDaysMillis(expectedMillis), TimeTestUtil.GetFullDaysMillis
|
||||
(DateTimeUtil.GetUtcMillisFromEpoch(pkcs7.GetSignDate())), EPS);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ByteRangeAndContentsEntriesTest() {
|
||||
String inPdf = sourceFolder + "byteRangeAndContentsEntries.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
NUnit.Framework.Assert.Catch(typeof(PdfException), () => signatureUtil.ReadSignatureData("Signature1"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void DoesSignatureFieldExistTest() {
|
||||
String inPdf = sourceFolder + "simpleSignature.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
NUnit.Framework.Assert.IsTrue(signatureUtil.DoesSignatureFieldExist("Signature1"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void DoesSignatureFieldExistEmptySignatureTest() {
|
||||
String inPdf = sourceFolder + "emptySignature.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
NUnit.Framework.Assert.IsTrue(signatureUtil.DoesSignatureFieldExist("Signature1"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignatureInTextTypeFieldTest() {
|
||||
String inPdf = sourceFolder + "signatureInTextTypeField.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
NUnit.Framework.Assert.IsFalse(signatureUtil.DoesSignatureFieldExist("Signature1"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetTotalRevisionsTest() {
|
||||
String inPdf = sourceFolder + "simpleSignature.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
NUnit.Framework.Assert.AreEqual(1, signatureUtil.GetTotalRevisions());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetRevisionTest() {
|
||||
String inPdf = sourceFolder + "simpleSignature.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
NUnit.Framework.Assert.AreEqual(1, signatureUtil.GetRevision("Signature1"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetRevisionEmptyFieldsTest() {
|
||||
String inPdf = sourceFolder + "emptySignature.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
NUnit.Framework.Assert.AreEqual(0, signatureUtil.GetRevision("Signature1"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetRevisionXfaFormTest() {
|
||||
String inPdf = sourceFolder + "simpleSignatureWithXfa.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
NUnit.Framework.Assert.AreEqual(1, signatureUtil.GetRevision("Signature1"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ExtractRevisionTest() {
|
||||
String inPdf = sourceFolder + "simpleSignature.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
NUnit.Framework.Assert.IsNotNull(signatureUtil.ExtractRevision("Signature1"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ExtractRevisionNotSignatureFieldTest() {
|
||||
String inPdf = sourceFolder + "signatureInTextTypeField.pdf";
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inPdf));
|
||||
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
|
||||
NUnit.Framework.Assert.IsNull(signatureUtil.ExtractRevision("Signature1"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System.IO;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
[NUnit.Framework.Category("UnitTest")]
|
||||
public class SignatureUtilUnitTest : ExtendedTSpdfTest {
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignatureCoversWholeDocumentBlankDocTest() {
|
||||
bool covers;
|
||||
using (PdfDocument blankDoc = new PdfDocument(new PdfWriter(new MemoryStream()))) {
|
||||
SignatureUtil signatureUtil = new SignatureUtil(blankDoc);
|
||||
covers = signatureUtil.SignatureCoversWholeDocument("sign");
|
||||
}
|
||||
NUnit.Framework.Assert.IsFalse(covers);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
/// <summary>Class for internal usage in tests.</summary>
|
||||
public sealed class SignaturesTestUtils {
|
||||
private const String EXPIRED_CERTIFICATE_DATE_PREFIX_MESSAGE = "certificate expired on ";
|
||||
|
||||
private SignaturesTestUtils() {
|
||||
}
|
||||
|
||||
// Empty constructor.
|
||||
/// <summary>Creates string which should be return while validating expired certificate.</summary>
|
||||
/// <param name="certificate">certificate for validation.</param>
|
||||
/// <returns>expected string.</returns>
|
||||
public static String GetExpiredMessage(IX509Certificate certificate) {
|
||||
return EXPIRED_CERTIFICATE_DATE_PREFIX_MESSAGE + certificate.GetEndDateTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Bouncycastle.Tsp;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Kernel.Exceptions;
|
||||
using TSpdf.Signatures.Exceptions;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Signatures.Testutils.Builder;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
[NUnit.Framework.Category("BouncyCastleUnitTest")]
|
||||
public class TSAClientBouncyCastleTest : ExtendedTSpdfTest {
|
||||
private static readonly IBouncyCastleFactory BOUNCY_CASTLE_FACTORY = BouncyCastleFactoryCreator.GetFactory
|
||||
();
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SetTSAInfoTest() {
|
||||
TSAClientBouncyCastle clientBouncyCastle = new TSAClientBouncyCastle("url");
|
||||
TSAClientBouncyCastleTest.CustomItsaInfoBouncyCastle infoBouncyCastle = new TSAClientBouncyCastleTest.CustomItsaInfoBouncyCastle
|
||||
();
|
||||
clientBouncyCastle.SetTSAInfo(infoBouncyCastle);
|
||||
NUnit.Framework.Assert.AreEqual(infoBouncyCastle, clientBouncyCastle.tsaInfo);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TestTsaClientBouncyCastleConstructor3Args() {
|
||||
String userName = "user";
|
||||
String password = "password";
|
||||
String url = "url";
|
||||
TSAClientBouncyCastle tsaClientBouncyCastle = new TSAClientBouncyCastle(url, userName, password);
|
||||
NUnit.Framework.Assert.AreEqual(url, tsaClientBouncyCastle.tsaURL);
|
||||
NUnit.Framework.Assert.AreEqual(userName, tsaClientBouncyCastle.tsaUsername);
|
||||
NUnit.Framework.Assert.AreEqual(password, tsaClientBouncyCastle.tsaPassword);
|
||||
NUnit.Framework.Assert.AreEqual(TSAClientBouncyCastle.DEFAULTTOKENSIZE, tsaClientBouncyCastle.tokenSizeEstimate
|
||||
);
|
||||
NUnit.Framework.Assert.AreEqual(TSAClientBouncyCastle.DEFAULTHASHALGORITHM, tsaClientBouncyCastle.digestAlgorithm
|
||||
);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TestTsaClientBouncyCastleConstructorAllArgs() {
|
||||
String userName = "user";
|
||||
String password = "password";
|
||||
String url = "url";
|
||||
int tokenSize = 1024;
|
||||
String digestAlgorithm = "SHA-1";
|
||||
TSAClientBouncyCastle tsaClientBouncyCastle = new TSAClientBouncyCastle(url, userName, password, tokenSize
|
||||
, digestAlgorithm);
|
||||
NUnit.Framework.Assert.AreEqual(url, tsaClientBouncyCastle.tsaURL);
|
||||
NUnit.Framework.Assert.AreEqual(userName, tsaClientBouncyCastle.tsaUsername);
|
||||
NUnit.Framework.Assert.AreEqual(password, tsaClientBouncyCastle.tsaPassword);
|
||||
NUnit.Framework.Assert.AreEqual(tokenSize, tsaClientBouncyCastle.tokenSizeEstimate);
|
||||
NUnit.Framework.Assert.AreEqual(digestAlgorithm, tsaClientBouncyCastle.digestAlgorithm);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TestTsaClientBouncyCastleConstructor1Arg() {
|
||||
String url = "url";
|
||||
TSAClientBouncyCastle tsaClientBouncyCastle = new TSAClientBouncyCastle(url);
|
||||
NUnit.Framework.Assert.AreEqual(url, tsaClientBouncyCastle.tsaURL);
|
||||
NUnit.Framework.Assert.IsNull(tsaClientBouncyCastle.tsaUsername);
|
||||
NUnit.Framework.Assert.IsNull(tsaClientBouncyCastle.tsaPassword);
|
||||
NUnit.Framework.Assert.AreEqual(TSAClientBouncyCastle.DEFAULTTOKENSIZE, tsaClientBouncyCastle.tokenSizeEstimate
|
||||
);
|
||||
NUnit.Framework.Assert.AreEqual(TSAClientBouncyCastle.DEFAULTHASHALGORITHM, tsaClientBouncyCastle.digestAlgorithm
|
||||
);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetTokenSizeEstimateTest() {
|
||||
String userName = "user";
|
||||
String password = "password";
|
||||
String url = "url";
|
||||
String digestAlgorithm = "SHA-256";
|
||||
int tokenSizeEstimate = 4096;
|
||||
TSAClientBouncyCastle tsaClientBouncyCastle = new TSAClientBouncyCastle(url, userName, password, tokenSizeEstimate
|
||||
, digestAlgorithm);
|
||||
NUnit.Framework.Assert.AreEqual(tokenSizeEstimate, tsaClientBouncyCastle.GetTokenSizeEstimate());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SetGetTsaReqPolicyTest() {
|
||||
String regPolicy = "regPolicy";
|
||||
TSAClientBouncyCastle clientBouncyCastle = new TSAClientBouncyCastle("url");
|
||||
clientBouncyCastle.SetTSAReqPolicy(regPolicy);
|
||||
NUnit.Framework.Assert.AreEqual(regPolicy, clientBouncyCastle.GetTSAReqPolicy());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetMessageDigestTest() {
|
||||
String userName = "user";
|
||||
String password = "password";
|
||||
String url = "url";
|
||||
String digestAlgorithm = "SHA-256";
|
||||
int tokenSizeEstimate = 4096;
|
||||
TSAClientBouncyCastle tsaClientBouncyCastle = new TSAClientBouncyCastle(url, userName, password, tokenSizeEstimate
|
||||
, digestAlgorithm);
|
||||
IIDigest digest = tsaClientBouncyCastle.GetMessageDigest();
|
||||
NUnit.Framework.Assert.IsNotNull(digest);
|
||||
NUnit.Framework.Assert.AreEqual(digestAlgorithm, digest.GetAlgorithmName());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetTimeStampTokenTest() {
|
||||
String allowedDigest = "SHA256";
|
||||
String signatureAlgorithm = "SHA256withRSA";
|
||||
String policyOid = "1.3.6.1.4.1.45794.1.1";
|
||||
TSAClientBouncyCastleTest.CustomTsaClientBouncyCastle tsaClientBouncyCastle = new TSAClientBouncyCastleTest.CustomTsaClientBouncyCastle
|
||||
("", signatureAlgorithm, allowedDigest);
|
||||
tsaClientBouncyCastle.SetTSAReqPolicy(policyOid);
|
||||
TSAClientBouncyCastleTest.CustomItsaInfoBouncyCastle itsaInfoBouncyCastle = new TSAClientBouncyCastleTest.CustomItsaInfoBouncyCastle
|
||||
();
|
||||
tsaClientBouncyCastle.SetTSAInfo(itsaInfoBouncyCastle);
|
||||
byte[] timestampTokenArray = tsaClientBouncyCastle.GetTimeStampToken(tsaClientBouncyCastle.GetMessageDigest
|
||||
().Digest());
|
||||
ITimeStampToken expectedToken = BOUNCY_CASTLE_FACTORY.CreateTimeStampResponse(tsaClientBouncyCastle.GetExpectedTsaResponseBytes
|
||||
()).GetTimeStampToken();
|
||||
ITimeStampTokenInfo expectedTsTokenInfo = expectedToken.GetTimeStampInfo();
|
||||
ITimeStampTokenInfo resultTsTokenInfo = itsaInfoBouncyCastle.GetTimeStampTokenInfo();
|
||||
NUnit.Framework.Assert.IsNotNull(timestampTokenArray);
|
||||
NUnit.Framework.Assert.IsNotNull(resultTsTokenInfo);
|
||||
NUnit.Framework.Assert.AreEqual(expectedTsTokenInfo.GetEncoded(), resultTsTokenInfo.GetEncoded());
|
||||
NUnit.Framework.Assert.AreEqual(expectedToken.GetEncoded(), timestampTokenArray);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetTimeStampTokenFailureExceptionTest() {
|
||||
String allowedDigest = "SHA1";
|
||||
String signatureAlgorithm = "SHA256withRSA";
|
||||
String url = "url";
|
||||
TSAClientBouncyCastleTest.CustomTsaClientBouncyCastle tsaClientBouncyCastle = new TSAClientBouncyCastleTest.CustomTsaClientBouncyCastle
|
||||
(url, signatureAlgorithm, allowedDigest);
|
||||
tsaClientBouncyCastle.SetTSAInfo(new TSAClientBouncyCastleTest.CustomItsaInfoBouncyCastle());
|
||||
byte[] digest = tsaClientBouncyCastle.GetMessageDigest().Digest();
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(PdfException), () => tsaClientBouncyCastle.GetTimeStampToken
|
||||
(digest));
|
||||
NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(SignExceptionMessageConstant.INVALID_TSA_RESPONSE
|
||||
, url, "128"), e.Message);
|
||||
}
|
||||
|
||||
private sealed class CustomTsaClientBouncyCastle : TSAClientBouncyCastle {
|
||||
private static readonly char[] PASSWORD = "testpassphrase".ToCharArray();
|
||||
|
||||
private static readonly String CERTS_SRC = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/";
|
||||
|
||||
private readonly IPrivateKey tsaPrivateKey;
|
||||
|
||||
private readonly IList<IX509Certificate> tsaCertificateChain;
|
||||
|
||||
private readonly String signatureAlgorithm;
|
||||
|
||||
private readonly String allowedDigest;
|
||||
|
||||
private byte[] expectedTsaResponseBytes;
|
||||
|
||||
public CustomTsaClientBouncyCastle(String url, String signatureAlgorithm, String allowedDigest)
|
||||
: base(url) {
|
||||
this.signatureAlgorithm = signatureAlgorithm;
|
||||
this.allowedDigest = allowedDigest;
|
||||
tsaPrivateKey = PemFileHelper.ReadFirstKey(CERTS_SRC + "signCertRsa01.pem", PASSWORD);
|
||||
String tsaCertFileName = CERTS_SRC + "tsCertRsa.pem";
|
||||
tsaCertificateChain = JavaUtil.ArraysAsList(PemFileHelper.ReadFirstChain(tsaCertFileName));
|
||||
}
|
||||
|
||||
public byte[] GetExpectedTsaResponseBytes() {
|
||||
return expectedTsaResponseBytes;
|
||||
}
|
||||
|
||||
protected internal override byte[] GetTSAResponse(byte[] requestBytes) {
|
||||
TestTimestampTokenBuilder builder = new TestTimestampTokenBuilder(tsaCertificateChain, tsaPrivateKey);
|
||||
expectedTsaResponseBytes = builder.CreateTSAResponse(requestBytes, signatureAlgorithm, allowedDigest);
|
||||
return expectedTsaResponseBytes;
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class CustomItsaInfoBouncyCastle : ITSAInfoBouncyCastle {
|
||||
private ITimeStampTokenInfo timeStampTokenInfo;
|
||||
|
||||
public void InspectTimeStampTokenInfo(ITimeStampTokenInfo info) {
|
||||
this.timeStampTokenInfo = info;
|
||||
}
|
||||
|
||||
public ITimeStampTokenInfo GetTimeStampTokenInfo() {
|
||||
return timeStampTokenInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures {
|
||||
[NUnit.Framework.Category("UnitTest")]
|
||||
public class VerificationOKTest : ExtendedTSpdfTest {
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ToStringTest() {
|
||||
VerificationOK verificationOK = new VerificationOK(null, typeof(CRLVerifier), "Mock verification");
|
||||
NUnit.Framework.Assert.AreEqual(typeof(CRLVerifier).FullName + ": Mock verification", verificationOK.ToString
|
||||
());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ToStringWithCertificateNotNullTest() {
|
||||
VerificationOK verificationOK = new VerificationOK(new X509MockCertificate(), typeof(CRLVerifier), "Mock verification"
|
||||
);
|
||||
// NPE is thrown because getSubjectDN method returns null for X509MockCertificate class.
|
||||
NUnit.Framework.Assert.Catch(typeof(NullReferenceException), () => verificationOK.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Kernel.Geom;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Kernel.Utils;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures.Sign {
|
||||
[NUnit.Framework.Category("BouncyCastleIntegrationTest")]
|
||||
public class AnnotationsSigningTest : ExtendedTSpdfTest {
|
||||
private static readonly String SOURCE_FOLDER = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/sign/AnnotationsSigningTest/";
|
||||
|
||||
private static readonly String DESTINATION_FOLDER = NUnit.Framework.TestContext.CurrentContext.TestDirectory
|
||||
+ "/test/TSpdf/signatures/sign/AnnotationsSigningTest/";
|
||||
|
||||
private static readonly String CERTS_SRC = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/";
|
||||
|
||||
private static readonly char[] PASSWORD = "testpassphrase".ToCharArray();
|
||||
|
||||
private IX509Certificate[] chain;
|
||||
|
||||
private IPrivateKey pk;
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
CreateOrClearDestinationFolder(DESTINATION_FOLDER);
|
||||
}
|
||||
|
||||
[NUnit.Framework.SetUp]
|
||||
public virtual void Init() {
|
||||
pk = PemFileHelper.ReadFirstKey(CERTS_SRC + "signCertRsa01.pem", PASSWORD);
|
||||
chain = PemFileHelper.ReadFirstChain(CERTS_SRC + "signCertRsa01.pem");
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SigningDocumentAppendModeIndirectPageAnnotsTest() {
|
||||
String srcFile = SOURCE_FOLDER + "annotsIndirect.pdf";
|
||||
String cmpPdf = SOURCE_FOLDER + "cmp_annotsIndirect.pdf";
|
||||
String outPdf = DESTINATION_FOLDER + "annotsIndirect";
|
||||
Rectangle rect = new Rectangle(30, 200, 200, 100);
|
||||
String fieldName = "Signature1";
|
||||
Sign(srcFile, fieldName, outPdf, chain, pk, DigestAlgorithms.SHA256, PdfSigner.CryptoStandard.CADES, "Test 1"
|
||||
, "TestCity", rect, false, true, PdfSigner.NOT_CERTIFIED, 12f);
|
||||
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(outPdf, cmpPdf, DESTINATION_FOLDER, "diff_"
|
||||
, GetTestMap(rect)));
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outPdf, cmpPdf));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SigningIntoExistingFieldWithPKeyTest() {
|
||||
//field is merged with widget and has /P key
|
||||
String srcFile = SOURCE_FOLDER + "emptySignature01.pdf";
|
||||
String cmpPdf = SOURCE_FOLDER + "cmp_emptySignature01.pdf";
|
||||
String outPdf = DESTINATION_FOLDER + "emptySignature01.pdf";
|
||||
String fieldName = "Signature1";
|
||||
Sign(srcFile, fieldName, outPdf, chain, pk, DigestAlgorithms.SHA256, PdfSigner.CryptoStandard.CADES, "Test 1"
|
||||
, "TestCity", null, false, false, PdfSigner.NOT_CERTIFIED, 12f);
|
||||
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(outPdf, cmpPdf, DESTINATION_FOLDER, "diff_"
|
||||
, GetTestMap(new Rectangle(41, 693, 237, 781))));
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outPdf, cmpPdf));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SigningIntoExistingFieldWithoutPKeyTest() {
|
||||
//field is merged with widget and widget doesn't have /P key
|
||||
String srcFile = SOURCE_FOLDER + "emptySignature02.pdf";
|
||||
String cmpPdf = SOURCE_FOLDER + "cmp_emptySignature02.pdf";
|
||||
String outPdf = DESTINATION_FOLDER + "emptySignature02.pdf";
|
||||
String fieldName = "Signature1";
|
||||
Sign(srcFile, fieldName, outPdf, chain, pk, DigestAlgorithms.SHA256, PdfSigner.CryptoStandard.CADES, "Test 1"
|
||||
, "TestCity", null, false, false, PdfSigner.NOT_CERTIFIED, 12f);
|
||||
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(outPdf, cmpPdf, DESTINATION_FOLDER, "diff_"
|
||||
, GetTestMap(new Rectangle(41, 693, 237, 781))));
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outPdf, cmpPdf));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SigningIntoExistingReuseAppearanceTest() {
|
||||
String srcFile = SOURCE_FOLDER + "emptySigWithAppearance.pdf";
|
||||
String cmpPdf = SOURCE_FOLDER + "cmp_emptySigWithAppearance.pdf";
|
||||
String outPdf = DESTINATION_FOLDER + "emptySigWithAppearance.pdf";
|
||||
String fieldName = "Signature1";
|
||||
Sign(srcFile, fieldName, outPdf, chain, pk, DigestAlgorithms.SHA256, PdfSigner.CryptoStandard.CADES, "Test 1"
|
||||
, "TestCity", null, true, false);
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outPdf, cmpPdf));
|
||||
}
|
||||
|
||||
protected internal virtual void Sign(String src, String name, String dest, IX509Certificate[] chain, IPrivateKey
|
||||
pk, String digestAlgorithm, PdfSigner.CryptoStandard subfilter, String reason, String location, Rectangle
|
||||
rectangleForNewField, bool setReuseAppearance, bool isAppendMode) {
|
||||
Sign(src, name, dest, chain, pk, digestAlgorithm, subfilter, reason, location, rectangleForNewField, setReuseAppearance
|
||||
, isAppendMode, PdfSigner.NOT_CERTIFIED, null);
|
||||
}
|
||||
|
||||
protected internal virtual void Sign(String src, String name, String dest, IX509Certificate[] chain, IPrivateKey
|
||||
pk, String digestAlgorithm, PdfSigner.CryptoStandard subfilter, String reason, String location, Rectangle
|
||||
rectangleForNewField, bool setReuseAppearance, bool isAppendMode, int certificationLevel, float? fontSize
|
||||
) {
|
||||
PdfReader reader = new PdfReader(src);
|
||||
StampingProperties properties = new StampingProperties();
|
||||
if (isAppendMode) {
|
||||
properties.UseAppendMode();
|
||||
}
|
||||
PdfSigner signer = new PdfSigner(reader, new FileStream(dest, FileMode.Create), properties);
|
||||
signer.SetCertificationLevel(certificationLevel);
|
||||
// Creating the appearance
|
||||
PdfSignatureAppearance appearance = signer.GetSignatureAppearance().SetReason(reason).SetLocation(location
|
||||
).SetReuseAppearance(setReuseAppearance);
|
||||
if (rectangleForNewField != null) {
|
||||
appearance.SetPageRect(rectangleForNewField);
|
||||
}
|
||||
if (fontSize != null) {
|
||||
appearance.SetLayer2FontSize((float)fontSize);
|
||||
}
|
||||
signer.SetFieldName(name);
|
||||
// Creating the signature
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, subfilter);
|
||||
}
|
||||
|
||||
private static IDictionary<int, IList<Rectangle>> GetTestMap(Rectangle ignoredArea) {
|
||||
IDictionary<int, IList<Rectangle>> result = new Dictionary<int, IList<Rectangle>>();
|
||||
result.Put(1, JavaUtil.ArraysAsList(ignoredArea));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Kernel.Crypto;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Test;
|
||||
using TSpdf.Test.Attributes;
|
||||
|
||||
namespace TSpdf.Signatures.Sign {
|
||||
[NUnit.Framework.Category("BouncyCastleUnitTest")]
|
||||
public class CrlClientOnlineTest : ExtendedTSpdfTest {
|
||||
private static readonly String certSrc = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/sign/CrlClientOnlineTest/";
|
||||
|
||||
private static readonly String certWithMalformedUrl = certSrc + "certWithMalformedUrl.crt";
|
||||
|
||||
private static readonly String certWithCorrectUrl = certSrc + "certWithCorrectUrl.crt";
|
||||
|
||||
private static readonly String destinationFolder = NUnit.Framework.TestContext.CurrentContext.TestDirectory
|
||||
+ "/test/TSpdf/signatures/sign/";
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void CrlClientOnlineURLConstructorTest() {
|
||||
String PROTOCOL = "file://";
|
||||
Uri[] urls = new Uri[] { new Uri(PROTOCOL + destinationFolder + "duplicateFolder"), new Uri(PROTOCOL + destinationFolder
|
||||
+ "duplicateFolder"), new Uri(PROTOCOL + destinationFolder + "uniqueFolder") };
|
||||
CrlClientOnline crlClientOnline = new CrlClientOnline(urls);
|
||||
NUnit.Framework.Assert.AreEqual(2, crlClientOnline.GetUrlsSize());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Added CRL url: https://examples.com", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void AddCrlUrlTest() {
|
||||
CrlClientOnline crlClientOnline = new CrlClientOnline("https://examples.com");
|
||||
NUnit.Framework.Assert.AreEqual(1, crlClientOnline.GetUrlsSize());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Skipped CRL url (malformed):", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void AddEmptyCrlUrlTest() {
|
||||
CrlClientOnline crlClientOnline = new CrlClientOnline("");
|
||||
NUnit.Framework.Assert.AreEqual(0, crlClientOnline.GetUrlsSize());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Skipped CRL url (malformed):", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void AddWrongCrlUrlTest() {
|
||||
CrlClientOnline crlClientOnline = new CrlClientOnline("test");
|
||||
NUnit.Framework.Assert.AreEqual(0, crlClientOnline.GetUrlsSize());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Checking certificate: ", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Skipped CRL url (malformed): test", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void CheckCrlCertWithMalformedUrlTest() {
|
||||
IX509Certificate chain = CryptoUtil.ReadPublicCertificate(new FileStream(certWithMalformedUrl, FileMode.Open
|
||||
, FileAccess.Read));
|
||||
CrlClientOnline crlClientOnline = new CrlClientOnline(new IX509Certificate[] { chain });
|
||||
NUnit.Framework.Assert.AreEqual(0, crlClientOnline.GetUrlsSize());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Checking certificate: ", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Added CRL url: http://www.example.com/crl/test.crl", LogLevel = LogLevelConstants.INFO)]
|
||||
public virtual void CheckCrlCertWithCorrectUrlTest() {
|
||||
IX509Certificate chain = CryptoUtil.ReadPublicCertificate(new FileStream(certWithCorrectUrl, FileMode.Open
|
||||
, FileAccess.Read));
|
||||
CrlClientOnline crlClientOnline = new CrlClientOnline(new IX509Certificate[] { chain });
|
||||
NUnit.Framework.Assert.AreEqual(1, crlClientOnline.GetUrlsSize());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void CannotGetEncodedWhenCertIsNullTest() {
|
||||
CrlClientOnline crlClientOnline = new CrlClientOnline();
|
||||
NUnit.Framework.Assert.IsNull(crlClientOnline.GetEncoded(null, ""));
|
||||
NUnit.Framework.Assert.AreEqual(0, crlClientOnline.GetUrlsSize());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Added CRL url: http://www.example.com/crl/test.crl", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Checking CRL: http://www.example.com/crl/test.crl", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage(TSpdf.IO.Logs.IoLogMessageConstant.INVALID_DISTRIBUTION_POINT, LogLevel = LogLevelConstants.INFO
|
||||
)]
|
||||
public virtual void UnreachableCrlDistributionPointTest() {
|
||||
CrlClientOnline crlClientOnline = new CrlClientOnline("http://www.example.com/crl/test.crl");
|
||||
IX509Certificate checkCert = new X509MockCertificate();
|
||||
ICollection<byte[]> bytes = crlClientOnline.GetEncoded(checkCert, "http://www.example.com/crl/test.crl");
|
||||
NUnit.Framework.Assert.IsTrue(bytes.IsEmpty());
|
||||
NUnit.Framework.Assert.AreEqual(1, crlClientOnline.GetUrlsSize());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("Looking for CRL for certificate ", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Found CRL url: http://www.example.com/crl/test.crl", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage("Checking CRL: http://www.example.com/crl/test.crl", LogLevel = LogLevelConstants.INFO)]
|
||||
[LogMessage(TSpdf.IO.Logs.IoLogMessageConstant.INVALID_DISTRIBUTION_POINT, LogLevel = LogLevelConstants.INFO
|
||||
)]
|
||||
public virtual void UnreachableCrlDistributionPointFromCertChainTest() {
|
||||
CrlClientOnline crlClientOnline = new CrlClientOnline();
|
||||
IX509Certificate checkCert = new X509MockCertificate();
|
||||
ICollection<byte[]> bytes = crlClientOnline.GetEncoded(checkCert, "http://www.example.com/crl/test.crl");
|
||||
NUnit.Framework.Assert.IsTrue(bytes.IsEmpty());
|
||||
NUnit.Framework.Assert.AreEqual(0, crlClientOnline.GetUrlsSize());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.IO;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Kernel.Logs;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Test;
|
||||
using TSpdf.Test.Attributes;
|
||||
|
||||
namespace TSpdf.Signatures.Sign {
|
||||
[NUnit.Framework.Category("BouncyCastleIntegrationTest")]
|
||||
public class EncryptedSigningTest : ExtendedTSpdfTest {
|
||||
private static readonly IBouncyCastleFactory FACTORY = BouncyCastleFactoryCreator.GetFactory();
|
||||
|
||||
private static readonly String SOURCE_FOLDER = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/sign/EncryptedSigningTest/";
|
||||
|
||||
private static readonly String DESTINATION_FOLDER = NUnit.Framework.TestContext.CurrentContext.TestDirectory
|
||||
+ "/test/TSpdf/signatures/sign/EncryptedSigningTest/";
|
||||
|
||||
private static readonly String CERTS_SRC = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/";
|
||||
|
||||
private static readonly char[] PASSWORD = "testpassphrase".ToCharArray();
|
||||
|
||||
private IX509Certificate[] chain;
|
||||
|
||||
private IPrivateKey pk;
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
CreateOrClearDestinationFolder(DESTINATION_FOLDER);
|
||||
}
|
||||
|
||||
[NUnit.Framework.SetUp]
|
||||
public virtual void Init() {
|
||||
pk = PemFileHelper.ReadFirstKey(CERTS_SRC + "signCertRsa01.pem", PASSWORD);
|
||||
chain = PemFileHelper.ReadFirstChain(CERTS_SRC + "signCertRsa01.pem");
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage(KernelLogMessageConstant.MD5_IS_NOT_FIPS_COMPLIANT, Ignore = true)]
|
||||
public virtual void SignEncryptedPdfTest() {
|
||||
String srcFile = SOURCE_FOLDER + "encrypted.pdf";
|
||||
String cmpPdf = SOURCE_FOLDER + "cmp_signedEncrypted.pdf";
|
||||
String outPdf = DESTINATION_FOLDER + "signedEncrypted.pdf";
|
||||
String fieldName = "Signature1";
|
||||
byte[] ownerPass = "World".GetBytes();
|
||||
PdfReader reader = new PdfReader(srcFile, new ReaderProperties().SetPassword(ownerPass));
|
||||
PdfSigner signer = new PdfSigner(reader, new FileStream(outPdf, FileMode.Create), new StampingProperties()
|
||||
.UseAppendMode());
|
||||
signer.SetFieldName(fieldName);
|
||||
// Creating the signature
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
|
||||
//Password to open out and cmp files are the same
|
||||
ReaderProperties properties = new ReaderProperties().SetPassword(ownerPass);
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outPdf, cmpPdf, properties, properties
|
||||
));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignCertificateSecurityPdfTest() {
|
||||
//RSA keys in FIPS are supported for signature verification only
|
||||
if (!FACTORY.GetProviderName().Contains("FIPS")) {
|
||||
String srcFile = SOURCE_FOLDER + "signCertificateSecurityPdf.pdf";
|
||||
String cmpPdf = SOURCE_FOLDER + "cmp_signCertificateSecurityPdf.pdf";
|
||||
String outPdf = DESTINATION_FOLDER + "signCertificateSecurityPdf.pdf";
|
||||
PdfReader reader = new PdfReader(srcFile, new ReaderProperties().SetPublicKeySecurityParams(chain[0], pk));
|
||||
PdfSigner signer = new PdfSigner(reader, new FileStream(outPdf, FileMode.Create), new StampingProperties()
|
||||
.UseAppendMode());
|
||||
// Creating the signature
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
|
||||
ReaderProperties properties = new ReaderProperties().SetPublicKeySecurityParams(chain[0], pk);
|
||||
//Public key to open out and cmp files are the same
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outPdf, cmpPdf, properties, properties
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.X9;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Kernel.Exceptions;
|
||||
using TSpdf.Kernel.Geom;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Test;
|
||||
using Org.BouncyCastle.Asn1.EdEC;
|
||||
using Org.BouncyCastle.Asn1.Nist;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
namespace TSpdf.Signatures.Sign {
|
||||
[NUnit.Framework.Category("IntegrationTest")]
|
||||
public class IsoSignatureExtensionsRoundtripTests : TSpdfTest {
|
||||
private static readonly IBouncyCastleFactory BOUNCY_CASTLE_FACTORY = BouncyCastleFactoryCreator.GetFactory
|
||||
();
|
||||
|
||||
private static readonly String SOURCE_FOLDER = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/sign/IsoSignatureExtensionsRoundtripTests/";
|
||||
|
||||
private static readonly String DESTINATION_FOLDER = NUnit.Framework.TestContext.CurrentContext.TestDirectory
|
||||
+ "/test/TSpdf/signatures/sign/IsoSignatureExtensionsRoundtripTests/";
|
||||
|
||||
private static readonly char[] SAMPLE_KEY_PASSPHRASE = "secret".ToCharArray();
|
||||
|
||||
private static readonly String SOURCE_FILE = SOURCE_FOLDER + "helloWorldDoc.pdf";
|
||||
|
||||
private const String SIGNATURE_FIELD = "Signature";
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
CreateOrClearDestinationFolder(DESTINATION_FOLDER);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TestEd25519() {
|
||||
if ("BCFIPS".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName())) {
|
||||
// algorithm identifier in key not recognised
|
||||
NUnit.Framework.Assert.Catch(typeof(KeyException), () => DoRoundTrip("ed25519", DigestAlgorithms.SHA512, EdECObjectIdentifiers.id_Ed25519));
|
||||
} else {
|
||||
DoRoundTrip("ed25519", DigestAlgorithms.SHA512, EdECObjectIdentifiers.id_Ed25519);
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TestEd448() {
|
||||
if ("BC".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName())) {
|
||||
DoRoundTrip("ed448", DigestAlgorithms.SHAKE256, EdECObjectIdentifiers.id_Ed448);
|
||||
} else {
|
||||
// SHAKE256 is currently not supported in BCFIPS
|
||||
NUnit.Framework.Assert.Catch(typeof(KeyException), () => DoRoundTrip("ed448", DigestAlgorithms.SHAKE256, EdECObjectIdentifiers.id_Ed448));
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TestBrainpoolP384r1WithSha384() {
|
||||
DoRoundTrip("brainpoolP384r1", DigestAlgorithms.SHA384, X9ObjectIdentifiers.ECDsaWithSha384);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TestBrainpoolP384r1WithSha3_384() {
|
||||
if ("BCFIPS".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName())) {
|
||||
DoRoundTrip("brainpoolP384r1", DigestAlgorithms.SHA3_384, NistObjectIdentifiers.IdEcdsaWithSha3_384);
|
||||
} else {
|
||||
// Signer SHA3-384WITHECDSA not recognised in BC mode
|
||||
NUnit.Framework.Assert.Catch(typeof(SecurityUtilityException), () => DoRoundTrip("brainpoolP384r1", DigestAlgorithms.SHA3_384, NistObjectIdentifiers.IdEcdsaWithSha3_384));
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TestNistP256WithSha3_256() {
|
||||
if ("BCFIPS".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName())) {
|
||||
DoRoundTrip("nistp256", DigestAlgorithms.SHA3_256, NistObjectIdentifiers.IdEcdsaWithSha3_256);
|
||||
} else {
|
||||
// Signer SHA3-256WITHECDSA not recognised in BC mode
|
||||
NUnit.Framework.Assert.Catch(typeof(SecurityUtilityException), () => DoRoundTrip("nistp256", DigestAlgorithms.SHA3_256, NistObjectIdentifiers.IdEcdsaWithSha3_256));
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TestRsaWithSha3_512() {
|
||||
// For now we use a generic OID, but NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_512 would
|
||||
// be more appropriate
|
||||
DoRoundTrip("rsa", DigestAlgorithms.SHA3_512, new DerObjectIdentifier(SecurityIDs.ID_RSA_WITH_SHA3_512));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TestRsaWithSha3_256() {
|
||||
if ("BCFIPS".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName())) {
|
||||
DoRoundTrip("dsa", DigestAlgorithms.SHA3_256, NistObjectIdentifiers.IdDsaWithSha3_256);
|
||||
} else {
|
||||
// Signer SHA3-256WITHDSA not recognised in BC mode
|
||||
NUnit.Framework.Assert.Catch(typeof(SecurityUtilityException), () => DoRoundTrip("dsa", DigestAlgorithms.SHA3_256, NistObjectIdentifiers.IdDsaWithSha3_256));
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TestEd25519ForceSha512WhenSigning() {
|
||||
if ("BCFIPS".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName())) {
|
||||
// algorithm identifier in key not recognised
|
||||
NUnit.Framework.Assert.Catch(typeof(KeyException), () => DoSign("ed25519", DigestAlgorithms.SHA1, new MemoryStream()));
|
||||
} else {
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(PdfException), () => DoSign("ed25519", DigestAlgorithms.
|
||||
SHA1, new MemoryStream()));
|
||||
NUnit.Framework.Assert.AreEqual("Ed25519 requires the document to be digested using SHA-512, not SHA1", e.
|
||||
Message);
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TestEd448ForceShake256WhenSigning() {
|
||||
if ("BC".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName())) {
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(PdfException), () => DoSign("ed448", DigestAlgorithms.SHA1, new MemoryStream()));
|
||||
NUnit.Framework.Assert.AreEqual("Ed448 requires the document to be digested using 512-bit SHAKE256, not SHA1", e.Message);
|
||||
} else {
|
||||
// SHAKE256 is currently not supported in BCFIPS
|
||||
NUnit.Framework.Assert.Catch(typeof(KeyException), () => DoSign("ed448", DigestAlgorithms.SHA1, new MemoryStream()));
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TestEd25519ForceSha512WhenValidating() {
|
||||
// file contains an Ed25519 signature where the document digest is computed using SHA-1
|
||||
String referenceFile = System.IO.Path.Combine(SOURCE_FOLDER, "bad-digest-ed25519.pdf").ToString();
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(PdfException), () => DoVerify(referenceFile, null));
|
||||
NUnit.Framework.Assert.AreEqual("Ed25519 requires the document to be digested using SHA-512, not SHA1", e.
|
||||
InnerException.InnerException.Message);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TestEd448ForceShake256WhenValidating() {
|
||||
// file contains an Ed448 signature where the document digest is computed using SHA-1
|
||||
String referenceFile = System.IO.Path.Combine(SOURCE_FOLDER, "bad-digest-ed448.pdf").ToString();
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(PdfException), () => DoVerify(referenceFile, null));
|
||||
NUnit.Framework.Assert.AreEqual("Ed448 requires the document to be digested using 512-bit SHAKE256, not SHA1"
|
||||
, e.InnerException.InnerException.Message);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TestRsaWithSha3ExtensionDeclarations() {
|
||||
MemoryStream baos = new MemoryStream();
|
||||
DoSign("rsa", DigestAlgorithms.SHA3_256, baos);
|
||||
CheckIsoExtensions(baos.ToArray(), JavaCollectionsUtil.Singleton(32001));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TestEd25519ExtensionDeclarations() {
|
||||
MemoryStream baos = new MemoryStream();
|
||||
if ("BCFIPS".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName())) {
|
||||
// algorithm identifier in key not recognised
|
||||
NUnit.Framework.Assert.Catch(typeof(KeyException), () => DoSign("ed25519", DigestAlgorithms.SHA512, baos));
|
||||
} else {
|
||||
DoSign("ed25519", DigestAlgorithms.SHA512, baos);
|
||||
CheckIsoExtensions(baos.ToArray(), JavaCollectionsUtil.Singleton(32002));
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TestEd448ExtensionDeclarations() {
|
||||
MemoryStream baos = new MemoryStream();
|
||||
if ("BC".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName())) {
|
||||
DoSign("ed448", DigestAlgorithms.SHAKE256, baos);
|
||||
CheckIsoExtensions(baos.ToArray(), JavaUtil.ArraysAsList(32002, 32001));
|
||||
} else {
|
||||
// SHAKE256 is currently not supported in BCFIPS
|
||||
NUnit.Framework.Assert.Catch(typeof(KeyException), () => DoSign("ed448", DigestAlgorithms.SHAKE256, baos));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TestIsoExtensionsWithMultipleSignatures() {
|
||||
// algorithm identifier in key not recognised in BCFIPS mode for ed25519
|
||||
NUnit.Framework.Assume.That(!"BCFIPS".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName()));
|
||||
|
||||
String keySample1 = "rsa";
|
||||
String keySample2 = "ed25519";
|
||||
MemoryStream baos1 = new MemoryStream();
|
||||
MemoryStream baos2 = new MemoryStream();
|
||||
IX509Certificate root = ReadCertificate(System.IO.Path.Combine(SOURCE_FOLDER, "ca.crt"));
|
||||
IX509Certificate signerCert1 = ReadCertificate(System.IO.Path.Combine(SOURCE_FOLDER, keySample1 + ".crt"));
|
||||
IX509Certificate signerCert2 = ReadCertificate(System.IO.Path.Combine(SOURCE_FOLDER, keySample2 + ".crt"));
|
||||
IX509Certificate[] signChain1 = new IX509Certificate[] { signerCert1, root };
|
||||
IX509Certificate[] signChain2 = new IX509Certificate[] { signerCert2, root };
|
||||
using (Stream in1 = new FileStream(SOURCE_FILE, FileMode.Open, FileAccess.Read)) {
|
||||
IPrivateKey signPrivateKey = ReadUnencryptedPrivateKey(System.IO.Path.Combine(SOURCE_FOLDER, keySample1 + ".key.pem"));
|
||||
IExternalSignature pks = new PrivateKeySignature(signPrivateKey, DigestAlgorithms.SHA3_256);
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(in1), baos1, new StampingProperties());
|
||||
signer.SetFieldName("Signature1");
|
||||
signer.SignDetached(pks, signChain1, null, null, null, 0, PdfSigner.CryptoStandard.CMS);
|
||||
}
|
||||
using (Stream in2 = new MemoryStream(baos1.ToArray())) {
|
||||
IPrivateKey signPrivateKey = ReadUnencryptedPrivateKey(System.IO.Path.Combine(SOURCE_FOLDER, keySample2 + ".key.pem"));
|
||||
IExternalSignature pks = new PrivateKeySignature(signPrivateKey, DigestAlgorithms.SHA512);
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(in2), baos2, new StampingProperties());
|
||||
signer.SetFieldName("Signature2");
|
||||
signer.SignDetached(pks, signChain2, null, null, null, 0, PdfSigner.CryptoStandard.CMS);
|
||||
}
|
||||
CheckIsoExtensions(baos2.ToArray(), JavaUtil.ArraysAsList(32001, 32002));
|
||||
}
|
||||
|
||||
private void DoRoundTrip(String keySampleName, String digestAlgo, DerObjectIdentifier expectedSigAlgoIdentifier
|
||||
) {
|
||||
String outFile = System.IO.Path.Combine(DESTINATION_FOLDER, keySampleName + "-" + digestAlgo + ".pdf").ToString
|
||||
();
|
||||
DoSign(keySampleName, digestAlgo, outFile);
|
||||
DoVerify(outFile, expectedSigAlgoIdentifier);
|
||||
}
|
||||
|
||||
private void DoSign(String keySampleName, String digestAlgo, String outFile) {
|
||||
// write to a file for easier inspection when debugging
|
||||
using (FileStream fos = new FileStream(outFile, FileMode.Create)) {
|
||||
DoSign(keySampleName, digestAlgo, fos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void DoSign(String keySampleName, String digestAlgo, Stream os) {
|
||||
IX509Certificate root = ReadCertificate(System.IO.Path.Combine(SOURCE_FOLDER, "ca.crt"));
|
||||
IX509Certificate signerCert = ReadCertificate(System.IO.Path.Combine(SOURCE_FOLDER, keySampleName + ".crt"
|
||||
));
|
||||
IX509Certificate[] signChain = new IX509Certificate[] { signerCert, root };
|
||||
IPrivateKey signPrivateKey = ReadUnencryptedPrivateKey(System.IO.Path.Combine(SOURCE_FOLDER, keySampleName
|
||||
+ ".key.pem"));
|
||||
// The default provider doesn't necessarily distinguish between different types of EdDSA keys
|
||||
// and accessing that information requires APIs that are not available in older JDKs we still support.
|
||||
IExternalSignature pks = new PrivateKeySignature(signPrivateKey, digestAlgo);
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(SOURCE_FILE), os, new StampingProperties());
|
||||
signer.SetFieldName(SIGNATURE_FIELD);
|
||||
signer.GetSignatureAppearance().SetPageRect(new Rectangle(50, 650, 200, 100)).SetReason("Test").SetLocation
|
||||
("TestCity").SetLayer2Text("Approval test signature.\nCreated by TSpdf7.");
|
||||
signer.SignDetached(pks, signChain, null, null, null, 0, PdfSigner.CryptoStandard.CMS);
|
||||
}
|
||||
|
||||
private void DoVerify(String fileName, DerObjectIdentifier expectedSigAlgoIdentifier) {
|
||||
using (PdfReader r = new PdfReader(fileName)) {
|
||||
using (PdfDocument pdfDoc = new PdfDocument(r)) {
|
||||
SignatureUtil u = new SignatureUtil(pdfDoc);
|
||||
PdfPKCS7 data = u.ReadSignatureData(SIGNATURE_FIELD);
|
||||
NUnit.Framework.Assert.IsTrue(data.VerifySignatureIntegrityAndAuthenticity());
|
||||
if (expectedSigAlgoIdentifier != null) {
|
||||
DerObjectIdentifier oid = new DerObjectIdentifier(data.GetSignatureMechanismOid());
|
||||
NUnit.Framework.Assert.AreEqual(expectedSigAlgoIdentifier, oid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckIsoExtensions(byte[] fileData, ICollection<int> expectedLevels) {
|
||||
using (PdfReader r = new PdfReader(new MemoryStream(fileData))) {
|
||||
using (PdfDocument pdfDoc = new PdfDocument(r)) {
|
||||
PdfArray isoExtensions = pdfDoc.GetCatalog().GetPdfObject().GetAsDictionary(PdfName.Extensions).GetAsArray
|
||||
(PdfName.ISO_);
|
||||
NUnit.Framework.Assert.AreEqual(expectedLevels.Count, isoExtensions.Size());
|
||||
ICollection<int> actualLevels = new HashSet<int>();
|
||||
for (int i = 0; i < isoExtensions.Size(); i++) {
|
||||
PdfDictionary extDict = isoExtensions.GetAsDictionary(i);
|
||||
actualLevels.Add(extDict.GetAsNumber(PdfName.ExtensionLevel).IntValue());
|
||||
}
|
||||
ICollection<int> expectedLevelSet = new HashSet<int>(expectedLevels);
|
||||
NUnit.Framework.Assert.AreEqual(expectedLevelSet, actualLevels);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IX509Certificate ReadCertificate(String path) {
|
||||
byte[] content = System.IO.File.ReadAllBytes(path);
|
||||
return BOUNCY_CASTLE_FACTORY.CreateX509Certificate(content);
|
||||
}
|
||||
|
||||
private IPrivateKey ReadUnencryptedPrivateKey(String path) {
|
||||
try {
|
||||
return PemFileHelper.ReadFirstKey(path.ToString(), SAMPLE_KEY_PASSPHRASE);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new KeyException(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
217
TSpdf.tests/TSpdf.sign.tests/TSpdf/signatures/sign/LtvSigTest.cs
Normal file
217
TSpdf.tests/TSpdf.sign.tests/TSpdf/signatures/sign/LtvSigTest.cs
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Signatures.Testutils.Client;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures.Sign {
|
||||
[NUnit.Framework.Category("BouncyCastleIntegrationTest")]
|
||||
public class LtvSigTest : ExtendedTSpdfTest {
|
||||
private static readonly String CERTS_SRC = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/";
|
||||
|
||||
private static readonly String SOURCE_FOLDER = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/sign/LtvSigTest/";
|
||||
|
||||
private static readonly String DESTINATION_FOLDER = NUnit.Framework.TestContext.CurrentContext.TestDirectory
|
||||
+ "/test/TSpdf/signatures/sign/LtvSigTest/";
|
||||
|
||||
private static readonly char[] PASSWORD = "testpassphrase".ToCharArray();
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
CreateOrClearDestinationFolder(DESTINATION_FOLDER);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void LtvEnabledTest01() {
|
||||
String tsaCertP12FileName = CERTS_SRC + "tsCertRsa.pem";
|
||||
String caCertP12FileName = CERTS_SRC + "rootRsa.pem";
|
||||
String srcFileName = SOURCE_FOLDER + "signedDoc.pdf";
|
||||
String ltvFileName = DESTINATION_FOLDER + "ltvEnabledTest01.pdf";
|
||||
String ltvTsFileName = DESTINATION_FOLDER + "ltvEnabledTsTest01.pdf";
|
||||
TestCrlClient testCrlClient = PrepareCrlClientForIssuer(caCertP12FileName);
|
||||
TestOcspClient testOcspClient = PrepareOcspClientForIssuer(caCertP12FileName);
|
||||
TestTsaClient testTsa = PrepareTsaClient(tsaCertP12FileName);
|
||||
PdfDocument document = new PdfDocument(new PdfReader(srcFileName), new PdfWriter(ltvFileName), new StampingProperties
|
||||
().UseAppendMode());
|
||||
LtvVerification ltvVerification = new LtvVerification(document);
|
||||
ltvVerification.AddVerification("Signature1", testOcspClient, testCrlClient, LtvVerification.CertificateOption
|
||||
.SIGNING_CERTIFICATE, LtvVerification.Level.OCSP_CRL, LtvVerification.CertificateInclusion.YES);
|
||||
ltvVerification.Merge();
|
||||
document.Close();
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(ltvFileName), new FileStream(ltvTsFileName, FileMode.Create
|
||||
), new StampingProperties().UseAppendMode());
|
||||
signer.Timestamp(testTsa, "timestampSig1");
|
||||
BasicCheckLtvDoc("ltvEnabledTsTest01.pdf", "timestampSig1");
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(ltvTsFileName, SOURCE_FOLDER + "cmp_ltvEnabledTsTest01.pdf"
|
||||
));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void LtvEnabledSingleSignatureNoCrlDataTest() {
|
||||
String signCertP12FileName = CERTS_SRC + "signCertRsaWithChain.pem";
|
||||
String tsaCertP12FileName = CERTS_SRC + "tsCertRsa.pem";
|
||||
String intermediateCertP12FileName = CERTS_SRC + "intermediateRsa.pem";
|
||||
String caCertP12FileName = CERTS_SRC + "rootRsa.pem";
|
||||
String srcFileName = SOURCE_FOLDER + "helloWorldDoc.pdf";
|
||||
String ltvFileName = DESTINATION_FOLDER + "ltvEnabledSingleSignatureNoCrlDataTest.pdf";
|
||||
IX509Certificate[] signChain = PemFileHelper.ReadFirstChain(signCertP12FileName);
|
||||
IExternalSignature pks = PrepareSignatureHandler(signCertP12FileName);
|
||||
TestTsaClient testTsa = PrepareTsaClient(tsaCertP12FileName);
|
||||
TestOcspClient testOcspClient = PrepareOcspClientForIssuer(intermediateCertP12FileName, caCertP12FileName);
|
||||
ICollection<ICrlClient> crlNotAvailableList = JavaUtil.ArraysAsList((ICrlClient)null, new _ICrlClient_149(
|
||||
));
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(srcFileName), new FileStream(ltvFileName, FileMode.Create),
|
||||
new StampingProperties());
|
||||
signer.SetFieldName("Signature1");
|
||||
signer.SignDetached(pks, signChain, crlNotAvailableList, testOcspClient, testTsa, 0, PdfSigner.CryptoStandard
|
||||
.CADES);
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(ltvFileName, SOURCE_FOLDER + "cmp_ltvEnabledSingleSignatureNoCrlDataTest.pdf"
|
||||
));
|
||||
}
|
||||
|
||||
private sealed class _ICrlClient_149 : ICrlClient {
|
||||
public _ICrlClient_149() {
|
||||
}
|
||||
|
||||
public ICollection<byte[]> GetEncoded(IX509Certificate checkCert, String url) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void LtvEnabledSingleSignatureNoOcspDataTest() {
|
||||
String signCertP12FileName = CERTS_SRC + "signCertRsaWithChain.pem";
|
||||
String tsaCertP12FileName = CERTS_SRC + "tsCertRsa.pem";
|
||||
String intermediateCertP12FileName = CERTS_SRC + "intermediateRsa.pem";
|
||||
String caCertP12FileName = CERTS_SRC + "rootRsa.pem";
|
||||
String srcFileName = SOURCE_FOLDER + "helloWorldDoc.pdf";
|
||||
String ltvFileName = DESTINATION_FOLDER + "ltvEnabledSingleSignatureNoOcspDataTest.pdf";
|
||||
IX509Certificate[] signChain = PemFileHelper.ReadFirstChain(signCertP12FileName);
|
||||
IExternalSignature pks = PrepareSignatureHandler(signCertP12FileName);
|
||||
TestTsaClient testTsa = PrepareTsaClient(tsaCertP12FileName);
|
||||
TestCrlClient testCrlClient = PrepareCrlClientForIssuer(caCertP12FileName, intermediateCertP12FileName);
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(srcFileName), new FileStream(ltvFileName, FileMode.Create),
|
||||
new StampingProperties());
|
||||
signer.SetFieldName("Signature1");
|
||||
signer.SignDetached(pks, signChain, JavaCollectionsUtil.SingletonList<ICrlClient>(testCrlClient), null, testTsa
|
||||
, 0, PdfSigner.CryptoStandard.CADES);
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(ltvFileName, SOURCE_FOLDER + "cmp_ltvEnabledSingleSignatureNoOcspDataTest.pdf"
|
||||
));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SecondLtvOriginalHasNoVri01() {
|
||||
String tsaCertFileName = CERTS_SRC + "tsCertRsa.pem";
|
||||
String caCertFileName = CERTS_SRC + "rootRsa.pem";
|
||||
String srcFileName = SOURCE_FOLDER + "ltvEnabledNoVriEntry.pdf";
|
||||
String ltvFileName = DESTINATION_FOLDER + "secondLtvOriginalHasNoVri01.pdf";
|
||||
String ltvTsFileName = DESTINATION_FOLDER + "secondLtvOriginalHasNoVriTs01.pdf";
|
||||
TestCrlClient testCrlClient = PrepareCrlClientForIssuer(caCertFileName);
|
||||
TestOcspClient testOcspClient = PrepareOcspClientForIssuer(caCertFileName);
|
||||
TestTsaClient testTsa = PrepareTsaClient(tsaCertFileName);
|
||||
PdfDocument document = new PdfDocument(new PdfReader(srcFileName), new PdfWriter(ltvFileName), new StampingProperties
|
||||
().UseAppendMode());
|
||||
LtvVerification ltvVerification = new LtvVerification(document);
|
||||
ltvVerification.AddVerification("timestampSig1", testOcspClient, testCrlClient, LtvVerification.CertificateOption
|
||||
.SIGNING_CERTIFICATE, LtvVerification.Level.OCSP_CRL, LtvVerification.CertificateInclusion.YES);
|
||||
ltvVerification.Merge();
|
||||
document.Close();
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(ltvFileName), new FileStream(ltvTsFileName, FileMode.Create
|
||||
), new StampingProperties().UseAppendMode());
|
||||
signer.Timestamp(testTsa, "timestampSig2");
|
||||
BasicCheckLtvDoc("secondLtvOriginalHasNoVriTs01.pdf", "timestampSig2");
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(ltvTsFileName, SOURCE_FOLDER + "cmp_secondLtvOriginalHasNoVriTs01.pdf"
|
||||
));
|
||||
}
|
||||
|
||||
private static IExternalSignature PrepareSignatureHandler(String signCertP12FileName) {
|
||||
IPrivateKey signPrivateKey = PemFileHelper.ReadFirstKey(signCertP12FileName, PASSWORD);
|
||||
return new PrivateKeySignature(signPrivateKey, DigestAlgorithms.SHA256);
|
||||
}
|
||||
|
||||
private static TestCrlClient PrepareCrlClientForIssuer(params String[] issuerCertP12FileNames) {
|
||||
TestCrlClient testCrlClient = new TestCrlClient();
|
||||
foreach (String issuerP12File in issuerCertP12FileNames) {
|
||||
IX509Certificate caCert = (IX509Certificate)PemFileHelper.ReadFirstChain(issuerP12File)[0];
|
||||
IPrivateKey caPrivateKey = PemFileHelper.ReadFirstKey(issuerP12File, PASSWORD);
|
||||
testCrlClient.AddBuilderForCertIssuer(caCert, caPrivateKey);
|
||||
}
|
||||
return testCrlClient;
|
||||
}
|
||||
|
||||
private static TestOcspClient PrepareOcspClientForIssuer(params String[] issuerCertP12FileNames) {
|
||||
TestOcspClient ocspClient = new TestOcspClient();
|
||||
foreach (String issuerP12File in issuerCertP12FileNames) {
|
||||
IX509Certificate issuerCertificate = (IX509Certificate)PemFileHelper.ReadFirstChain(issuerP12File)[0];
|
||||
IPrivateKey issuerPrivateKey = PemFileHelper.ReadFirstKey(issuerP12File, PASSWORD);
|
||||
ocspClient.AddBuilderForCertIssuer(issuerCertificate, issuerPrivateKey);
|
||||
}
|
||||
return ocspClient;
|
||||
}
|
||||
|
||||
private static TestTsaClient PrepareTsaClient(String tsaCertP12FileName) {
|
||||
IX509Certificate[] tsaChain = PemFileHelper.ReadFirstChain(tsaCertP12FileName);
|
||||
IPrivateKey tsaPrivateKey = PemFileHelper.ReadFirstKey(tsaCertP12FileName, PASSWORD);
|
||||
return new TestTsaClient(JavaUtil.ArraysAsList(tsaChain), tsaPrivateKey);
|
||||
}
|
||||
|
||||
private void BasicCheckLtvDoc(String outFileName, String tsSigName) {
|
||||
PdfDocument outDocument = new PdfDocument(new PdfReader(DESTINATION_FOLDER + outFileName));
|
||||
PdfDictionary dssDict = outDocument.GetCatalog().GetPdfObject().GetAsDictionary(PdfName.DSS);
|
||||
NUnit.Framework.Assert.IsNotNull(dssDict);
|
||||
NUnit.Framework.Assert.AreEqual(4, dssDict.Size());
|
||||
outDocument.Close();
|
||||
PadesSigTest.BasicCheckSignedDoc(DESTINATION_FOLDER + outFileName, tsSigName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Signatures.Testutils.Client;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures.Sign {
|
||||
[NUnit.Framework.Category("BouncyCastleIntegrationTest")]
|
||||
public class LtvWithTwoSignaturesTest : ExtendedTSpdfTest {
|
||||
private static readonly String certsSrc = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/";
|
||||
|
||||
private static readonly String sourceFolder = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/sign/LtvWithTwoSignaturesTest/";
|
||||
|
||||
private static readonly String destinationFolder = NUnit.Framework.TestContext.CurrentContext.TestDirectory
|
||||
+ "/test/TSpdf/signatures/sign/LtvWithTwoSignaturesTest/";
|
||||
|
||||
private static readonly char[] password = "testpassphrase".ToCharArray();
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
CreateOrClearDestinationFolder(destinationFolder);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void AddLtvInfo() {
|
||||
String caCertFileName = certsSrc + "rootRsa.pem";
|
||||
String interCertFileName = certsSrc + "intermediateRsa.pem";
|
||||
String srcFileName = sourceFolder + "signedTwice.pdf";
|
||||
String ltvFileName = destinationFolder + "ltvEnabledTest01.pdf";
|
||||
String ltvFileName2 = destinationFolder + "ltvEnabledTest02.pdf";
|
||||
IX509Certificate caCert = (IX509Certificate)PemFileHelper.ReadFirstChain(caCertFileName)[0];
|
||||
IPrivateKey caPrivateKey = PemFileHelper.ReadFirstKey(caCertFileName, password);
|
||||
IX509Certificate interCert = (IX509Certificate)PemFileHelper.ReadFirstChain(interCertFileName)[0];
|
||||
IPrivateKey interPrivateKey = PemFileHelper.ReadFirstKey(interCertFileName, password);
|
||||
TestOcspClient testOcspClient = new TestOcspClient().AddBuilderForCertIssuer(interCert, interPrivateKey).AddBuilderForCertIssuer
|
||||
(caCert, caPrivateKey);
|
||||
TestCrlClient testCrlClient = new TestCrlClient().AddBuilderForCertIssuer(caCert, caPrivateKey);
|
||||
AddLtvInfo(srcFileName, ltvFileName, "Signature1", testOcspClient, testCrlClient);
|
||||
AddLtvInfo(ltvFileName, ltvFileName2, "Signature2", testOcspClient, testCrlClient);
|
||||
PdfReader reader = new PdfReader(ltvFileName2);
|
||||
PdfDocument document = new PdfDocument(reader);
|
||||
PdfDictionary catalogDictionary = document.GetCatalog().GetPdfObject();
|
||||
PdfDictionary dssDictionary = catalogDictionary.GetAsDictionary(PdfName.DSS);
|
||||
PdfDictionary vri = dssDictionary.GetAsDictionary(PdfName.VRI);
|
||||
NUnit.Framework.Assert.IsNotNull(vri);
|
||||
NUnit.Framework.Assert.AreEqual(2, vri.Size());
|
||||
PdfArray ocsps = dssDictionary.GetAsArray(PdfName.OCSPs);
|
||||
NUnit.Framework.Assert.IsNotNull(ocsps);
|
||||
NUnit.Framework.Assert.AreEqual(5, ocsps.Size());
|
||||
PdfArray certs = dssDictionary.GetAsArray(PdfName.Certs);
|
||||
NUnit.Framework.Assert.IsNotNull(certs);
|
||||
NUnit.Framework.Assert.AreEqual(5, certs.Size());
|
||||
PdfArray crls = dssDictionary.GetAsArray(PdfName.CRLs);
|
||||
NUnit.Framework.Assert.IsNotNull(crls);
|
||||
NUnit.Framework.Assert.AreEqual(2, crls.Size());
|
||||
}
|
||||
|
||||
private void AddLtvInfo(String src, String dest, String sigName, TestOcspClient testOcspClient, TestCrlClient
|
||||
testCrlClient) {
|
||||
PdfDocument document = new PdfDocument(new PdfReader(src), new PdfWriter(dest), new StampingProperties().UseAppendMode
|
||||
());
|
||||
LtvVerification ltvVerification = new LtvVerification(document);
|
||||
ltvVerification.AddVerification(sigName, testOcspClient, testCrlClient, LtvVerification.CertificateOption.
|
||||
WHOLE_CHAIN, LtvVerification.Level.OCSP_CRL, LtvVerification.CertificateInclusion.YES);
|
||||
ltvVerification.Merge();
|
||||
document.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.IO;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1.Esf;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1.X509;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Kernel.Geom;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures.Sign {
|
||||
[NUnit.Framework.Category("BouncyCastleIntegrationTest")]
|
||||
public class PadesSigTest : ExtendedTSpdfTest {
|
||||
private static readonly IBouncyCastleFactory FACTORY = BouncyCastleFactoryCreator.GetFactory();
|
||||
|
||||
private static readonly String certsSrc = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/";
|
||||
|
||||
private static readonly String sourceFolder = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/sign/PadesSigTest/";
|
||||
|
||||
private static readonly String destinationFolder = NUnit.Framework.TestContext.CurrentContext.TestDirectory
|
||||
+ "/test/TSpdf/signatures/sign/PadesSigTest/";
|
||||
|
||||
private static readonly char[] password = "testpassphrase".ToCharArray();
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
CreateOrClearDestinationFolder(destinationFolder);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void PadesRsaSigTest01() {
|
||||
SignApproval(certsSrc + "signCertRsa01.pem", destinationFolder + "padesRsaSigTest01.pdf");
|
||||
BasicCheckSignedDoc(destinationFolder + "padesRsaSigTest01.pdf", "Signature1");
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(destinationFolder + "padesRsaSigTest01.pdf"
|
||||
, sourceFolder + "cmp_padesRsaSigTest01.pdf"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void PadesRsaSigTestWithChain01() {
|
||||
SignApproval(certsSrc + "signCertRsaWithChain.pem", destinationFolder + "padesRsaSigTestWithChain01.pdf");
|
||||
BasicCheckSignedDoc(destinationFolder + "padesRsaSigTestWithChain01.pdf", "Signature1");
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(destinationFolder + "padesRsaSigTestWithChain01.pdf"
|
||||
, sourceFolder + "cmp_padesRsaSigTestWithChain01.pdf"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[NUnit.Framework.Ignore("DEVSIX-1620: For some reason signatures created with the given cert (either by TSpdf or acrobat) are considered invalid"
|
||||
)]
|
||||
public virtual void PadesDsaSigTest01() {
|
||||
SignApproval(certsSrc + "signCertDsa01.pem", destinationFolder + "padesDsaSigTest01.pdf");
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void PadesEccSigTest01() {
|
||||
SignApproval(certsSrc + "signCertEcc01.pem", destinationFolder + "padesEccSigTest01.pdf");
|
||||
BasicCheckSignedDoc(destinationFolder + "padesEccSigTest01.pdf", "Signature1");
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(destinationFolder + "padesEccSigTest01.pdf"
|
||||
, sourceFolder + "cmp_padesEccSigTest01.pdf"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void PadesEpesProfileTest01() {
|
||||
String notExistingSignaturePolicyOid = "2.16.724.631.3.1.124.2.29.9";
|
||||
IASN1ObjectIdentifier asn1PolicyOid = FACTORY.CreateASN1ObjectIdentifierInstance(FACTORY.CreateASN1ObjectIdentifier
|
||||
(notExistingSignaturePolicyOid));
|
||||
IAlgorithmIdentifier hashAlg = FACTORY.CreateAlgorithmIdentifier(FACTORY.CreateASN1ObjectIdentifier(DigestAlgorithms
|
||||
.GetAllowedDigest("SHA1")));
|
||||
// indicate that the policy hash value is not known; see ETSI TS 101 733 V2.2.1, 5.8.1
|
||||
byte[] zeroSigPolicyHash = new byte[] { 0 };
|
||||
IDEROctetString hash = FACTORY.CreateDEROctetString(zeroSigPolicyHash);
|
||||
ISignaturePolicyId signaturePolicyId = FACTORY.CreateSignaturePolicyId(asn1PolicyOid, FACTORY.CreateOtherHashAlgAndValue
|
||||
(hashAlg, hash));
|
||||
ISignaturePolicyIdentifier sigPolicyIdentifier = FACTORY.CreateSignaturePolicyIdentifier(signaturePolicyId
|
||||
);
|
||||
SignApproval(certsSrc + "signCertRsa01.pem", destinationFolder + "padesEpesProfileTest01.pdf", sigPolicyIdentifier
|
||||
);
|
||||
BasicCheckSignedDoc(destinationFolder + "padesEpesProfileTest01.pdf", "Signature1");
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(destinationFolder + "padesEpesProfileTest01.pdf"
|
||||
, sourceFolder + "cmp_padesEpesProfileTest01.pdf"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignaturePolicyInfoUnavailableUrlTest() {
|
||||
String signedFileName = destinationFolder + "signaturePolicyInfoUnavailableUrl_signed.pdf";
|
||||
SignaturePolicyInfo spi = new SignaturePolicyInfo("1.2.3.4.5.6.7.8.9.10", "aVRleHQ0TGlmZVJhbmRvbVRleHQ=",
|
||||
"SHA-1", "https://signature-policy.org/not-available");
|
||||
SignApproval(certsSrc + "signCertRsa01.pem", signedFileName, spi);
|
||||
BasicCheckSignedDoc(signedFileName, "Signature1");
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(signedFileName, sourceFolder + "cmp_signaturePolicyInfoUnavailableUrl_signed.pdf"
|
||||
));
|
||||
}
|
||||
|
||||
private void SignApproval(String signCertFileName, String outFileName) {
|
||||
SignApproval(signCertFileName, outFileName, null, null);
|
||||
}
|
||||
|
||||
private void SignApproval(String signCertFileName, String outFileName, SignaturePolicyInfo signaturePolicyInfo
|
||||
) {
|
||||
SignApproval(signCertFileName, outFileName, null, signaturePolicyInfo);
|
||||
}
|
||||
|
||||
private void SignApproval(String signCertFileName, String outFileName, ISignaturePolicyIdentifier signaturePolicyId
|
||||
) {
|
||||
SignApproval(signCertFileName, outFileName, signaturePolicyId, null);
|
||||
}
|
||||
|
||||
private void SignApproval(String signCertFileName, String outFileName, ISignaturePolicyIdentifier sigPolicyIdentifier
|
||||
, SignaturePolicyInfo sigPolicyInfo) {
|
||||
String srcFileName = sourceFolder + "helloWorldDoc.pdf";
|
||||
IX509Certificate[] signChain = PemFileHelper.ReadFirstChain(signCertFileName);
|
||||
IPrivateKey signPrivateKey = PemFileHelper.ReadFirstKey(signCertFileName, password);
|
||||
IExternalSignature pks = new PrivateKeySignature(signPrivateKey, DigestAlgorithms.SHA256);
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(srcFileName), new FileStream(outFileName, FileMode.Create),
|
||||
new StampingProperties());
|
||||
signer.SetFieldName("Signature1");
|
||||
signer.GetSignatureAppearance().SetPageRect(new Rectangle(50, 650, 200, 100)).SetReason("Test").SetLocation
|
||||
("TestCity").SetLayer2Text("Approval test signature.\nCreated by TSpdf7.");
|
||||
if (sigPolicyIdentifier != null) {
|
||||
signer.SignDetached(pks, signChain, null, null, null, 0, PdfSigner.CryptoStandard.CADES, sigPolicyIdentifier
|
||||
);
|
||||
}
|
||||
else {
|
||||
if (sigPolicyInfo != null) {
|
||||
signer.SignDetached(pks, signChain, null, null, null, 0, PdfSigner.CryptoStandard.CADES, sigPolicyInfo);
|
||||
}
|
||||
else {
|
||||
signer.SignDetached(pks, signChain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void BasicCheckSignedDoc(String filePath, String signatureName) {
|
||||
PdfDocument outDocument = new PdfDocument(new PdfReader(filePath));
|
||||
SignatureUtil sigUtil = new SignatureUtil(outDocument);
|
||||
PdfPKCS7 signatureData = sigUtil.ReadSignatureData(signatureName);
|
||||
NUnit.Framework.Assert.IsTrue(signatureData.VerifySignatureIntegrityAndAuthenticity());
|
||||
outDocument.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.IO;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Kernel.Geom;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Signatures.Testutils.Client;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures.Sign {
|
||||
[NUnit.Framework.Category("BouncyCastleIntegrationTest")]
|
||||
public class PadesSignatureLevelTest : ExtendedTSpdfTest {
|
||||
private static readonly String certsSrc = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/";
|
||||
|
||||
private static readonly String sourceFolder = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/sign/PadesSignatureLevelTest/";
|
||||
|
||||
private static readonly String destinationFolder = NUnit.Framework.TestContext.CurrentContext.TestDirectory
|
||||
+ "/test/TSpdf/signatures/sign/PadesSignatureLevelTest/";
|
||||
|
||||
private static readonly char[] password = "testpassphrase".ToCharArray();
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
CreateOrClearDestinationFolder(destinationFolder);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void PadesSignatureLevelTTest01() {
|
||||
String outFileName = destinationFolder + "padesSignatureLevelTTest01.pdf";
|
||||
String srcFileName = sourceFolder + "helloWorldDoc.pdf";
|
||||
String signCertFileName = certsSrc + "signCertRsa01.pem";
|
||||
String tsaCertFileName = certsSrc + "tsCertRsa.pem";
|
||||
IX509Certificate[] signRsaChain = PemFileHelper.ReadFirstChain(signCertFileName);
|
||||
IPrivateKey signRsaPrivateKey = PemFileHelper.ReadFirstKey(signCertFileName, password);
|
||||
IExternalSignature pks = new PrivateKeySignature(signRsaPrivateKey, DigestAlgorithms.SHA256);
|
||||
IX509Certificate[] tsaChain = PemFileHelper.ReadFirstChain(tsaCertFileName);
|
||||
IPrivateKey tsaPrivateKey = PemFileHelper.ReadFirstKey(tsaCertFileName, password);
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(srcFileName), new FileStream(outFileName, FileMode.Create),
|
||||
new StampingProperties());
|
||||
signer.SetFieldName("Signature1");
|
||||
signer.GetSignatureAppearance().SetPageRect(new Rectangle(50, 650, 200, 100)).SetReason("Test").SetLocation
|
||||
("TestCity").SetLayer2Text("Approval test signature.\nCreated by TSpdf7.");
|
||||
TestTsaClient testTsa = new TestTsaClient(JavaUtil.ArraysAsList(tsaChain), tsaPrivateKey);
|
||||
signer.SignDetached(pks, signRsaChain, null, null, testTsa, 0, PdfSigner.CryptoStandard.CADES);
|
||||
PadesSigTest.BasicCheckSignedDoc(destinationFolder + "padesSignatureLevelTTest01.pdf", "Signature1");
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outFileName, sourceFolder + "cmp_padesSignatureLevelTTest01.pdf"
|
||||
));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void PadesSignatureLevelLTTest01() {
|
||||
String outFileName = destinationFolder + "padesSignatureLevelLTTest01.pdf";
|
||||
String srcFileName = sourceFolder + "signedPAdES-T.pdf";
|
||||
String caCertFileName = certsSrc + "rootRsa.pem";
|
||||
IX509Certificate caCert = (IX509Certificate)PemFileHelper.ReadFirstChain(caCertFileName)[0];
|
||||
IPrivateKey caPrivateKey = PemFileHelper.ReadFirstKey(caCertFileName, password);
|
||||
ICrlClient crlClient = new TestCrlClient().AddBuilderForCertIssuer(caCert, caPrivateKey);
|
||||
TestOcspClient ocspClient = new TestOcspClient().AddBuilderForCertIssuer(caCert, caPrivateKey);
|
||||
PdfDocument document = new PdfDocument(new PdfReader(srcFileName), new PdfWriter(outFileName), new StampingProperties
|
||||
().UseAppendMode());
|
||||
LtvVerification ltvVerification = new LtvVerification(document);
|
||||
ltvVerification.AddVerification("Signature1", ocspClient, crlClient, LtvVerification.CertificateOption.SIGNING_CERTIFICATE
|
||||
, LtvVerification.Level.OCSP_CRL, LtvVerification.CertificateInclusion.YES);
|
||||
ltvVerification.Merge();
|
||||
document.Close();
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outFileName, sourceFolder + "cmp_padesSignatureLevelLTTest01.pdf"
|
||||
));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void PadesSignatureLevelLTATest01() {
|
||||
String outFileName = destinationFolder + "padesSignatureLevelLTATest01.pdf";
|
||||
String srcFileName = sourceFolder + "signedPAdES-LT.pdf";
|
||||
String tsaCertFileName = certsSrc + "tsCertRsa.pem";
|
||||
IX509Certificate[] tsaChain = PemFileHelper.ReadFirstChain(tsaCertFileName);
|
||||
IPrivateKey tsaPrivateKey = PemFileHelper.ReadFirstKey(tsaCertFileName, password);
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(srcFileName), new FileStream(outFileName, FileMode.Create),
|
||||
new StampingProperties().UseAppendMode());
|
||||
TestTsaClient testTsa = new TestTsaClient(JavaUtil.ArraysAsList(tsaChain), tsaPrivateKey);
|
||||
signer.Timestamp(testTsa, "timestampSig1");
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outFileName, sourceFolder + "cmp_padesSignatureLevelLTATest01.pdf"
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Kernel.Exceptions;
|
||||
using TSpdf.Kernel.Geom;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Kernel.Utils;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Exceptions;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures.Sign {
|
||||
[NUnit.Framework.Category("BouncyCastleIntegrationTest")]
|
||||
public class Pdf20SigningTest : ExtendedTSpdfTest {
|
||||
private static readonly IBouncyCastleFactory FACTORY = BouncyCastleFactoryCreator.GetFactory();
|
||||
|
||||
private static readonly String SOURCE_FOLDER = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/sign/Pdf20SigningTest/";
|
||||
|
||||
private static readonly String DESTINATION_FOLDER = NUnit.Framework.TestContext.CurrentContext.TestDirectory
|
||||
+ "/test/TSpdf/signatures/sign/Pdf20SigningTest/";
|
||||
|
||||
private static readonly String KEYSTORE_PATH = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/signCertRsa01.pem";
|
||||
|
||||
private static readonly char[] PASSWORD = "testpassphrase".ToCharArray();
|
||||
|
||||
private IX509Certificate[] chain;
|
||||
|
||||
private IPrivateKey pk;
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
CreateOrClearDestinationFolder(DESTINATION_FOLDER);
|
||||
}
|
||||
|
||||
[NUnit.Framework.SetUp]
|
||||
public virtual void Init() {
|
||||
pk = PemFileHelper.ReadFirstKey(KEYSTORE_PATH, PASSWORD);
|
||||
chain = PemFileHelper.ReadFirstChain(KEYSTORE_PATH);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignExistingFieldWhenDirectAcroformAndNoSigFlagTest() {
|
||||
String srcFile = SOURCE_FOLDER + "signExistingFieldWhenDirectAcroformAndNoSigFlag.pdf";
|
||||
String outPdf = DESTINATION_FOLDER + "signExistingFieldWhenDirectAcroformAndNoSigFlag.pdf";
|
||||
String fieldName = "Signature1";
|
||||
Sign(srcFile, fieldName, outPdf, chain, pk, DigestAlgorithms.SHA256, PdfSigner.CryptoStandard.CADES, PdfSigner
|
||||
.NOT_CERTIFIED);
|
||||
PdfDocument doc = new PdfDocument(new PdfReader(outPdf));
|
||||
PdfNumber sigFlag = doc.GetCatalog().GetPdfObject().GetAsDictionary(PdfName.AcroForm).GetAsNumber(PdfName.
|
||||
SigFlags);
|
||||
NUnit.Framework.Assert.AreEqual(new PdfNumber(3).IntValue(), sigFlag.IntValue());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignPdf2CertificationAfterApprovalTest() {
|
||||
String srcFile = SOURCE_FOLDER + "approvalSignedDocPdf2.pdf";
|
||||
String outPdf = DESTINATION_FOLDER + "signedPdf2CertificationAfterApproval.pdf";
|
||||
Rectangle rect = new Rectangle(30, 50, 200, 100);
|
||||
String fieldName = "Signature2";
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(PdfException), () => Sign(srcFile, fieldName, outPdf, chain
|
||||
, pk, DigestAlgorithms.RIPEMD160, PdfSigner.CryptoStandard.CADES, "Test 1", "TestCity", rect, false, true
|
||||
, PdfSigner.CERTIFIED_NO_CHANGES_ALLOWED, null));
|
||||
NUnit.Framework.Assert.AreEqual(SignExceptionMessageConstant.CERTIFICATION_SIGNATURE_CREATION_FAILED_DOC_SHALL_NOT_CONTAIN_SIGS
|
||||
, e.Message);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignedTwicePdf2Test() {
|
||||
String srcFile = SOURCE_FOLDER + "signedTwice.pdf";
|
||||
String cmpPdfFileThree = SOURCE_FOLDER + "cmp_signedTwice.pdf";
|
||||
String outPdfFileOne = DESTINATION_FOLDER + "signedOnce.pdf";
|
||||
String outPdfFileTwo = DESTINATION_FOLDER + "updated.pdf";
|
||||
String outPdfFileThree = DESTINATION_FOLDER + "signedTwice.pdf";
|
||||
// sign document
|
||||
Rectangle rectangle1 = new Rectangle(36, 100, 200, 100);
|
||||
Sign(srcFile, "Signature1", outPdfFileOne, chain, pk, DigestAlgorithms.SHA256, PdfSigner.CryptoStandard.CADES
|
||||
, "Sign 1", "TestCity", rectangle1, false, true);
|
||||
// update document
|
||||
PdfDocument pdfDoc = new PdfDocument(new PdfReader(outPdfFileOne), new PdfWriter(outPdfFileTwo), new StampingProperties
|
||||
().UseAppendMode());
|
||||
pdfDoc.AddNewPage();
|
||||
pdfDoc.Close();
|
||||
// sign document again
|
||||
Rectangle rectangle2 = new Rectangle(236, 100, 200, 100);
|
||||
Sign(outPdfFileTwo, "Signature2", outPdfFileThree, chain, pk, DigestAlgorithms.SHA256, PdfSigner.CryptoStandard
|
||||
.CADES, "Sign 2", "TestCity", rectangle2, false, true);
|
||||
IDictionary<int, IList<Rectangle>> map = new Dictionary<int, IList<Rectangle>>();
|
||||
IList<Rectangle> list = new List<Rectangle>();
|
||||
list.Add(rectangle1);
|
||||
list.Add(rectangle2);
|
||||
map.Put(1, list);
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outPdfFileThree, cmpPdfFileThree));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignPdf2CmsTest() {
|
||||
String srcFile = SOURCE_FOLDER + "signPdf2Cms.pdf";
|
||||
String cmpPdf = SOURCE_FOLDER + "cmp_signPdf2Cms.pdf";
|
||||
String outPdf = DESTINATION_FOLDER + "signPdf2Cms.pdf";
|
||||
Rectangle rect = new Rectangle(30, 200, 200, 100);
|
||||
String fieldName = "Signature1";
|
||||
Sign(srcFile, fieldName, outPdf, chain, pk, DigestAlgorithms.SHA256, PdfSigner.CryptoStandard.CMS, "Test 1"
|
||||
, "TestCity", rect, false, true, PdfSigner.NOT_CERTIFIED, 12f);
|
||||
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(outPdf, cmpPdf, DESTINATION_FOLDER, "diff_"
|
||||
, GetTestMap(rect)));
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outPdf, cmpPdf));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignPdf2CadesTest() {
|
||||
String srcFile = SOURCE_FOLDER + "signPdf2Cades.pdf";
|
||||
String cmpPdf = SOURCE_FOLDER + "cmp_signPdf2Cades.pdf";
|
||||
String outPdf = DESTINATION_FOLDER + "signPdf2Cades.pdf";
|
||||
Rectangle rect = new Rectangle(30, 200, 200, 100);
|
||||
String fieldName = "Signature1";
|
||||
Sign(srcFile, fieldName, outPdf, chain, pk, DigestAlgorithms.SHA256, PdfSigner.CryptoStandard.CADES, "Test 1"
|
||||
, "TestCity", rect, false, true, PdfSigner.NOT_CERTIFIED, 12f);
|
||||
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(outPdf, cmpPdf, DESTINATION_FOLDER, "diff_"
|
||||
, GetTestMap(rect)));
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outPdf, cmpPdf));
|
||||
}
|
||||
|
||||
protected internal virtual void Sign(String src, String name, String dest, IX509Certificate[] chain, IPrivateKey
|
||||
pk, String digestAlgorithm, PdfSigner.CryptoStandard subfilter, int certificationLevel) {
|
||||
PdfReader reader = new PdfReader(src);
|
||||
StampingProperties properties = new StampingProperties();
|
||||
properties.UseAppendMode();
|
||||
PdfSigner signer = new PdfSigner(reader, new FileStream(dest, FileMode.Create), properties);
|
||||
signer.SetCertificationLevel(certificationLevel);
|
||||
signer.SetFieldName(name);
|
||||
// Creating the signature
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, subfilter);
|
||||
}
|
||||
|
||||
protected internal virtual void Sign(String src, String name, String dest, IX509Certificate[] chain, IPrivateKey
|
||||
pk, String digestAlgorithm, PdfSigner.CryptoStandard subfilter, String reason, String location, Rectangle
|
||||
rectangleForNewField, bool setReuseAppearance, bool isAppendMode, int certificationLevel, float? fontSize
|
||||
) {
|
||||
PdfReader reader = new PdfReader(src);
|
||||
StampingProperties properties = new StampingProperties();
|
||||
if (isAppendMode) {
|
||||
properties.UseAppendMode();
|
||||
}
|
||||
PdfSigner signer = new PdfSigner(reader, new FileStream(dest, FileMode.Create), properties);
|
||||
signer.SetCertificationLevel(certificationLevel);
|
||||
// Creating the appearance
|
||||
PdfSignatureAppearance appearance = signer.GetSignatureAppearance().SetReason(reason).SetLocation(location
|
||||
).SetReuseAppearance(setReuseAppearance);
|
||||
if (rectangleForNewField != null) {
|
||||
appearance.SetPageRect(rectangleForNewField);
|
||||
}
|
||||
if (fontSize != null) {
|
||||
appearance.SetLayer2FontSize((float)fontSize);
|
||||
}
|
||||
signer.SetFieldName(name);
|
||||
// Creating the signature
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, subfilter);
|
||||
}
|
||||
|
||||
protected internal virtual void Sign(String src, String name, String dest, IX509Certificate[] chain, IPrivateKey
|
||||
pk, String digestAlgorithm, PdfSigner.CryptoStandard subfilter, String reason, String location, Rectangle
|
||||
rectangleForNewField, bool setReuseAppearance, bool isAppendMode) {
|
||||
Sign(src, name, dest, chain, pk, digestAlgorithm, subfilter, reason, location, rectangleForNewField, setReuseAppearance
|
||||
, isAppendMode, PdfSigner.NOT_CERTIFIED, null);
|
||||
}
|
||||
|
||||
private static IDictionary<int, IList<Rectangle>> GetTestMap(Rectangle ignoredArea) {
|
||||
IDictionary<int, IList<Rectangle>> result = new Dictionary<int, IList<Rectangle>>();
|
||||
result.Put(1, JavaUtil.ArraysAsList(ignoredArea));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Forms;
|
||||
using TSpdf.Kernel.Font;
|
||||
using TSpdf.Kernel.Geom;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Kernel.Utils;
|
||||
using TSpdf.Pdfa.Exceptions;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Test;
|
||||
using TSpdf.Test.Pdfa;
|
||||
|
||||
namespace TSpdf.Signatures.Sign {
|
||||
// Android-Conversion-Skip-Line (TODO DEVSIX-7377 introduce pdf\a validation on Android)
|
||||
[NUnit.Framework.Category("BouncyCastleIntegrationTest")]
|
||||
public class PdfASigningTest : ExtendedTSpdfTest {
|
||||
public static readonly String sourceFolder = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/sign/PdfASigningTest/";
|
||||
|
||||
public static readonly String destinationFolder = NUnit.Framework.TestContext.CurrentContext.TestDirectory
|
||||
+ "/test/TSpdf/signatures/sign/PdfASigningTest/";
|
||||
|
||||
public static readonly String keystorePath = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/signCertRsa01.pem";
|
||||
|
||||
public static readonly char[] password = "testpassphrase".ToCharArray();
|
||||
|
||||
public static readonly String FONT = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/font/FreeSans.ttf";
|
||||
|
||||
private IX509Certificate[] chain;
|
||||
|
||||
private IPrivateKey pk;
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
CreateOrClearDestinationFolder(destinationFolder);
|
||||
}
|
||||
|
||||
[NUnit.Framework.SetUp]
|
||||
public virtual void Init() {
|
||||
pk = PemFileHelper.ReadFirstKey(keystorePath, password);
|
||||
chain = PemFileHelper.ReadFirstChain(keystorePath);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SimpleSigningTest() {
|
||||
String src = sourceFolder + "simplePdfADocument.pdf";
|
||||
String fileName = "simpleSignature.pdf";
|
||||
String dest = destinationFolder + fileName;
|
||||
int x = 36;
|
||||
int y = 548;
|
||||
int w = 200;
|
||||
int h = 100;
|
||||
Rectangle rect = new Rectangle(x, y, w, h);
|
||||
String fieldName = "Signature1";
|
||||
Sign(src, fieldName, dest, chain, pk, DigestAlgorithms.SHA256, PdfSigner.CryptoStandard.CADES, "Test 1", "TestCity"
|
||||
, rect, false, false, PdfSigner.NOT_CERTIFIED, 12f);
|
||||
NUnit.Framework.Assert.IsNull(new VeraPdfValidator().Validate(dest));
|
||||
// Android-Conversion-Skip-Line (TODO DEVSIX-7377 introduce pdf\a validation on Android)
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(dest, sourceFolder + "cmp_" + fileName
|
||||
));
|
||||
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(dest, sourceFolder + "cmp_" + fileName, destinationFolder
|
||||
, "diff_", GetTestMap(new Rectangle(27, 550, 195, 40))));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SigningPdfA2DocumentTest() {
|
||||
String src = sourceFolder + "simplePdfA2Document.pdf";
|
||||
String @out = destinationFolder + "signedPdfA2Document.pdf";
|
||||
PdfReader reader = new PdfReader(new FileStream(src, FileMode.Open, FileAccess.Read));
|
||||
PdfSigner signer = new PdfSigner(reader, new FileStream(@out, FileMode.Create), new StampingProperties());
|
||||
signer.SetFieldLockDict(new PdfSigFieldLock());
|
||||
signer.SetCertificationLevel(PdfSigner.CERTIFIED_NO_CHANGES_ALLOWED);
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
|
||||
NUnit.Framework.Assert.IsNull(new VeraPdfValidator().Validate(@out));
|
||||
}
|
||||
|
||||
// Android-Conversion-Skip-Line (TODO DEVSIX-7377 introduce pdf\a validation on Android)
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void FailedSigningPdfA2DocumentTest() {
|
||||
String src = sourceFolder + "simplePdfADocument.pdf";
|
||||
String @out = destinationFolder + "signedPdfADocument2.pdf";
|
||||
PdfReader reader = new PdfReader(new FileStream(src, FileMode.Open, FileAccess.Read));
|
||||
PdfSigner signer = new PdfSigner(reader, new FileStream(@out, FileMode.Create), new StampingProperties());
|
||||
signer.SetFieldLockDict(new PdfSigFieldLock());
|
||||
signer.SetCertificationLevel(PdfSigner.NOT_CERTIFIED);
|
||||
int x = 36;
|
||||
int y = 548;
|
||||
int w = 200;
|
||||
int h = 100;
|
||||
Rectangle rect = new Rectangle(x, y, w, h);
|
||||
PdfFont font = PdfFontFactory.CreateFont("Helvetica", "WinAnsi", PdfFontFactory.EmbeddingStrategy.PREFER_EMBEDDED
|
||||
);
|
||||
PdfSignatureAppearance appearance = signer.GetSignatureAppearance().SetReason("pdfA test").SetLocation("TestCity"
|
||||
).SetLayer2Font(font).SetReuseAppearance(false).SetPageRect(rect);
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(PdfAConformanceException), () => signer.SignDetached(pks
|
||||
, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES));
|
||||
NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(PdfAConformanceException.ALL_THE_FONTS_MUST_BE_EMBEDDED_THIS_ONE_IS_NOT_0
|
||||
, "Helvetica"), e.Message);
|
||||
}
|
||||
|
||||
protected internal virtual void Sign(String src, String name, String dest, IX509Certificate[] chain, IPrivateKey
|
||||
pk, String digestAlgorithm, PdfSigner.CryptoStandard subfilter, String reason, String location, Rectangle
|
||||
rectangleForNewField, bool setReuseAppearance, bool isAppendMode) {
|
||||
Sign(src, name, dest, chain, pk, digestAlgorithm, subfilter, reason, location, rectangleForNewField, setReuseAppearance
|
||||
, isAppendMode, PdfSigner.NOT_CERTIFIED, null);
|
||||
}
|
||||
|
||||
protected internal virtual void Sign(String src, String name, String dest, IX509Certificate[] chain, IPrivateKey
|
||||
pk, String digestAlgorithm, PdfSigner.CryptoStandard subfilter, String reason, String location, Rectangle
|
||||
rectangleForNewField, bool setReuseAppearance, bool isAppendMode, int certificationLevel, float? fontSize
|
||||
) {
|
||||
PdfReader reader = new PdfReader(src);
|
||||
StampingProperties properties = new StampingProperties();
|
||||
if (isAppendMode) {
|
||||
properties.UseAppendMode();
|
||||
}
|
||||
PdfSigner signer = new PdfSigner(reader, new FileStream(dest, FileMode.Create), properties);
|
||||
signer.SetCertificationLevel(certificationLevel);
|
||||
PdfFont font = PdfFontFactory.CreateFont(FONT, "WinAnsi", PdfFontFactory.EmbeddingStrategy.PREFER_EMBEDDED
|
||||
);
|
||||
// Creating the appearance
|
||||
PdfSignatureAppearance appearance = signer.GetSignatureAppearance().SetReason(reason).SetLocation(location
|
||||
).SetLayer2Font(font).SetReuseAppearance(setReuseAppearance);
|
||||
if (rectangleForNewField != null) {
|
||||
appearance.SetPageRect(rectangleForNewField);
|
||||
}
|
||||
if (fontSize != null) {
|
||||
appearance.SetLayer2FontSize((float)fontSize);
|
||||
}
|
||||
signer.SetFieldName(name);
|
||||
// Creating the signature
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, subfilter);
|
||||
}
|
||||
|
||||
private static IDictionary<int, IList<Rectangle>> GetTestMap(Rectangle ignoredArea) {
|
||||
IDictionary<int, IList<Rectangle>> result = new Dictionary<int, IList<Rectangle>>();
|
||||
result.Put(1, JavaCollectionsUtil.SingletonList(ignoredArea));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,472 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Forms;
|
||||
using TSpdf.IO.Image;
|
||||
using TSpdf.Kernel.Colors;
|
||||
using TSpdf.Kernel.Geom;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Kernel.Pdf.Canvas;
|
||||
using TSpdf.Kernel.Pdf.Xobject;
|
||||
using TSpdf.Kernel.Utils;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures.Sign {
|
||||
[NUnit.Framework.Category("BouncyCastleIntegrationTest")]
|
||||
public class PdfSignatureAppearanceTest : ExtendedTSpdfTest {
|
||||
public static readonly String SOURCE_FOLDER = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/sign/PdfSignatureAppearanceTest/";
|
||||
|
||||
public static readonly String DESTINATION_FOLDER = NUnit.Framework.TestContext.CurrentContext.TestDirectory
|
||||
+ "/test/TSpdf/signatures/sign/PdfSignatureAppearanceTest/";
|
||||
|
||||
public static readonly String KEYSTORE_PATH = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/sign/PdfSignatureAppearanceTest/test.pem";
|
||||
|
||||
public static readonly char[] PASSWORD = "testpassphrase".ToCharArray();
|
||||
|
||||
private IX509Certificate[] chain;
|
||||
|
||||
private IPrivateKey pk;
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
CreateOrClearDestinationFolder(DESTINATION_FOLDER);
|
||||
}
|
||||
|
||||
[NUnit.Framework.SetUp]
|
||||
public virtual void Init() {
|
||||
pk = PemFileHelper.ReadFirstKey(KEYSTORE_PATH, PASSWORD);
|
||||
chain = PemFileHelper.ReadFirstChain(KEYSTORE_PATH);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TextAutoscaleTest01() {
|
||||
String fileName = "textAutoscaleTest01.pdf";
|
||||
String dest = DESTINATION_FOLDER + fileName;
|
||||
Rectangle rect = new Rectangle(36, 648, 200, 100);
|
||||
TestSignatureAppearanceAutoscale(dest, rect, PdfSignatureAppearance.RenderingMode.DESCRIPTION);
|
||||
AssertAppearanceFontSize(dest, 13.94f);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TextAutoscaleTest02() {
|
||||
String fileName = "textAutoscaleTest02.pdf";
|
||||
String dest = DESTINATION_FOLDER + fileName;
|
||||
Rectangle rect = new Rectangle(36, 648, 150, 50);
|
||||
TestSignatureAppearanceAutoscale(dest, rect, PdfSignatureAppearance.RenderingMode.DESCRIPTION);
|
||||
AssertAppearanceFontSize(dest, 6.83f);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TextAutoscaleTest03() {
|
||||
String fileName = "textAutoscaleTest03.pdf";
|
||||
String dest = DESTINATION_FOLDER + fileName;
|
||||
Rectangle rect = new Rectangle(36, 648, 200, 100);
|
||||
TestSignatureAppearanceAutoscale(dest, rect, PdfSignatureAppearance.RenderingMode.NAME_AND_DESCRIPTION);
|
||||
AssertAppearanceFontSize(dest, 44.35f);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TextAutoscaleTest04() {
|
||||
String fileName = "textAutoscaleTest04.pdf";
|
||||
String dest = DESTINATION_FOLDER + fileName;
|
||||
Rectangle rect = new Rectangle(36, 648, 100, 50);
|
||||
TestSignatureAppearanceAutoscale(dest, rect, PdfSignatureAppearance.RenderingMode.NAME_AND_DESCRIPTION);
|
||||
AssertAppearanceFontSize(dest, 21.25f);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TextAutoscaleTest05() {
|
||||
String fileName = "textAutoscaleTest05.pdf";
|
||||
String dest = DESTINATION_FOLDER + fileName;
|
||||
Rectangle rect = new Rectangle(36, 648, 200, 100);
|
||||
TestSignatureAppearanceAutoscale(dest, rect, PdfSignatureAppearance.RenderingMode.GRAPHIC_AND_DESCRIPTION);
|
||||
AssertAppearanceFontSize(dest, 12.77f);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TextAutoscaleTest06() {
|
||||
String fileName = "textAutoscaleTest06.pdf";
|
||||
String dest = DESTINATION_FOLDER + fileName;
|
||||
Rectangle rect = new Rectangle(36, 648, 100, 50);
|
||||
TestSignatureAppearanceAutoscale(dest, rect, PdfSignatureAppearance.RenderingMode.GRAPHIC_AND_DESCRIPTION);
|
||||
AssertAppearanceFontSize(dest, 6.26f);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TestSigningInAppendModeWithHybridDocument() {
|
||||
String src = SOURCE_FOLDER + "hybrid.pdf";
|
||||
String dest = DESTINATION_FOLDER + "signed_hybrid.pdf";
|
||||
String cmp = SOURCE_FOLDER + "cmp_signed_hybrid.pdf";
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(src), new FileStream(dest, FileMode.Create), new StampingProperties
|
||||
().UseAppendMode());
|
||||
PdfSignatureAppearance appearance = signer.GetSignatureAppearance();
|
||||
appearance.SetLayer2FontSize(13.8f).SetPageRect(new Rectangle(36, 748, 200, 100)).SetPageNumber(1).SetReason
|
||||
("Test").SetLocation("Nagpur");
|
||||
signer.SetFieldName("Sign1");
|
||||
signer.SetCertificationLevel(PdfSigner.NOT_CERTIFIED);
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
|
||||
// Make sure TSpdf can open the document
|
||||
new PdfDocument(new PdfReader(dest)).Close();
|
||||
// Assert that the document can be rendered correctly
|
||||
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(dest, cmp, DESTINATION_FOLDER, "diff_", GetIgnoredAreaTestMap
|
||||
(new Rectangle(36, 748, 200, 100))));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void FontColorTest01() {
|
||||
String fileName = "fontColorTest01.pdf";
|
||||
String dest = DESTINATION_FOLDER + fileName;
|
||||
Rectangle rect = new Rectangle(36, 648, 100, 50);
|
||||
String src = SOURCE_FOLDER + "simpleDocument.pdf";
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(src), new FileStream(dest, FileMode.Create), new StampingProperties
|
||||
());
|
||||
// Creating the appearance
|
||||
signer.GetSignatureAppearance().SetLayer2FontColor(ColorConstants.RED).SetLayer2Text("Verified and signed by me."
|
||||
).SetPageRect(rect);
|
||||
signer.SetFieldName("Signature1");
|
||||
// Creating the signature
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
|
||||
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(dest, SOURCE_FOLDER + "cmp_" + fileName, DESTINATION_FOLDER
|
||||
, "diff_"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignaturesOnRotatedPages() {
|
||||
StringBuilder assertionResults = new StringBuilder();
|
||||
for (int i = 1; i <= 4; i++) {
|
||||
TestSignatureOnRotatedPage(i, PdfSignatureAppearance.RenderingMode.GRAPHIC_AND_DESCRIPTION, assertionResults
|
||||
);
|
||||
TestSignatureOnRotatedPage(i, PdfSignatureAppearance.RenderingMode.GRAPHIC, assertionResults);
|
||||
TestSignatureOnRotatedPage(i, PdfSignatureAppearance.RenderingMode.NAME_AND_DESCRIPTION, assertionResults);
|
||||
TestSignatureOnRotatedPage(i, PdfSignatureAppearance.RenderingMode.DESCRIPTION, assertionResults);
|
||||
}
|
||||
NUnit.Framework.Assert.AreEqual("", assertionResults.ToString());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignatureFieldNotMergedWithWidgetTest() {
|
||||
using (PdfDocument outputDoc = new PdfDocument(new PdfReader(SOURCE_FOLDER + "signatureFieldNotMergedWithWidget.pdf"
|
||||
))) {
|
||||
SignatureUtil sigUtil = new SignatureUtil(outputDoc);
|
||||
PdfPKCS7 signatureData = sigUtil.ReadSignatureData("Signature1");
|
||||
NUnit.Framework.Assert.IsTrue(signatureData.VerifySignatureIntegrityAndAuthenticity());
|
||||
}
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignExistingNotMergedFieldNotReusedAPTest() {
|
||||
// TODO: DEVSIX-5162 (the signature is expected to have auto-generated appearance, but now it's empty)
|
||||
// Field is not merged with widget and has /P key
|
||||
String src = SOURCE_FOLDER + "emptyFieldNotMerged.pdf";
|
||||
String fileName = "signExistingNotMergedFieldNotReusedAP.pdf";
|
||||
String dest = DESTINATION_FOLDER + fileName;
|
||||
PdfReader reader = new PdfReader(src);
|
||||
PdfSigner signer = new PdfSigner(reader, new FileStream(dest, FileMode.Create), new StampingProperties());
|
||||
signer.SetCertificationLevel(PdfSigner.NOT_CERTIFIED);
|
||||
signer.GetSignatureAppearance().SetLayer2Text("Verified and signed by me.").SetReason("Test 1").SetLocation
|
||||
("TestCity").SetReuseAppearance(false);
|
||||
signer.SetFieldName("Signature1");
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
|
||||
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(dest, SOURCE_FOLDER + "cmp_" + fileName, DESTINATION_FOLDER
|
||||
, "diff_"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignExistingNotMergedFieldReusedAPTest() {
|
||||
// TODO: DEVSIX-5162 (signature appearance expected to be updated (reused appearance will be used as a background))
|
||||
// Field is not merged with widget and has /P key
|
||||
String src = SOURCE_FOLDER + "emptyFieldNotMerged.pdf";
|
||||
String fileName = "signExistingNotMergedFieldReusedAP.pdf";
|
||||
String dest = DESTINATION_FOLDER + fileName;
|
||||
PdfReader reader = new PdfReader(src);
|
||||
PdfSigner signer = new PdfSigner(reader, new FileStream(dest, FileMode.Create), new StampingProperties());
|
||||
signer.SetCertificationLevel(PdfSigner.NOT_CERTIFIED);
|
||||
signer.GetSignatureAppearance().SetLayer2Text("Verified and signed by me.").SetReason("Test 1").SetLocation
|
||||
("TestCity").SetReuseAppearance(true);
|
||||
signer.SetFieldName("Signature1");
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
|
||||
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(dest, SOURCE_FOLDER + "cmp_" + fileName, DESTINATION_FOLDER
|
||||
, "diff_"));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignExistingNotMergedFieldReusedAPEntryNDicTest() {
|
||||
// TODO: DEVSIX-5162 (remove expected exception after fix)
|
||||
// Field is not merged with widget and has /P key
|
||||
String src = SOURCE_FOLDER + "emptyFieldNotMergedEntryNDict.pdf";
|
||||
String fileName = "signExistingNotMergedFieldReusedAPEntryNDic.pdf";
|
||||
String dest = DESTINATION_FOLDER + fileName;
|
||||
PdfReader reader = new PdfReader(src);
|
||||
PdfSigner signer = new PdfSigner(reader, new FileStream(dest, FileMode.Create), new StampingProperties());
|
||||
signer.SetCertificationLevel(PdfSigner.NOT_CERTIFIED);
|
||||
signer.GetSignatureAppearance().SetLayer2Text("Verified and signed by me.").SetReason("Test 1").SetLocation
|
||||
("TestCity").SetReuseAppearance(true);
|
||||
signer.SetFieldName("Signature1");
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
|
||||
NUnit.Framework.Assert.Catch(typeof(NullReferenceException), () => signer.SignDetached(pks, chain, null, null
|
||||
, null, 0, PdfSigner.CryptoStandard.CADES));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void Layer0Test() {
|
||||
String src = SOURCE_FOLDER + "simpleDocument.pdf";
|
||||
String fileName = "layer0Test.pdf";
|
||||
String dest = DESTINATION_FOLDER + fileName;
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(src), new FileStream(dest, FileMode.Create), new StampingProperties
|
||||
());
|
||||
// Creating the appearance
|
||||
PdfSignatureAppearance appearance = signer.GetSignatureAppearance();
|
||||
signer.SetFieldName("Signature1");
|
||||
Rectangle rect = new Rectangle(0, 600, 100, 100);
|
||||
appearance.SetPageRect(rect);
|
||||
// If we do not set any text, the text will be generated and the current date will be used,
|
||||
// which we want to avoid because of visual comparison
|
||||
appearance.SetLayer2Text("Hello");
|
||||
PdfFormXObject layer0 = appearance.GetLayer0();
|
||||
// Draw red rectangle with blue border
|
||||
new PdfCanvas(layer0, signer.GetDocument()).SaveState().SetFillColor(ColorConstants.RED).SetStrokeColor(ColorConstants
|
||||
.BLUE).Rectangle(0, 0, 100, 100).FillStroke().RestoreState();
|
||||
// Get the same layer once more, so that the logic when n0 is not null is triggered
|
||||
layer0 = appearance.GetLayer0();
|
||||
// Draw yellow circle with black border
|
||||
new PdfCanvas(layer0, signer.GetDocument()).SaveState().SetFillColor(ColorConstants.YELLOW).SetStrokeColor
|
||||
(ColorConstants.BLACK).Circle(50, 50, 50).FillStroke().RestoreState();
|
||||
// Signing
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
|
||||
CompareSignatureAppearances(dest, SOURCE_FOLDER + "cmp_" + fileName);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void Layer0WithImageTest() {
|
||||
String src = SOURCE_FOLDER + "simpleDocument.pdf";
|
||||
String fileName = "layer0WithImageTest.pdf";
|
||||
String dest = DESTINATION_FOLDER + fileName;
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(src), new FileStream(dest, FileMode.Create), new StampingProperties
|
||||
());
|
||||
// Creating the appearance
|
||||
PdfSignatureAppearance appearance = signer.GetSignatureAppearance();
|
||||
appearance.SetImage(ImageDataFactory.Create(SOURCE_FOLDER + "TSpdf.png"));
|
||||
signer.SetFieldName("Signature1");
|
||||
Rectangle rect = new Rectangle(0, 600, 100, 100);
|
||||
appearance.SetPageRect(rect);
|
||||
// If we do not set any text, the text will be generated and the current date will be used,
|
||||
// which we want to avoid because of visual comparison
|
||||
appearance.SetLayer2Text("Hello");
|
||||
// Signing
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
|
||||
CompareSignatureAppearances(dest, SOURCE_FOLDER + "cmp_" + fileName);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void Layer0WithImageAndPositiveImageScaleTest() {
|
||||
String src = SOURCE_FOLDER + "simpleDocument.pdf";
|
||||
String fileName = "layer0WithImageAndPositiveImageScaleTest.pdf";
|
||||
String dest = DESTINATION_FOLDER + fileName;
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(src), new FileStream(dest, FileMode.Create), new StampingProperties
|
||||
());
|
||||
// Creating the appearance
|
||||
PdfSignatureAppearance appearance = signer.GetSignatureAppearance();
|
||||
appearance.SetImage(ImageDataFactory.Create(SOURCE_FOLDER + "TSpdf.png"));
|
||||
appearance.SetImageScale(1.5F);
|
||||
signer.SetFieldName("Signature1");
|
||||
Rectangle rect = new Rectangle(0, 600, 100, 100);
|
||||
appearance.SetPageRect(rect);
|
||||
// If we do not set any text, the text will be generated and the current date will be used,
|
||||
// which we want to avoid because of visual comparison
|
||||
appearance.SetLayer2Text("Hello");
|
||||
// Signing
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
|
||||
CompareSignatureAppearances(dest, SOURCE_FOLDER + "cmp_" + fileName);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void Layer0WithImageAndNegativeImageScaleTest() {
|
||||
String src = SOURCE_FOLDER + "simpleDocument.pdf";
|
||||
String fileName = "layer0WithImageAndNegativeImageScale.pdf";
|
||||
String dest = DESTINATION_FOLDER + fileName;
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(src), new FileStream(dest, FileMode.Create), new StampingProperties
|
||||
());
|
||||
// Creating the appearance
|
||||
PdfSignatureAppearance appearance = signer.GetSignatureAppearance();
|
||||
appearance.SetImage(ImageDataFactory.Create(SOURCE_FOLDER + "TSpdf.png"));
|
||||
appearance.SetImageScale(-15F);
|
||||
signer.SetFieldName("Signature1");
|
||||
Rectangle rect = new Rectangle(0, 600, 100, 100);
|
||||
appearance.SetPageRect(rect);
|
||||
// If we do not set any text, the text will be generated and the current date will be used,
|
||||
// which we want to avoid because of visual comparison
|
||||
appearance.SetLayer2Text("Hello");
|
||||
// Signing
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
|
||||
CompareSignatureAppearances(dest, SOURCE_FOLDER + "cmp_" + fileName);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void Layer2Test() {
|
||||
String src = SOURCE_FOLDER + "simpleDocument.pdf";
|
||||
String fileName = "layer2Test.pdf";
|
||||
String dest = DESTINATION_FOLDER + fileName;
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(src), new FileStream(dest, FileMode.Create), new StampingProperties
|
||||
());
|
||||
// Creating the appearance
|
||||
PdfSignatureAppearance appearance = signer.GetSignatureAppearance();
|
||||
signer.SetFieldName("Signature1");
|
||||
Rectangle rect = new Rectangle(0, 600, 100, 100);
|
||||
appearance.SetPageRect(rect);
|
||||
PdfFormXObject layer2 = appearance.GetLayer2();
|
||||
// Draw red rectangle with blue border
|
||||
new PdfCanvas(layer2, signer.GetDocument()).SaveState().SetFillColor(ColorConstants.RED).SetStrokeColor(ColorConstants
|
||||
.BLUE).Rectangle(0, 0, 100, 100).FillStroke().RestoreState();
|
||||
// Get the same layer once more, so that the logic when n0 is not null is triggered
|
||||
layer2 = appearance.GetLayer2();
|
||||
// Draw yellow circle with black border
|
||||
new PdfCanvas(layer2, signer.GetDocument()).SaveState().SetFillColor(ColorConstants.YELLOW).SetStrokeColor
|
||||
(ColorConstants.BLACK).Circle(50, 50, 50).FillStroke().RestoreState();
|
||||
// Signing
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
|
||||
CompareSignatureAppearances(dest, SOURCE_FOLDER + "cmp_" + fileName);
|
||||
}
|
||||
|
||||
private static void CompareSignatureAppearances(String outPdf, String cmpPdf) {
|
||||
TSpdfTest.PrintOutCmpPdfNameAndDir(outPdf, cmpPdf);
|
||||
using (PdfDocument outDoc = new PdfDocument(new PdfReader(outPdf))) {
|
||||
using (PdfDocument cmpDoc = new PdfDocument(new PdfReader(cmpPdf))) {
|
||||
PdfDictionary outN = (PdfDictionary)PdfAcroForm.GetAcroForm(outDoc, false).GetField("Signature1").GetPdfObject
|
||||
().GetAsDictionary(PdfName.AP).Get(PdfName.N).GetIndirectReference().GetRefersTo();
|
||||
PdfDictionary cmpN = (PdfDictionary)PdfAcroForm.GetAcroForm(cmpDoc, false).GetField("Signature1").GetPdfObject
|
||||
().GetAsDictionary(PdfName.AP).Get(PdfName.N).GetIndirectReference().GetRefersTo();
|
||||
NUnit.Framework.Assert.IsNull(new CompareTool().CompareDictionariesStructure(outN, cmpN));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void TestSignatureOnRotatedPage(int pageNum, PdfSignatureAppearance.RenderingMode renderingMode, StringBuilder
|
||||
assertionResults) {
|
||||
String fileName = "signaturesOnRotatedPages" + pageNum + "_mode_" + renderingMode.ToString() + ".pdf";
|
||||
String src = SOURCE_FOLDER + "documentWithRotatedPages.pdf";
|
||||
String dest = DESTINATION_FOLDER + fileName;
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(src), new FileStream(dest, FileMode.Create), new StampingProperties
|
||||
().UseAppendMode());
|
||||
PdfSignatureAppearance appearance = signer.GetSignatureAppearance();
|
||||
appearance.SetLayer2Text("Digitally signed by Test User. All rights reserved. Take care!").SetPageRect(new
|
||||
Rectangle(100, 100, 100, 50)).SetRenderingMode(renderingMode).SetSignatureGraphic(ImageDataFactory.Create
|
||||
(SOURCE_FOLDER + "TSpdf.png")).SetPageNumber(pageNum);
|
||||
signer.SetCertificationLevel(PdfSigner.NOT_CERTIFIED);
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
|
||||
// Make sure TSpdf can open the document
|
||||
new PdfDocument(new PdfReader(dest)).Close();
|
||||
try {
|
||||
// TODO DEVSIX-864 compareVisually() should be changed to compareByContent() because it slows down the test
|
||||
String testResult = new CompareTool().CompareVisually(dest, SOURCE_FOLDER + "cmp_" + fileName, DESTINATION_FOLDER
|
||||
, "diff_");
|
||||
if (null != testResult) {
|
||||
assertionResults.Append(testResult);
|
||||
}
|
||||
}
|
||||
catch (CompareTool.CompareToolExecutionException e) {
|
||||
assertionResults.Append(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void TestSignatureAppearanceAutoscale(String dest, Rectangle rect, PdfSignatureAppearance.RenderingMode
|
||||
renderingMode) {
|
||||
String src = SOURCE_FOLDER + "simpleDocument.pdf";
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(src), new FileStream(dest, FileMode.Create), new StampingProperties
|
||||
());
|
||||
// Creating the appearance
|
||||
signer.GetSignatureAppearance().SetLayer2FontSize(0).SetReason("Test 1").SetLocation("TestCity").SetPageRect
|
||||
(rect).SetRenderingMode(renderingMode).SetSignatureGraphic(ImageDataFactory.Create(SOURCE_FOLDER + "TSpdf.png"
|
||||
));
|
||||
signer.SetFieldName("Signature1");
|
||||
// Creating the signature
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
|
||||
}
|
||||
|
||||
private static void AssertAppearanceFontSize(String filename, float expectedFontSize) {
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfReader(filename));
|
||||
PdfAcroForm acroForm = PdfAcroForm.GetAcroForm(pdfDocument, false);
|
||||
PdfStream stream = acroForm.GetField("Signature1").GetWidgets()[0].GetNormalAppearanceObject().GetAsDictionary
|
||||
(PdfName.Resources).GetAsDictionary(PdfName.XObject).GetAsStream(new PdfName("FRM")).GetAsDictionary(PdfName
|
||||
.Resources).GetAsDictionary(PdfName.XObject).GetAsStream(new PdfName("n2"));
|
||||
String[] streamContents = TSpdf.Commons.Utils.StringUtil.Split(TSpdf.Commons.Utils.JavaUtil.GetStringForBytes
|
||||
(stream.GetBytes()), "\\s");
|
||||
String fontSize = null;
|
||||
for (int i = 1; i < streamContents.Length; i++) {
|
||||
if ("Tf".Equals(streamContents[i])) {
|
||||
fontSize = streamContents[i - 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
float foundFontSize = float.Parse(fontSize, System.Globalization.CultureInfo.InvariantCulture);
|
||||
NUnit.Framework.Assert.IsTrue(Math.Abs(foundFontSize - expectedFontSize) < 0.1 * expectedFontSize, MessageFormatUtil
|
||||
.Format("Font size: exptected {0}, found {1}", expectedFontSize, fontSize));
|
||||
}
|
||||
|
||||
private static IDictionary<int, IList<Rectangle>> GetIgnoredAreaTestMap(Rectangle ignoredArea) {
|
||||
IDictionary<int, IList<Rectangle>> result = new Dictionary<int, IList<Rectangle>>();
|
||||
result.Put(1, JavaUtil.ArraysAsList(ignoredArea));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures.Sign {
|
||||
[NUnit.Framework.Category("UnitTest")]
|
||||
public class PdfSignatureTest : ExtendedTSpdfTest {
|
||||
public static readonly String sourceFolder = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/sign/PdfSignatureTest/";
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SetByteRangeTest() {
|
||||
PdfSignature signature = GetTestSignature(sourceFolder + "simpleSignature.pdf");
|
||||
int[] byteRange = new int[] { 0, 141, 16526, 2494 };
|
||||
signature.SetByteRange(byteRange);
|
||||
PdfArray expected = new PdfArray((new int[] { 0, 141, 16526, 2494 }));
|
||||
NUnit.Framework.Assert.AreEqual(expected.ToIntArray(), signature.GetByteRange().ToIntArray());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SetContentsTest() {
|
||||
PdfSignature signature = GetTestSignature(sourceFolder + "simpleSignature.pdf");
|
||||
byte[] newContents = new PdfString("new TSpdf signature").GetValueBytes();
|
||||
signature.SetContents(newContents);
|
||||
NUnit.Framework.Assert.AreEqual("new TSpdf signature", signature.GetContents().GetValue());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SetAndGetCertTest() {
|
||||
PdfSignature signature = GetTestSignature(sourceFolder + "adbe.x509.rsa_sha1_signature.pdf");
|
||||
byte[] certChain = new PdfString("Hello, TSpdf!!").GetValueBytes();
|
||||
signature.SetCert(certChain);
|
||||
NUnit.Framework.Assert.AreEqual("Hello, TSpdf!!", signature.GetCertObject().ToString());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetCertObjectTest() {
|
||||
PdfSignature signature = GetTestSignature(sourceFolder + "adbe.x509.rsa_sha1_signature.pdf");
|
||||
NUnit.Framework.Assert.IsTrue(signature.GetCertObject().IsArray());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SetAndGetNameTest() {
|
||||
PdfSignature signature = GetTestSignature(sourceFolder + "simpleSignature.pdf");
|
||||
NUnit.Framework.Assert.IsNull(signature.GetName());
|
||||
String name = "TSpdf person";
|
||||
signature.SetName(name);
|
||||
NUnit.Framework.Assert.AreEqual(name, signature.GetName());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SetSignatureCreatorTest() {
|
||||
PdfSignature signature = GetTestSignature(sourceFolder + "noPropBuilds.pdf");
|
||||
NUnit.Framework.Assert.IsNull(signature.GetPdfObject().GetAsDictionary(PdfName.Prop_Build));
|
||||
signature.SetSignatureCreator("TSpdf.Name");
|
||||
String propBuild = signature.GetPdfObject().GetAsDictionary(PdfName.Prop_Build).GetAsDictionary(PdfName.App
|
||||
).GetAsName(PdfName.Name).GetValue();
|
||||
NUnit.Framework.Assert.AreEqual("TSpdf.Name", propBuild);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void PdfSignatureAppDefaultConstructorTest() {
|
||||
PdfSignatureApp signatureApp = new PdfSignatureApp();
|
||||
NUnit.Framework.Assert.IsTrue(signatureApp.GetPdfObject().IsDictionary());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void CertAsArrayNotStringTest() {
|
||||
PdfSignature signature = GetTestSignature(sourceFolder + "adbe.x509.rsa_sha1_signature.pdf");
|
||||
PdfObject certObject = signature.GetCertObject();
|
||||
NUnit.Framework.Assert.IsTrue(certObject is PdfArray);
|
||||
NUnit.Framework.Assert.IsNull(signature.GetCert());
|
||||
}
|
||||
|
||||
private static PdfSignature GetTestSignature(String pathToPdf) {
|
||||
using (PdfDocument doc = new PdfDocument(new PdfReader(pathToPdf))) {
|
||||
SignatureUtil sigUtil = new SignatureUtil(doc);
|
||||
return sigUtil.GetSignature("Signature1");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.IO;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Kernel.Geom;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures.Sign {
|
||||
[NUnit.Framework.Category("BouncyCastleIntegrationTest")]
|
||||
public class SequentialSignaturesTest : ExtendedTSpdfTest {
|
||||
private static readonly String certsSrc = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/";
|
||||
|
||||
private static readonly String sourceFolder = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/sign/SequentialSignaturesTest/";
|
||||
|
||||
private static readonly String destinationFolder = NUnit.Framework.TestContext.CurrentContext.TestDirectory
|
||||
+ "/test/TSpdf/signatures/sign/SequentialSignaturesTest/";
|
||||
|
||||
private static readonly char[] password = "testpassphrase".ToCharArray();
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
CreateOrClearDestinationFolder(destinationFolder);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SequentialSignOfFileWithAnnots() {
|
||||
String signCertFileName = certsSrc + "signCertRsa01.pem";
|
||||
String outFileName = destinationFolder + "sequentialSignOfFileWithAnnots.pdf";
|
||||
String srcFileName = sourceFolder + "signedWithAnnots.pdf";
|
||||
String cmpFileName = sourceFolder + "cmp_sequentialSignOfFileWithAnnots.pdf";
|
||||
IX509Certificate[] signChain = PemFileHelper.ReadFirstChain(signCertFileName);
|
||||
IPrivateKey signPrivateKey = PemFileHelper.ReadFirstKey(signCertFileName, password);
|
||||
IExternalSignature pks = new PrivateKeySignature(signPrivateKey, DigestAlgorithms.SHA256);
|
||||
String signatureName = "Signature2";
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(srcFileName), new FileStream(outFileName, FileMode.Create),
|
||||
new StampingProperties().UseAppendMode());
|
||||
signer.SetFieldName(signatureName);
|
||||
signer.GetSignatureAppearance().SetPageRect(new Rectangle(50, 350, 200, 100)).SetReason("Test").SetLocation
|
||||
("TestCity").SetLayer2Text("Approval test signature.\nCreated by TSpdf7.");
|
||||
signer.SignDetached(pks, signChain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
|
||||
PadesSigTest.BasicCheckSignedDoc(outFileName, signatureName);
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outFileName, cmpFileName));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SecondSignOfTaggedDocTest() {
|
||||
String signCertFileName = certsSrc + "signCertRsa01.pem";
|
||||
String outFileName = destinationFolder + "secondSignOfTagged.pdf";
|
||||
String srcFileName = sourceFolder + "taggedAndSignedDoc.pdf";
|
||||
String cmpFileName = sourceFolder + "cmp_secondSignOfTagged.pdf";
|
||||
IX509Certificate[] signChain = PemFileHelper.ReadFirstChain(signCertFileName);
|
||||
IPrivateKey signPrivateKey = PemFileHelper.ReadFirstKey(signCertFileName, password);
|
||||
IExternalSignature pks = new PrivateKeySignature(signPrivateKey, DigestAlgorithms.SHA256);
|
||||
String signatureName = "Signature2";
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(srcFileName), new FileStream(outFileName, FileMode.Create),
|
||||
new StampingProperties().UseAppendMode());
|
||||
PdfDocument document = signer.GetDocument();
|
||||
document.GetWriter().SetCompressionLevel(CompressionConstants.NO_COMPRESSION);
|
||||
signer.SetFieldName(signatureName);
|
||||
PdfSignatureAppearance appearance = signer.GetSignatureAppearance();
|
||||
appearance.SetPageNumber(1);
|
||||
signer.GetSignatureAppearance().SetPageRect(new Rectangle(50, 550, 200, 100)).SetReason("Test2").SetLocation
|
||||
("TestCity2").SetLayer2Text("Approval test signature #2.\nCreated by TSpdf7.");
|
||||
signer.SignDetached(pks, signChain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
|
||||
PadesSigTest.BasicCheckSignedDoc(outFileName, "Signature1");
|
||||
PadesSigTest.BasicCheckSignedDoc(outFileName, "Signature2");
|
||||
using (PdfDocument twiceSigned = new PdfDocument(new PdfReader(outFileName))) {
|
||||
using (PdfDocument resource = new PdfDocument(new PdfReader(srcFileName))) {
|
||||
float resourceStrElemNumber = resource.GetStructTreeRoot().GetPdfObject().GetAsArray(PdfName.K).GetAsDictionary
|
||||
(0).GetAsArray(PdfName.K).Size();
|
||||
float outStrElemNumber = twiceSigned.GetStructTreeRoot().GetPdfObject().GetAsArray(PdfName.K).GetAsDictionary
|
||||
(0).GetAsArray(PdfName.K).Size();
|
||||
// Here we assert the amount of objects in StructTreeRoot in resource file and twice signed file
|
||||
// as the original signature validation failed by Adobe because of struct tree change. If the fix
|
||||
// would make this tree unchanged, then the assertion should be adjusted with comparing the tree of
|
||||
// objects in StructTreeRoot to ensure that it won't be changed.
|
||||
NUnit.Framework.Assert.AreNotEqual(resourceStrElemNumber, outStrElemNumber);
|
||||
}
|
||||
}
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outFileName, cmpFileName));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.IO;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Bouncycastle.Security;
|
||||
using TSpdf.Forms;
|
||||
using TSpdf.Kernel.Geom;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Kernel.Utils;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Exceptions;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures.Sign {
|
||||
[NUnit.Framework.Category("BouncyCastleIntegrationTest")]
|
||||
public class SignDeferredTest : ExtendedTSpdfTest {
|
||||
private static readonly String certsSrc = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/";
|
||||
|
||||
private static readonly String sourceFolder = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/sign/SignDeferredTest/";
|
||||
|
||||
private static readonly String destinationFolder = NUnit.Framework.TestContext.CurrentContext.TestDirectory
|
||||
+ "/test/TSpdf/signatures/sign/SignDeferredTest/";
|
||||
|
||||
private static readonly char[] password = "testpassphrase".ToCharArray();
|
||||
|
||||
private const String HASH_ALGORITHM = DigestAlgorithms.SHA256;
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
CreateOrClearDestinationFolder(destinationFolder);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void PrepareDocForSignDeferredTest() {
|
||||
String input = sourceFolder + "helloWorldDoc.pdf";
|
||||
String output = destinationFolder + "newTemplateForSignDeferred.pdf";
|
||||
String sigFieldName = "DeferredSignature1";
|
||||
PdfName filter = PdfName.Adobe_PPKLite;
|
||||
PdfName subFilter = PdfName.Adbe_pkcs7_detached;
|
||||
int estimatedSize = 8192;
|
||||
PdfReader reader = new PdfReader(input);
|
||||
PdfSigner signer = new PdfSigner(reader, new FileStream(output, FileMode.Create), new StampingProperties()
|
||||
);
|
||||
PdfSignatureAppearance appearance = signer.GetSignatureAppearance();
|
||||
appearance.SetLayer2Text("Signature field which signing is deferred.").SetPageRect(new Rectangle(36, 600,
|
||||
200, 100)).SetPageNumber(1);
|
||||
signer.SetFieldName(sigFieldName);
|
||||
IExternalSignatureContainer external = new ExternalBlankSignatureContainer(filter, subFilter);
|
||||
signer.SignExternalContainer(external, estimatedSize);
|
||||
// validate result
|
||||
ValidateTemplateForSignedDeferredResult(output, sigFieldName, filter, subFilter, estimatedSize);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void PrepareDocForSignDeferredNotEnoughSizeTest() {
|
||||
String input = sourceFolder + "helloWorldDoc.pdf";
|
||||
String sigFieldName = "DeferredSignature1";
|
||||
PdfName filter = PdfName.Adobe_PPKLite;
|
||||
PdfName subFilter = PdfName.Adbe_pkcs7_detached;
|
||||
PdfReader reader = new PdfReader(input);
|
||||
PdfSigner signer = new PdfSigner(reader, new MemoryStream(), new StampingProperties());
|
||||
PdfSignatureAppearance appearance = signer.GetSignatureAppearance();
|
||||
appearance.SetLayer2Text("Signature field which signing is deferred.").SetPageRect(new Rectangle(36, 600,
|
||||
200, 100)).SetPageNumber(1);
|
||||
signer.SetFieldName(sigFieldName);
|
||||
IExternalSignatureContainer external = new ExternalBlankSignatureContainer(filter, subFilter);
|
||||
// This size is definitely not enough
|
||||
int estimatedSize = -1;
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(System.IO.IOException), () => signer.SignExternalContainer
|
||||
(external, estimatedSize));
|
||||
NUnit.Framework.Assert.AreEqual(SignExceptionMessageConstant.NOT_ENOUGH_SPACE, e.Message);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void PrepareDocForSignDeferredLittleSpaceTest() {
|
||||
String input = sourceFolder + "helloWorldDoc.pdf";
|
||||
String sigFieldName = "DeferredSignature1";
|
||||
PdfName filter = PdfName.Adobe_PPKLite;
|
||||
PdfName subFilter = PdfName.Adbe_pkcs7_detached;
|
||||
PdfReader reader = new PdfReader(input);
|
||||
PdfSigner signer = new PdfSigner(reader, new MemoryStream(), new StampingProperties());
|
||||
PdfSignatureAppearance appearance = signer.GetSignatureAppearance();
|
||||
appearance.SetLayer2Text("Signature field which signing is deferred.").SetPageRect(new Rectangle(36, 600,
|
||||
200, 100)).SetPageNumber(1);
|
||||
signer.SetFieldName(sigFieldName);
|
||||
IExternalSignatureContainer external = new ExternalBlankSignatureContainer(filter, subFilter);
|
||||
// This size is definitely not enough, however, the size check will pass.
|
||||
// The test will fail lately on an invalid key
|
||||
int estimatedSize = 0;
|
||||
Exception e = NUnit.Framework.Assert.Catch(typeof(ArgumentException), () => signer.SignExternalContainer(external
|
||||
, estimatedSize));
|
||||
NUnit.Framework.Assert.AreEqual(SignExceptionMessageConstant.TOO_BIG_KEY, e.Message);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void DeferredHashCalcAndSignTest01() {
|
||||
String srcFileName = sourceFolder + "templateForSignCMSDeferred.pdf";
|
||||
String outFileName = destinationFolder + "deferredHashCalcAndSignTest01.pdf";
|
||||
String cmpFileName = sourceFolder + "cmp_deferredHashCalcAndSignTest01.pdf";
|
||||
String signCertFileName = certsSrc + "signCertRsa01.pem";
|
||||
IX509Certificate[] signChain = PemFileHelper.ReadFirstChain(signCertFileName);
|
||||
IPrivateKey signPrivateKey = PemFileHelper.ReadFirstKey(signCertFileName, password);
|
||||
IExternalSignatureContainer extSigContainer = new SignDeferredTest.CmsDeferredSigner(signPrivateKey, signChain
|
||||
);
|
||||
String sigFieldName = "DeferredSignature1";
|
||||
PdfDocument docToSign = new PdfDocument(new PdfReader(srcFileName));
|
||||
FileStream outStream = new FileStream(outFileName, FileMode.Create);
|
||||
PdfSigner.SignDeferred(docToSign, sigFieldName, outStream, extSigContainer);
|
||||
docToSign.Close();
|
||||
outStream.Dispose();
|
||||
// validate result
|
||||
PadesSigTest.BasicCheckSignedDoc(outFileName, sigFieldName);
|
||||
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(outFileName, cmpFileName, destinationFolder
|
||||
, null));
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outFileName, cmpFileName));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void CalcHashOnDocCreationThenDeferredSignTest01() {
|
||||
String input = sourceFolder + "helloWorldDoc.pdf";
|
||||
String outFileName = destinationFolder + "calcHashOnDocCreationThenDeferredSignTest01.pdf";
|
||||
String cmpFileName = sourceFolder + "cmp_calcHashOnDocCreationThenDeferredSignTest01.pdf";
|
||||
// pre-calculate hash on creating pre-signed PDF
|
||||
String sigFieldName = "DeferredSignature1";
|
||||
PdfName filter = PdfName.Adobe_PPKLite;
|
||||
PdfName subFilter = PdfName.Adbe_pkcs7_detached;
|
||||
int estimatedSize = 8192;
|
||||
PdfReader reader = new PdfReader(input);
|
||||
MemoryStream baos = new MemoryStream();
|
||||
PdfSigner signer = new PdfSigner(reader, baos, new StampingProperties());
|
||||
signer.SetCertificationLevel(PdfSigner.CERTIFIED_NO_CHANGES_ALLOWED);
|
||||
PdfSignatureAppearance appearance = signer.GetSignatureAppearance();
|
||||
appearance.SetLayer2Text("Signature field which signing is deferred.").SetPageRect(new Rectangle(36, 600,
|
||||
200, 100)).SetPageNumber(1);
|
||||
signer.SetFieldName(sigFieldName);
|
||||
SignDeferredTest.DigestCalcBlankSigner external = new SignDeferredTest.DigestCalcBlankSigner(filter, subFilter
|
||||
);
|
||||
signer.SignExternalContainer(external, estimatedSize);
|
||||
byte[] docBytesHash = external.GetDocBytesHash();
|
||||
byte[] preSignedBytes = baos.ToArray();
|
||||
// sign the hash
|
||||
String signCertFileName = certsSrc + "signCertRsa01.pem";
|
||||
IX509Certificate[] signChain = PemFileHelper.ReadFirstChain(signCertFileName);
|
||||
IPrivateKey signPrivateKey = PemFileHelper.ReadFirstKey(signCertFileName, password);
|
||||
byte[] cmsSignature = SignDocBytesHash(docBytesHash, signPrivateKey, signChain);
|
||||
// fill the signature to the presigned document
|
||||
SignDeferredTest.ReadySignatureSigner extSigContainer = new SignDeferredTest.ReadySignatureSigner(cmsSignature
|
||||
);
|
||||
PdfDocument docToSign = new PdfDocument(new PdfReader(new MemoryStream(preSignedBytes)));
|
||||
FileStream outStream = new FileStream(outFileName, FileMode.Create);
|
||||
PdfSigner.SignDeferred(docToSign, sigFieldName, outStream, extSigContainer);
|
||||
docToSign.Close();
|
||||
outStream.Dispose();
|
||||
// validate result
|
||||
PadesSigTest.BasicCheckSignedDoc(outFileName, sigFieldName);
|
||||
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(outFileName, cmpFileName, destinationFolder
|
||||
, null));
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outFileName, cmpFileName));
|
||||
}
|
||||
|
||||
internal static void ValidateTemplateForSignedDeferredResult(String output, String sigFieldName, PdfName filter
|
||||
, PdfName subFilter, int estimatedSize) {
|
||||
PdfDocument outDocument = new PdfDocument(new PdfReader(output));
|
||||
PdfObject outSigDictObj = PdfAcroForm.GetAcroForm(outDocument, false).GetField(sigFieldName).GetValue();
|
||||
NUnit.Framework.Assert.IsTrue(outSigDictObj.IsDictionary());
|
||||
PdfDictionary outSigDict = (PdfDictionary)outSigDictObj;
|
||||
PdfArray byteRange = outSigDict.GetAsArray(PdfName.ByteRange);
|
||||
NUnit.Framework.Assert.IsNotNull(byteRange);
|
||||
NUnit.Framework.Assert.IsTrue(byteRange.Size() == 4);
|
||||
NUnit.Framework.Assert.AreEqual(filter, outSigDict.GetAsName(PdfName.Filter));
|
||||
NUnit.Framework.Assert.AreEqual(subFilter, outSigDict.GetAsName(PdfName.SubFilter));
|
||||
PdfString outSigContents = outSigDict.GetAsString(PdfName.Contents);
|
||||
NUnit.Framework.Assert.IsTrue(outSigContents.IsHexWriting());
|
||||
NUnit.Framework.Assert.AreEqual(new byte[estimatedSize], outSigContents.GetValueBytes());
|
||||
}
|
||||
|
||||
internal static byte[] CalcDocBytesHash(Stream docBytes) {
|
||||
byte[] docBytesHash = null;
|
||||
try {
|
||||
docBytesHash = DigestAlgorithms.Digest(docBytes, SignTestPortUtil.GetMessageDigest(HASH_ALGORITHM));
|
||||
}
|
||||
catch (Exception) {
|
||||
}
|
||||
// dummy catch clause
|
||||
return docBytesHash;
|
||||
}
|
||||
|
||||
internal static byte[] SignDocBytesHash(byte[] docBytesHash, IPrivateKey pk, IX509Certificate[] chain) {
|
||||
if (pk == null || chain == null) {
|
||||
return null;
|
||||
}
|
||||
byte[] signatureContent = null;
|
||||
try {
|
||||
PdfPKCS7 pkcs7 = new PdfPKCS7(null, chain, HASH_ALGORITHM, false);
|
||||
byte[] attributes = pkcs7.GetAuthenticatedAttributeBytes(docBytesHash, PdfSigner.CryptoStandard.CMS, null,
|
||||
null);
|
||||
PrivateKeySignature signature = new PrivateKeySignature(pk, HASH_ALGORITHM);
|
||||
byte[] attrSign = signature.Sign(attributes);
|
||||
pkcs7.SetExternalSignatureValue(attrSign, null, signature.GetSignatureAlgorithmName());
|
||||
signatureContent = pkcs7.GetEncodedPKCS7(docBytesHash);
|
||||
}
|
||||
catch (AbstractGeneralSecurityException) {
|
||||
}
|
||||
// dummy catch clause
|
||||
return signatureContent;
|
||||
}
|
||||
|
||||
internal class CmsDeferredSigner : IExternalSignatureContainer {
|
||||
private IPrivateKey pk;
|
||||
|
||||
private IX509Certificate[] chain;
|
||||
|
||||
public CmsDeferredSigner(IPrivateKey pk, IX509Certificate[] chain) {
|
||||
this.pk = pk;
|
||||
this.chain = chain;
|
||||
}
|
||||
|
||||
public virtual byte[] Sign(Stream docBytes) {
|
||||
byte[] docBytesHash = CalcDocBytesHash(docBytes);
|
||||
byte[] signatureContent = null;
|
||||
if (docBytesHash != null) {
|
||||
// sign the hash and create PKCS7 CMS signature
|
||||
signatureContent = SignDocBytesHash(docBytesHash, pk, chain);
|
||||
}
|
||||
if (signatureContent == null) {
|
||||
signatureContent = new byte[0];
|
||||
}
|
||||
return signatureContent;
|
||||
}
|
||||
|
||||
public virtual void ModifySigningDictionary(PdfDictionary signDic) {
|
||||
}
|
||||
}
|
||||
|
||||
internal class DigestCalcBlankSigner : IExternalSignatureContainer {
|
||||
private readonly PdfName filter;
|
||||
|
||||
private readonly PdfName subFilter;
|
||||
|
||||
private byte[] docBytesHash;
|
||||
|
||||
public DigestCalcBlankSigner(PdfName filter, PdfName subFilter) {
|
||||
this.filter = filter;
|
||||
this.subFilter = subFilter;
|
||||
}
|
||||
|
||||
public virtual byte[] GetDocBytesHash() {
|
||||
return docBytesHash;
|
||||
}
|
||||
|
||||
public virtual byte[] Sign(Stream docBytes) {
|
||||
docBytesHash = CalcDocBytesHash(docBytes);
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
public virtual void ModifySigningDictionary(PdfDictionary signDic) {
|
||||
signDic.Put(PdfName.Filter, filter);
|
||||
signDic.Put(PdfName.SubFilter, subFilter);
|
||||
}
|
||||
}
|
||||
|
||||
internal class ReadySignatureSigner : IExternalSignatureContainer {
|
||||
private byte[] cmsSignatureContents;
|
||||
|
||||
public ReadySignatureSigner(byte[] cmsSignatureContents) {
|
||||
this.cmsSignatureContents = cmsSignatureContents;
|
||||
}
|
||||
|
||||
public virtual byte[] Sign(Stream docBytes) {
|
||||
return cmsSignatureContents;
|
||||
}
|
||||
|
||||
public virtual void ModifySigningDictionary(PdfDictionary signDic) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Kernel.Geom;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Kernel.Utils;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures.Sign {
|
||||
[NUnit.Framework.Category("BouncyCastleIntegrationTest")]
|
||||
public class SimpleSigningTest : ExtendedTSpdfTest {
|
||||
private static readonly String SOURCE_FOLDER = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/sign/SimpleSigningTest/";
|
||||
|
||||
private static readonly String DESTINATION_FOLDER = NUnit.Framework.TestContext.CurrentContext.TestDirectory
|
||||
+ "/test/TSpdf/signatures/sign/SimpleSigningTest/";
|
||||
|
||||
private static readonly String CERTS_SRC = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/";
|
||||
|
||||
private static readonly char[] PASSWORD = "testpassphrase".ToCharArray();
|
||||
|
||||
private IX509Certificate[] chain;
|
||||
|
||||
private IPrivateKey pk;
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
CreateOrClearDestinationFolder(DESTINATION_FOLDER);
|
||||
}
|
||||
|
||||
[NUnit.Framework.SetUp]
|
||||
public virtual void Init() {
|
||||
pk = PemFileHelper.ReadFirstKey(CERTS_SRC + "signCertRsa01.pem", PASSWORD);
|
||||
chain = PemFileHelper.ReadFirstChain(CERTS_SRC + "signCertRsa01.pem");
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void PdfDocWithParagraphSigningTest() {
|
||||
String srcFile = SOURCE_FOLDER + "simpleDocument.pdf";
|
||||
String cmpPdf = SOURCE_FOLDER + "cmp_simpleSignature.pdf";
|
||||
String outPdf = DESTINATION_FOLDER + "simpleSignature.pdf";
|
||||
Rectangle rect = new Rectangle(36, 648, 200, 100);
|
||||
String fieldName = "Signature1";
|
||||
Sign(srcFile, fieldName, outPdf, chain, pk, DigestAlgorithms.SHA256, PdfSigner.CryptoStandard.CADES, "Test 1"
|
||||
, "TestCity", rect, false, false, PdfSigner.NOT_CERTIFIED, 12f);
|
||||
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(outPdf, cmpPdf, DESTINATION_FOLDER, "diff_"
|
||||
, GetTestMap(rect)));
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outPdf, cmpPdf));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignWithoutPKeyTest() {
|
||||
String srcFile = SOURCE_FOLDER + "emptySignatureWithoutPKey.pdf";
|
||||
String cmpPdf = SOURCE_FOLDER + "cmp_signedWithoutPKey.pdf";
|
||||
String outPdf = DESTINATION_FOLDER + "signedWithoutPKey.pdf";
|
||||
Rectangle rect = new Rectangle(36, 648, 200, 100);
|
||||
String fieldName = "Signature1";
|
||||
Sign(srcFile, fieldName, outPdf, chain, pk, DigestAlgorithms.SHA256, PdfSigner.CryptoStandard.CADES, "Test 1"
|
||||
, "TestCity", rect, false, false, PdfSigner.NOT_CERTIFIED, 12f);
|
||||
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(outPdf, cmpPdf, DESTINATION_FOLDER, "diff_"
|
||||
, GetTestMap(rect)));
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outPdf, cmpPdf));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SignWithTempFileTest() {
|
||||
String srcFile = SOURCE_FOLDER + "simpleDocument.pdf";
|
||||
String cmpPdf = SOURCE_FOLDER + "cmp_signedWithTempFile.pdf";
|
||||
String outPdf = DESTINATION_FOLDER + "signedWithTempFile.pdf";
|
||||
String tempFileName = "tempFile";
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(srcFile), new PdfWriter(outPdf), DESTINATION_FOLDER + tempFileName
|
||||
, new StampingProperties());
|
||||
Rectangle rect = new Rectangle(36, 648, 200, 100);
|
||||
signer.SetCertificationLevel(PdfSigner.NOT_CERTIFIED);
|
||||
signer.SetFieldName("Signature1");
|
||||
// Creating the appearance
|
||||
CreateAppearance(signer, "Test 1", "TestCity", false, rect, 12f);
|
||||
// Creating the signature
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
|
||||
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(outPdf, cmpPdf, DESTINATION_FOLDER, "diff_"
|
||||
, GetTestMap(rect)));
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outPdf, cmpPdf));
|
||||
}
|
||||
|
||||
protected internal virtual void Sign(String src, String name, String dest, IX509Certificate[] chain, IPrivateKey
|
||||
pk, String digestAlgorithm, PdfSigner.CryptoStandard subfilter, String reason, String location, Rectangle
|
||||
rectangleForNewField, bool setReuseAppearance, bool isAppendMode, int certificationLevel, float? fontSize
|
||||
) {
|
||||
PdfReader reader = new PdfReader(src);
|
||||
StampingProperties properties = new StampingProperties();
|
||||
if (isAppendMode) {
|
||||
properties.UseAppendMode();
|
||||
}
|
||||
PdfSigner signer = new PdfSigner(reader, new FileStream(dest, FileMode.Create), properties);
|
||||
signer.SetCertificationLevel(certificationLevel);
|
||||
// Creating the appearance
|
||||
CreateAppearance(signer, reason, location, setReuseAppearance, rectangleForNewField, fontSize);
|
||||
signer.SetFieldName(name);
|
||||
// Creating the signature
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, subfilter);
|
||||
}
|
||||
|
||||
private static IDictionary<int, IList<Rectangle>> GetTestMap(Rectangle ignoredArea) {
|
||||
IDictionary<int, IList<Rectangle>> result = new Dictionary<int, IList<Rectangle>>();
|
||||
result.Put(1, JavaUtil.ArraysAsList(ignoredArea));
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void CreateAppearance(PdfSigner signer, String reason, String location, bool setReuseAppearance
|
||||
, Rectangle rectangleForNewField, float? fontSize) {
|
||||
PdfSignatureAppearance appearance = signer.GetSignatureAppearance().SetReason(reason).SetLocation(location
|
||||
).SetReuseAppearance(setReuseAppearance);
|
||||
if (rectangleForNewField != null) {
|
||||
appearance.SetPageRect(rectangleForNewField);
|
||||
}
|
||||
if (fontSize != null) {
|
||||
appearance.SetLayer2FontSize((float)fontSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Kernel.Geom;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Kernel.Utils;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures.Sign {
|
||||
[NUnit.Framework.Category("BouncyCastleIntegrationTest")]
|
||||
public class TaggedPdfSigningTest : ExtendedTSpdfTest {
|
||||
private static readonly String SOURCE_FOLDER = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/sign/TaggedPdfSigningTest/";
|
||||
|
||||
private static readonly String DESTINATION_FOLDER = NUnit.Framework.TestContext.CurrentContext.TestDirectory
|
||||
+ "/test/TSpdf/signatures/sign/TaggedPdfSigningTest/";
|
||||
|
||||
private static readonly String CERTS_SRC = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/";
|
||||
|
||||
private static readonly char[] PASSWORD = "testpassphrase".ToCharArray();
|
||||
|
||||
private IX509Certificate[] chain;
|
||||
|
||||
private IPrivateKey pk;
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
CreateOrClearDestinationFolder(DESTINATION_FOLDER);
|
||||
}
|
||||
|
||||
[NUnit.Framework.SetUp]
|
||||
public virtual void Init() {
|
||||
pk = PemFileHelper.ReadFirstKey(CERTS_SRC + "signCertRsa01.pem", PASSWORD);
|
||||
chain = PemFileHelper.ReadFirstChain(CERTS_SRC + "signCertRsa01.pem");
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SigningTaggedDocumentTest() {
|
||||
String srcFile = SOURCE_FOLDER + "simpleTaggedDocument.pdf";
|
||||
String cmpPdf = SOURCE_FOLDER + "cmp_simpleTaggedDocument.pdf";
|
||||
String outPdf = DESTINATION_FOLDER + "simpleTaggedDocument.pdf";
|
||||
Rectangle rect = new Rectangle(36, 648, 200, 100);
|
||||
String fieldName = "Signature1";
|
||||
Sign(srcFile, fieldName, outPdf, chain, pk, DigestAlgorithms.SHA256, PdfSigner.CryptoStandard.CADES, "Test 1"
|
||||
, "TestCity", rect, false, false);
|
||||
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(outPdf, cmpPdf, DESTINATION_FOLDER, "diff_"
|
||||
, GetTestMap(rect)));
|
||||
NUnit.Framework.Assert.IsNull(new CompareTool().CompareTagStructures(outPdf, cmpPdf));
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outPdf, cmpPdf));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void SigningTaggedDocumentAppendModeTest() {
|
||||
String srcFile = SOURCE_FOLDER + "simpleTaggedDocumentAppendMode.pdf";
|
||||
String cmpPdf = SOURCE_FOLDER + "cmp_simpleTaggedDocumentAppendMode.pdf";
|
||||
String outPdf = DESTINATION_FOLDER + "signedTaggedDocumentAppendMode.pdf";
|
||||
Rectangle rect = new Rectangle(36, 648, 200, 100);
|
||||
String fieldName = "Signature1";
|
||||
Sign(srcFile, fieldName, outPdf, chain, pk, DigestAlgorithms.SHA256, PdfSigner.CryptoStandard.CADES, "Test 1"
|
||||
, "TestCity", rect, false, true);
|
||||
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(outPdf, cmpPdf, DESTINATION_FOLDER, "diff_"
|
||||
, GetTestMap(rect)));
|
||||
NUnit.Framework.Assert.IsNull(new CompareTool().CompareTagStructures(outPdf, cmpPdf));
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outPdf, cmpPdf));
|
||||
}
|
||||
|
||||
protected internal virtual void Sign(String src, String name, String dest, IX509Certificate[] chain, IPrivateKey
|
||||
pk, String digestAlgorithm, PdfSigner.CryptoStandard subfilter, String reason, String location, Rectangle
|
||||
rectangleForNewField, bool setReuseAppearance, bool isAppendMode) {
|
||||
Sign(src, name, dest, chain, pk, digestAlgorithm, subfilter, reason, location, rectangleForNewField, setReuseAppearance
|
||||
, isAppendMode, PdfSigner.NOT_CERTIFIED, null);
|
||||
}
|
||||
|
||||
protected internal virtual void Sign(String src, String name, String dest, IX509Certificate[] chain, IPrivateKey
|
||||
pk, String digestAlgorithm, PdfSigner.CryptoStandard subfilter, String reason, String location, Rectangle
|
||||
rectangleForNewField, bool setReuseAppearance, bool isAppendMode, int certificationLevel, float? fontSize
|
||||
) {
|
||||
PdfReader reader = new PdfReader(src);
|
||||
StampingProperties properties = new StampingProperties();
|
||||
if (isAppendMode) {
|
||||
properties.UseAppendMode();
|
||||
}
|
||||
PdfSigner signer = new PdfSigner(reader, new FileStream(dest, FileMode.Create), properties);
|
||||
signer.SetCertificationLevel(certificationLevel);
|
||||
// Creating the appearance
|
||||
PdfSignatureAppearance appearance = signer.GetSignatureAppearance().SetReason(reason).SetLocation(location
|
||||
).SetReuseAppearance(setReuseAppearance);
|
||||
if (rectangleForNewField != null) {
|
||||
appearance.SetPageRect(rectangleForNewField);
|
||||
}
|
||||
if (fontSize != null) {
|
||||
appearance.SetLayer2FontSize((float)fontSize);
|
||||
}
|
||||
signer.SetFieldName(name);
|
||||
// Creating the signature
|
||||
IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm);
|
||||
signer.SignDetached(pks, chain, null, null, null, 0, subfilter);
|
||||
}
|
||||
|
||||
private static IDictionary<int, IList<Rectangle>> GetTestMap(Rectangle ignoredArea) {
|
||||
IDictionary<int, IList<Rectangle>> result = new Dictionary<int, IList<Rectangle>>();
|
||||
result.Put(1, JavaUtil.ArraysAsList(ignoredArea));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.IO;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Signatures.Testutils.Client;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures.Sign {
|
||||
[NUnit.Framework.Category("BouncyCastleIntegrationTest")]
|
||||
public class TimestampSigTest : ExtendedTSpdfTest {
|
||||
private static readonly String certsSrc = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/";
|
||||
|
||||
private static readonly String sourceFolder = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/sign/TimestampSigTest/";
|
||||
|
||||
private static readonly String destinationFolder = NUnit.Framework.TestContext.CurrentContext.TestDirectory
|
||||
+ "/test/TSpdf/signatures/sign/TimestampSigTest/";
|
||||
|
||||
private static readonly char[] password = "testpassphrase".ToCharArray();
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
CreateOrClearDestinationFolder(destinationFolder);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TimestampTest01() {
|
||||
String tsaCertFileName = certsSrc + "tsCertRsa.pem";
|
||||
String srcFileName = sourceFolder + "helloWorldDoc.pdf";
|
||||
String outFileName = destinationFolder + "timestampTest01.pdf";
|
||||
IX509Certificate[] tsaChain = PemFileHelper.ReadFirstChain(tsaCertFileName);
|
||||
IPrivateKey tsaPrivateKey = PemFileHelper.ReadFirstKey(tsaCertFileName, password);
|
||||
PdfSigner signer = new PdfSigner(new PdfReader(srcFileName), new FileStream(outFileName, FileMode.Create),
|
||||
new StampingProperties());
|
||||
TestTsaClient testTsa = new TestTsaClient(JavaUtil.ArraysAsList(tsaChain), tsaPrivateKey);
|
||||
signer.Timestamp(testTsa, "timestampSig1");
|
||||
PadesSigTest.BasicCheckSignedDoc(destinationFolder + "timestampTest01.pdf", "timestampSig1");
|
||||
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outFileName, sourceFolder + "cmp_timestampTest01.pdf"
|
||||
));
|
||||
}
|
||||
// TimeStampToken tsWrong = new TimeStampResponse(Files.readAllBytes(Paths.get("c:\\Users\\yulian\\Desktop\\myTs"))).getTimeStampToken();
|
||||
//
|
||||
// JcaSimpleSignerInfoVerifierBuilder sigVerifBuilder = new JcaSimpleSignerInfoVerifierBuilder();
|
||||
// X509Certificate caCert = (X509Certificate)Pkcs12FileHelper.readFirstChain(p12FileName, password)[0];
|
||||
// SignerInformationVerifier signerInfoVerif = sigVerifBuilder.setProvider(BouncyCastleProvider.PROVIDER_NAME).build(caCert.getPublicKey());
|
||||
// boolean signatureValid = tsWrong.isSignatureValid(signerInfoVerif);
|
||||
//
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Bouncycastle.Openssl;
|
||||
|
||||
namespace TSpdf.Signatures.Testutils {
|
||||
public sealed class PemFileHelper {
|
||||
private static readonly IBouncyCastleFactory FACTORY = BouncyCastleFactoryCreator.GetFactory();
|
||||
|
||||
private PemFileHelper() {
|
||||
// Empty constructor.
|
||||
}
|
||||
|
||||
public static IX509Certificate[] ReadFirstChain(String pemFileName) {
|
||||
return ReadCertificates(pemFileName).ToArray(new IX509Certificate[0]);
|
||||
}
|
||||
|
||||
public static IPrivateKey ReadFirstKey(String pemFileName, char[] keyPass) {
|
||||
return ReadPrivateKey(pemFileName, keyPass);
|
||||
}
|
||||
|
||||
public static List<IX509Certificate> InitStore(String pemFileName) {
|
||||
IX509Certificate[] chain = ReadFirstChain(pemFileName);
|
||||
return chain.Length > 0 ? new List<IX509Certificate> { chain[0] } : chain.ToList();
|
||||
}
|
||||
|
||||
private static IList<IX509Certificate> ReadCertificates(String pemFileName) {
|
||||
using (TextReader file = new StreamReader(pemFileName)) {
|
||||
IPEMParser parser = FACTORY.CreatePEMParser(file, null);
|
||||
Object readObject = parser.ReadObject();
|
||||
IList<IX509Certificate> certificates = new List<IX509Certificate>();
|
||||
while (readObject != null) {
|
||||
if (readObject is IX509Certificate) {
|
||||
certificates.Add((IX509Certificate)readObject);
|
||||
}
|
||||
readObject = parser.ReadObject();
|
||||
}
|
||||
return certificates;
|
||||
}
|
||||
}
|
||||
|
||||
private static IPrivateKey ReadPrivateKey(String pemFileName, char[] keyPass) {
|
||||
using (TextReader file = new StreamReader(pemFileName)) {
|
||||
IPEMParser parser = FACTORY.CreatePEMParser(file, keyPass);
|
||||
Object readObject = parser.ReadObject();
|
||||
while (!(readObject is IPrivateKey) && readObject != null) {
|
||||
readObject = parser.ReadObject();
|
||||
}
|
||||
return (IPrivateKey)readObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Cert.Ocsp;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto.Generators;
|
||||
using TSpdf.Commons.Bouncycastle.Math;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
|
||||
namespace TSpdf.Signatures.Testutils {
|
||||
public class SignTestPortUtil {
|
||||
private static readonly IBouncyCastleFactory FACTORY = BouncyCastleFactoryCreator.GetFactory();
|
||||
|
||||
public static ICertificateID GenerateCertificateId(IX509Certificate issuerCert, IBigInteger serialNumber, String hashAlgorithm) {
|
||||
return FACTORY.CreateCertificateID(hashAlgorithm, issuerCert, serialNumber);
|
||||
}
|
||||
|
||||
public static IOCSPReq GenerateOcspRequestWithNonce(ICertificateID id) {
|
||||
IOCSPReqBuilder gen = FACTORY.CreateOCSPReqBuilder();
|
||||
gen.AddRequest(id);
|
||||
|
||||
// create details for nonce extension
|
||||
IDictionary extensions = new Hashtable();
|
||||
|
||||
extensions[FACTORY.CreateOCSPObjectIdentifiers().GetIdPkixOcspNonce()] = FACTORY.CreateExtension(false,
|
||||
FACTORY.CreateDEROctetString(FACTORY.CreateDEROctetString(PdfEncryption.GenerateNewDocumentId()).GetEncoded()));
|
||||
|
||||
gen.SetRequestExtensions(FACTORY.CreateExtensions(extensions));
|
||||
return gen.Build();
|
||||
}
|
||||
|
||||
public static IIDigest GetMessageDigest(String hashAlgorithm) {
|
||||
return FACTORY.CreateIDigest(hashAlgorithm);
|
||||
}
|
||||
|
||||
public static IX509Crl ParseCrlFromStream(Stream input) {
|
||||
return FACTORY.CreateX509Crl(input);
|
||||
}
|
||||
|
||||
public static IRsaKeyPairGenerator BuildRSA2048KeyPairGenerator() {
|
||||
return FACTORY.CreateRsa2048KeyPairGenerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,555 @@
|
||||
/*
|
||||
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: Bruno Lowagie, Paulo Soares, et al.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1.Util;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.IO.Util;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures.Testutils {
|
||||
public class SignaturesCompareTool {
|
||||
private static readonly IBouncyCastleFactory BOUNCY_CASTLE_FACTORY = BouncyCastleFactoryCreator.GetFactory
|
||||
();
|
||||
|
||||
private const String OID_MESSAGE_DIGEST = "1.2.840.113549.1.9.4";
|
||||
|
||||
private const String OID_SIGNED_DATA = "1.2.840.113549.1.7.2";
|
||||
|
||||
private const String OID_TST_INFO = "1.2.840.113549.1.9.16.1.4";
|
||||
|
||||
private const String OID_SIGNING_TIME = "1.2.840.113549.1.9.5";
|
||||
|
||||
private const String OID_SIGNATURE_TIMESTAMP_ATTRIBUTE = "1.2.840.113549.1.9.16.2.14";
|
||||
|
||||
private const String OID_ADBE_REVOCATION_INFO_ARCHIVAL = "1.2.840.113583.1.1.8";
|
||||
|
||||
private const String OID_OCSP_RESPONSE = "1.3.6.1.5.5.7.48.1.1";
|
||||
|
||||
private const String OID_OCSP_NONCE_EXTENSION = "1.3.6.1.5.5.7.48.1.2";
|
||||
|
||||
private static readonly IASN1Dump DUMP = BOUNCY_CASTLE_FACTORY.CreateASN1Dump();
|
||||
|
||||
private static readonly ICollection<String> IGNORED_OIDS;
|
||||
|
||||
static SignaturesCompareTool() {
|
||||
HashSet<String> tempSet = new HashSet<String>();
|
||||
tempSet.Add(OID_MESSAGE_DIGEST);
|
||||
tempSet.Add(OID_TST_INFO);
|
||||
tempSet.Add(OID_SIGNING_TIME);
|
||||
tempSet.Add(OID_OCSP_NONCE_EXTENSION);
|
||||
IGNORED_OIDS = JavaCollectionsUtil.UnmodifiableSet(tempSet);
|
||||
}
|
||||
|
||||
public static String CompareSignatures(String dest, String cmp) {
|
||||
return CompareSignatures(dest, cmp, new ReaderProperties(), new ReaderProperties());
|
||||
}
|
||||
|
||||
public static String CompareSignatures(String dest, String cmp, ReaderProperties destProperties, ReaderProperties
|
||||
cmpProperties) {
|
||||
TSpdfTest.PrintOutCmpPdfNameAndDir(dest, cmp);
|
||||
StringBuilder errorText = new StringBuilder();
|
||||
try {
|
||||
using (PdfDocument outDocument = new PdfDocument(new PdfReader(dest, destProperties))) {
|
||||
using (PdfDocument cmpDocument = new PdfDocument(new PdfReader(cmp, cmpProperties))) {
|
||||
SignatureUtil outSigUtil = new SignatureUtil(outDocument);
|
||||
SignatureUtil cmpSigUtil = new SignatureUtil(cmpDocument);
|
||||
if (!Enumerable.SequenceEqual(cmpSigUtil.GetSignatureNames(), outSigUtil.GetSignatureNames())) {
|
||||
AddError(errorText, "Signatures lists are different:", outSigUtil.GetSignatureNames().ToString(), cmpSigUtil
|
||||
.GetSignatureNames().ToString());
|
||||
}
|
||||
IList<String> signatures = cmpSigUtil.GetSignatureNames();
|
||||
foreach (String sig in signatures) {
|
||||
IASN1Sequence outSignedData = BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(GetSignatureContent(sig, outSigUtil
|
||||
));
|
||||
IASN1Sequence cmpSignedData = BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(GetSignatureContent(sig, cmpSigUtil
|
||||
));
|
||||
bool isEqual = CompareSignedData(outSignedData, cmpSignedData, errorText);
|
||||
if (!isEqual) {
|
||||
CreateTxtFilesFromAsn1Sequences(outSignedData, cmpSignedData, dest, sig, errorText);
|
||||
}
|
||||
}
|
||||
CompareDssEntries(outDocument, cmpDocument, dest, errorText);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
errorText.Append(e.Message);
|
||||
}
|
||||
return String.IsNullOrEmpty(errorText.ToString()) ? null : errorText.ToString();
|
||||
}
|
||||
|
||||
private static void CreateTxtFilesFromAsn1Sequences(IASN1Sequence outSignedData, IASN1Sequence cmpSignedData
|
||||
, String dest, String sig, StringBuilder errorText) {
|
||||
String sigFileName = dest.JSubstring(0, dest.LastIndexOf("."));
|
||||
String outSigFile = sigFileName + "_" + sig + "_out.txt";
|
||||
String cmpSigFile = sigFileName + "_" + sig + "_cmp.txt";
|
||||
WriteToFile(outSigFile, sig + "\n" + DUMP.DumpAsString(outSignedData, true) + "\n");
|
||||
WriteToFile(cmpSigFile, sig + "\n" + DUMP.DumpAsString(cmpSignedData, true) + "\n");
|
||||
errorText.Insert(0, "See signature output files: " + "\nout: " + UrlUtil.GetNormalizedFileUriString(outSigFile
|
||||
) + "\ncmp: " + UrlUtil.GetNormalizedFileUriString(cmpSigFile) + "\n");
|
||||
}
|
||||
|
||||
private static bool CompareDssEntries(PdfDocument outDocument, PdfDocument cmpDocument, String dest, StringBuilder
|
||||
errorText) {
|
||||
PdfDictionary outDss = outDocument.GetCatalog().GetPdfObject().GetAsDictionary(PdfName.DSS);
|
||||
PdfDictionary cmpDss = cmpDocument.GetCatalog().GetPdfObject().GetAsDictionary(PdfName.DSS);
|
||||
if (outDss == null || cmpDss == null) {
|
||||
if (outDss == cmpDss) {
|
||||
return true;
|
||||
}
|
||||
AddError(errorText, "DSS dictionaries are different");
|
||||
return false;
|
||||
}
|
||||
bool ocspCertificatesEqual = CompareRevocationDataFromDss(outDss, cmpDss, PdfName.OCSPs, dest, errorText,
|
||||
(outSequence, cmpSequence, errorStringBuilder) => SignaturesCompareTool.CompareAsn1Structures(outSequence
|
||||
, cmpSequence, errorStringBuilder));
|
||||
bool crlCertificatesEqual = CompareRevocationDataFromDss(outDss, cmpDss, PdfName.CRLs, dest, errorText, (outSequence
|
||||
, cmpSequence, errorStringBuilder) => SignaturesCompareTool.CompareSequencesWithSignatureValue(outSequence
|
||||
, cmpSequence, errorStringBuilder));
|
||||
return ocspCertificatesEqual && crlCertificatesEqual;
|
||||
}
|
||||
|
||||
private static bool CompareRevocationDataFromDss(PdfDictionary outDss, PdfDictionary cmpDss, PdfName entryName
|
||||
, String dest, StringBuilder errorText, SignaturesCompareTool.SequenceComparator comparator) {
|
||||
String errorMessage = entryName.GetValue() + " entries inside DSS dictionaries are different";
|
||||
PdfArray outDssEntry = outDss.GetAsArray(entryName);
|
||||
PdfArray cmpDssEntry = cmpDss.GetAsArray(entryName);
|
||||
if (outDssEntry == null || cmpDssEntry == null) {
|
||||
if (outDssEntry == cmpDssEntry) {
|
||||
return true;
|
||||
}
|
||||
AddError(errorText, errorMessage);
|
||||
return false;
|
||||
}
|
||||
if (outDssEntry.Size() != cmpDssEntry.Size()) {
|
||||
AddError(errorText, errorMessage);
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < outDssEntry.Size(); ++i) {
|
||||
PdfStream outDssEntryItem = outDssEntry.GetAsStream(i);
|
||||
PdfStream cmpDssEntryItem = cmpDssEntry.GetAsStream(i);
|
||||
if (outDssEntryItem == null || cmpDssEntryItem == null) {
|
||||
if (outDssEntryItem == cmpDssEntryItem) {
|
||||
continue;
|
||||
}
|
||||
AddError(errorText, errorMessage);
|
||||
return false;
|
||||
}
|
||||
IASN1Sequence outDecodedItem = BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(outDssEntryItem.GetBytes());
|
||||
IASN1Sequence cmpDecodedItem = BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(cmpDssEntryItem.GetBytes());
|
||||
if (!comparator(outDecodedItem, cmpDecodedItem, errorText)) {
|
||||
CreateTxtFilesFromAsn1Sequences(outDecodedItem, cmpDecodedItem, dest, "DSS_" + entryName.GetValue() + "_"
|
||||
+ i, errorText);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool CompareOcspResponses(IASN1Encodable[] outOcspResponse, IASN1Encodable[] cmpOcspResponse
|
||||
, StringBuilder errorText) {
|
||||
if (outOcspResponse.Length != 2 || cmpOcspResponse.Length != 2) {
|
||||
AddError(errorText, "OCSP response has unexpected structure");
|
||||
}
|
||||
IASN1OctetString outResponseString = BOUNCY_CASTLE_FACTORY.CreateASN1OctetString(outOcspResponse[1]);
|
||||
IASN1OctetString cmpResponseString = BOUNCY_CASTLE_FACTORY.CreateASN1OctetString(cmpOcspResponse[1]);
|
||||
if (outResponseString.Equals(cmpResponseString)) {
|
||||
return true;
|
||||
}
|
||||
IASN1Sequence parsedOutResponse = BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(outResponseString.GetOctets());
|
||||
IASN1Sequence parsedCmpResponse = BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(cmpResponseString.GetOctets());
|
||||
return CompareSequencesWithSignatureValue(parsedOutResponse, parsedCmpResponse, errorText);
|
||||
}
|
||||
|
||||
/// <summary>SignedData is top-level CMS-object for signatures, see "5.1.</summary>
|
||||
/// <remarks>
|
||||
/// SignedData is top-level CMS-object for signatures, see "5.1. SignedData Type" at
|
||||
/// https://datatracker.ietf.org/doc/html/rfc5652#section-5.1 .
|
||||
/// </remarks>
|
||||
/// <param name="outSignedData">current output signed data</param>
|
||||
/// <param name="cmpSignedData">reference signed data used for comparison as a ground truth</param>
|
||||
/// <param name="errorText">string builder in order to accumulate errors</param>
|
||||
/// <returns>true if signed data objects are the similar, false otherwise</returns>
|
||||
private static bool CompareSignedData(IASN1Sequence outSignedData, IASN1Sequence cmpSignedData, StringBuilder
|
||||
errorText) {
|
||||
if (outSignedData.Size() != cmpSignedData.Size() || outSignedData.Size() != 2) {
|
||||
AddError(errorText, "Signature top level elements count is incorrect (should be exactly 2):", outSignedData
|
||||
.Size().ToString(), cmpSignedData.Size().ToString());
|
||||
return false;
|
||||
}
|
||||
IASN1ObjectIdentifier outObjId = BOUNCY_CASTLE_FACTORY.CreateASN1ObjectIdentifier(outSignedData.GetObjectAt
|
||||
(0));
|
||||
IASN1ObjectIdentifier cmpObjId = BOUNCY_CASTLE_FACTORY.CreateASN1ObjectIdentifier(cmpSignedData.GetObjectAt
|
||||
(0));
|
||||
if (!outObjId.Equals(cmpObjId) || !outObjId.GetId().Equals(OID_SIGNED_DATA)) {
|
||||
AddError(errorText, "Signatures object identifier is incorrect (should be " + OID_SIGNED_DATA + ")", outObjId
|
||||
.GetId().ToString(), cmpObjId.GetId().ToString());
|
||||
return false;
|
||||
}
|
||||
IASN1Sequence outContent = BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(BOUNCY_CASTLE_FACTORY.CreateASN1TaggedObject
|
||||
(outSignedData.GetObjectAt(1)).GetObject());
|
||||
IASN1Sequence cmpContent = BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(BOUNCY_CASTLE_FACTORY.CreateASN1TaggedObject
|
||||
(cmpSignedData.GetObjectAt(1)).GetObject());
|
||||
if (outContent.Size() != cmpContent.Size()) {
|
||||
AddError(errorText, "Signatures base elements counts are different", outContent.Size().ToString(), cmpContent
|
||||
.Size().ToString());
|
||||
return false;
|
||||
}
|
||||
int signerInfoIndex = GetSignerInfoIndex(cmpContent);
|
||||
if (BOUNCY_CASTLE_FACTORY.CreateASN1Set(outContent.GetObjectAt(signerInfoIndex)) == null) {
|
||||
AddError(errorText, "SignerInfo object indexes are different", null, null);
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < cmpContent.Size(); i++) {
|
||||
// SignerInfo objects will be compared separately
|
||||
if (i == signerInfoIndex) {
|
||||
continue;
|
||||
}
|
||||
// Sequences and sets related to timestamp token info should be ignored.
|
||||
if (OID_TST_INFO.Equals(GetASN1ObjectId(cmpContent.GetObjectAt(i).ToASN1Primitive())) && OID_TST_INFO.Equals
|
||||
(GetASN1ObjectId(outContent.GetObjectAt(i).ToASN1Primitive()))) {
|
||||
continue;
|
||||
}
|
||||
if (!cmpContent.GetObjectAt(i).Equals(outContent.GetObjectAt(i))) {
|
||||
AddError(errorText, "SignedData objects are different", null, null);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
IASN1Set cmpSignerInfos = BOUNCY_CASTLE_FACTORY.CreateASN1Set(cmpContent.GetObjectAt(signerInfoIndex));
|
||||
IASN1Set outSignerInfos = BOUNCY_CASTLE_FACTORY.CreateASN1Set(outContent.GetObjectAt(signerInfoIndex));
|
||||
// Currently, TSpdf signature validation mechanism do not support signatures,
|
||||
// containing more than one SignerInfo entry. However, it is still valid signature.
|
||||
if (cmpSignerInfos.Size() != outSignerInfos.Size() || cmpSignerInfos.Size() != 1) {
|
||||
AddError(errorText, "Incorrect SignerInfos objects count", outSignerInfos.Size().ToString(), cmpSignerInfos
|
||||
.Size().ToString());
|
||||
return false;
|
||||
}
|
||||
IASN1Sequence outSignerInfo = BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(outSignerInfos.GetObjectAt(0));
|
||||
IASN1Sequence cmpSignerInfo = BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(cmpSignerInfos.GetObjectAt(0));
|
||||
return CompareSequencesWithSignatureValue(outSignerInfo, cmpSignerInfo, errorText);
|
||||
}
|
||||
|
||||
private static bool CompareSequencesWithSignatureValue(IASN1Sequence outSequence, IASN1Sequence cmpSequence
|
||||
, StringBuilder errorText) {
|
||||
if (cmpSequence.Size() != outSequence.Size()) {
|
||||
AddError(errorText, "Incorrect SignerInfo entries count", outSequence.Size().ToString(), cmpSequence.Size(
|
||||
).ToString());
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < cmpSequence.Size(); i++) {
|
||||
// Skipping comparison of encoded strings fields which are SignatureValue fields.
|
||||
// They are expected to be different.
|
||||
if (BOUNCY_CASTLE_FACTORY.CreateASN1OctetString(outSequence.GetObjectAt(i)) != null || BOUNCY_CASTLE_FACTORY
|
||||
.CreateASN1BitString(outSequence.GetObjectAt(i)) != null) {
|
||||
if (outSequence.GetObjectAt(i).GetType().Equals(cmpSequence.GetObjectAt(i).GetType())) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
AddError(errorText, "Signature values indexes are different!", null, null);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!CompareAsn1Structures(outSequence.GetObjectAt(i).ToASN1Primitive(), cmpSequence.GetObjectAt(i).ToASN1Primitive
|
||||
(), errorText)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool CompareAsn1Structures(IASN1Primitive @out, IASN1Primitive cmp, StringBuilder errorText
|
||||
) {
|
||||
if (!@out.GetType().Equals(cmp.GetType())) {
|
||||
AddError(errorText, "ASN1 objects types are different", @out.GetType().FullName, cmp.GetType().FullName);
|
||||
return false;
|
||||
}
|
||||
if (BOUNCY_CASTLE_FACTORY.CreateASN1TaggedObject(cmp) != null) {
|
||||
return CompareAsn1Structures(BOUNCY_CASTLE_FACTORY.CreateASN1TaggedObject(@out).GetObject(), BOUNCY_CASTLE_FACTORY
|
||||
.CreateASN1TaggedObject(cmp).GetObject(), errorText);
|
||||
}
|
||||
else {
|
||||
if (BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(cmp) != null) {
|
||||
if (!CompareContainers(BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(@out).ToArray(), BOUNCY_CASTLE_FACTORY.CreateASN1Sequence
|
||||
(cmp).ToArray(), errorText)) {
|
||||
AddError(errorText, "ASN1Sequence objects are different");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (BOUNCY_CASTLE_FACTORY.CreateASN1Set(cmp) != null) {
|
||||
if (!CompareContainers(BOUNCY_CASTLE_FACTORY.CreateASN1Set(@out).ToArray(), BOUNCY_CASTLE_FACTORY.CreateASN1Set
|
||||
(cmp).ToArray(), errorText)) {
|
||||
AddError(errorText, "ASN1Set objects are different");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (BOUNCY_CASTLE_FACTORY.CreateASN1GeneralizedTime(cmp) != null || BOUNCY_CASTLE_FACTORY.CreateASN1UTCTime
|
||||
(cmp) != null) {
|
||||
// Ignore time values since usually they shouldn't be equal
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (!cmp.Equals(@out)) {
|
||||
AddError(errorText, "ASN1 objects are different", DUMP.DumpAsString(@out, true), DUMP.DumpAsString(cmp, true
|
||||
));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool CompareContainers(IASN1Encodable[] outArray, IASN1Encodable[] cmpArray, StringBuilder
|
||||
errorText) {
|
||||
if (cmpArray.Length != outArray.Length) {
|
||||
AddError(errorText, "Container lengths are different", JavaUtil.IntegerToString(outArray.Length), JavaUtil.IntegerToString
|
||||
(cmpArray.Length));
|
||||
return false;
|
||||
}
|
||||
String cmpASN1ObjectId = GetASN1ObjectId(cmpArray);
|
||||
String outASN1ObjectId = GetASN1ObjectId(outArray);
|
||||
if (!Object.Equals(cmpASN1ObjectId, outASN1ObjectId)) {
|
||||
AddError(errorText, "Containers ids are different", outASN1ObjectId, cmpASN1ObjectId);
|
||||
return false;
|
||||
}
|
||||
if (IGNORED_OIDS.Contains(cmpASN1ObjectId)) {
|
||||
return true;
|
||||
}
|
||||
if (OID_SIGNATURE_TIMESTAMP_ATTRIBUTE.Equals(cmpASN1ObjectId)) {
|
||||
return CompareTimestampAttributes(outArray, cmpArray, errorText);
|
||||
}
|
||||
if (OID_OCSP_RESPONSE.Equals(cmpASN1ObjectId)) {
|
||||
return CompareOcspResponses(outArray, cmpArray, errorText);
|
||||
}
|
||||
if (OID_ADBE_REVOCATION_INFO_ARCHIVAL.Equals(cmpASN1ObjectId)) {
|
||||
return CompareRevocationInfoArchivalAttribute(outArray, cmpArray, errorText);
|
||||
}
|
||||
for (int i = 0; i < cmpArray.Length; i++) {
|
||||
if (!CompareAsn1Structures(outArray[i].ToASN1Primitive(), cmpArray[i].ToASN1Primitive(), errorText)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>See ISO 32000-2, 12.8.3.3.2 "Revocation of CMS-based signatures"</summary>
|
||||
/// <param name="out">out signature revocation info attribute value</param>
|
||||
/// <param name="cmp">cmp signature revocation info attribute value</param>
|
||||
/// <param name="errorText">string builder in order to accumulate errors</param>
|
||||
/// <returns>true if signed data objects are the similar, false otherwise</returns>
|
||||
private static bool CompareRevocationInfoArchivalAttribute(IASN1Encodable[] @out, IASN1Encodable[] cmp, StringBuilder
|
||||
errorText) {
|
||||
String structureIsInvalidError = "Signature revocation info archival attribute structure is invalid";
|
||||
if (!IsExpectedRevocationInfoArchivalAttributeStructure(@out) || !IsExpectedRevocationInfoArchivalAttributeStructure
|
||||
(cmp)) {
|
||||
AddError(errorText, structureIsInvalidError, String.Join("", JavaUtil.ArraysToEnumerable(@out).Select((e) =>
|
||||
DUMP.DumpAsString(e)).ToList()), String.Join("", JavaUtil.ArraysToEnumerable(cmp).Select((e) => DUMP.
|
||||
DumpAsString(e)).ToList()));
|
||||
return false;
|
||||
}
|
||||
IASN1Sequence outSequence = BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(BOUNCY_CASTLE_FACTORY.CreateASN1Set(@out
|
||||
[1]).GetObjectAt(0).ToASN1Primitive());
|
||||
IASN1Sequence cmpSequence = BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(BOUNCY_CASTLE_FACTORY.CreateASN1Set(cmp
|
||||
[1]).GetObjectAt(0).ToASN1Primitive());
|
||||
if (outSequence.Size() != cmpSequence.Size()) {
|
||||
AddError(errorText, "Signature revocation info archival attributes have different sets of revocation info types "
|
||||
+ "(different sizes)", outSequence.Size().ToString(), cmpSequence.Size().ToString());
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < outSequence.Size(); i++) {
|
||||
if (BOUNCY_CASTLE_FACTORY.CreateASN1TaggedObject(outSequence.GetObjectAt(i)) == null || BOUNCY_CASTLE_FACTORY
|
||||
.CreateASN1TaggedObject(cmpSequence.GetObjectAt(i)) == null) {
|
||||
AddError(errorText, structureIsInvalidError, String.Join("", JavaUtil.ArraysToEnumerable(@out).Select((e) =>
|
||||
DUMP.DumpAsString(e)).ToList()), String.Join("", JavaUtil.ArraysToEnumerable(cmp).Select((e) => DUMP.
|
||||
DumpAsString(e)).ToList()));
|
||||
return false;
|
||||
}
|
||||
IASN1TaggedObject outTaggedObject = BOUNCY_CASTLE_FACTORY.CreateASN1TaggedObject(outSequence.GetObjectAt(i
|
||||
));
|
||||
IASN1TaggedObject cmpTaggedObject = BOUNCY_CASTLE_FACTORY.CreateASN1TaggedObject(cmpSequence.GetObjectAt(i
|
||||
));
|
||||
if (outTaggedObject.GetTagNo() != cmpTaggedObject.GetTagNo()) {
|
||||
AddError(errorText, "Signature revocation info archival attributes have different tagged objects tag numbers"
|
||||
, outTaggedObject.GetTagNo().ToString(), cmpTaggedObject.GetTagNo().ToString());
|
||||
return false;
|
||||
}
|
||||
if (BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(outTaggedObject.GetObject()) == null || BOUNCY_CASTLE_FACTORY
|
||||
.CreateASN1Sequence(cmpTaggedObject.GetObject()) == null) {
|
||||
AddError(errorText, structureIsInvalidError, String.Join("", JavaUtil.ArraysToEnumerable(@out).Select((e) =>
|
||||
DUMP.DumpAsString(e)).ToList()), String.Join("", JavaUtil.ArraysToEnumerable(cmp).Select((e) => DUMP.
|
||||
DumpAsString(e)).ToList()));
|
||||
return false;
|
||||
}
|
||||
// revocation entries can be either CRLs or OCSPs in most cases
|
||||
IASN1Sequence outRevocationEntries = BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(outTaggedObject.GetObject());
|
||||
IASN1Sequence cmpRevocationEntries = BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(cmpTaggedObject.GetObject());
|
||||
if (outRevocationEntries.Size() != cmpRevocationEntries.Size()) {
|
||||
AddError(errorText, "Signature revocation info archival attributes have different number of entries", outRevocationEntries
|
||||
.Size().ToString(), cmpRevocationEntries.Size().ToString());
|
||||
return false;
|
||||
}
|
||||
if (outTaggedObject.GetTagNo() == 0) {
|
||||
// CRL revocation info case
|
||||
for (int j = 0; j < outRevocationEntries.Size(); j++) {
|
||||
if (BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(outRevocationEntries.GetObjectAt(j)) == null || BOUNCY_CASTLE_FACTORY
|
||||
.CreateASN1Sequence(outRevocationEntries.GetObjectAt(j)) == null) {
|
||||
AddError(errorText, "Signature revocation info attribute has unexpected CRL entry type", outRevocationEntries
|
||||
.GetObjectAt(j).GetType().FullName.ToString(), cmpRevocationEntries.GetObjectAt(j).GetType().FullName.
|
||||
ToString());
|
||||
return false;
|
||||
}
|
||||
if (!CompareSequencesWithSignatureValue(BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(outRevocationEntries.GetObjectAt
|
||||
(j)), BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(cmpRevocationEntries.GetObjectAt(j)), errorText)) {
|
||||
AddError(errorText, MessageFormatUtil.Format("Signature revocation info attribute CRLs at {0} are different"
|
||||
, j.ToString()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!CompareAsn1Structures(outRevocationEntries, cmpRevocationEntries, errorText)) {
|
||||
AddError(errorText, "Revocation info attribute entries are different");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool IsExpectedRevocationInfoArchivalAttributeStructure(IASN1Encodable[] container) {
|
||||
return container.Length == 2 && BOUNCY_CASTLE_FACTORY.CreateASN1Set(container[1]) != null && BOUNCY_CASTLE_FACTORY
|
||||
.CreateASN1Set(container[1]).Size() == 1 && BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(BOUNCY_CASTLE_FACTORY
|
||||
.CreateASN1Set(container[1]).GetObjectAt(0).ToASN1Primitive()) != null;
|
||||
}
|
||||
|
||||
private static bool CompareTimestampAttributes(IASN1Encodable[] @out, IASN1Encodable[] cmp, StringBuilder
|
||||
errorText) {
|
||||
if (cmp.Length == 2) {
|
||||
if (BOUNCY_CASTLE_FACTORY.CreateASN1Set(cmp[1]) != null && BOUNCY_CASTLE_FACTORY.CreateASN1Set(@out[1]) !=
|
||||
null) {
|
||||
IASN1Primitive outSequence = BOUNCY_CASTLE_FACTORY.CreateASN1Set(@out[1]).GetObjectAt(0).ToASN1Primitive();
|
||||
IASN1Primitive cmpSequence = BOUNCY_CASTLE_FACTORY.CreateASN1Set(cmp[1]).GetObjectAt(0).ToASN1Primitive();
|
||||
if (BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(outSequence) != null && BOUNCY_CASTLE_FACTORY.CreateASN1Sequence
|
||||
(cmpSequence) != null) {
|
||||
return CompareSignedData(BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(outSequence), BOUNCY_CASTLE_FACTORY.CreateASN1Sequence
|
||||
(cmpSequence), errorText);
|
||||
}
|
||||
}
|
||||
}
|
||||
AddError(errorText, "Signature timestamp attribute structure is invalid", String.Join("", JavaUtil.ArraysToEnumerable
|
||||
(@out).Select((e) => DUMP.DumpAsString(e)).ToList()), String.Join("", JavaUtil.ArraysToEnumerable(cmp)
|
||||
.Select((e) => DUMP.DumpAsString(e)).ToList()));
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int GetSignerInfoIndex(IASN1Sequence baseElement) {
|
||||
for (int i = 3; i < baseElement.Size(); i++) {
|
||||
if (BOUNCY_CASTLE_FACTORY.CreateASN1Set(baseElement.GetObjectAt(i)) != null) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw new InvalidOperationException("SignerInfo entry has not been found.");
|
||||
}
|
||||
|
||||
private static String GetASN1ObjectId(IASN1Primitive primitive) {
|
||||
if (BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(primitive) != null) {
|
||||
return GetASN1ObjectId(BOUNCY_CASTLE_FACTORY.CreateASN1Sequence(primitive).ToArray());
|
||||
}
|
||||
if (BOUNCY_CASTLE_FACTORY.CreateASN1Set(primitive) != null) {
|
||||
return GetASN1ObjectId(BOUNCY_CASTLE_FACTORY.CreateASN1Set(primitive).ToArray());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String GetASN1ObjectId(IASN1Encodable[] primitives) {
|
||||
if (primitives.Length != 0 && BOUNCY_CASTLE_FACTORY.CreateASN1ObjectIdentifier(primitives[0]) != null) {
|
||||
return BOUNCY_CASTLE_FACTORY.CreateASN1ObjectIdentifier(primitives[0]).GetId();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static IASN1Primitive GetSignatureContent(String signatureName, SignatureUtil util) {
|
||||
PdfSignature signature = util.GetSignature(signatureName);
|
||||
byte[] contents = signature.GetContents().GetValueBytes();
|
||||
IASN1InputStream inputStream = BOUNCY_CASTLE_FACTORY.CreateASN1InputStream(new MemoryStream(contents));
|
||||
return inputStream.ReadObject();
|
||||
}
|
||||
|
||||
private static void WriteToFile(String path, String content) {
|
||||
using (StreamWriter writer = new StreamWriter(path, true)) {
|
||||
writer.Write(content);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddError(StringBuilder errorBuilder, String errorText) {
|
||||
AddError(errorBuilder, errorText, null, null);
|
||||
}
|
||||
|
||||
private static void AddError(StringBuilder errorBuilder, String errorText, String @out, String cmp) {
|
||||
errorBuilder.Append(errorText);
|
||||
if (null != @out) {
|
||||
errorBuilder.Append("\nout: ").Append(@out);
|
||||
}
|
||||
if (null != cmp) {
|
||||
errorBuilder.Append("\ncmp: ").Append(cmp);
|
||||
}
|
||||
errorBuilder.Append("\n\n");
|
||||
}
|
||||
|
||||
internal delegate bool SequenceComparator(IASN1Sequence outSequence, IASN1Sequence cmpSequence, StringBuilder
|
||||
errorText);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
namespace TSpdf.Signatures.Testutils {
|
||||
public class TimeTestUtil {
|
||||
private const int MILLIS_IN_DAY = 86_400_000;
|
||||
|
||||
// This method is used to trim the hours of the day, so that two dates could be compared
|
||||
// with a day accuracy. We need such a method since in .NET the signing DateTime extracted
|
||||
// from the signature depends on the current time zone set on the machine.
|
||||
// TODO DEVSIX-5812 Remove the method alongside the utility class once the issue is fixed
|
||||
public static long GetFullDaysMillis(double millis) {
|
||||
return (long)millis / MILLIS_IN_DAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1.X500;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Bouncycastle.Math;
|
||||
|
||||
namespace TSpdf.Signatures.Testutils
|
||||
{
|
||||
class X509MockCertificate : IX509Certificate
|
||||
{
|
||||
public X509MockCertificate()
|
||||
{
|
||||
this.criticalExtensions = new HashSet<string>();
|
||||
}
|
||||
|
||||
internal ISet<string> criticalExtensions;
|
||||
|
||||
internal IList extendedKeyUsage;
|
||||
|
||||
public bool[] KeyUsage { get; set; }
|
||||
|
||||
public void SetCriticalExtensions(ISet<string> criticalExtensions)
|
||||
{
|
||||
this.criticalExtensions = criticalExtensions;
|
||||
}
|
||||
|
||||
public IX500Name GetIssuerDN()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IBigInteger GetSerialNumber()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IPublicKey GetPublicKey()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public byte[] GetEncoded()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public byte[] GetTbsCertificate() {
|
||||
return Array.Empty<byte>();
|
||||
}
|
||||
|
||||
public IASN1OctetString GetExtensionValue(string oid)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Verify(IPublicKey issuerPublicKey)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ISet<string> GetCriticalExtensionOids()
|
||||
{
|
||||
return this.criticalExtensions;
|
||||
}
|
||||
|
||||
public void CheckValidity(DateTime time)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetEndDateTime()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public DateTime GetNotBefore()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IX500Name GetSubjectDN()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void SetExtendedKeyUsage(IList extendedKeyUsage)
|
||||
{
|
||||
this.extendedKeyUsage = extendedKeyUsage;
|
||||
}
|
||||
|
||||
public IList GetExtendedKeyUsage()
|
||||
{
|
||||
return this.extendedKeyUsage;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1.X500;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Utils;
|
||||
|
||||
namespace TSpdf.Signatures.Testutils.Builder {
|
||||
public class TestCrlBuilder {
|
||||
private static readonly IBouncyCastleFactory FACTORY = BouncyCastleFactoryCreator.GetFactory();
|
||||
private const String SIGN_ALG = "SHA256withRSA";
|
||||
|
||||
private readonly IPrivateKey issuerPrivateKey;
|
||||
private readonly IX509v2CRLBuilder crlBuilder;
|
||||
|
||||
private DateTime nextUpdate = DateTimeUtil.GetCurrentUtcTime().AddDays(30);
|
||||
|
||||
public TestCrlBuilder(IX509Certificate issuerCert, IPrivateKey issuerPrivateKey, DateTime thisUpdate) {
|
||||
IX500Name issuerCertSubjectDn = issuerCert.GetSubjectDN();
|
||||
this.crlBuilder = FACTORY.CreateX509v2CRLBuilder(issuerCertSubjectDn, thisUpdate);
|
||||
this.issuerPrivateKey = issuerPrivateKey;
|
||||
}
|
||||
|
||||
public virtual void SetNextUpdate(DateTime nextUpdate) {
|
||||
this.nextUpdate = nextUpdate;
|
||||
}
|
||||
|
||||
/// <summary>See CRLReason</summary>
|
||||
public virtual void AddCrlEntry(IX509Certificate certificate, DateTime revocationDate, int reason) {
|
||||
crlBuilder.AddCRLEntry(certificate.GetSerialNumber(), revocationDate, reason);
|
||||
}
|
||||
|
||||
public virtual byte[] MakeCrl() {
|
||||
crlBuilder.SetNextUpdate(nextUpdate);
|
||||
IX509Crl crl = crlBuilder.Build(FACTORY.CreateContentSigner(SIGN_ALG, issuerPrivateKey));
|
||||
return crl.GetEncoded();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1.Ocsp;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1.X500;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1.X509;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Cert.Ocsp;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Utils;
|
||||
|
||||
namespace TSpdf.Signatures.Testutils.Builder {
|
||||
public class TestOcspResponseBuilder {
|
||||
private static readonly IBouncyCastleFactory FACTORY = BouncyCastleFactoryCreator.GetFactory();
|
||||
private const String SIGN_ALG = "SHA256withRSA";
|
||||
|
||||
private IBasicOCSPRespBuilder responseBuilder;
|
||||
|
||||
private IX509Certificate issuerCert;
|
||||
private IPrivateKey issuerPrivateKey;
|
||||
|
||||
private ICertificateStatus certificateStatus;
|
||||
|
||||
private DateTime thisUpdate = DateTimeUtil.GetCurrentTime();
|
||||
|
||||
private DateTime nextUpdate = DateTimeUtil.GetCurrentTime();
|
||||
|
||||
public TestOcspResponseBuilder(IX509Certificate issuerCert, IPrivateKey issuerPrivateKey,
|
||||
ICertificateStatus certificateStatus)
|
||||
{
|
||||
this.issuerCert = issuerCert;
|
||||
this.issuerPrivateKey = issuerPrivateKey;
|
||||
this.certificateStatus = certificateStatus;
|
||||
IX500Name subjectDN = issuerCert.GetSubjectDN();
|
||||
thisUpdate = thisUpdate.AddDays(-1);
|
||||
nextUpdate = nextUpdate.AddDays(30);
|
||||
responseBuilder = FACTORY.CreateBasicOCSPRespBuilder(FACTORY.CreateRespID(subjectDN));
|
||||
}
|
||||
|
||||
public TestOcspResponseBuilder(IX509Certificate issuerCert, IPrivateKey issuerPrivateKey)
|
||||
: this(issuerCert, issuerPrivateKey, FACTORY.CreateCertificateStatus().GetGood())
|
||||
{
|
||||
}
|
||||
|
||||
public IX509Certificate GetIssuerCert() {
|
||||
return issuerCert;
|
||||
}
|
||||
|
||||
public virtual void SetCertificateStatus(ICertificateStatus certificateStatus) {
|
||||
this.certificateStatus = certificateStatus;
|
||||
}
|
||||
|
||||
public virtual void SetThisUpdate(DateTime thisUpdate) {
|
||||
this.thisUpdate = thisUpdate;
|
||||
}
|
||||
|
||||
public virtual void SetNextUpdate(DateTime nextUpdate) {
|
||||
this.nextUpdate = nextUpdate;
|
||||
}
|
||||
|
||||
public virtual byte[] MakeOcspResponse(byte[] requestBytes) {
|
||||
IBasicOCSPResponse ocspResponse = MakeOcspResponseObject(requestBytes);
|
||||
return ocspResponse.GetEncoded();
|
||||
}
|
||||
|
||||
public virtual IBasicOCSPResponse MakeOcspResponseObject(byte[] requestBytes) {
|
||||
IOCSPReq ocspRequest = FACTORY.CreateOCSPReq(requestBytes);
|
||||
IReq[] requestList = ocspRequest.GetRequestList();
|
||||
|
||||
IExtension extNonce = ocspRequest.GetExtension(FACTORY.CreateOCSPObjectIdentifiers()
|
||||
.GetIdPkixOcspNonce());
|
||||
if (!FACTORY.IsNullExtension(extNonce)) {
|
||||
// TODO ensure
|
||||
IExtensions responseExtensions = FACTORY.CreateExtensions(new Dictionary<IASN1ObjectIdentifier, IExtension>() {
|
||||
{
|
||||
FACTORY.CreateOCSPObjectIdentifiers().GetIdPkixOcspNonce(), extNonce
|
||||
}});
|
||||
responseBuilder.SetResponseExtensions(responseExtensions);
|
||||
}
|
||||
|
||||
foreach (IReq req in requestList) {
|
||||
responseBuilder.AddResponse(req.GetCertID(), certificateStatus, thisUpdate.ToUniversalTime(), nextUpdate.ToUniversalTime(),
|
||||
FACTORY.CreateExtensions());
|
||||
}
|
||||
DateTime time = DateTimeUtil.GetCurrentUtcTime();
|
||||
return responseBuilder.Build(FACTORY.CreateContentSigner(SIGN_ALG, issuerPrivateKey), new IX509Certificate[] { issuerCert }, time);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Bouncycastle.Math;
|
||||
using TSpdf.Commons.Bouncycastle.Tsp;
|
||||
using TSpdf.Commons.Utils;
|
||||
|
||||
namespace TSpdf.Signatures.Testutils.Builder {
|
||||
public class TestTimestampTokenBuilder {
|
||||
private static readonly IBouncyCastleFactory FACTORY = BouncyCastleFactoryCreator.GetFactory();
|
||||
private IList<IX509Certificate> tsaCertificateChain;
|
||||
|
||||
// just a more or less random oid of timestamp policy
|
||||
private static readonly String POLICY_OID = "1.3.6.1.4.1.45794.1.1";
|
||||
|
||||
private IPrivateKey tsaPrivateKey;
|
||||
|
||||
public TestTimestampTokenBuilder(IList<IX509Certificate> tsaCertificateChain, IPrivateKey tsaPrivateKey
|
||||
) {
|
||||
if (tsaCertificateChain.Count == 0) {
|
||||
throw new ArgumentException("tsaCertificateChain shall not be empty");
|
||||
}
|
||||
this.tsaCertificateChain = tsaCertificateChain;
|
||||
this.tsaPrivateKey = tsaPrivateKey;
|
||||
}
|
||||
|
||||
public virtual byte[] CreateTimeStampToken(ITimeStampRequest request) {
|
||||
ITimeStampTokenGenerator tsTokGen = CreateTimeStampTokenGenerator(tsaPrivateKey, tsaCertificateChain[0],
|
||||
"SHA1", POLICY_OID);
|
||||
tsTokGen.SetAccuracySeconds(1);
|
||||
|
||||
// TODO setting this is somewhat wrong. Acrobat and openssl recognize timestamp tokens generated with this line as corrupted
|
||||
// openssl error message: 2304:error:2F09506F:time stamp routines:INT_TS_RESP_VERIFY_TOKEN:tsa name mismatch:ts_rsp_verify.c:476:
|
||||
// tsTokGen.setTSA(new GeneralName(new X500Name(PrincipalUtil.getIssuerX509Principal(tsCertificate).getName())));
|
||||
|
||||
tsTokGen.SetCertificates(tsaCertificateChain);
|
||||
// should be unique for every timestamp
|
||||
IBigInteger serialNumber = FACTORY.CreateBigInteger(SystemUtil.GetTimeBasedSeed().ToString());
|
||||
DateTime genTime = DateTimeUtil.GetCurrentUtcTime();
|
||||
ITimeStampToken tsToken = tsTokGen.Generate(request, serialNumber, genTime);
|
||||
return tsToken.GetEncoded();
|
||||
}
|
||||
|
||||
public virtual byte[] CreateTSAResponse(byte[] requestBytes, String signatureAlgorithm, String allowedDigest) {
|
||||
try {
|
||||
String digestForTsSigningCert = DigestAlgorithms.GetAllowedDigest(allowedDigest);
|
||||
ITimeStampTokenGenerator tokenGenerator = CreateTimeStampTokenGenerator(tsaPrivateKey,
|
||||
tsaCertificateChain[0], allowedDigest, POLICY_OID);
|
||||
|
||||
IList<String> algorithms = new List<string>();
|
||||
algorithms.Add(digestForTsSigningCert);
|
||||
ITimeStampResponseGenerator generator = FACTORY.CreateTimeStampResponseGenerator(tokenGenerator, (IList)algorithms);
|
||||
ITimeStampRequest request = FACTORY.CreateTimeStampRequest(requestBytes);
|
||||
return generator.Generate(request, request.GetNonce(), new DateTime()).GetEncoded();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static ITimeStampTokenGenerator CreateTimeStampTokenGenerator(IPrivateKey pk, IX509Certificate cert,
|
||||
String allowedDigest, String policyOid) {
|
||||
return FACTORY.CreateTimeStampTokenGenerator(pk, cert,
|
||||
DigestAlgorithms.GetDigest(DigestAlgorithms.GetAllowedDigest(allowedDigest)), policyOid);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1.X500;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1.X509;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Cert.Jcajce;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Bouncycastle.Math;
|
||||
using TSpdf.Commons.Bouncycastle.Operator;
|
||||
using TSpdf.Commons.Utils;
|
||||
|
||||
namespace TSpdf.Signatures.Testutils.Cert {
|
||||
public class TestCertificateBuilder {
|
||||
private static readonly IBouncyCastleFactory FACTORY = BouncyCastleFactoryCreator.GetFactory();
|
||||
private const String signatureAlgorithm = "SHA256WithRSA";
|
||||
|
||||
private IPublicKey publicKey;
|
||||
|
||||
private IX509Certificate signingCert;
|
||||
|
||||
private IPrivateKey signingKey;
|
||||
|
||||
private String subjectDN;
|
||||
|
||||
private DateTime startDate;
|
||||
|
||||
private DateTime endDate;
|
||||
|
||||
public TestCertificateBuilder(IPublicKey publicKey, IX509Certificate signingCert, IPrivateKey
|
||||
signingKey, String subjectDN) {
|
||||
// requires corresponding key pairs to be used in this class
|
||||
this.publicKey = publicKey;
|
||||
this.signingCert = signingCert;
|
||||
this.signingKey = signingKey;
|
||||
this.subjectDN = subjectDN;
|
||||
this.startDate = DateTimeUtil.GetCurrentUtcTime();
|
||||
this.endDate = startDate.AddDays(365 * 100);
|
||||
}
|
||||
|
||||
public virtual void SetStartDate(DateTime startDate) {
|
||||
this.startDate = startDate;
|
||||
}
|
||||
|
||||
public virtual void SetEndDate(DateTime endDate) {
|
||||
this.endDate = endDate;
|
||||
}
|
||||
|
||||
// TODO generalize
|
||||
public virtual IX509Certificate BuildAuthorizedOCSPResponderCert() {
|
||||
IX500Name subjectDnName = FACTORY.CreateX500Name(subjectDN);
|
||||
IBigInteger certSerialNumber = FACTORY.CreateBigInteger(Convert.ToString(SystemUtil.GetTimeBasedSeed())); // Using the current timestamp as the certificate serial number
|
||||
IContentSigner contentSigner = FACTORY.CreateContentSigner(signatureAlgorithm, signingKey);
|
||||
IJcaX509v3CertificateBuilder certBuilder = FACTORY.CreateJcaX509v3CertificateBuilder(signingCert,
|
||||
certSerialNumber, startDate, endDate, subjectDnName, publicKey);
|
||||
|
||||
// TODO generalize extensions setting
|
||||
// Extensions --------------------------
|
||||
bool ca = true;
|
||||
AddExtension(FACTORY.CreateExtensions().GetBasicConstraints(), true, FACTORY.CreateBasicConstraints(ca),
|
||||
certBuilder);
|
||||
|
||||
AddExtension(FACTORY.CreateOCSPObjectIdentifiers().GetIdPkixOcspNoCheck(), false, FACTORY.CreateDERNull(),
|
||||
certBuilder);
|
||||
|
||||
AddExtension(FACTORY.CreateExtensions().GetKeyUsage(), false, FACTORY.CreateKeyUsage(
|
||||
FACTORY.CreateKeyUsage().GetDigitalSignature() | FACTORY.CreateKeyUsage().GetNonRepudiation()),
|
||||
certBuilder);
|
||||
|
||||
AddExtension(FACTORY.CreateExtensions().GetExtendedKeyUsage(), false, FACTORY.CreateExtendedKeyUsage
|
||||
(FACTORY.CreateKeyPurposeId().GetIdKpOCSPSigning()),
|
||||
certBuilder);
|
||||
|
||||
ISubjectPublicKeyInfo issuerPublicKeyInfo = FACTORY.CreateSubjectPublicKeyInfo(signingCert.GetPublicKey());
|
||||
IAuthorityKeyIdentifier authKeyIdentifier = FACTORY.CreateAuthorityKeyIdentifier(issuerPublicKeyInfo);
|
||||
AddExtension(FACTORY.CreateExtensions().GetAuthorityKeyIdentifier(), false, authKeyIdentifier, certBuilder);
|
||||
|
||||
ISubjectPublicKeyInfo subjectPublicKeyInfo = FACTORY.CreateSubjectPublicKeyInfo(publicKey);
|
||||
ISubjectKeyIdentifier subjectKeyIdentifier = FACTORY.CreateSubjectKeyIdentifier(subjectPublicKeyInfo);
|
||||
AddExtension(FACTORY.CreateExtensions().GetSubjectKeyIdentifier(), false, subjectKeyIdentifier, certBuilder);
|
||||
// -------------------------------------
|
||||
return certBuilder.Build(contentSigner);
|
||||
}
|
||||
|
||||
private static void AddExtension(IASN1ObjectIdentifier extensionOID, bool critical, IASN1Encodable extensionValue,
|
||||
IJcaX509v3CertificateBuilder certBuilder) {
|
||||
certBuilder.AddExtension(extensionOID, critical, extensionValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Kernel.Exceptions;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Testutils.Builder;
|
||||
|
||||
namespace TSpdf.Signatures.Testutils.Client {
|
||||
public class TestCrlClient : ICrlClient {
|
||||
private readonly IList<TestCrlBuilder> crlBuilders;
|
||||
|
||||
public TestCrlClient() {
|
||||
crlBuilders = new List<TestCrlBuilder>();
|
||||
}
|
||||
|
||||
public virtual TSpdf.Signatures.Testutils.Client.TestCrlClient AddBuilderForCertIssuer(TestCrlBuilder crlBuilder
|
||||
) {
|
||||
crlBuilders.Add(crlBuilder);
|
||||
return this;
|
||||
}
|
||||
|
||||
public virtual TSpdf.Signatures.Testutils.Client.TestCrlClient AddBuilderForCertIssuer(IX509Certificate issuerCert
|
||||
, IPrivateKey issuerPrivateKey) {
|
||||
DateTime yesterday = DateTimeUtil.GetCurrentUtcTime().AddDays(-1);
|
||||
crlBuilders.Add(new TestCrlBuilder(issuerCert, issuerPrivateKey, yesterday));
|
||||
return this;
|
||||
}
|
||||
|
||||
public virtual ICollection<byte[]> GetEncoded(IX509Certificate checkCert, String url) {
|
||||
return crlBuilders.Select((testCrlBuilder) => {
|
||||
try {
|
||||
return testCrlBuilder.MakeCrl();
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
throw new PdfException(ignore);
|
||||
}
|
||||
}
|
||||
).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Cert.Ocsp;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Signatures.Testutils.Builder;
|
||||
|
||||
namespace TSpdf.Signatures.Testutils.Client {
|
||||
public class TestOcspClient : IOcspClient {
|
||||
private static readonly IBouncyCastleFactory BOUNCY_CASTLE_FACTORY = BouncyCastleFactoryCreator.GetFactory
|
||||
();
|
||||
|
||||
private readonly IDictionary<String, TestOcspResponseBuilder> issuerIdToResponseBuilder = new LinkedDictionary
|
||||
<String, TestOcspResponseBuilder>();
|
||||
|
||||
public virtual TestOcspClient AddBuilderForCertIssuer(IX509Certificate cert, IPrivateKey privateKey) {
|
||||
issuerIdToResponseBuilder.Put(cert.GetSerialNumber().ToString(16), new TestOcspResponseBuilder(cert, privateKey
|
||||
));
|
||||
return this;
|
||||
}
|
||||
|
||||
public virtual TestOcspClient AddBuilderForCertIssuer(IX509Certificate cert, TestOcspResponseBuilder builder
|
||||
) {
|
||||
issuerIdToResponseBuilder.Put(cert.GetSerialNumber().ToString(16), builder);
|
||||
return this;
|
||||
}
|
||||
|
||||
public virtual byte[] GetEncoded(IX509Certificate checkCert, IX509Certificate issuerCert, String url) {
|
||||
byte[] bytes = null;
|
||||
try {
|
||||
ICertificateID id = SignTestPortUtil.GenerateCertificateId(issuerCert, checkCert.GetSerialNumber(), BOUNCY_CASTLE_FACTORY
|
||||
.CreateCertificateID().GetHashSha1());
|
||||
TestOcspResponseBuilder builder = issuerIdToResponseBuilder.Get(issuerCert.GetSerialNumber().ToString(16));
|
||||
if (builder == null) {
|
||||
throw new ArgumentException("This TestOcspClient instance is not capable of providing OCSP response for the given issuerCert:"
|
||||
+ issuerCert.GetSubjectDN().ToString());
|
||||
}
|
||||
bytes = builder.MakeOcspResponse(SignTestPortUtil.GenerateOcspRequestWithNonce(id).GetEncoded());
|
||||
}
|
||||
catch (Exception ignored) {
|
||||
if (ignored is Exception) {
|
||||
throw (Exception)ignored;
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Bouncycastle.Math;
|
||||
using TSpdf.Commons.Bouncycastle.Tsp;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Signatures.Testutils.Builder;
|
||||
|
||||
namespace TSpdf.Signatures.Testutils.Client {
|
||||
public class TestTsaClient : ITSAClient {
|
||||
private static readonly IBouncyCastleFactory BOUNCY_CASTLE_FACTORY = BouncyCastleFactoryCreator.GetFactory
|
||||
();
|
||||
|
||||
private const String DIGEST_ALG = "SHA256";
|
||||
|
||||
private readonly IPrivateKey tsaPrivateKey;
|
||||
|
||||
private IList<IX509Certificate> tsaCertificateChain;
|
||||
|
||||
public TestTsaClient(IList<IX509Certificate> tsaCertificateChain, IPrivateKey tsaPrivateKey) {
|
||||
this.tsaCertificateChain = tsaCertificateChain;
|
||||
this.tsaPrivateKey = tsaPrivateKey;
|
||||
}
|
||||
|
||||
public virtual int GetTokenSizeEstimate() {
|
||||
return 4096;
|
||||
}
|
||||
|
||||
public virtual IIDigest GetMessageDigest() {
|
||||
return SignTestPortUtil.GetMessageDigest(DIGEST_ALG);
|
||||
}
|
||||
|
||||
public virtual byte[] GetTimeStampToken(byte[] imprint) {
|
||||
ITimeStampRequestGenerator tsqGenerator = BOUNCY_CASTLE_FACTORY.CreateTimeStampRequestGenerator();
|
||||
tsqGenerator.SetCertReq(true);
|
||||
IBigInteger nonce = TSpdf.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateBigInteger().ValueOf
|
||||
(SystemUtil.GetTimeBasedSeed());
|
||||
ITimeStampRequest request = tsqGenerator.Generate(BOUNCY_CASTLE_FACTORY.CreateASN1ObjectIdentifier(DigestAlgorithms
|
||||
.GetAllowedDigest(DIGEST_ALG)), imprint, nonce);
|
||||
return new TestTimestampTokenBuilder(tsaCertificateChain, tsaPrivateKey).CreateTimeStampToken(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Bouncycastle.Tsp;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Exceptions;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Signatures.Testutils.Builder;
|
||||
using TSpdf.Signatures.Testutils.Client;
|
||||
using TSpdf.Test;
|
||||
using TSpdf.Test.Attributes;
|
||||
|
||||
namespace TSpdf.Signatures.Verify {
|
||||
[NUnit.Framework.Category("BouncyCastleUnitTest")]
|
||||
public class CertificateVerificationClassTest : ExtendedTSpdfTest {
|
||||
private static readonly IBouncyCastleFactory FACTORY = BouncyCastleFactoryCreator.GetFactory();
|
||||
|
||||
// Such messageTemplate is equal to any log message. This is required for porting reasons.
|
||||
private const String ANY_LOG_MESSAGE = "{0}";
|
||||
|
||||
private const int COUNTER_TO_MAKE_CRL_AVAILABLE_AT_THE_CURRENT_TIME = -1;
|
||||
|
||||
private static readonly String CERTS_SRC = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/";
|
||||
|
||||
private static readonly char[] PASSWORD = "testpassphrase".ToCharArray();
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
}
|
||||
|
||||
[NUnit.Framework.OneTimeTearDown]
|
||||
public static void After() {
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ValidCertificateChain01() {
|
||||
IX509Certificate[] certChain = PemFileHelper.ReadFirstChain(CERTS_SRC + "signCertRsaWithChain.pem");
|
||||
String caCertFileName = CERTS_SRC + "rootRsa.pem";
|
||||
List<IX509Certificate> caKeyStore = PemFileHelper.InitStore(caCertFileName);
|
||||
IList<VerificationException> verificationExceptions = CertificateVerification.VerifyCertificates(certChain
|
||||
, caKeyStore);
|
||||
NUnit.Framework.Assert.IsTrue(verificationExceptions.IsEmpty());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TimestampCertificateAndKeyStoreCorrespondTest() {
|
||||
String tsaCertFileName = CERTS_SRC + "tsCertRsa.pem";
|
||||
List<IX509Certificate> caKeyStore = PemFileHelper.InitStore(tsaCertFileName);
|
||||
NUnit.Framework.Assert.IsTrue(VerifyTimestampCertificates(tsaCertFileName, caKeyStore));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage("certificate hash does not match certID hash.")]
|
||||
public virtual void TimestampCertificateAndKeyStoreDoNotCorrespondTest() {
|
||||
String tsaCertFileName = CERTS_SRC + "tsCertRsa.pem";
|
||||
String notTsaCertFileName = CERTS_SRC + "rootRsa.pem";
|
||||
List<IX509Certificate> caKeyStore = PemFileHelper.InitStore(notTsaCertFileName);
|
||||
NUnit.Framework.Assert.IsFalse(VerifyTimestampCertificates(tsaCertFileName, caKeyStore));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage(ANY_LOG_MESSAGE)]
|
||||
public virtual void KeyStoreWithoutCertificatesTest() {
|
||||
String tsaCertFileName = CERTS_SRC + "tsCertRsa.pem";
|
||||
NUnit.Framework.Assert.IsFalse(VerifyTimestampCertificates(tsaCertFileName, null));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ExpiredCertificateTest() {
|
||||
// Android-Conversion-Ignore-Test (TODO DEVSIX-6447 fix different X509Certificate#checkValidity behavior)
|
||||
IX509Certificate expiredCert = (IX509Certificate)PemFileHelper.ReadFirstChain(CERTS_SRC + "expiredCert.pem"
|
||||
)[0];
|
||||
String verificationResult = CertificateVerification.VerifyCertificate(expiredCert, null);
|
||||
String expectedResultString = SignaturesTestUtils.GetExpiredMessage(expiredCert);
|
||||
NUnit.Framework.Assert.AreEqual(expectedResultString, verificationResult);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void UnsupportedCriticalExtensionTest() {
|
||||
IX509Certificate unsupportedExtensionCert = (IX509Certificate)PemFileHelper.ReadFirstChain(CERTS_SRC + "unsupportedCriticalExtensionCert.pem"
|
||||
)[0];
|
||||
String verificationResult = CertificateVerification.VerifyCertificate(unsupportedExtensionCert, null);
|
||||
NUnit.Framework.Assert.AreEqual(CertificateVerification.HAS_UNSUPPORTED_EXTENSIONS, verificationResult);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ClrWithGivenCertificateTest() {
|
||||
String caCertFileName = CERTS_SRC + "rootRsa.pem";
|
||||
IX509Certificate caCert = (IX509Certificate)PemFileHelper.ReadFirstChain(caCertFileName)[0];
|
||||
IPrivateKey caPrivateKey = PemFileHelper.ReadFirstKey(caCertFileName, PASSWORD);
|
||||
String checkCertFileName = CERTS_SRC + "signCertRsa01.pem";
|
||||
IX509Certificate checkCert = (IX509Certificate)PemFileHelper.ReadFirstChain(checkCertFileName)[0];
|
||||
TestCrlBuilder crlBuilder = new TestCrlBuilder(caCert, caPrivateKey, DateTimeUtil.GetCurrentUtcTime().AddDays
|
||||
(COUNTER_TO_MAKE_CRL_AVAILABLE_AT_THE_CURRENT_TIME));
|
||||
crlBuilder.AddCrlEntry(caCert, DateTimeUtil.GetCurrentUtcTime().AddDays(COUNTER_TO_MAKE_CRL_AVAILABLE_AT_THE_CURRENT_TIME
|
||||
), FACTORY.CreateCRLReason().GetKeyCompromise());
|
||||
TestCrlBuilder crlForCheckBuilder = new TestCrlBuilder(caCert, caPrivateKey, DateTimeUtil.GetCurrentUtcTime
|
||||
().AddDays(COUNTER_TO_MAKE_CRL_AVAILABLE_AT_THE_CURRENT_TIME));
|
||||
crlForCheckBuilder.AddCrlEntry(checkCert, DateTimeUtil.GetCurrentUtcTime().AddDays(COUNTER_TO_MAKE_CRL_AVAILABLE_AT_THE_CURRENT_TIME
|
||||
), FACTORY.CreateCRLReason().GetKeyCompromise());
|
||||
TestCrlClient crlClient = new TestCrlClient().AddBuilderForCertIssuer(crlBuilder);
|
||||
TestCrlClient crlForCheckClient = new TestCrlClient().AddBuilderForCertIssuer(crlForCheckBuilder);
|
||||
ICollection<byte[]> crlBytesForRootCertCollection = crlClient.GetEncoded(caCert, null);
|
||||
ICollection<byte[]> crlBytesForCheckCertCollection = crlForCheckClient.GetEncoded(checkCert, null);
|
||||
IList<IX509Crl> crls = new List<IX509Crl>();
|
||||
foreach (byte[] crlBytes in crlBytesForRootCertCollection) {
|
||||
crls.Add(SignTestPortUtil.ParseCrlFromStream(new MemoryStream(crlBytes)));
|
||||
}
|
||||
foreach (byte[] crlBytes in crlBytesForCheckCertCollection) {
|
||||
crls.Add(SignTestPortUtil.ParseCrlFromStream(new MemoryStream(crlBytes)));
|
||||
}
|
||||
String verificationResult = CertificateVerification.VerifyCertificate(checkCert, crls);
|
||||
NUnit.Framework.Assert.AreEqual(CertificateVerification.CERTIFICATE_REVOKED, verificationResult);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ValidCertWithEmptyCrlCollectionTest() {
|
||||
String caCertFileName = CERTS_SRC + "rootRsa.pem";
|
||||
IX509Certificate rootCert = (IX509Certificate)PemFileHelper.ReadFirstChain(caCertFileName)[0];
|
||||
String verificationResult = CertificateVerification.VerifyCertificate(rootCert, JavaCollectionsUtil.EmptyList
|
||||
<IX509Crl>());
|
||||
NUnit.Framework.Assert.IsNull(verificationResult);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ValidCertWithCrlDoesNotContainCertTest() {
|
||||
int COUNTER_TO_MAKE_CRL_AVAILABLE_AT_THE_CURRENT_TIME = -1;
|
||||
String rootCertFileName = CERTS_SRC + "rootRsa.pem";
|
||||
IX509Certificate rootCert = (IX509Certificate)PemFileHelper.ReadFirstChain(rootCertFileName)[0];
|
||||
String certForAddingToCrlName = CERTS_SRC + "signCertRsa01.pem";
|
||||
IX509Certificate certForCrl = (IX509Certificate)PemFileHelper.ReadFirstChain(certForAddingToCrlName)[0];
|
||||
IPrivateKey caPrivateKey = PemFileHelper.ReadFirstKey(certForAddingToCrlName, PASSWORD);
|
||||
TestCrlBuilder crlForCheckBuilder = new TestCrlBuilder(certForCrl, caPrivateKey, DateTimeUtil.GetCurrentUtcTime
|
||||
().AddDays(COUNTER_TO_MAKE_CRL_AVAILABLE_AT_THE_CURRENT_TIME));
|
||||
TestCrlClient crlClient = new TestCrlClient().AddBuilderForCertIssuer(crlForCheckBuilder);
|
||||
ICollection<byte[]> crlBytesForRootCertCollection = crlClient.GetEncoded(certForCrl, null);
|
||||
IList<IX509Crl> crls = new List<IX509Crl>();
|
||||
foreach (byte[] crlBytes in crlBytesForRootCertCollection) {
|
||||
crls.Add(SignTestPortUtil.ParseCrlFromStream(new MemoryStream(crlBytes)));
|
||||
}
|
||||
NUnit.Framework.Assert.IsNull(CertificateVerification.VerifyCertificate(rootCert, crls));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void EmptyCertChainTest() {
|
||||
IX509Certificate[] emptyCertChain = new IX509Certificate[] { };
|
||||
String expectedResult = MessageFormatUtil.Format("Certificate Unknown failed: {0}", SignExceptionMessageConstant
|
||||
.INVALID_STATE_WHILE_CHECKING_CERT_CHAIN);
|
||||
IList<VerificationException> resultedExceptionList = CertificateVerification.VerifyCertificates(emptyCertChain
|
||||
, null, (ICollection<IX509Crl>)null);
|
||||
NUnit.Framework.Assert.AreEqual(1, resultedExceptionList.Count);
|
||||
NUnit.Framework.Assert.AreEqual(expectedResult, resultedExceptionList[0].Message);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ValidCertChainWithEmptyKeyStoreTest() {
|
||||
String validCertChainFileName = CERTS_SRC + "signCertRsaWithChain.pem";
|
||||
String emptyCertChain = CERTS_SRC + "emptyCertChain.pem";
|
||||
IX509Certificate[] validCertChain = PemFileHelper.ReadFirstChain(validCertChainFileName);
|
||||
List<IX509Certificate> emptyKeyStore = PemFileHelper.InitStore(emptyCertChain);
|
||||
IList<VerificationException> resultedExceptionList = CertificateVerification.VerifyCertificates(validCertChain
|
||||
, emptyKeyStore, (ICollection<IX509Crl>)null);
|
||||
String expectedResult = MessageFormatUtil.Format(SignExceptionMessageConstant.CERTIFICATE_TEMPLATE_FOR_EXCEPTION_MESSAGE
|
||||
, FACTORY.CreateX500Name((IX509Certificate)validCertChain[2]).ToString(), SignExceptionMessageConstant
|
||||
.CANNOT_BE_VERIFIED_CERTIFICATE_CHAIN);
|
||||
NUnit.Framework.Assert.AreEqual(1, resultedExceptionList.Count);
|
||||
NUnit.Framework.Assert.AreEqual(expectedResult, resultedExceptionList[0].Message);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ValidCertChainWithRootCertAsKeyStoreTest() {
|
||||
String validCertChainFileName = CERTS_SRC + "signCertRsaWithChain.pem";
|
||||
String emptyCertChain = CERTS_SRC + "rootRsa.pem";
|
||||
IX509Certificate[] validCertChain = PemFileHelper.ReadFirstChain(validCertChainFileName);
|
||||
List<IX509Certificate> emptyKeyStore = PemFileHelper.InitStore(emptyCertChain);
|
||||
IList<VerificationException> resultedExceptionList = CertificateVerification.VerifyCertificates(validCertChain
|
||||
, emptyKeyStore, (ICollection<IX509Crl>)null);
|
||||
NUnit.Framework.Assert.AreEqual(0, resultedExceptionList.Count);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void CertChainWithExpiredCertTest() {
|
||||
// Android-Conversion-Ignore-Test (TODO DEVSIX-6447 fix different X509Certificate#checkValidity behavior)
|
||||
String validCertChainFileName = CERTS_SRC + "signCertRsaWithExpiredChain.pem";
|
||||
IX509Certificate[] validCertChain = PemFileHelper.ReadFirstChain(validCertChainFileName);
|
||||
IX509Certificate expectedExpiredCert = (IX509Certificate)validCertChain[1];
|
||||
String expiredCertName = FACTORY.CreateX500Name(expectedExpiredCert).ToString();
|
||||
IX509Certificate rootCert = (IX509Certificate)validCertChain[2];
|
||||
String rootCertName = FACTORY.CreateX500Name(rootCert).ToString();
|
||||
IList<VerificationException> resultedExceptionList = CertificateVerification.VerifyCertificates(validCertChain
|
||||
, null, (ICollection<IX509Crl>)null);
|
||||
NUnit.Framework.Assert.AreEqual(2, resultedExceptionList.Count);
|
||||
String expectedFirstResultMessage = MessageFormatUtil.Format(SignExceptionMessageConstant.CERTIFICATE_TEMPLATE_FOR_EXCEPTION_MESSAGE
|
||||
, expiredCertName, SignaturesTestUtils.GetExpiredMessage(expectedExpiredCert));
|
||||
String expectedSecondResultMessage = MessageFormatUtil.Format(SignExceptionMessageConstant.CERTIFICATE_TEMPLATE_FOR_EXCEPTION_MESSAGE
|
||||
, rootCertName, SignExceptionMessageConstant.CANNOT_BE_VERIFIED_CERTIFICATE_CHAIN);
|
||||
NUnit.Framework.Assert.AreEqual(expectedFirstResultMessage, resultedExceptionList[0].Message);
|
||||
NUnit.Framework.Assert.AreEqual(expectedSecondResultMessage, resultedExceptionList[1].Message);
|
||||
}
|
||||
|
||||
private static bool VerifyTimestampCertificates(String tsaClientCertificate, List<IX509Certificate> caKeyStore
|
||||
) {
|
||||
IX509Certificate[] tsaChain = PemFileHelper.ReadFirstChain(tsaClientCertificate);
|
||||
IPrivateKey tsaPrivateKey = PemFileHelper.ReadFirstKey(tsaClientCertificate, PASSWORD);
|
||||
TestTsaClient testTsaClient = new TestTsaClient(JavaUtil.ArraysAsList(tsaChain), tsaPrivateKey);
|
||||
byte[] tsaCertificateBytes = testTsaClient.GetTimeStampToken(testTsaClient.GetMessageDigest().Digest());
|
||||
ITimeStampToken timeStampToken = FACTORY.CreateTimeStampToken(FACTORY.CreateContentInfo(FACTORY.CreateASN1Sequence
|
||||
(tsaCertificateBytes)));
|
||||
return CertificateVerification.VerifyTimestampCertificates(timeStampToken, caKeyStore);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Signatures.Testutils.Builder;
|
||||
using TSpdf.Signatures.Testutils.Client;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures.Verify {
|
||||
[NUnit.Framework.Category("BouncyCastleUnitTest")]
|
||||
public class CrlVerifierTest : ExtendedTSpdfTest {
|
||||
private static readonly IBouncyCastleFactory FACTORY = BouncyCastleFactoryCreator.GetFactory();
|
||||
|
||||
private static readonly String certsSrc = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/";
|
||||
|
||||
private static readonly char[] password = "testpassphrase".ToCharArray();
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ValidCrl01() {
|
||||
String caCertP12FileName = certsSrc + "rootRsa.pem";
|
||||
IX509Certificate caCert = (IX509Certificate)PemFileHelper.ReadFirstChain(caCertP12FileName)[0];
|
||||
IPrivateKey caPrivateKey = PemFileHelper.ReadFirstKey(caCertP12FileName, password);
|
||||
TestCrlBuilder crlBuilder = new TestCrlBuilder(caCert, caPrivateKey, DateTimeUtil.GetCurrentUtcTime().AddDays
|
||||
(-1));
|
||||
NUnit.Framework.Assert.IsTrue(VerifyTest(crlBuilder));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void InvalidRevokedCrl01() {
|
||||
String caCertP12FileName = certsSrc + "rootRsa.pem";
|
||||
IX509Certificate caCert = (IX509Certificate)PemFileHelper.ReadFirstChain(caCertP12FileName)[0];
|
||||
IPrivateKey caPrivateKey = PemFileHelper.ReadFirstKey(caCertP12FileName, password);
|
||||
TestCrlBuilder crlBuilder = new TestCrlBuilder(caCert, caPrivateKey, DateTimeUtil.GetCurrentUtcTime().AddDays
|
||||
(-1));
|
||||
String checkCertFileName = certsSrc + "signCertRsa01.pem";
|
||||
IX509Certificate checkCert = (IX509Certificate)PemFileHelper.ReadFirstChain(checkCertFileName)[0];
|
||||
crlBuilder.AddCrlEntry(checkCert, DateTimeUtil.GetCurrentUtcTime().AddDays(-40), FACTORY.CreateCRLReason()
|
||||
.GetKeyCompromise());
|
||||
NUnit.Framework.Assert.Catch(typeof(VerificationException), () => VerifyTest(crlBuilder));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void InvalidOutdatedCrl01() {
|
||||
String caCertP12FileName = certsSrc + "rootRsa.pem";
|
||||
IX509Certificate caCert = (IX509Certificate)PemFileHelper.ReadFirstChain(caCertP12FileName)[0];
|
||||
IPrivateKey caPrivateKey = PemFileHelper.ReadFirstKey(caCertP12FileName, password);
|
||||
TestCrlBuilder crlBuilder = new TestCrlBuilder(caCert, caPrivateKey, DateTimeUtil.GetCurrentUtcTime().AddDays
|
||||
(-2));
|
||||
crlBuilder.SetNextUpdate(DateTimeUtil.GetCurrentUtcTime().AddDays(-1));
|
||||
NUnit.Framework.Assert.IsFalse(VerifyTest(crlBuilder));
|
||||
}
|
||||
|
||||
private bool VerifyTest(TestCrlBuilder crlBuilder) {
|
||||
String caCertFileName = certsSrc + "rootRsa.pem";
|
||||
IX509Certificate caCert = (IX509Certificate)PemFileHelper.ReadFirstChain(caCertFileName)[0];
|
||||
String checkCertFileName = certsSrc + "signCertRsa01.pem";
|
||||
IX509Certificate checkCert = (IX509Certificate)PemFileHelper.ReadFirstChain(checkCertFileName)[0];
|
||||
TestCrlClient crlClient = new TestCrlClient().AddBuilderForCertIssuer(crlBuilder);
|
||||
ICollection<byte[]> crlBytesCollection = crlClient.GetEncoded(checkCert, null);
|
||||
bool verify = false;
|
||||
foreach (byte[] crlBytes in crlBytesCollection) {
|
||||
IX509Crl crl = (IX509Crl)SignTestPortUtil.ParseCrlFromStream(new MemoryStream(crlBytes));
|
||||
CRLVerifier verifier = new CRLVerifier(null, null);
|
||||
verify = verifier.Verify(crl, checkCert, caCert, DateTimeUtil.GetCurrentUtcTime());
|
||||
break;
|
||||
}
|
||||
return verify;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures.Verify {
|
||||
[NUnit.Framework.Category("BouncyCastleIntegrationTest")]
|
||||
public class LtvVerifierTest : ExtendedTSpdfTest {
|
||||
private static readonly String sourceFolder = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/verify/LtvVerifierTest/";
|
||||
|
||||
private static readonly String certsSrc = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/";
|
||||
|
||||
private static readonly char[] password = "testpass".ToCharArray();
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
}
|
||||
|
||||
[NUnit.Framework.OneTimeTearDown]
|
||||
public static void After() {
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ValidLtvDocTest01() {
|
||||
String ltvTsFileName = sourceFolder + "ltvDoc.pdf";
|
||||
LtvVerifier verifier = new LtvVerifier(new PdfDocument(new PdfReader(ltvTsFileName)));
|
||||
verifier.SetCertificateOption(LtvVerification.CertificateOption.WHOLE_CHAIN);
|
||||
verifier.SetRootStore(PemFileHelper.InitStore(certsSrc + "rootStore.pem"));
|
||||
IList<VerificationOK> verificationMessages = verifier.Verify(null);
|
||||
NUnit.Framework.Assert.AreEqual(7, verificationMessages.Count);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ValidLtvDocTest02() {
|
||||
String ltvTsFileName = sourceFolder + "ltvDoc.pdf";
|
||||
LtvVerifier verifier = new LtvVerifier(new PdfDocument(new PdfReader(ltvTsFileName)));
|
||||
verifier.SetCertificateOption(LtvVerification.CertificateOption.WHOLE_CHAIN);
|
||||
verifier.SetRootStore(PemFileHelper.InitStore(certsSrc + "rootStore.pem"));
|
||||
IList<VerificationOK> verificationMessages = verifier.Verify(null);
|
||||
NUnit.Framework.Assert.AreEqual(7, verificationMessages.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is offered under a commercial and under the AGPL license.
|
||||
For commercial licensing, contact us at https://TSpdfpdf.com/sales. For AGPL licensing, see below.
|
||||
|
||||
AGPL licensing:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1.Ocsp;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Signatures.Testutils.Client;
|
||||
using TSpdf.Test;
|
||||
using TSpdf.Test.Attributes;
|
||||
|
||||
namespace TSpdf.Signatures.Verify {
|
||||
[NUnit.Framework.Category("BouncyCastleUnitTest")]
|
||||
public class OcspCertificateVerificationTest : ExtendedTSpdfTest {
|
||||
private static readonly IBouncyCastleFactory FACTORY = BouncyCastleFactoryCreator.GetFactory();
|
||||
|
||||
// Such messageTemplate is equal to any log message. This is required for porting reasons.
|
||||
private const String ANY_LOG_MESSAGE = "{0}";
|
||||
|
||||
private static readonly String ocspCertsSrc = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/verify/OcspCertificateVerificationTest/";
|
||||
|
||||
private static readonly String rootOcspCert = ocspCertsSrc + "ocspRootRsa.pem";
|
||||
|
||||
private static readonly String signOcspCert = ocspCertsSrc + "ocspSignRsa.pem";
|
||||
|
||||
private static readonly String notOcspAndOcspCert = ocspCertsSrc + "notOcspAndOcspCertificates.pem";
|
||||
|
||||
private static readonly char[] password = "testpassphrase".ToCharArray();
|
||||
|
||||
private const String ocspServiceUrl = "http://localhost:9000/demo/ocsp/ocsp-service";
|
||||
|
||||
private static IX509Certificate checkCert;
|
||||
|
||||
private static IX509Certificate rootCert;
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
checkCert = (IX509Certificate)PemFileHelper.ReadFirstChain(signOcspCert)[0];
|
||||
rootCert = (IX509Certificate)PemFileHelper.ReadFirstChain(rootOcspCert)[0];
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void KeyStoreWithRootOcspCertificateTest() {
|
||||
IBasicOCSPResponse response = GetOcspResponse();
|
||||
NUnit.Framework.Assert.IsTrue(CertificateVerification.VerifyOcspCertificates(response, PemFileHelper.InitStore
|
||||
(rootOcspCert)));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void KeyStoreWithSignOcspCertificateTest() {
|
||||
IBasicOCSPResponse response = GetOcspResponse();
|
||||
NUnit.Framework.Assert.IsFalse(CertificateVerification.VerifyOcspCertificates(response, PemFileHelper.InitStore
|
||||
(signOcspCert)));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void KeyStoreWithNotOcspAndOcspCertificatesTest() {
|
||||
IBasicOCSPResponse response = GetOcspResponse();
|
||||
NUnit.Framework.Assert.IsTrue(CertificateVerification.VerifyOcspCertificates(response, PemFileHelper.InitStore
|
||||
(notOcspAndOcspCert)));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage(ANY_LOG_MESSAGE)]
|
||||
public virtual void KeyStoreWithNotOcspCertificateTest() {
|
||||
NUnit.Framework.Assert.IsFalse(CertificateVerification.VerifyOcspCertificates(null, PemFileHelper.InitStore
|
||||
(signOcspCert)));
|
||||
}
|
||||
|
||||
private static IBasicOCSPResponse GetOcspResponse() {
|
||||
TestOcspClient testClient = new TestOcspClient();
|
||||
IPrivateKey key = PemFileHelper.ReadFirstKey(rootOcspCert, password);
|
||||
testClient.AddBuilderForCertIssuer(rootCert, key);
|
||||
byte[] ocspResponseBytes = testClient.GetEncoded(checkCert, rootCert, ocspServiceUrl);
|
||||
IASN1Primitive var2 = FACTORY.CreateASN1Primitive(ocspResponseBytes);
|
||||
return FACTORY.CreateBasicOCSPResponse(var2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using TSpdf.Bouncycastleconnector;
|
||||
using TSpdf.Commons.Bouncycastle;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1;
|
||||
using TSpdf.Commons.Bouncycastle.Asn1.Ocsp;
|
||||
using TSpdf.Commons.Bouncycastle.Cert;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto;
|
||||
using TSpdf.Commons.Bouncycastle.Crypto.Generators;
|
||||
using TSpdf.Commons.Bouncycastle.Security;
|
||||
using TSpdf.Commons.Utils;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Signatures.Testutils;
|
||||
using TSpdf.Signatures.Testutils.Builder;
|
||||
using TSpdf.Signatures.Testutils.Cert;
|
||||
using TSpdf.Signatures.Testutils.Client;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures.Verify {
|
||||
[NUnit.Framework.Category("BouncyCastleUnitTest")]
|
||||
public class OcspVerifierTest : ExtendedTSpdfTest {
|
||||
private static readonly IBouncyCastleFactory FACTORY = BouncyCastleFactoryCreator.GetFactory();
|
||||
|
||||
private static readonly String certsSrc = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/certs/";
|
||||
|
||||
private static readonly char[] password = "testpassphrase".ToCharArray();
|
||||
|
||||
private static readonly String caCertFileName = certsSrc + "rootRsa.pem";
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ValidOcspTest01() {
|
||||
IX509Certificate caCert = (IX509Certificate)PemFileHelper.ReadFirstChain(caCertFileName)[0];
|
||||
IPrivateKey caPrivateKey = PemFileHelper.ReadFirstKey(caCertFileName, password);
|
||||
TestOcspResponseBuilder builder = new TestOcspResponseBuilder(caCert, caPrivateKey);
|
||||
NUnit.Framework.Assert.IsTrue(VerifyTest(builder));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ValidOcspWithoutOcspResponseBuilderTest() {
|
||||
IX509Certificate caCert = (IX509Certificate)PemFileHelper.ReadFirstChain(certsSrc + "signCertRsa01.pem")[0
|
||||
];
|
||||
IX509Certificate rootCert = (IX509Certificate)PemFileHelper.ReadFirstChain(caCertFileName)[0];
|
||||
DateTime checkDate = DateTimeUtil.GetCurrentUtcTime();
|
||||
OCSPVerifier ocspVerifier = new OCSPVerifier(null, null);
|
||||
NUnit.Framework.Assert.IsTrue(ocspVerifier.Verify(caCert, rootCert, checkDate).IsEmpty());
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void InvalidRevokedOcspTest01() {
|
||||
IX509Certificate caCert = (IX509Certificate)PemFileHelper.ReadFirstChain(caCertFileName)[0];
|
||||
IPrivateKey caPrivateKey = PemFileHelper.ReadFirstKey(caCertFileName, password);
|
||||
TestOcspResponseBuilder builder = new TestOcspResponseBuilder(caCert, caPrivateKey);
|
||||
builder.SetCertificateStatus(FACTORY.CreateRevokedStatus(DateTimeUtil.GetCurrentUtcTime().AddDays(-20), FACTORY
|
||||
.CreateCRLReason().GetKeyCompromise()));
|
||||
NUnit.Framework.Assert.IsFalse(VerifyTest(builder));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void InvalidUnknownOcspTest01() {
|
||||
IX509Certificate caCert = (IX509Certificate)PemFileHelper.ReadFirstChain(caCertFileName)[0];
|
||||
IPrivateKey caPrivateKey = PemFileHelper.ReadFirstKey(caCertFileName, password);
|
||||
TestOcspResponseBuilder builder = new TestOcspResponseBuilder(caCert, caPrivateKey);
|
||||
builder.SetCertificateStatus(FACTORY.CreateUnknownStatus());
|
||||
NUnit.Framework.Assert.IsFalse(VerifyTest(builder));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void InvalidOutdatedOcspTest01() {
|
||||
IX509Certificate caCert = (IX509Certificate)PemFileHelper.ReadFirstChain(caCertFileName)[0];
|
||||
IPrivateKey caPrivateKey = PemFileHelper.ReadFirstKey(caCertFileName, password);
|
||||
TestOcspResponseBuilder builder = new TestOcspResponseBuilder(caCert, caPrivateKey);
|
||||
DateTime thisUpdate = DateTimeUtil.GetCurrentTime().AddDays(-30);
|
||||
DateTime nextUpdate = DateTimeUtil.GetCurrentTime().AddDays(-15);
|
||||
builder.SetThisUpdate(thisUpdate);
|
||||
builder.SetNextUpdate(nextUpdate);
|
||||
NUnit.Framework.Assert.IsFalse(VerifyTest(builder));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ExpiredIssuerCertTest01() {
|
||||
IX509Certificate caCert = (IX509Certificate)PemFileHelper.ReadFirstChain(certsSrc + "intermediateExpiredCert.pem"
|
||||
)[0];
|
||||
IPrivateKey caPrivateKey = PemFileHelper.ReadFirstKey(certsSrc + "intermediateExpiredCert.pem", password);
|
||||
TestOcspResponseBuilder builder = new TestOcspResponseBuilder(caCert, caPrivateKey);
|
||||
NUnit.Framework.Assert.IsTrue(VerifyTest(builder, certsSrc + "signCertRsaWithExpiredChain.pem", caCert.GetNotBefore
|
||||
()));
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void AuthorizedOCSPResponderTest() {
|
||||
DateTime ocspResponderCertStartDate = DateTimeUtil.GetCurrentUtcTime();
|
||||
DateTime ocspResponderCertEndDate = ocspResponderCertStartDate.AddDays(365 * 100);
|
||||
DateTime checkDate = DateTimeUtil.GetCurrentUtcTime();
|
||||
bool verifyRes = VerifyAuthorizedOCSPResponderTest(ocspResponderCertStartDate, ocspResponderCertEndDate, checkDate
|
||||
);
|
||||
NUnit.Framework.Assert.IsTrue(verifyRes);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ExpiredAuthorizedOCSPResponderTest_atValidPeriod() {
|
||||
DateTime ocspResponderCertStartDate = DateTimeUtil.Parse("15/10/2005", "dd/MM/yyyy");
|
||||
DateTime ocspResponderCertEndDate = DateTimeUtil.Parse("15/10/2010", "dd/MM/yyyy");
|
||||
DateTime checkDate = DateTimeUtil.Parse("15/10/2008", "dd/MM/yyyy");
|
||||
bool verifyRes = VerifyAuthorizedOCSPResponderTest(ocspResponderCertStartDate, ocspResponderCertEndDate, checkDate
|
||||
);
|
||||
NUnit.Framework.Assert.IsTrue(verifyRes);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void ExpiredAuthorizedOCSPResponderTest_now() {
|
||||
DateTime ocspResponderCertStartDate = DateTimeUtil.Parse("15/10/2005", "dd/MM/yyyy");
|
||||
DateTime ocspResponderCertEndDate = DateTimeUtil.Parse("15/10/2010", "dd/MM/yyyy");
|
||||
DateTime checkDate = DateTimeUtil.GetCurrentUtcTime();
|
||||
NUnit.Framework.Assert.Catch(typeof(AbstractCertificateExpiredException), () => VerifyAuthorizedOCSPResponderTest
|
||||
(ocspResponderCertStartDate, ocspResponderCertEndDate, checkDate));
|
||||
}
|
||||
|
||||
// Not getting here because of exception
|
||||
//Assert.assertFalse(verifyRes);
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void GetOcspResponseNullTest() {
|
||||
OCSPVerifier verifier = new OCSPVerifier(null, null);
|
||||
NUnit.Framework.Assert.IsNull(verifier.GetOcspResponse(null, null));
|
||||
}
|
||||
|
||||
private bool VerifyTest(TestOcspResponseBuilder rootRsaOcspBuilder) {
|
||||
return VerifyTest(rootRsaOcspBuilder, certsSrc + "signCertRsa01.pem", DateTimeUtil.GetCurrentUtcTime());
|
||||
}
|
||||
|
||||
private bool VerifyTest(TestOcspResponseBuilder rootRsaOcspBuilder, String checkCertFileName, DateTime checkDate
|
||||
) {
|
||||
IX509Certificate checkCert = (IX509Certificate)PemFileHelper.ReadFirstChain(checkCertFileName)[0];
|
||||
IX509Certificate rootCert = rootRsaOcspBuilder.GetIssuerCert();
|
||||
TestOcspClient ocspClient = new TestOcspClient().AddBuilderForCertIssuer(rootCert, rootRsaOcspBuilder);
|
||||
byte[] basicOcspRespBytes = ocspClient.GetEncoded(checkCert, rootCert, null);
|
||||
IASN1Primitive var2 = FACTORY.CreateASN1Primitive(basicOcspRespBytes);
|
||||
IBasicOCSPResponse basicOCSPResp = FACTORY.CreateBasicOCSPResponse(var2);
|
||||
OCSPVerifier ocspVerifier = new OCSPVerifier(null, null);
|
||||
return ocspVerifier.Verify(basicOCSPResp, checkCert, rootCert, checkDate);
|
||||
}
|
||||
|
||||
public virtual bool VerifyAuthorizedOCSPResponderTest(DateTime ocspResponderCertStartDate, DateTime ocspResponderCertEndDate
|
||||
, DateTime checkDate) {
|
||||
IX509Certificate caCert = (IX509Certificate)PemFileHelper.ReadFirstChain(certsSrc + "intermediateRsa.pem")
|
||||
[0];
|
||||
IPrivateKey caPrivateKey = PemFileHelper.ReadFirstKey(certsSrc + "intermediateRsa.pem", password);
|
||||
String checkCertFileName = certsSrc + "signCertRsaWithChain.pem";
|
||||
IX509Certificate checkCert = (IX509Certificate)PemFileHelper.ReadFirstChain(checkCertFileName)[0];
|
||||
IRsaKeyPairGenerator keyGen = SignTestPortUtil.BuildRSA2048KeyPairGenerator();
|
||||
IAsymmetricCipherKeyPair key = keyGen.GenerateKeyPair();
|
||||
IPrivateKey ocspRespPrivateKey = key.GetPrivateKey();
|
||||
IPublicKey ocspRespPublicKey = key.GetPublicKey();
|
||||
TestCertificateBuilder certBuilder = new TestCertificateBuilder(ocspRespPublicKey, caCert, caPrivateKey, "CN=TSpdfTestOCSPResponder, OU=test, O=TSpdf"
|
||||
);
|
||||
certBuilder.SetStartDate(ocspResponderCertStartDate);
|
||||
certBuilder.SetEndDate(ocspResponderCertEndDate);
|
||||
IX509Certificate ocspResponderCert = certBuilder.BuildAuthorizedOCSPResponderCert();
|
||||
TestOcspResponseBuilder builder = new TestOcspResponseBuilder(ocspResponderCert, ocspRespPrivateKey);
|
||||
TestOcspClient ocspClient = new TestOcspClient().AddBuilderForCertIssuer(caCert, builder);
|
||||
byte[] basicOcspRespBytes = ocspClient.GetEncoded(checkCert, caCert, null);
|
||||
IASN1Primitive var2 = FACTORY.CreateASN1Primitive(basicOcspRespBytes);
|
||||
IBasicOCSPResponse basicOCSPResp = FACTORY.CreateBasicOCSPResponse(var2);
|
||||
OCSPVerifier ocspVerifier = new OCSPVerifier(null, null);
|
||||
return ocspVerifier.Verify(basicOCSPResp, checkCert, caCert, checkDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using System.IO;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Kernel.Pdf.Canvas.Parser;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Test;
|
||||
using TSpdf.Test.Attributes;
|
||||
|
||||
namespace TSpdf.Signatures.Verify.Pdfinsecurity {
|
||||
[NUnit.Framework.Category("BouncyCastleIntegrationTest")]
|
||||
public class IncrementalSavingAttackTest : ExtendedTSpdfTest {
|
||||
private static readonly String sourceFolder = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/verify/pdfinsecurity/IncrementalSavingAttackTest/";
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
[LogMessage(TSpdf.IO.Logs.IoLogMessageConstant.XREF_ERROR_WHILE_READING_TABLE_WILL_BE_REBUILT)]
|
||||
public virtual void TestISA03() {
|
||||
String filePath = sourceFolder + "isa-3.pdf";
|
||||
String signatureName = "Signature1";
|
||||
PdfDocument document = new PdfDocument(new PdfReader(filePath));
|
||||
SignatureUtil sigUtil = new SignatureUtil(document);
|
||||
PdfPKCS7 pdfPKCS7 = sigUtil.ReadSignatureData(signatureName);
|
||||
NUnit.Framework.Assert.IsTrue(pdfPKCS7.VerifySignatureIntegrityAndAuthenticity());
|
||||
NUnit.Framework.Assert.IsFalse(sigUtil.SignatureCoversWholeDocument(signatureName));
|
||||
document.Close();
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TestISAValidPdf() {
|
||||
String filePath = sourceFolder + "isaValidPdf.pdf";
|
||||
String signatureName = "Signature1";
|
||||
PdfDocument document = new PdfDocument(new PdfReader(filePath));
|
||||
SignatureUtil sigUtil = new SignatureUtil(document);
|
||||
PdfPKCS7 pdfPKCS7 = sigUtil.ReadSignatureData(signatureName);
|
||||
NUnit.Framework.Assert.IsTrue(pdfPKCS7.VerifySignatureIntegrityAndAuthenticity());
|
||||
NUnit.Framework.Assert.IsFalse(sigUtil.SignatureCoversWholeDocument(signatureName));
|
||||
String textFromPage = PdfTextExtractor.GetTextFromPage(document.GetPage(1));
|
||||
// We are working with the latest revision of the document, that's why we should get amended page text.
|
||||
// However Signature shall be marked as not covering the complete document, indicating its invalidity
|
||||
// for the current revision.
|
||||
NUnit.Framework.Assert.AreEqual("This is manipulated malicious text, ha-ha!", textFromPage);
|
||||
NUnit.Framework.Assert.AreEqual(2, sigUtil.GetTotalRevisions());
|
||||
NUnit.Framework.Assert.AreEqual(1, sigUtil.GetRevision(signatureName));
|
||||
Stream sigInputStream = sigUtil.ExtractRevision(signatureName);
|
||||
PdfDocument sigRevDocument = new PdfDocument(new PdfReader(sigInputStream));
|
||||
SignatureUtil sigRevUtil = new SignatureUtil(sigRevDocument);
|
||||
PdfPKCS7 sigRevSignatureData = sigRevUtil.ReadSignatureData(signatureName);
|
||||
NUnit.Framework.Assert.IsTrue(sigRevSignatureData.VerifySignatureIntegrityAndAuthenticity());
|
||||
NUnit.Framework.Assert.IsTrue(sigRevUtil.SignatureCoversWholeDocument(signatureName));
|
||||
sigRevDocument.Close();
|
||||
document.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
This file is part of the TSpdf (R) project.
|
||||
Copyright (c) 1987-2023 TSpdf
|
||||
Authors: TSpdf Software.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License version 3
|
||||
as published by the Free Software Foundation with the addition of the
|
||||
following permission added to Section 15 as permitted in Section 7(a):
|
||||
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
||||
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
||||
OF THIRD PARTY RIGHTS
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, see http://www.gnu.org/licenses or write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
||||
http://TSpdfpdf.com/terms-of-use/
|
||||
|
||||
The interactive user interfaces in modified source and object code versions
|
||||
of this program must display Appropriate Legal Notices, as required under
|
||||
Section 5 of the GNU Affero General Public License.
|
||||
|
||||
In accordance with Section 7(b) of the GNU Affero General Public License,
|
||||
a covered work must retain the producer line in every PDF that is created
|
||||
or manipulated using TSpdf.
|
||||
|
||||
You can be released from the requirements of the license by purchasing
|
||||
a commercial license. Buying such a license is mandatory as soon as you
|
||||
develop commercial activities involving the TSpdf software without
|
||||
disclosing the source code of your own applications.
|
||||
These activities include: offering paid services to customers as an ASP,
|
||||
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
||||
source product.
|
||||
|
||||
For more information, please contact TSpdf Software Corp. at this
|
||||
address: sales@TSpdfpdf.com
|
||||
*/
|
||||
using System;
|
||||
using TSpdf.Kernel.Pdf;
|
||||
using TSpdf.Signatures;
|
||||
using TSpdf.Test;
|
||||
|
||||
namespace TSpdf.Signatures.Verify.Pdfinsecurity {
|
||||
[NUnit.Framework.Category("BouncyCastleIntegrationTest")]
|
||||
public class SignatureWrappingAttackTest : ExtendedTSpdfTest {
|
||||
private static readonly String sourceFolder = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
||||
.CurrentContext.TestDirectory) + "/resources/TSpdf/signatures/verify/pdfinsecurity/SignatureWrappingAttackTest/";
|
||||
|
||||
[NUnit.Framework.OneTimeSetUp]
|
||||
public static void Before() {
|
||||
}
|
||||
|
||||
[NUnit.Framework.Test]
|
||||
public virtual void TestSWA01() {
|
||||
String filePath = sourceFolder + "siwa.pdf";
|
||||
String signatureName = "Signature1";
|
||||
PdfDocument document = new PdfDocument(new PdfReader(filePath));
|
||||
SignatureUtil sigUtil = new SignatureUtil(document);
|
||||
PdfPKCS7 pdfPKCS7 = sigUtil.ReadSignatureData(signatureName);
|
||||
NUnit.Framework.Assert.IsTrue(pdfPKCS7.VerifySignatureIntegrityAndAuthenticity());
|
||||
NUnit.Framework.Assert.IsFalse(sigUtil.SignatureCoversWholeDocument(signatureName));
|
||||
document.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFGTCCBL+gAwIBAgICEAAwCwYJYIZIAWUDBAMCMD8xCzAJBgNVBAYTAkJZMQ4w
|
||||
DAYDVQQKDAVpVGV4dDEgMB4GA1UEAwwXaVRleHRUZXN0Q3JsRGlzdHJQb2ludHMw
|
||||
IBcNMjAwMTAxMDAwMDAwWhgPMjA1MDAxMDEwMDAwMDBaMD8xCzAJBgNVBAYTAkJZ
|
||||
MQ4wDAYDVQQKDAVpVGV4dDEgMB4GA1UEAwwXaVRleHRUZXN0Q3JsRGlzdHJQb2lu
|
||||
dHMwggNGMIICOQYHKoZIzjgEATCCAiwCggEBAI77SJ199WctRnmgFvhPokiV8ksS
|
||||
rTudNlF1hdIjTarZ6xsbrWSHB5GwIJ69ZlXS7ccG4J9zkmSjG/KRNhy49QX+C287
|
||||
WEdccYHDeH+KBkgXAcQhdJJA9dtfgIg02TunoN31fl7c2kUeZYo0B/O+z9rkJfsd
|
||||
C0AMPUoeCoTE2mly+aeh4eDHCevd0sGD3dQ1EJ5wwRJxfbMJ3okS+vmUF4/rU5y+
|
||||
/fvHC7xDdzSxYV8NJZkwRTWJ3Ocnf0c5fph2xAX7CoWOZtnN/s+kDAb9yEduTRi+
|
||||
nArAkuQ8hIX6aGHCleZiC6Kb5kUcJiq23CzFR+X/m+ErsDGkNvU7HqVFbNUCIQCm
|
||||
4cobGNjEU5VyLtA6iAKbRVEAGcPluZfgYpqFVMUlAwKCAQAm7rs1dfzxww5FX8sj
|
||||
X7K9Ho2U+1y9hX5RqB6Ed3PtqsH3YD1fZgqo+m3jzfwc/tQsgHrQF9KDljXHu9ed
|
||||
80mBkqQQ0cRWybXi7G8FCV9NRQMXraa4RABaRPESo9+9x4yu3ypwjCNXMVhEI9AA
|
||||
B7UpEUVg9cZN0S1oRR1y/S1oENDoY9veUC/XTqzYHWQ4zJngV7iO49E7pRVdtXTF
|
||||
UvnEQgKc5bdz89yjrXjbqJVCuBWcayIsG4T/nSsSTc9TcOf3I7UWdA0CgY8j5HwT
|
||||
J8Uem4ONpKMy0Fu++sFawTkq6VLag8dJNxlMX2ZDZl9g6zPkuH6VAi7AQnUP5AgB
|
||||
fo38A4IBBQACggEAAwtHv2soJPfUaN7yz9PZjZQGQY6YHaF20JO6e5nZ8U7xt4dS
|
||||
k50RDmeJfEQkF+tCD3zQdrEGBA9hKw4VwHCcln/cjgnau0ZX6+mJX0hWSkAZntxH
|
||||
KeewRFuHSe5krpVHmel55OIdq2mjAf03d3TQMi+r9SKSKnsoYh2A6UdUxvLDJZNS
|
||||
Pse5HVRVhZcaC2N1bzBz4VyhMA6yBH1yfTD2sjdXEcnu1/5XMnIK42D1c30Bud03
|
||||
AAG9FV0uk572Nf6HZ832uR37cRmMFDEcDfYzd8BXO5z66I3jnLPlkvQXfOAwJgJl
|
||||
jYjIOal4Tq2At+MJHBD4oEeBwT3oiQ6IiWd8B6OBuDCBtTAdBgNVHQ4EFgQU26tc
|
||||
Xt0BK5TtgVqDDW5vPwOKS9kwHwYDVR0jBBgwFoAU26tcXt0BK5TtgVqDDW5vPwOK
|
||||
S9kwDgYDVR0PAQH/BAQDAgbAMGMGA1UdHwRcMFowWKBWoFSGOWh0dHA6Ly90ZXN0
|
||||
LmV4YW1wbGUuY29tL2V4YW1wbGUtY2EvY3Jscy9jYS1jcmwvbGF0ZXN0LmNybIYX
|
||||
aHR0cDovL3d3dy5leGFtcGxlLmNvbS8wCwYJYIZIAWUDBAMCA0cAMEQCIDq+hhSC
|
||||
G6CHIHs151iGoDODCBNkE2e8qcRZflxspexxAiBi59c79XPuVZM76Kh6Gr5q6Wdg
|
||||
TvbojnlvPkhoeFiz9A==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIICxDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIPI609nk2/T8CAggA
|
||||
MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECMcOYQyXTZg8BIICcMqFPce39Zsr
|
||||
peKtuqr+vuMmu2s/Kxz5hkGGJrig/HAb+8gHl9VNaXcQqr/ePJ1EQj6ZV5j8WUYx
|
||||
5yu7+APHQ1YPoWKPm/sMVM2ZQwfPATPkp5+p2AaymnjeXUA6jb2Jm7fIEdhbRG15
|
||||
H6JRjdFJRkqrfRQoyjrpTCXDq0ScLSIVvcCIg3PJ2U5RNXdrlRKxgtQXrX6bOtyc
|
||||
2v3TZx6T1KLyoKSO+IWP/aINH7rD3mm5KAffSUINenAeAXsVjUvcn3POpBHLhFKG
|
||||
MgVjUNOGBLc9ySHRCNtXqXELOEJihwNVfoXSKwfS0iDllDOYsmJW7cylrZ25jOKt
|
||||
RNssmmzRMWa87hk28uJ1J9uKiY9YTxLxC1kcoPN6y3JI9R9WuJ4+npF/cpKr6lmM
|
||||
ChQyKTIkZxKgUd/Wdt+Ydds5eK9tV7JZn9f2Cw72Es/91sI319g3Nz9sKjO7kfhu
|
||||
4Uac9EaDEwlkmyYz+nEHHysbf+9NWN3YPaGEVKcTrT1UXWEtumUg7FJln1//0vU2
|
||||
aW8F2wSSREWytjBNMXV/9sr5Vt9sLoDEPgn6sEjpfHBtEnzJo8+DqtAYm9/syFSI
|
||||
FApUnEvB4IprrOjFWXuDnNBF0leIgcJCQgw62G3R9cF8XPVEIzVHFCtJ7KSXVbZR
|
||||
eESHJ6y2PHWhC2rBGyOnQh4ZthpoFL3hLlYBfmG3vWyoWSPMEfJuzHqBqBgN6pf1
|
||||
RTKssY9KtPc3ltenVaOrAdteIzIGNQ2YlL4oFm+x4l5F3bSBL6oHWe2OtN0zV89E
|
||||
LXiolc7WqWwICZXFHnnyVVRBYVI+h59+5EykUVDiSCLQmrMLLoPSOg==
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,82 @@
|
||||
external-url-prefix: "http://localhost:9000"
|
||||
keysets:
|
||||
test:
|
||||
path-prefix: keys
|
||||
keys:
|
||||
rootRsa:
|
||||
path: key1.pem
|
||||
signRsa:
|
||||
path: key2.pem
|
||||
ocsp-responder:
|
||||
path: key3.pem
|
||||
|
||||
|
||||
pki-architectures:
|
||||
test:
|
||||
keyset: test
|
||||
entity-defaults:
|
||||
country-name: BY
|
||||
organization-name: TSpdf
|
||||
entities:
|
||||
rootRsa:
|
||||
common-name: TSpdfTestRootRsa
|
||||
signRsa:
|
||||
common-name: TSpdfTestSignRsa
|
||||
ocsp-responder:
|
||||
common-name: TSpdfTestOcspResponder
|
||||
certs:
|
||||
rootRsa:
|
||||
subject: rootRsa
|
||||
issuer: rootRsa
|
||||
validity:
|
||||
valid-from: "2000-01-01T00:00:00+0000"
|
||||
valid-to: "2500-01-01T00:00:00+0000"
|
||||
extensions:
|
||||
- id: basic_constraints
|
||||
critical: true
|
||||
value:
|
||||
ca: true
|
||||
- id: key_usage
|
||||
critical: true
|
||||
smart-value:
|
||||
schema: key-usage
|
||||
params: [digital_signature, key_cert_sign, crl_sign]
|
||||
signRsa:
|
||||
subject: signRsa
|
||||
issuer: rootRsa
|
||||
validity:
|
||||
valid-from: "2000-01-01T00:00:00+0000"
|
||||
valid-to: "2100-01-01T00:00:00+0000"
|
||||
extensions:
|
||||
- id: key_usage
|
||||
critical: true
|
||||
smart-value:
|
||||
schema: key-usage
|
||||
params: [digital_signature, non_repudiation]
|
||||
- id: authority_information_access
|
||||
smart-value:
|
||||
schema: aia-urls
|
||||
params:
|
||||
ocsp-responder-names: [ocsp-service]
|
||||
ocsp-responder:
|
||||
subject: ocsp-responder
|
||||
issuer: rootRsa
|
||||
validity:
|
||||
valid-from: "2000-01-01T00:00:00+0000"
|
||||
valid-to: "2100-01-01T00:00:00+0000"
|
||||
extensions:
|
||||
- id: key_usage
|
||||
critical: true
|
||||
smart-value:
|
||||
schema: key-usage
|
||||
params: [digital_signature]
|
||||
- id: extended_key_usage
|
||||
critical: true
|
||||
value: [ocsp_signing]
|
||||
- id: ocsp_no_check
|
||||
services:
|
||||
ocsp:
|
||||
ocsp-service:
|
||||
for-issuer: rootRsa
|
||||
responder-cert: ocsp-responder
|
||||
signing-key: ocsp-responder
|
||||
@@ -0,0 +1,50 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDUTCCAjmgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwODELMAkGA1UEBhMCQlkx
|
||||
DjAMBgNVBAoMBWlUZXh0MRkwFwYDVQQDDBBpVGV4dFRlc3RSb290UnNhMCAXDTAw
|
||||
MDEwMTAwMDAwMFoYDzI1MDAwMTAxMDAwMDAwWjA4MQswCQYDVQQGEwJCWTEOMAwG
|
||||
A1UECgwFaVRleHQxGTAXBgNVBAMMEGlUZXh0VGVzdFJvb3RSc2EwggEiMA0GCSqG
|
||||
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDX58A5mPTZY0KQaGyz+ub4TEL/2GQKTcYf
|
||||
63jfcb6JOuZKNmEOaz4xd3fVSVYhFNjQFUiVXqyK5bo3biownQ29YAPY9sdJDh9x
|
||||
FLV9pos03beco4GQ5kHDMX2BqkdRTQT5FempyBO8Zwv+3uflr8PGmN2dW91apsse
|
||||
2d+agwd/ADAX1vfWPED1kzAPXn1FOTqovbsK7sJofi8Mps3s37Q0t8AUsldYucfE
|
||||
y1gueCOZRLT1JxQmoxDppUO/JJHweotan+AX5UJsuYYAkWf9wKTdgiGEiBRhVXB5
|
||||
NSNaeGLiZJERGAXaEY6lHA7aGjv8vnmo0YfWPZVH6oP0kR3SqcNFAgMBAAGjYzBh
|
||||
MB0GA1UdDgQWBBSD4eOtT11lgdTpeBaZYBcOyXxDhjAfBgNVHSMEGDAWgBSD4eOt
|
||||
T11lgdTpeBaZYBcOyXxDhjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
|
||||
hjANBgkqhkiG9w0BAQsFAAOCAQEAETmTp4pUX+EbgzV7WL+FiNWdJbXaBvNHTTQx
|
||||
6JRRnzqV+6E60cCfXUK50FM2koswzP80hfFwZ/9OH9Ms12gLT0w+APobT3n5jJ3H
|
||||
2KnUH3Fbkh5JkKGwsk2r4M7q0701hR7U2VfB3n9tTElgEi6uRIhC980a1gNZqlC0
|
||||
rWa1XOuqyr5p5H5fkThgdbOEKC85nSZt1U0/q0FoAYtat5IaSTXwNhgJLCnFt4Le
|
||||
DkIbPku435rsitt+dMr1X/YXK27fCkTQXmmCn62YppRSUvwQdvUjJWcj9RPwqEiR
|
||||
bSagmLviLsTMtbe3+HEi9YBh23iQLgz49nEme7LxQHSl7deLZg==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQ5SzxKwwVl8Vt+rNB
|
||||
tZ+IKAICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEEcAigNA6wf6vXIt
|
||||
F3uWYbQEggTQ106/2UngQpk07M3yknu3OIU6p3Gry4aalr/gHSmMk+dmm0eql6UV
|
||||
1OsrzraXmgS9B+qiXTtqws3qHBpk8Vl1AnJUgY28t2+4Bci3omaUSFYb6XiBCvhq
|
||||
tpCpHV/Dy9XIRVW/GCMdEBxPfqZeE1yNYCnxs9E3y+IjcbO0elYcolcOQqkem0st
|
||||
rzMENyOAnVxdY4z9/wr7uCe8ow+oivzVDxQNIxvhcCMBHiDs7N9icVVW7TlknGMK
|
||||
ZzRC+j19xwq/lw6KjzP3uD3qte2mS5SiiiCB6viGqccrBljKtfm0f8SyF9sSpHJI
|
||||
hx5/ZmObsw9SfNutil+lEHCJrHfTyAqc2Zbqj4AlvocOuIQ7CDd0mG68BWkHkHRK
|
||||
/SZqCQ5aU8Q1FYsLf9ghsZc7k53n+9md3q/JOlUN3EZp2J9dTDxjC/f/6kpv/pF9
|
||||
vtHY3434p7e4+O9Iej3Y6/UCljQpD0A5Pdnp81vlyn8muYYOVY2/NVX100cK47Hk
|
||||
11KbyFGr/YoT4mbq8T4b5y9VQHaXFA3Ivlf9nntsPEafuooPuAz+c5yfoQCZ12xo
|
||||
XCGRlkHCHz9oMKKGsyM02zHvEM6ASfFbVrM6lrvdH7ZVEDsuaRDFwOi9+Qz6arCm
|
||||
lKacvjlsM3fziLk+xpGJmfEQ6wVkZUBCKHcVJ9/+Va/UuaLbnoca8TJ6d2UAhfrC
|
||||
e2331HJ/FZ3xqZMi5taW2Kl/vDtNmUwEOgIuAZGjP4TgGCV+6TJzdILPw1vdXFzH
|
||||
nV1lpWU7Th4/5LbonBzbY57vCg3OhbwA1pvXbe3RqjL+82V1FeAR1OThBD0Qfvnk
|
||||
rHcaYoJVN3qEbubqkADYEshXMAHW2k7Ih9PBqjmRwazr+SG19x7j7n5jK40X8MDx
|
||||
jdbMmr7dXAxCNNR63TvndGE1V8unb0SGwQkuuf/ZHynur0eAP6RrqhDRhxasphiv
|
||||
yf+3qRTDf3iBizSxuq2L9QcSVq++z6PgkKwHfwpFByFhMytsv3E/RE4Lt4kzUpsr
|
||||
f2CereSyQlAAV0nnaWKEEfetvZNzjnXACXX4JSdZACnslCfepoT6lyjXN4AAtZPt
|
||||
ihZWicCXkvWuLoUdtdwmBYer6elkVAiszFT6agBoR/R4tDLiK+EoyXlfSAjStbCn
|
||||
UCOPODXgAq5H3FFgzhMQR9DnxwIIS1UDVTabFTB/3w79cU/lXDeMGmPXdHCDR4/1
|
||||
KTHsvBfaujwTOiFKAJlmDgoiwy8MLEu+q3X+XLBOrBYLSD8QT6YELkqnn5hhqI9C
|
||||
NhkTay4qczmfW6jemFdoI+JQMvNKf83Ip71nVC8oet7toXRg+hErbrV9p8m8oD2p
|
||||
tPSXJrPFSBu0QDfMeqMG1TnbyZxbetJsc4PsQ2F2NIBnf194zftZMPNXaZ7f93h/
|
||||
5O4yemAQkQIfOtQdxxPeDMGRzNvn1367UITuMtBhgTac3UlkfiaNAOq+kTRpd/bA
|
||||
u6YnV9WxZQiTuPcvo0575D4kJfqhwEvBm2wRNqRxTnIDhSSTgSaUNUr3OG0JA396
|
||||
BEthkM608enAblG5cOyBD38ExamnI+x7n5T4b8q+/zfLfiqR11XPcDN7dcbXdf0b
|
||||
TQ1wN8Tx11Udm5pCqX5JZCK9gncmapwY16rwDa5x5TGhxCV3CAwVOlk=
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
||||
@@ -0,0 +1,71 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDjDCCAnSgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwODELMAkGA1UEBhMCQlkx
|
||||
DjAMBgNVBAoMBWlUZXh0MRkwFwYDVQQDDBBpVGV4dFRlc3RSb290UnNhMCAXDTAw
|
||||
MDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjA4MQswCQYDVQQGEwJCWTEOMAwG
|
||||
A1UECgwFaVRleHQxGTAXBgNVBAMMEGlUZXh0VGVzdFNpZ25Sc2EwggEiMA0GCSqG
|
||||
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1HmwyVlxIQ/a6CojLqueS0TeHnzP2WYLR
|
||||
zvB8CupkSLFlJTXqS0Vsa8mrMSUjAzH3vM2+WfmXsYEnEEmNniVVbC1qwjVw0Kai
|
||||
W+NhtrIm54uEK5LrNR0+FthxAHBUqty0ewmcqoM2k9h0v0zZ76bQVteAcSlA1yXN
|
||||
RjQgFbUrA6GCL1NlypytUus8gvAda3H115k+bmJJp3R6S161VfCf4yalHFRfaWni
|
||||
5gB8ZZvChdd1g5kOMPJ8igo7sl51y9GVNRSvT3U+n9VPIxVcn8YeR9HD1xzGbt4U
|
||||
QGGEfpJ2UliN+sX+eZpf4IoUqEwCC+WizzMI+ipB0qAAQ2GX7ssVAgMBAAGjgZ0w
|
||||
gZowHQYDVR0OBBYEFJ+U4ODrWZwA+nmdz4pvUUZD3eRfMB8GA1UdIwQYMBaAFIPh
|
||||
461PXWWB1Ol4FplgFw7JfEOGMA4GA1UdDwEB/wQEAwIGwDBIBggrBgEFBQcBAQQ8
|
||||
MDowOAYIKwYBBQUHMAGGLGh0dHA6Ly9sb2NhbGhvc3Q6OTAwMC90ZXN0L29jc3Av
|
||||
b2NzcC1zZXJ2aWNlMA0GCSqGSIb3DQEBCwUAA4IBAQB9Ou48Yia8qammrCTlmP0/
|
||||
XI0l1Hp09JXRRc+CMXB3J7wUHj8gShgEZZ7o7ZEO1tpfSqVt95KrKUdu8WbAr3U/
|
||||
bJu0K6XGqEDyw5svH/kzygqw7J9h7Qd0OZCRjYnHyFlK21C233VQoSlOq/hngSn1
|
||||
w8Hzy6atgFdTa0sICMal1VHRu7DfYVpsGZmZqGk/kTheHw9t21Nz6JpUtFKnPF/e
|
||||
UsyFjldcxXoIy5rtyrBkckLLnbW2/pD/PcKApRsIFImLl4aQywE+P2GyW1OoMXpx
|
||||
K4yAobmodB++waw44KVqAk8XvJca85f5oYWKB6kavJDs2kb2c7cLtR1duLj9Tfdj
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDUTCCAjmgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwODELMAkGA1UEBhMCQlkx
|
||||
DjAMBgNVBAoMBWlUZXh0MRkwFwYDVQQDDBBpVGV4dFRlc3RSb290UnNhMCAXDTAw
|
||||
MDEwMTAwMDAwMFoYDzI1MDAwMTAxMDAwMDAwWjA4MQswCQYDVQQGEwJCWTEOMAwG
|
||||
A1UECgwFaVRleHQxGTAXBgNVBAMMEGlUZXh0VGVzdFJvb3RSc2EwggEiMA0GCSqG
|
||||
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDX58A5mPTZY0KQaGyz+ub4TEL/2GQKTcYf
|
||||
63jfcb6JOuZKNmEOaz4xd3fVSVYhFNjQFUiVXqyK5bo3biownQ29YAPY9sdJDh9x
|
||||
FLV9pos03beco4GQ5kHDMX2BqkdRTQT5FempyBO8Zwv+3uflr8PGmN2dW91apsse
|
||||
2d+agwd/ADAX1vfWPED1kzAPXn1FOTqovbsK7sJofi8Mps3s37Q0t8AUsldYucfE
|
||||
y1gueCOZRLT1JxQmoxDppUO/JJHweotan+AX5UJsuYYAkWf9wKTdgiGEiBRhVXB5
|
||||
NSNaeGLiZJERGAXaEY6lHA7aGjv8vnmo0YfWPZVH6oP0kR3SqcNFAgMBAAGjYzBh
|
||||
MB0GA1UdDgQWBBSD4eOtT11lgdTpeBaZYBcOyXxDhjAfBgNVHSMEGDAWgBSD4eOt
|
||||
T11lgdTpeBaZYBcOyXxDhjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
|
||||
hjANBgkqhkiG9w0BAQsFAAOCAQEAETmTp4pUX+EbgzV7WL+FiNWdJbXaBvNHTTQx
|
||||
6JRRnzqV+6E60cCfXUK50FM2koswzP80hfFwZ/9OH9Ms12gLT0w+APobT3n5jJ3H
|
||||
2KnUH3Fbkh5JkKGwsk2r4M7q0701hR7U2VfB3n9tTElgEi6uRIhC980a1gNZqlC0
|
||||
rWa1XOuqyr5p5H5fkThgdbOEKC85nSZt1U0/q0FoAYtat5IaSTXwNhgJLCnFt4Le
|
||||
DkIbPku435rsitt+dMr1X/YXK27fCkTQXmmCn62YppRSUvwQdvUjJWcj9RPwqEiR
|
||||
bSagmLviLsTMtbe3+HEi9YBh23iQLgz49nEme7LxQHSl7deLZg==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQuRsrG2YMFDv51bk5
|
||||
fXHw+AICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEPDTrII77xr0oFCe
|
||||
QNu83ZsEggTQmQyiTM60R8V66+rhCj1Yck4QzQWMl7UTz50IAeukE2f109yaAg1I
|
||||
oUDK/7q7yCu7ebuEhES5yof++qQYp6XSRF4twTB0LmELxrHTEDNfJzuH3l2kt1C2
|
||||
Qf2UXJeMbEX/SxCC7R3BtPV7607VKWadvr38nSDNH5/AOtlR4M3f0qH2CoxqVaJk
|
||||
+3YcYxU2QXhPsBntzmDy6+cYduy37NwtajGezf3MlE0X6nWElSyPyE9Ni0jNxkAr
|
||||
P3DMZI2qVd37XaUGqeIc5iT84+dh9AEeUMO0B8zKi2bRUEPKMCmJ0mUP2tRRQ+nR
|
||||
tEOR/G8DXG0a8b8xjKzmRfYTy6h2WlIp4KJ8x0QM8ppXR+FicFgqU4eIe9OcgW7U
|
||||
JAk4Pjp/Osi5l2hPN7y8kFv9CMM0QEzYJsPXWh4M5tj13ckgnVl6EIvyVb4mjxZN
|
||||
LDNS6a/3ilks4buCM+xHpaxlqCnXUzuPoT/xYkNsTNP9wmSMOIIOsiKvW2FK9n1x
|
||||
A9djdOCHo5/DmD5KWOEMp4r1aPBSmh9vfEUR7sCPu5JgtRw4jh2d1gfB5hbZv8xS
|
||||
edEJbhrcLlwcB9p960oeGp5iqk1LTJSgzzt6lmZiIX7fT++yH1lQT7zaO2aVigIM
|
||||
ezOROjFUCmvwUs5KH/z7E8mSWI/XUEhMcQjvVCrvCdvcjL8MpwL+gPxeCyOcybal
|
||||
zOrJukG9hrT8DBvpDvkyYP1vmV6eH/USkC2di6F58pXyQObqfJSbP5n0iYNcZqel
|
||||
9v6ZCR+om/oyDGb8FvI13Nz1F135L8+DPtMwfY5Du5PQkzK5BRNwndh4BuBHPz1B
|
||||
RcrkK+8gn8ZCfsmapzS+Dy18slVENRMF+9tFhE9Rd/tdbpfCrotMHZ2swr/Jvg03
|
||||
VNElqKv8bodeZRMHILOId7qP5yS8X2ySCQ00Y6B2BIvmh/EECXai62PMYf/ohbo3
|
||||
KziVCUOhCms61bwPWpOu66LFV+FG9aXSPL/Ep4y1t35PXHWTmCdcFIG7j77I0Lj2
|
||||
ZMj6Z/T6zE04xx0k6iH+EhRS5uj7WxoZAL5UO6Ijop7GBdMoMguAq5P28DPipa2x
|
||||
CyuQ+Z+xJoZQ5BX1LWlAK7p6YJSHpye9CcVXrdrMlOciOAkmpcIm9DSsbWE8UKl0
|
||||
JyNukYGyEFUN/NafYjr/WbQfWRZHfBeJS98Eoqq6XdiOBdPnBm+C35UHtsHI6vA7
|
||||
MvxJab4ZNQ6M7Vf9oCyBmo+YteaN5PapT+ieHFmLEPV1odR7UC/DEkkQzHZzRD0K
|
||||
M8+0ad8fz8BRhBNm9oLNcLrebeasCVEDxclb8r82C0omHSBCs7D5ToF5u/beRqiR
|
||||
TaT3P0E+tsxawZzGniN10DeXb0T/JShzo2AKJLoaUuIhGGTQsho5UnU/WnPd+0xL
|
||||
6jGGxJ947a3Roj2Fj+3hI1X7PKVB+n4ZWqZrKQQk/n0PWfvwUE+BpzAgai75Gc3P
|
||||
1UHtNRNRtN9d5KK2rMxOCDoyantxEiW8TNg93I9EKKF/MN+lyjSmyt6TgNVdj3BR
|
||||
FxsN33Xx1ccHqfX3/xcsLHNOOy7xCQgPoX6rsxuIpMDILJtniJx38Ex4ySmNqPyQ
|
||||
GbJqgFKtxXbj1RonRAUMchu9eGlKWoEqPwdfvkbUDf2M2FJC5WHM4wM=
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user