DigiDoc Java library - jdigidoc (ver 3.12.0-785)

JDigiDoc is a library created in the Java programming language.

For new developments, it is recommended to use new DigiDoc4j Java library for digital signing. 

This library offers the functionality of creating, reading, signing, obtaining validity confirmations for and checking signatures and validity confirmations of digitally signed files in the DIGIDOC-XML 1.3 and BDOC 2.1 formats. BDOC 2.1 signatures with time-stamps (ASiC-E) are not supported, i.e. only signatures with time-marking profile are supported.

In addition to digital signing, the JDigiDoc library also offers encryption and decryption pursuant to the XML-ENC standard. 
 The JDigiDoc library is useful for creating ID card authentication support in the web server. 

Information related to the library can be found from GitHub environment github.com/open-eid/jdigidoc where the library's source code along with commit history can be found. Important library versions are tagged with relevant source code tags and published as binary packages.

JDK/JRE 1.6 or newer is required for using the JDigiDoc library. Please refer to the JDigiDoc documentation concerning dependence on other libraries.

JDigiDoc library documentation (.PDF) (updated 02.2016)

Support start End of new developments Support end Extended support  
2003 06.2015 06.2016 negotiableAdditional information

 

The configuration file contains references to the test certificates, yet the test certificates need to be installed separately. The .jar file necessary for this purpose can be accessed here.

When using the library, it is essential that the test certificates be removed in LIVE applications as the library does not provide warning concerning test signatures for files with test signatures. 

The package includes the binary, source code, command line utility, Sertifitseerimiskeskus certificates (www.sk.ee/certs) and documentation.

Version Released Release notes Download
3.12.0-785 25.02.2016 Release notes Download
3.11.0-778 13.08.2015 Release notes Download
3.10.0-777 11.03.2015 Release notes Download
3.9 07.07.14
  • Used coverity.com static analysis tool to find source code defects and vulnerabilities. 
  • Conducted code review, removed obsolete code, cleaned up lib/ directory and removed unnecessary dependencies.
  • Updated default configuration file, removed redundant and not widely used entries. 
  • Added new commands to jdigidoc.java utility program that can be used as a sample code for signature creation in web browser. -ddoc-calc-sign command can be used to calculate the hash to be signed, the actual signature calculation can then be made with browser plug-in. -ddoc-add-sign-value command enables to add the signature value (e.g. calculated via the plug-in) to a DigiDoc document.
  • Added support for parsing X509IssuerName contents created with older CDigiDoc library versions (not compliant to RFC2253). 
  • Improved DDOC and BDOC files’ validation, added check that the signer certificate’s data would match the X509SerialNumber and X509IssuerName elements’ contents.
  • Improved BDOC document’s validation:
    • it is now checked that the signed data file’s mime-type value in manifest.xml file and in signatures*.xml file’s <DataObjectFormat><MimeType> element are the same.
    • Improved check for manifest.xml file’s contents and data file References compliance
    • Improved data file path validation, it is now checked that the data files are in the BDOC container.
    • Added check for empty mimetype file.
  • Improved BDOC document’s validation in case of ECDSA signatures:
    • Improved BDOC file’s validation in case of ECDSA signatures, error 129 is returned if SHA-1 hash function has been used in the document.
    • Fixed ECDSA SHA-512 signature method naming error that affected signature creation and validation with the mentioned method. 
    • Fixed ECDSA hash calculation during signature creation and validation, added the missing ECDSA signature method definitions to SignedInfo.calculateDigest() method.
  • Improved BDOC document’s data file mime-type handling. During BDOC container’s parsing, if no signatures are found in the BDOC container then the data file’s mime-type value in manifest.xml is copied to signatures*.xml file’s <DataObjectFormat><MimeType> element.
  • Improved BDOC data file handling in the library. By default, data file ID value in a BDOC container is set according to the data file’s name. IDs in the form of “ID<seq_no>” should not be used in case of BDOC documents. 
  • Improved SignedDoc.addDataFile() method for BDOC files, the method now also adds manifest.xml entry for the file if the entry didn’t exist previously.
  • Fixed parsing of BDOC document’s <SigPolicyHash><DigestMethod> element’s Algorithm attribute value. Previously, the value was not recognized and was set to NULL.
  • Improved DDOC files validation: 
    • Added check for <Transforms> elements which are not supported in DDOC files.
    • Improved check of DataFile element’s ContentType attribute, EMBEDDED_BASE64 should be used there, other values are not allowed by default. 
  • Removed support for DDOC files with EMBEDDED content type (the data file is added as pure XML). Removed the CONTENT_EMBEDDED configuration file entry, changed the related methods to deprecated status, including DataFile class’ setBody(byte[], String), setBody(Node), getInitialCodepage(), setInitialCodepage(String).
  • Added jdigidoc.java utility program’s commands -ddoc-rm-df and -ddoc-rm-sig that enable testing removing data files and signatures from DigiDoc documents.
  • Improved signature adding and removal restrictions in case of erroneous files (incl. files that are valid with warnings). No restrictions are made to adding or removing signatures, except of in case of BDOC files where SHA-1 hash function has been used and in case of files that are in old format (DIGIDOC-XML 1.0, 1.1, 1.2; BDOC 1.0). 
  • Improved error handling when removing data files or signatures from container with methods SignedDoc.removeDataFile(int) and SignedDoc.removeSignature(int). An Exception is thrown if there is no data file or signature with the given index and the removal did not succeed.
  • Fixed DigiDoc file’s parsing error that occurred when the file was read from a stream and m_fileName variable was not set.
  • Changed the DigiDocFactory.readSignedDocFromStreamOfType(InputStream, boolean) method to deprecated, use DigiDocFactory.readSignedDocOfType(String, boolean, List) instead.
  • Changed the ArrayList type to List in DigiDocFactory class’ readSignedDocOfType(), readSignedDocFromStreamOfType() methods and DigiDocVerifyFactory class’ verifyManifestEntries(), verifySignatureValue(), verifySignersCerificate(), verifySigningTime(), verifySignatureOCSP(), verifySignature(), verifySignaturePolicies() and parseDN() methods.
  • Improved error handling of SignedDoc.getSignature(int) and SignedDoc.getDataFile(int) methods. The methods return NULL if there is no existing signature or data file with the given index.
  • Changed the behaviour of DataFile.getDigest() and DataFile. getDigestType() methods - in case of signed BDOC documents, NULL is always returned by the methods, as various digest methods may be used simultaneously in a single container and thus the digest value is ambiguous. Use Reference.getDigestAlgorithm() and Reference.getDigestValue() methods in case of each signature. In case of unsigned DDOC documents, the getDigestType() method always returns SHA-1; in case of unsigned BDOC documents, SHA-256 (the default digest algorithm).
  • Removed DataFile.setDigestType() method. In case of DDOC documents, SHA-1 is the only allowed method. In case of BDOC documents, use Reference.setDigestAlgorithm(String) method in case of each signature.
  • Fixed error of handling quotation marks in ClaimedRole and SignatureProductionPlace elements during signature creation and validation. Quotation marks are not replaced during canonicalization according to Canonical XML Version 1.0. Note that as a result, the files that contain quotation marks in the respective elements and have been created with v3.9 might not be compatible with v3.8 of the library.
  • Fixed handling of special characters <, >, & and carriage return in X509IssuerName and ResponderID elements. The characters are now replaced during canonicalization according to Canonical XML Version 1.0. Note that as a result, the files that contain these special characters in the respective elements and have been created with v3.9 might not be compatible with v3.8 of the library.
  • Changed the jdigidoc.cfg configuration file parameter SIGN_OCSP_REQUESTS default value to “false”. It is now assumed that by default, the IP-based OCSP access is used and thus, the requests do not need to be signed.
  • Added exception 163 (ERR_OCSP_UNAUTHORIZED) which is thrown by BouncyCastleNotaryFactory.getConfirmation() method when the user does not have authorized access to the OCSP service.
  • Changed the checkCertificate(), checkCertificateOcspOrCrl(), checkCertOcsp() and sendCertOcsp() certificate verification methods in BouncyCastleNotaryFactory class to deprecated.
  • Changed not supported versions of BouncyCastleNotaryFactory.getConfirmation() methods to deprecated. Use getConfirmation(Signature, X509Certificate, X509Certificate, X509Certificate, String) or getConfirmation(Signature, byte[], X509Certificate, X509Certificate, X509Certificate, String, String, String, String, String).
  • Improved error handling when creating new OCSP request, it is checked that the signer’s certificate and its CA would not be NULL.
  • Fixed NullPoinerException error that occurred during logging when validating signature with no OCSP confirmation.
  • Changed compression functionality during CDOC encryption process to deprecated, by default the data is never compressed. Removed DENC_COMPRESS_MODE configuration file parameter. BDOC files must be encrypted with no compression and should not be added to additional DDOC container before encryption.
  • Fixed problem with unallowed characters in BDOC signature's <EncapsulatedX509Certificate> element's Id attribute value. The problem occurred during signature creation in case of a Lithuanian CA when the signer's CA certificate CN value contained special characters. During signature creation, the Id attribute is now created in the form of "S<signature_id>-CA_CERT<seq_no>".
  • Fixed BDOC and DDOC signature validation in case the signer CA certificate's DN value contains multiple fields with the same identifier. The problem occurred in case of some certificates with Latvian CA.
  • Fixed DDOC signature validation in case of specific signature values with 13-byte SHA-1 prefix and 0x00 as the first byte of the signed hash. Previously, the signature validation process erroneously returned "Invalid signature asn.1 prefix with 0x00 byte" (error code 174).
  • Made fixes to jdigidoc.java utility program's encryption commands. The CDOC EncryptionProperty attributes "OriginalMimeType", "orig_file", "Filename" and EncryptedData attribute "MimeType" are now set according to CDOC 1.0 specification.
N/A
3.8.1.709 28.02.14
  • Added support for adding a data file to BDOC container from an in-memory byte array. Method DataFile.setBody(byte[] data) can be used for that purpose.
  • Added command -ddoc-add-mem to jdigidoc.java utility program. The command enables adding data file to DDOC or BDOC container from an in-memory byte array via method DataFile.setBody(byte[] data).
  • Changed DataFile.setBody(byte[] data) method in case of adding data file content to DDOC files - the input data is now always converted to base64 encoding. In case the data file is already in base64 format then method DataFile.setBodyAsData(byte[] data, boolean b64, long len) should be used instead to avoid double base64 encoding of the data.
  • Added method DataFile.setBodyAsData(byte[] data, boolean b64, long len) which enables adding data file contents to DDOC container from an in-memory byte array. If the boolean parameter b64 is set to true then the original data is not converted to base64.
  • Fixed DDOC data file hash calculation problem which occurred when using method DataFile.setBase64Body(byte[]).
  • Improved cache file handling, added possibility to avoid creation of any temporary cache files by setting the jdigidoc.cfg configuration file parameter DIGIDOC_MAX_DATAFILE_CACHED value to a negative integer.
  • Fixed BDOC signature's Reference element validation problem which occurred when the container was verified before writing it to an output file or stream.
  • Fixed BDOC container's mimetype file compression, the file's contents are not compressed.
  • Fixed unhandled error situation which occurred when adding an OCSP confirmation but the OCSP responder CA certificate was not in trusted certificates' list.
  • Improved slot handling when signing via PKCS11 module, tokens are only searched from slots where a token is present.
  • DigiDocService related functionality in JDigiDoc is not fully supported and has been deprecated. Added @deprecated annotations to DigiDocServiceFactory class and its methods, removed -mid-sign and -dss-server-test1 commands from jdigidoc.java utility program and M-ID related entries from configuration file.

DDOC/BDOC/CDOC security fixes:

  • Removed support for DTD entity declarations in DDOC, BDOC and CDOC files XML content. This is a security fix screening the parsing of DigiDoc files from "XML Entity Expansion" type attacks. There is a potential that an arbitrary (hostile) content might be crafted into DigiDoc files and as the result, a server using unpatched JDigiDoc library could be engineered into trouble, e.g. to use excessive memory resources.
  • The developers have to be aware of following factors: 

a) JDigiDoc could be used on many different systems
b) Other similar (and unpatched) libraries are in use elsewhere in context of the "XML Entity Expansion" feature.
c) There was no software bug in JDigiDoc but an adaption to too wide standards.
d) The extent of trouble with any affected server heavily depends on the overall security level of the operating environment, and not so much on the particular content within any DigiDoc file.

Known issues:

  • BDOC file's validation process does not discover error situation if there is a correctly signed data file in the container but manifest.xml does not contain an entry for that data file.
  • BDOC file's validation process does not discover error situation if the mimetype file is empty.
  • In case of a specific signature value with 13-byte SHA-1 prefix and 0x00 as the first byte of the signed hash, the signature validation process erroneously returns „Invalid signature asn.1 prefix with 0x00 byte“ (error 174).
N/A
3.8.0.667 18.12.13
  •  Improved the validation of signer's certificate path, added check if all of the chain's certificates validity period includes the signature creation time (producedAt field's value in OCSP response).
  • Fixed validation of DDOC files that are created in hashcode mode(used in DigiDocService).
  • Added API method DigiDocGenFactory.isTestCard(X509Certificate) for identifying if a certificate is SK issued test certificate. The identification is done with comparing certificate policy OID values.
  • Changed DigiDoc file's validation process if a fatal error is discovered. The validation process is terminated and exception is returned when it is not possible to parse the input file's XML structure.
  • Changed signer role and resolution data handling inside DigiDoc document. Only one <ClaimedRole> element is created for DDOC and BDOC documents during signing. The element can contain only the signer's role or role and resolution combined in a single string in the form of "role / resolution".
  • Added new API method Signature.verify(SignedDoc, ArrayList) to enable better validation of one signature object separately. The method can be used to distinguish the single signature's validation errors from the rest of the DigiDoc document.
  • Added warnings system. In case of minor technical errors in the signed DigiDoc file, validation result VALID WITH WARNINGS is used, meaning that the file is legally valid but further alterations (adding/removing signatures) are restricted. It is recommended to implement using validation status VALID WITH WARNINGS as described in documentation. The warnings system is implemented in jdigidoc.java utility program (identically to DigiDoc3 Client desktop applicaton), warning situations include:
    • DDOC file's <DataFile> element's xmlns attribute is missing (error code 173)
    • The DigiDoc file format is older than officially accepted, i.e. the file is DDOC 1.0, 1.1, 1.2 or BDOC 1.0 (error code 177).
    • DDOC file's <X509IssuerName> or <X509SerialNumber> element's xmlns attribute is missing (error code 176).
    • Weaker digest method has been used in BDOC file than officially accepted (error code 129).
    • The signature has been created with a test certificate (error code 178).
  • Changed the priorities of DigiDoc file's validation result statuses.
  • Added error codes 172 (ERR_DF_NAME), 173 (ERR_DF_INV_HASH_GOOD_ALT_HASH), 174 (ERR_SIGVAL_00), 175 (ERR_TRANSFORMS), 176 (ERR_ISSUER_XMLNS), 177 (ERR_OLD_VER), 178 (ERR_TEST_SIGNATURE)
  • Changed the printed output of jdigidoc.java utility program's -ddoc-validate command, fixed the problem of printing out registry code value in case of corporate certificates.
  • Removed -ddoc-list command from jdigidoc.java utility program. -ddoc-validate provides the same functionality and should be used instead.
  • Changed the default directory where temporary files are stored in case of handling big input files. By default, the java.io.tmpdir value is now used. The parameter DIGIDOC_DF_CACHE_DIR must be specified in jdigidoc.cfg file in order to change the default directory value.
  • Added error code 172, returned when parsing the signed file when there are unallowed symbols '/' and '\' in datafile name.
  • Fixed problem with missing xmlns attribute in elements <X509IssuerName> and <X509SerialNumber> when creating signatures in case of DDOC 1.3 files. Added DDOC file's error handling in case of missing xmlns attribute in these elements.
  • Added additional check for file name in SaxDigiDocFactory class, method readSignedDocOfType(String, InputStream, boolean, ArrayList).
  • Fixed DIGIDOC_OCSP_RESPONDER_URL handling as default ocsp responder url in jdigidoc.cfg config file
  • Removed DIGIDOC_DEFAULT_DIGEST BDOC configuration parameter from jdigidoc.cfg configuration file, kept configuration parameter DIGIDOC_DIGEST_TYPE which now specifies default digest type for all hashes.
  • Removed configuration file parameter CHECK_SIGNATURE_VALUE_ASN1. Signature values with erroneous ASN.1 prefix values are regarded as not valid.
  • Added support for new KLASS3-SK 2010 CA certificate.
  • Added KLASS3-SK 2010 OCSP RESPONDER, EID-SK and ESTEID-SK 2007 certificate entries to jdigidoc.cfg configuration file.
  • Removed duplicate entries for TEST of ESTEID-SK 2011 OCSP responder in jdigidoc.cfg configuration file.
  • Fixed releasing output stream after file parsing in setOrCacheBodyAndCalcHashes function in Datafile class
  • Fixed DDOC DataFile attribute DigestType in xmlHeader method value SHA-1 (was sha1)
  • Fixed DDOC byte-order-mark (BOM) symbol handling
  • Added support for DDOC with DataFile id=DO.
  • Changed checking for DDOC document's <DataFile> element's Id attribute value when validating the file's XML structure. By default, it is checked that the value is in the form D<number> or DO, other values are not allowed.
  • Removed BDOC 1.0 support.
  • Added support for BDOC 2.1 file format
  • Added error handling for BDOC files that include <Transforms> element. The element is not supported in DigiDoc libraries.
  • Fixed BDOC Mimetype handling. Added error handling if the Mimetype file is missing from the container. Mimetype file must be the first file in BDOC zip container.
  • Added BDOC Elliptic Curve Cryptography (ECC) based certificates support. Added ListAlgorithms.java utility for EC algorithm code availability checking. For ECC added BouncyCastle crypto lib version 1.48
  • Added BDOC error handling for duplicate signatures*.xml file names
  • Added BDOC error handling for two signatures in one signatures*.xml file (error code 75 is returned).
  • Added BDOC, DDOC error handling for duplicate DataFile name. Duplicate datafile by name in container results in error.
  • Fixed BDOC error handling for datafile reference. Unsigned datafile in signed container results in error.
  • Fixed BDOC and DDOC multiple ocsp responses error handling.
  • Fixed checking of OCSP nonce field's ASN.1 prefix value in case of BDOC files when creating signatures.

DDOC/BDOC/CDOC security fixes:

  • Fixed DDOC DataFile/Reference error checking. This is a highly relevant security fix having an effect on the verification of DDOC files. The unfixed library can mistakenly give positive results on validation of invalid DDOC container contained a data file that was not referenced by any signature.
  • Fixed DDOC DataFile element DigestValue attribute verification. This is a highly relevant security fix having an effect on the verification of DDOC files. The unfixed library can mistakenly give positive results on validation of invalid DDOC container with modified DataFile element contents.

Known issues:

  • BDOC file's validation process does not discover error situation if there is a correctly signed data file in the container but manifest.xml does not contain an entry for that data file.
  • BDOC file's validation process does not discover error situation if the mimetype file is empty.
  • In case of DDOC files, method DataFile.setBase64Body(byte[]) does not function properly, the digest of the data file is not calculated correctly. Method DataFile.setBody(byte[]) should be used instead.
  • In case of DDOC files, method DataFile.setBody(byte[]) does not function properly if temporary cache files are used for storing data file contents during signature creation. The error can be avoided when commenting out jdigidoc.cfg configuration file parameter DIGIDOC_MAX_DATAFILE_CACHED, so that temporary cache files are not created.
  • In case of BDOC files, adding data file to a container from a byte array is not supported, the data must be added from a file in the file system with method SignedDoc.addDataFile(File, String, String).
N/A
3.7.2.652 22.08.13
  • Removed support for BDOC 1.0 format. It's not possible to create or verify BDOC files.
  • Fixed one critical bug in the DDOC parsing routines. By persuading a victim to open a specially-crafted DDOC file, a remote attacker could exploit this vulnerability to overwrite arbitrary files on the system with the privileges of the victim.
N/A
3.7.1.537 09.04.13 Changed the handling of DigiDoc container which has no xmlns attribute in the <DataFile> element. Additional info. N/A
3.7.0.459 01.2013
  • Added the support of PKCS11 or PKCS12 interface for DDOC signing with utility
  • Added the identification of test certificate chain on the basis of the certificatePolicies OID value for DDOC signing and verification
  • Fixed the certificate of the new test OCSP service in the chain of trust for DDOC signing and verification: TEST of SK OCSP RESPONDER 2011
  • Fixed the m_logger field of the DDOC ee.sk.digidoc.DataFile class: the Datafile class can be serialized
  • Fixed the prefix content check of the ASN.1 signature to match the SignatureMethod field for DDOC verification
  • Fixed the time and nonce producedAT field check of XML signing for DDOC verification
  • Fixed the OCSP response verification for DDOC verification
  • Fixed the handling of several OCSP responder certificates with the same CN for DDOC verification
  • Fixed DDOC verification for the DDOC 1.0 format
  • Fixed CDOC encryption with the encryptStream method for the 2048 byte block size
  • Fixed BDOC verification for large containers
  • Fixed the error handling of the file left unsigned for BDOC verification
  • Fixed the key usage check for DDOC signing with the PKCS#11 interface
  • Fixed unpacking with the stream method for CDOC decryption
  • Removed DDOC functions that are not in use any more: verifyCertificate, findCAforCertificate, addCaCert, initCACerts
  • Fixed the logic of xmlns mirroring in the XML root element for DDOC signing and verification
  • Added HSM support to DDOC signing and verification: added the relevant SLOT usage logic
  • Added HSM support to CDOC decryption: added the relevant SLOT usage logic
  • Added the BOM (Byte order mark) character support to DDOC verification
  • Fixed the support of the DDOC 1.2 format for DDOC verification: fixed the DDOC 1.2 NONCE calculation logic
  • Fixed error handling in DDOC verification when there is no OCSP responder certificate
  • Fixed the error handling of the wrong mimetype for BDOC verification
  • Fixed the error handling of the faulty XML file for DDOC verification
  • Removed support for DDOC format version 1.0, 1.1, 1.2 for DDOC signing. Only DDOC verification and exctracting files from container are supported. Creating container, signing and removing signature are not supported
  • DDOC/CDOC security fixes:
    • Added the check of the ASN.1 structure of the nonce field for DDOC signing and verification. This is a highly relevant security fix having an effect on the verification of DDOC files. The unfixed library can mistakenly give positive results on verificaton invalid DDOC container with wrong ASN.1 structure on the nonce field.
    • Added the check of the ASN.1 structure of the signature value for DDOC signing and verification. This is a highly relevant security fix having an effect on the verification of DDOC files. The unfixed library can mistakenly give positive results on verificaton invalid DDOC container with wrong ASN.1 structure on the signature value.
    • Added the check of the nonce field of the signature for DDOC signing and verification. This is a highly relevant security fix having an effect on the verification of DDOC files. The unfixed library can mistakenly give positive results on verificaton invalid DDOC container with the wrong nonce field value on the signature.
    • Removed the EMBEDDED type DDOC file support for verification. This is a highly relevant security fix having an effect on the verification of DDOC files. The unfixed library can mistakenly give positive results on verificaton invalid EMBEDDED type DDOC container.
  • Source code
  • Known issues:
    • There is an error when saving files with maximum allowed name lenght of 255 characters to and from DDOC container.
    • Files encrypted using jdigidoc version 3.6 stream method cant be decrypted. 
    • After adding files larger than 600MB to DDOC container, it's not possible to properly open that container later on. 
N/A
3.6.0.157 05.2012

Changes compared to version 2.3.19.

  • Changes according ETSI Plug test results
  • Changes according Cross library (jdigidoc & libdigidoc & libdigidocpp) test results (DDOC, CDOC, BDOC)
  • Removed DETACHED, DDOC 1.4 support
  • CDOC padding improvements
  • Updated documentation in doc folder SK-CDD-PRG-GUIDE
  • Updated BDOC support with SHA-2 family hashes
  • Support for software based private keys
  • Changes in API behaviour verify() and Signature.verify() methods
  • Added new API method decryptStreamUsingTokenType
  • Versioning switched to same scheme (3.5, 3.6 ...) as other middleware components
  • DDOC security updates
    • DigiDocService intermediate resultate file (DDOC hashcode file) verification fix. This is a significant security fix which affects verification of DDOC files. A library without this security fix can mistakenly give positive results on verificaton of invalid DDOC hashcode container.
    • Detached DDOC file verification fix. This is a significant security fix which affects verification of DDOC files. A library without this security fix can mistakenly give positive results on verificaton of invalid DDOC container.
    • Added key usage check in certificate on verification of a signature. This is a significant security fix which affects verification of DDOC files. A library without this security fix can mistakenly give positive results on verificaton of a signature created with incorrect certificate.
  • Source code
N/A

 


ASK FOR HELP

If you didn't find an answer to your question, send it to our team.



  • See instructions
  • Please estimate your ability to use the computer, so that we can provide you with the best guidance

         

  • Verification failed

How can we improve the article and be more helpful?
Send Close