The CAdESSigner component creates CAdES- and CMS-compliant electronic signatures.
CAdESSigner can sign documents and files in compliance with CMS Advanced Electronic Signatures (CAdES) specification. Originally developed by ETSI on the basis of PKCS#7 format and initially adopted in the European Union, CAdES has quickly become a recognized international standard for signing all sorts of electronic documents.
Besides being a signature standard in its own right, CAdES is used as part of other higher-level signature standards, such as PAdES or S/MIME. It provides a convenient framework for creating short-lived and long-term signatures over any kind of documents, and is now used by governments, healthcare providers, banks, and independent service providers all across the globe.
Standards and technologies supported
CAdESSigner offers the following signing capabilities:
- Create and upgrade CAdES signatures in accordance with the most recent CAdES specification (ETSI EN 319 122). Some features from older versions are also supported.
- All profiles are supported (BES, EPES, T, C, X, XL, A, including Baseline and Extended variants).
- Timestamping using external TSAs.
- All industry-standard cryptographic algorithms (RSA, ECDSA, SHA256-512, and many others).
Configuring the signature parameters
Configuring CAdESSigner to make it produce a signature of the right type is the main task you would need to perform in your code. Normally the service or software you will be communicating your signed documents to will provide you with the list of requirements that your signatures should match.
Typically, those will dictate the following key aspects of the signatures:
- The signature Level (such BES, T, XL, A, or XLong). This can be passed as the Level parameter of the Sign method.
- Whether the signature should be detached or enveloping: this can be adjusted via the Detached parameter of the Sign method.
- When creating a timestamped signature (such as T or A), provide the address of your online TSA service via TimestampServer property.
- When creating long-term signatures that include the signing chain and validation material, tune up validation parameters via RevocationCheck, OfflineMode, and IgnoreChainValidationErrors properties.
In some circumstances you will also need to adjust the following lower-level settings:
- Set ClaimedSigningTime to include the local signature creation time (not timestamped by a TTP).
- Specify EPES signature parameters via PolicyHash, PolicyHashAlgorithm, PolicyID, and PolicyURI properties.
- Provide the hash algorithm via the HashAlgorithm property.
CAdESSigner can use certificates residing on different media. Besides generic certificates stored in PFX or PEM files (A1), it can operate with non-exportable certificates residing on hardware media (A3) or in the cloud.
Non-exportable certificates can be accessed transparently via a Windows CSP or a PKCS#11 driver, if supplied by the certificate issuer. Proprietary interfaces can be plugged in with the external signing feature (see below).
You can use CertificateManager and CertificateStorage components to access the signing certificate. Assign the certificate to SigningCertificate property, and optionally provide the remainder of its chain via SigningChain property.
Note: If signing with a non-exportable key (such as residing on a hardware device or in the cloud), please make sure you keep the original CertificateStorage object open until the signing is completed. This is because the storage component provides a 'bridge' to the private key. If the storage is closed prematurely, this bridge is destroyed, and the private key can't be used.
You don't need to provide a signing certificate or chain when timestamping and upgrading signatures, since this type of operation does not involve the signing private key.
Signing a file
Now that you have set up all signature properties and attached the signing certificate, it is time to proceed to signing. You can provide the input document in one of the following forms: as a file (assign the path to InputFile property), as a stream (assign to InputStream property), or as a byte array (assign to InputBytes). Similarly, the output can be collected in one of the same forms, either by passing the destination path or stream via OutputFile and OutputStream respectively, or by reading the resulting document bytes from the OutputBytes property after the signing completes.
Having set up the input and output (unless using OutputBytes, which should be read later), call the component's Sign method, passing the desired signature level and type as parameters. This will initiate the signing process. Depending on the settings, the signing may be as straightforward as calculating the document hash and signing it with the private key (e.g. in CAdES-BES or B-B variant), or it may involve advanced chain validation routines (CAdES-XL or -A). During the latter the component may contact a number of external revocation information sources (CRL and OCSP servers) to establish the validity of the signing certificate.
If a TSA server was provided via the TimestampServer property, the component will contact it too to timestamp the new signature.
During the signing CAdESSigner may fire events to let your code know of certain conditions. It may fire TLSCertValidate if one of the HTTP endpoints involved in the operation (which may be a CRL, OCSP, or TSA service) works over TLS and needs its certificate to be validated.
Apart from signing, CAdESSigner can perform operations on signatures of other kinds. Use Upgrade method to upgrade an existing CAdES signature to a higher level (e.g. BES to XL). Use Timestamp to add a generic or validation timestamp to an existing signature. Use the Countersign method to add a countersignature to an existing signature. For any of these operations the input should constitute a valid CAdES signature.
External signing and DCAuth
CAdESSigner, like many other components offered by the product, supports two methods of signing with external keys. These methods are fully independent of each other: you can choose the one that suits your usage scenario best.
Synchronous method: ExternalSign
This is a simpler method that basically lets you infiltrate into the heart of the signing routine by taking care of the hash signing operation. The component does the rest of the job (hash calculation, preparation of signature objects, CRL/OCSP retrieval).
To initiate this method, call SignExternal instead of Sign. When the hash is ready, it will be passed back to your code with ExternalSign event. Your event handler needs to sign the hash with the private key and return the created signature back to the component - which will embed it into the document.
You don't need your signing certificate to contain an associated private key when using this method. The certificate itself (its public copy) may be needed though, as it is often included in the hash calculation.
This method is synchronous, meaning SignExternal provides you the results immediately upon its completion.
Asynchronous method: DCAuth
DCAuth is a SecureBlackbox-own know-how technology. This protocol was designed to allow sharing of private keys across environments, allowing the signer and the private key to reside on different systems. It works in the following way:
- The signing party - such as CAdESSigner - initiates the operation using SignAsyncBegin call. This produces two outcomes: a pre-signed document (a document with a blank signature placeholder), and a request state (an object containing a hash that needs to be signed). At this point the CAdESSigner instance can be released, and the process itself terminated (which may be useful when run as part of a web page).
- The request state is passed to the private key holder party. The private key holder passes the request state to a DCAuth object, which parses the request state, extracts the hash, and signs it. The output of DCAuth processing is another object, response state, which contains the signature. The private key holder then sends the response state back to the signing party.
- The signing party re-creates the controls, and passes the response state, together with the pre-signed version of the document, to the signer's SignAsyncEnd method. SignAsyncEnd extracts the signature from the response state and incorporates it into the pre-signed document.
This method is asynchronous in that sense that, from the signing party's viewpoint, it splits the signing operation into the pre-signing and completion stages which can be performed independently from each other and in different execution contexts. This makes this method particularly helpful for use in web pages and other scenarios where the signing key is not available in real time.
Fine-grained chain validation setup
Chain validation is a sophisticated, multi-faceted procedure that involves a lot of variables. Depending on the configuration of your operating environment, the specifics of the PKI framework being used, and the validation policy you need to follow, you may want to tune up your chain validation parameters so they fit them best. Below is given a summary of such parameters.
- RevocationCheck property lets you choose between and/or prioritize revocation origins. OCSP sources are often preferred to CRL because of their real-time capability and the smaller size of validation tokens they produce.
- OfflineMode is a master switch that stops class from looking for any validation tokens online. If this property is switched on, the component will only use KnownCertificates, TrustedCertificates, KnownCRLs, and KnownOCSPs collections to look for the missing validation material.
- IgnoreChainValidationErrors makes the component ignore any major validation issues it encounters (such us an untrusted chain or missing CRL). This option is handy for debugging and for creating signatures in the environments where the signing certificate is not trusted.
- KnownCertificates, KnownCRLs, and KnownOCSPs let you provide your own validation material. This may be useful when working in OfflineMode, where the signer has no access to the validation sources, or where the validation material has already been collected.
- TrustedCertificates lets you provide a list of trust anchors, either as a complement to the system's or as an alternative for it.
- BlockedCertificates lets you provide a list of blocked/distrusted certificates. Any CA certificate contained in it will be deemed untrusted/invalid.
The following parameters are not directly related to chain validation, but may have an implicit effect on it.
- Proxy, SocketSettings, and TLSSettings let you tune up the connectivity and TLS options in accordance with local preferences.
- TLSClientChain lets you provide the client certificate and its chain for TLS client authentication.
- Subscribe to TLSCertValidate to validate any TLS certificates of the services involved in chain validation.
The results of the chain validation procedure, upon its completion, are published in the following properties:
- ChainValidationResult contains the primary result of the chain validation routine: valid, valid but untrusted, invalid, or undefined.
- ChainValidationDetails provides the details of the factors that contributed to the chain validation result, such as an outdated certificate, a missing CRL, or a missing CA certificate.
- ValidationLog contains the detailed chain validation log. The log can often be very helpful in nailing down various validation issues.
The following is the full list of the properties of the module with short descriptions. Click on the links for further details.
|BlockedCertificates||The certificates that must be rejected as trust anchors.|
|ChainValidationDetails||The details of a certificate chain validation outcome.|
|ChainValidationResult||The general outcome of a certificate chain validation routine. Use ChainValidationDetails to get information about the reasons that contributed to the validation result.|
|ClaimedSigningTime||The signing time from the signer's computer.|
|DataBytes||A byte array containing the external data source.|
|DataFile||A path to a file containing an external data source.|
|ExternalCrypto||Provides access to external signing and DC parameters.|
|HashAlgorithm||Specifies the hash algorithm to be used.|
|IgnoreChainValidationErrors||Makes the component tolerant to chain validation errors.|
|InputBytes||Use this property to pass the input to component in the byte array form.|
|InputFile||A path to a file containing the data to be signed or updated.|
|KnownCertificates||Additional certificates for chain validation.|
|KnownCRLs||Additional CRLs for chain validation.|
|KnownOCSPs||Additional OCSP responses for chain validation.|
|OfflineMode||Switches the component to the offline mode.|
|OutputBytes||Use this property to read the output the component object has produced.|
|OutputFile||A file where the signed data is to be saved.|
|PolicyHash||The signature policy hash value.|
|PolicyHashAlgorithm||The algorithm that was used to calculate the signature policy hash.|
|PolicyID||The policy ID to be included into the signature.|
|PolicyURI||The signature policy URI to be included in the signature.|
|Profile||Specifies a pre-defined profile to apply when creating the signature.|
|Proxy||The proxy server settings.|
|RevocationCheck||Specifies the kind(s) of revocation check to perform.|
|SignatureIndex||The index of the signature to update.|
|SignedAttributes||Custom signature attributes to be covered by the electronic signature.|
|SigningCertificate||The certificate to be used for signing.|
|SigningChain||The signing certificate chain.|
|SocketSettings||Manages network connection settings.|
|TimestampServer||The address of the timestamping server.|
|TLSClientChain||The TLS client certificate chain.|
|TLSServerChain||The TLS server's certificate chain.|
|TLSSettings||Manages TLS layer settings.|
|TrustedCertificates||A list of trusted certificates for chain validation.|
|UnsignedAttributes||Custom unsigned attributes to be included in the electronic signature.|
|ValidationLog||Contains the complete log of the certificate validation routine.|
The following is the full list of the methods of the module with short descriptions. Click on the links for further details.
|Archive||Archives the signature.|
|Config||Sets or retrieves a configuration setting.|
|Countersign||Countersigns the existing signature.|
|CountersignExternal||Countersigns the existing signature using an external signing facility.|
|ExtractAsyncData||Extracts user data from the DC signing service response.|
|Sign||Creates a new CAdES signature over the provided data.|
|SignAsyncBegin||Initiates asynchronous (DC) signing.|
|SignAsyncEnd||Completes the asynchronous signing operation.|
|SignExternal||Signs the document using an external signing facility.|
|Timestamp||Adds a timestamp to the signature.|
|Upgrade||Upgrades existing CAdES to a new level.|
The following is the full list of the events fired by the module with short descriptions. Click on the links for further details.
|Error||Information about errors during CAdES signing.|
|ExternalSign||Handles remote or external signing initiated by the SignExternal method or other source.|
|Notification||This event notifies the application about an underlying control flow event.|
|TLSCertValidate||This event is fired upon receipt of the TLS server's certificate, allowing the user to control its acceptance.|
The following is a list of configuration settings for the module with short descriptions. Click on the links for further details.
|AddReferencesToAllUsedCertsAndRevInfo||Whether to include all certificates and revocation references in CompleteCertificateRefs attribute.|
|AddReferencesToIrrevocableCerts||Whether references to irrevocable certificates should be included in CompleteCertificateRefs attribute.|
|AddReferenceToSigningCert||Whether a reference to the signing certificate should be included in CompleteCertificateRefs attribute.|
|AllowPartialValidationInfo||Whether to allow for missing validation info.|
|CmsOptAnnexKArchiveTimestampV2Mode||Toggles use of Annex K method of calculating validation timestamp hashes.|
|CmsOptCheckATSHashIndexElements||Enables extra checks when processing ATSHashIndex attribute.|
|CmsOptCompareRDNAsStrings||Enforces comparison of RDN elements as text strings, rather than their byte encodings.|
|CmsOptDigitPADSSCompatibility||Enables Digit PADSS compatibility mode.|
|CmsOptForceSigningCertificateV2Usage||Enforces use of signing-certificate-v2 attribute.|
|CmsOptIgnoreDERReqInArchiveTimestamps||Switches off DER encoding requirement for archival timestamps.|
|CmsOptImzagerMIMCompatibility||Enables Imzager MIM compatibility mode.|
|CmsOptIncludeCertToAttributes||Regulates whether to include the signing certificate to the signature as the signing-certificate attribute.|
|CmsOptIncludeCertToMessage||Regulates whether to include the signing certificate and its chain to the CMS.|
|CmsOptInsertContentType||Regulates whether the content-type time attribute should be included in the signature structure.|
|CmsOptInsertMessageDigests||Regulates whether the message-digest signed attribute should be included in the signature structure.|
|CmsOptInsertSigningTime||Regulates whether the signing-time attribute should be included in the signature structure.|
|CmsOptSkipEnvContentInfoOnSigArchival||Excludes hashing of enveloped content when calculating an archival timestamp.|
|CmsOptUseATSHashIndexV1||Enables use of ATSHashIndexV1 attribute.|
|CmsOptUseGeneralizedTimeFormat||Enables or disables encoding of the signing-time attribute using ASN.1 GENERALIZEDTIME type.|
|CmsOptUseGenericSigAlgorithmOIDs||Enables use of generic signature algorithm OIDs in the signature.|
|CmsOptUsePlainContentForTimestampHashes||Makes CAdESSigner ignore ASN.1 content formatting when calculating timestamp hashes.|
|ContentType||The content type of the CMS message.|
|DeepCountersignatureValidation||Whether to validate countersignatures.|
|DeepTimestampValidation||Whether to perform deep validation of all timestamps.|
|ForceCompleteChainValidation||Whether to check the CA certificates when the signing certificate is invalid.|
|ForceCompleteChainValidationForTrusted||Whether to continue with the full validation up to the root CA certificate for mid-level trust anchors.|
|GracePeriod||Specifies a grace period to apply during revocation information checks.|
|IgnoreChainValidationErrors||Don't stop on chain validation errors.|
|IgnoreOCSPNoCheckExtension||Whether OCSP NoCheck extension should be ignored.|
|IgnoreSystemTrust||Whether trusted Windows Certificate Stores should be treated as trusted.|
|ImplicitlyTrustSelfSignedCertificates||Whether to trust self-signed certificates.|
|PolicyExplicitText||The explicit text of the user notice.|
|PolicyUNNumbers||The noticeNumbers part of the NoticeReference CAdES attribute.|
|PolicyUNOrganization||The organization part of the NoticeReference qualifier.|
|PromoteLongOCSPResponses||Whether long OCSP responses are requested.|
|ReportInvalidTimestamps||Whether to raise errors for invalid timestamps.|
|SchemeParams||The algorithm scheme parameters to employ.|
|SkipValidationTimestampedSignatures||Whether to validate signatures with validation timestamps.|
|SuppressValuesInC||Makes CAdESSigner not add certificate and revocation values to its C-level signatures.|
|TempPath||Path for storing temporary files.|
|TLSChainValidationDetails||Contains the advanced details of the TLS server certificate validation.|
|TLSChainValidationResult||Contains the result of the TLS server certificate validation.|
|TLSClientAuthRequested||Indicates whether the TLS server requests client authentication.|
|TLSValidationLog||Contains the log of the TLS server certificate validation.|
|TolerateMinorChainIssues||Whether to tolerate minor chain issues.|
|TspHashAlgorithm||Sets a specific hash algorithm for use with the timestamping service.|
|TspReqPolicy||Sets a request policy ID to include in the timestamping request.|
|UseArchivalTimestampV3||Whether to stick to archival timestamp V3 in the new signatures.|
|UseMicrosoftCTL||Enables or disables automatic use of Microsoft online certificate trust list.|
|UsePSS||Whether to use RSASSA-PSS algorithm.|
|UseSystemCertificates||Enables or disables the use of the system certificates.|
|UseUndefSize||Toggles the use of indefinite/definite ASN.1 tag length encoding.|
|UseValidationCache||Enables or disable the use of the product-wide certificate chain validation cache.|
|CheckKeyIntegrityBeforeUse||Enables or disable private key integrity check before use.|
|CookieCaching||Specifies whether a cookie cache should be used for HTTP(S) transports.|
|Cookies||Gets or sets local cookies for the component (supported for HTTPClient, RESTClient and SOAPClient only).|
|DefDeriveKeyIterations||Specifies the default key derivation algorithm iteration count.|
|EnableClientSideSSLFFDHE||Enables or disables finite field DHE key exchange support in TLS clients.|
|GlobalCookies||Gets or sets global cookies for all the HTTP transports.|
|HttpUserAgent||Specifies the user agent name to be used by all HTTP clients.|
|LogDestination||Specifies the debug log destination.|
|LogDetails||Specifies the debug log details to dump.|
|LogFile||Specifies the debug log filename.|
|LogFilters||Specifies the debug log filters.|
|LogFlushMode||Specifies the log flush mode.|
|LogLevel||Specifies the debug log level.|
|LogMaxEventCount||Specifies the maximum number of events to cache before further action is taken.|
|LogRotationMode||Specifies the log rotation mode.|
|MaxASN1BufferLength||Specifies the maximal allowed length for ASN.1 primitive tag data.|
|MaxASN1TreeDepth||Specifies the maximal depth for processed ASN.1 trees.|
|OCSPHashAlgorithm||Specifies the hash algorithm to be used to identify certificates in OCSP requests.|
|UseOwnDNSResolver||Specifies whether the client components should use own DNS resolver.|
|UseSharedSystemStorages||Specifies whether the validation engine should use a global per-process copy of the system certificate stores.|
|UseSystemOAEPAndPSS||Enforces or disables the use of system-driven RSA OAEP and PSS computations.|
|UseSystemRandom||Enables or disables the use of the OS PRNG.|