Page 1 of 2
Form of SubjectName text in PDF export
Posted: Tue Aug 17, 2010 7:47 am
by LukasT
Hello,
how looks form of subjectName for Subject name string in PDF export? I have tried to put SubjectName from cert store but stimulsoft returned exception - DigitalSign error at step 2: Certificate is not found .
Thank you...
Form of SubjectName text in PDF export
Posted: Tue Aug 17, 2010 8:54 am
by Ivan
Hello,
There are two ways to create the digital signature for PDF file:
- using the interface of the system library of cryptograph;
- directly by specifying the string - certificate identifier.
In the first case it is necessary to set the Get Certificate From CryptoUI property to true. When
exporting, the menu for selecting certificate from the current storage of certificates will be displayed.
It is necessary to select one certificate from the list of available ones.
In the second way, it is necessary to use the "SubjectNameString" property and write in it the
string - certificate identifier. Identifier is the name of the certificate owner (full string) or a part of the
name (substring).
Also please try to set the UseLocalMachineCertificates property in export settings to true or false.
Thank you.
Form of SubjectName text in PDF export
Posted: Tue Aug 17, 2010 10:26 am
by LukasT
Sorry Ivan, but some problems exists...
I am using X509Certificate class, and there is property SubjectName which contains several parameters as CN, OU, DC etc. But I thing, that finding certificate using only CN is wrong way... because I can have more certificates with the same CN in cert store... if I know, for finding certificate is common used this function:
Code: Select all
(X509Certificate2Collection)store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName, subject, false);
as subject must be whole subjectName...
I have tried tu put into ((StiPdfExportSettings)sett).SubjectNameString both - only CN value or whole subjectName and both caused exception...
Second strange issue is in export dialog in viewer... if I don't have checked using Crpto UI, i can put into field for subject name only 33 characters... that is not enough to put whole subjectName... but even if I put only CN value, certificate is not found

Form of SubjectName text in PDF export
Posted: Wed Aug 18, 2010 2:38 am
by Ivan
Hello,
LukasT wrote:I am using X509Certificate class, and there is property SubjectName which contains several parameters as CN, OU, DC etc. But I thing, that finding certificate using only CN is wrong way... because I can have more certificates with the same CN in cert store... if I know, for finding certificate is common used this function: ...
For working with certificates we use Crypt32.dll and CryptUI.dll libraries.
For getting the certificate the CertFindCertificateInStore command is used and the CryptSignMessage command is used for signing the document.
These commands are universal and work with majority of certificates on the basic level and know nothing about options of the certificate types.
Unfortunately, we do not plan to work further on this functionality.
LukasT wrote:as subject must be whole subjectName... I have tried tu put into ((StiPdfExportSettings)sett).SubjectNameString both - only CN value or whole subjectName and both caused exception...
Second strange issue is in export dialog in viewer... if I don't have checked using Crpto UI, i can put into field for subject name only 33 characters... that is not enough to put whole subjectName... but even if I put only CN value, certificate is not found

We fixed the issue. Fields length is increased up to 256 symbols.
Thank you.
Form of SubjectName text in PDF export
Posted: Wed Aug 18, 2010 6:02 am
by LukasT
Thank you for fix...
I have tried everything possible, but still no success
My code is:
Code: Select all
...
sett = new StiPdfExportSettings();
((StiPdfExportSettings)sett).UseDigitalSignature = true;
((StiPdfExportSettings)sett).GetCertificateFromCryptoUI = false;
((StiPdfExportSettings)sett).UseLocalMachineCertificates = true;
((StiPdfExportSettings)sett).SubjectNameString = subjectName;
rep.CompiledReport.ExportDocument(format, filename, sett);
...
Subject name is valid because I am using it correctly in my function for signing other exported formats...
Is possible to send me any part of your code which you use for getting certificate from store?
And I have found one interesting unanswered question... that is the same using Crypt32.dll like you have, isn't it?
http://social.msdn.microsoft.com/Forums ... f29d560a1c
Form of SubjectName text in PDF export
Posted: Wed Aug 18, 2010 8:23 am
by Ivan
Hello,
LukasT wrote:Is possible to send me any part of your code which you use for getting certificate from store?
We use the following code:
Code: Select all
[StructLayout(LayoutKind.Sequential)]
public struct CERT_CONTEXT
{
public uint dwCertEncodingType;
public IntPtr pbCertEncoded;
public uint cbCertEncoded;
public IntPtr pCertInfo;
public IntPtr hCertStore;
}
Code: Select all
uint ENCODING_TYPE = Win32.PKCS_7_ASN_ENCODING | Win32.X509_ASN_ENCODING;
string CERT_STORE_NAME = "MY";
uint CERT_SYSTEM_STORE = Win32.CERT_SYSTEM_STORE_CURRENT_USER;
if (useLocalMachineCertificates)
{
CERT_SYSTEM_STORE = Win32.CERT_SYSTEM_STORE_LOCAL_MACHINE;
}
#region Open store
IntPtr hStoreHandle = Win32.CertOpenStore(
(IntPtr)Win32.CERT_STORE_PROV_SYSTEM,
0,
IntPtr.Zero,
CERT_SYSTEM_STORE,
Encoding.Unicode.GetBytes(CERT_STORE_NAME));
if (hStoreHandle == IntPtr.Zero) ThrowDigitalSignError(1);
#endregion
#region FindCertificateInStore
if ((certificateID != null) && (certificateID != string.Empty))
{
IntPtr SIGNER_NAME = Marshal.StringToBSTR(certificateID);
int certificateIsValid = 0;
do
{
pCertContext = Win32.CertFindCertificateInStore(
hStoreHandle,
ENCODING_TYPE,
0,
Win32.CERT_FIND_SUBJECT_STR,
SIGNER_NAME,
pCertContext);
if (pCertContext == IntPtr.Zero) ThrowDigitalSignError(2, "Certificate is not found", true);
SignerCert = (Win32.CERT_CONTEXT)Marshal.PtrToStructure(pCertContext, typeof(Win32.CERT_CONTEXT));
certificateIsValid = Win32.CertVerifyTimeValidity(IntPtr.Zero, SignerCert.pCertInfo);
}
while (certificateIsValid != 0);
}
else
{
ThrowDigitalSignError(2, "Subject name string is empty");
}
#endregion
Thank you.
Form of SubjectName text in PDF export
Posted: Thu Aug 19, 2010 6:06 am
by LukasT
Thank you Ivan...
so, now I have the same method as you use (probably you have code from pinvoke.net... it seems)... If I call CertEnumCertificatesInStore method, it returns me all certificates in store ... that is OK. But than I call CertFindCertificateInStore method with subjectName from first function and it returns me zero pointer

Really strange issue... So I will test it and debug it and get to know you where is the problem
And Ivan, are you shure, that your code is running correctly in runtime? Please check it and try to sign PDF document in runtime using some certificate without CryptoUI...
Form of SubjectName text in PDF export
Posted: Thu Aug 19, 2010 8:10 am
by LukasT
So...
I have realized what is going on. Parameter CERT_FIND_SUBJECT_STR in function CertFindCertificateInStore is really only for finding certificates in store by CN value... even so your engine returns exception DigitalSign error at step 2: Certificate is not found... looks really your code is not all right...
My correct example:
Code: Select all
public class Simplecert
{
const string MY = "MY";
const string OTHERS = "AddressBook";
const uint PKCS_7_ASN_ENCODING = 0x00010000;
const uint X509_ASN_ENCODING = 0x00000001;
const uint CERT_FIND_SUBJECT_STR = 0x00080007;
const uint CERT_FIND_SUBJECT_NAME = 0x00020007;
static uint MY_ENCODING_TYPE = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;
static string lpszCertSubject = "..."; //value from CN in SubjectName
public static void Main()
{
IntPtr hSysStore = IntPtr.Zero;
IntPtr hCertCntxt = IntPtr.Zero;
IntPtr SIGNER_NAME = Marshal.StringToBSTR(lpszCertSubject);
hSysStore = Crypt.CertOpenSystemStore(IntPtr.Zero, MY);
Console.WriteLine("Store Handle:\t0x{0:X}", hSysStore.ToInt32());
X509Certificate cert;
IntPtr currentCertContext = Crypt.CertEnumCertificatesInStore(hSysStore, (IntPtr)0);
while (currentCertContext != (IntPtr)0)
{
cert = new X509Certificate(currentCertContext);
// Do something with the certificate...
Console.WriteLine(cert.ToString(true));
currentCertContext = Crypt.CertEnumCertificatesInStore(hSysStore, currentCertContext);
}
if (hSysStore != IntPtr.Zero)
{
hCertCntxt = Crypt.CertFindCertificateInStore(
hSysStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_NAME,
SIGNER_NAME,
IntPtr.Zero);
if (hCertCntxt != IntPtr.Zero)
{ //use certcontext from managed code
Console.WriteLine("CertContext:\t0x{0:X}", hCertCntxt.ToInt32());
X509Certificate foundcert = new X509Certificate(hCertCntxt);
Console.WriteLine("\nFound certificate with SubjectName string \"{0}\"", lpszCertSubject);
Console.WriteLine("SubjectName:\t{0}", foundcert.Subject);
Console.WriteLine("Serial No:\t{0}", foundcert.GetSerialNumberString());
Console.WriteLine("HashString:\t{0}", foundcert.GetCertHashString());
}
else
Console.WriteLine("Could not find SubjectName containing string \"{0}\"", lpszCertSubject);
}
Console.ReadKey();
}
}
Second issue is not mistake, but only not implemented feature - finding certificate by whole subjectName using CERT_FIND_SUBJECT_NAME and CertNameToStr function... I thing this is better way, because than I can have more certificates with one CN (what is quite common) and than function will find right certificate which I want...
Form of SubjectName text in PDF export
Posted: Mon Aug 23, 2010 2:15 am
by LukasT
Is any progress in this issue, please?
Form of SubjectName text in PDF export
Posted: Mon Aug 23, 2010 8:53 am
by Ivan
Hello,
We made some improvements in that direction.
Please check the next prerelease build from 23-Aug-2010 when it will be available and let us know about the result.
Thank you.