List of usage examples for org.bouncycastle.asn1 ASN1OctetString toString
public String toString()
From source file:eu.europa.esig.dss.cades.signature.CAdESLevelBETSITS101733Test.java
License:Open Source License
@Override protected void onDocumentSigned(byte[] byteArray) { try {//ww w . j a va2 s . c o m CAdESSignature signature = new CAdESSignature(byteArray); assertNotNull(signature.getCmsSignedData()); ASN1InputStream asn1sInput = new ASN1InputStream(byteArray); ASN1Sequence asn1Seq = (ASN1Sequence) asn1sInput.readObject(); logger.info("SEQ : " + asn1Seq.toString()); assertEquals(2, asn1Seq.size()); ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(asn1Seq.getObjectAt(0)); assertEquals(PKCSObjectIdentifiers.signedData, oid); logger.info("OID : " + oid.toString()); ASN1TaggedObject taggedObj = DERTaggedObject.getInstance(asn1Seq.getObjectAt(1)); logger.info("TAGGED OBJ : " + taggedObj.toString()); ASN1Primitive object = taggedObj.getObject(); logger.info("OBJ : " + object.toString()); SignedData signedData = SignedData.getInstance(object); logger.info("SIGNED DATA : " + signedData.toString()); ASN1Set digestAlgorithms = signedData.getDigestAlgorithms(); logger.info("DIGEST ALGOS : " + digestAlgorithms.toString()); ContentInfo encapContentInfo = signedData.getEncapContentInfo(); logger.info("ENCAPSULATED CONTENT INFO : " + encapContentInfo.getContentType() + " " + encapContentInfo.getContent()); ASN1Set certificates = signedData.getCertificates(); logger.info("CERTIFICATES (" + certificates.size() + ") : " + certificates); List<X509Certificate> foundCertificates = new ArrayList<X509Certificate>(); for (int i = 0; i < certificates.size(); i++) { ASN1Sequence seqCertif = ASN1Sequence.getInstance(certificates.getObjectAt(i)); logger.info("SEQ cert " + i + " : " + seqCertif); X509CertificateHolder certificateHolder = new X509CertificateHolder(seqCertif.getEncoded()); CertificateToken certificate = DSSASN1Utils.getCertificate(certificateHolder); X509Certificate x509Certificate = certificate.getCertificate(); x509Certificate.checkValidity(); logger.info("Cert " + i + " : " + certificate); foundCertificates.add(x509Certificate); } ASN1Set crLs = signedData.getCRLs(); logger.info("CRLs : " + crLs); ASN1Set signerInfosAsn1 = signedData.getSignerInfos(); logger.info("SIGNER INFO ASN1 : " + signerInfosAsn1.toString()); assertEquals(1, signerInfosAsn1.size()); ASN1Sequence seqSignedInfo = ASN1Sequence.getInstance(signerInfosAsn1.getObjectAt(0)); SignerInfo signedInfo = SignerInfo.getInstance(seqSignedInfo); logger.info("SIGNER INFO : " + signedInfo.toString()); SignerIdentifier sid = signedInfo.getSID(); logger.info("SIGNER IDENTIFIER : " + sid.getId()); IssuerAndSerialNumber issuerAndSerialNumber = IssuerAndSerialNumber.getInstance(signedInfo.getSID()); logger.info("ISSUER AND SN : " + issuerAndSerialNumber.toString()); BigInteger serial = issuerAndSerialNumber.getSerialNumber().getValue(); X509Certificate signerCertificate = null; for (X509Certificate x509Certificate : foundCertificates) { // TODO check issuer name if (serial.equals(x509Certificate.getSerialNumber())) { signerCertificate = x509Certificate; } } assertNotNull(signerCertificate); ASN1OctetString encryptedDigest = signedInfo.getEncryptedDigest(); logger.info("ENCRYPT DIGEST : " + encryptedDigest.toString()); ASN1Sequence seq = ASN1Sequence.getInstance(object); ASN1Integer version = ASN1Integer.getInstance(seq.getObjectAt(0)); logger.info("VERSION : " + version.toString()); ASN1Set digestManualSet = ASN1Set.getInstance(seq.getObjectAt(1)); logger.info("DIGEST SET : " + digestManualSet.toString()); assertEquals(digestAlgorithms, digestManualSet); ASN1Sequence seqDigest = ASN1Sequence.getInstance(digestManualSet.getObjectAt(0)); // assertEquals(1, seqDigest.size()); ASN1ObjectIdentifier oidDigestAlgo = ASN1ObjectIdentifier.getInstance(seqDigest.getObjectAt(0)); assertEquals(new ASN1ObjectIdentifier(DigestAlgorithm.SHA256.getOid()), oidDigestAlgo); ASN1Sequence seqEncapsulatedInfo = ASN1Sequence.getInstance(seq.getObjectAt(2)); logger.info("ENCAPSULATED INFO : " + seqEncapsulatedInfo.toString()); ASN1ObjectIdentifier oidContentType = ASN1ObjectIdentifier .getInstance(seqEncapsulatedInfo.getObjectAt(0)); logger.info("OID CONTENT TYPE : " + oidContentType.toString()); ASN1TaggedObject taggedContent = DERTaggedObject.getInstance(seqEncapsulatedInfo.getObjectAt(1)); ASN1OctetString contentOctetString = ASN1OctetString.getInstance(taggedContent.getObject()); String content = new String(contentOctetString.getOctets()); assertEquals(HELLO_WORLD, content); logger.info("CONTENT : " + content); byte[] digest = DSSUtils.digest(DigestAlgorithm.SHA256, HELLO_WORLD.getBytes()); String encodeHexDigest = Hex.toHexString(digest); logger.info("CONTENT DIGEST COMPUTED : " + encodeHexDigest); ASN1Set authenticatedAttributes = signedInfo.getAuthenticatedAttributes(); logger.info("AUTHENTICATED ATTRIBUTES : " + authenticatedAttributes.toString()); // ASN1Sequence seqAuthAttrib = ASN1Sequence.getInstance(authenticatedAttributes.getObjectAt(0)); logger.info("Nb Auth Attributes : " + authenticatedAttributes.size()); String embeddedDigest = ""; for (int i = 0; i < authenticatedAttributes.size(); i++) { ASN1Sequence authAttrSeq = ASN1Sequence.getInstance(authenticatedAttributes.getObjectAt(i)); logger.info(authAttrSeq.toString()); ASN1ObjectIdentifier attrOid = ASN1ObjectIdentifier.getInstance(authAttrSeq.getObjectAt(0)); if (PKCSObjectIdentifiers.pkcs_9_at_messageDigest.equals(attrOid)) { ASN1Set setMessageDigest = ASN1Set.getInstance(authAttrSeq.getObjectAt(1)); ASN1OctetString asn1ObjString = ASN1OctetString.getInstance(setMessageDigest.getObjectAt(0)); embeddedDigest = Hex.toHexString(asn1ObjString.getOctets()); } } assertEquals(encodeHexDigest, embeddedDigest); ASN1OctetString encryptedInfoOctedString = signedInfo.getEncryptedDigest(); String signatureValue = Hex.toHexString(encryptedInfoOctedString.getOctets()); logger.info("SIGNATURE VALUE : " + signatureValue); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, signerCertificate); byte[] decrypted = cipher.doFinal(encryptedInfoOctedString.getOctets()); ASN1InputStream inputDecrypted = new ASN1InputStream(decrypted); ASN1Sequence seqDecrypt = (ASN1Sequence) inputDecrypted.readObject(); logger.info("Decrypted : " + seqDecrypt); DigestInfo digestInfo = new DigestInfo(seqDecrypt); assertEquals(oidDigestAlgo, digestInfo.getAlgorithmId().getAlgorithm()); String decryptedDigestEncodeBase64 = Utils.toBase64(digestInfo.getDigest()); logger.info("Decrypted Base64 : " + decryptedDigestEncodeBase64); byte[] encoded = signedInfo.getAuthenticatedAttributes().getEncoded(); MessageDigest messageDigest = MessageDigest.getInstance(DigestAlgorithm.SHA256.getName()); byte[] digestOfAuthenticatedAttributes = messageDigest.digest(encoded); String computedDigestEncodeBase64 = Utils.toBase64(digestOfAuthenticatedAttributes); logger.info("Computed Base64 : " + computedDigestEncodeBase64); assertEquals(decryptedDigestEncodeBase64, computedDigestEncodeBase64); Utils.closeQuietly(asn1sInput); Utils.closeQuietly(inputDecrypted); } catch (Exception e) { logger.error(e.getMessage(), e); fail(e.getMessage()); } }
From source file:eu.europa.esig.dss.cades.signature.CAdESLevelBTest.java
License:Open Source License
@Override protected void onDocumentSigned(byte[] byteArray) { try {//from www . jav a 2s .c o m CAdESSignature signature = new CAdESSignature(byteArray); assertNotNull(signature.getCmsSignedData()); ASN1InputStream asn1sInput = new ASN1InputStream(byteArray); ASN1Sequence asn1Seq = (ASN1Sequence) asn1sInput.readObject(); logger.info("SEQ : " + asn1Seq.toString()); assertEquals(2, asn1Seq.size()); ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(asn1Seq.getObjectAt(0)); assertEquals(PKCSObjectIdentifiers.signedData, oid); logger.info("OID : " + oid.toString()); ASN1TaggedObject taggedObj = DERTaggedObject.getInstance(asn1Seq.getObjectAt(1)); logger.info("TAGGED OBJ : " + taggedObj.toString()); ASN1Primitive object = taggedObj.getObject(); logger.info("OBJ : " + object.toString()); SignedData signedData = SignedData.getInstance(object); logger.info("SIGNED DATA : " + signedData.toString()); ASN1Set digestAlgorithms = signedData.getDigestAlgorithms(); logger.info("DIGEST ALGOS : " + digestAlgorithms.toString()); ContentInfo encapContentInfo = signedData.getEncapContentInfo(); logger.info("ENCAPSULATED CONTENT INFO : " + encapContentInfo.getContentType() + " " + encapContentInfo.getContent()); ASN1Set certificates = signedData.getCertificates(); logger.info("CERTIFICATES (" + certificates.size() + ") : " + certificates); List<X509Certificate> foundCertificates = new ArrayList<X509Certificate>(); for (int i = 0; i < certificates.size(); i++) { ASN1Sequence seqCertif = ASN1Sequence.getInstance(certificates.getObjectAt(i)); logger.info("SEQ cert " + i + " : " + seqCertif); X509CertificateHolder certificateHolder = new X509CertificateHolder(seqCertif.getEncoded()); X509Certificate certificate = new JcaX509CertificateConverter() .setProvider(BouncyCastleProvider.PROVIDER_NAME).getCertificate(certificateHolder); certificate.checkValidity(); logger.info("Cert " + i + " : " + certificate); foundCertificates.add(certificate); } ASN1Set crLs = signedData.getCRLs(); logger.info("CRLs : " + crLs); ASN1Set signerInfosAsn1 = signedData.getSignerInfos(); logger.info("SIGNER INFO ASN1 : " + signerInfosAsn1.toString()); assertEquals(1, signerInfosAsn1.size()); ASN1Sequence seqSignedInfo = ASN1Sequence.getInstance(signerInfosAsn1.getObjectAt(0)); SignerInfo signedInfo = SignerInfo.getInstance(seqSignedInfo); logger.info("SIGNER INFO : " + signedInfo.toString()); SignerIdentifier sid = signedInfo.getSID(); logger.info("SIGNER IDENTIFIER : " + sid.getId()); IssuerAndSerialNumber issuerAndSerialNumber = IssuerAndSerialNumber.getInstance(signedInfo.getSID()); logger.info("ISSUER AND SN : " + issuerAndSerialNumber.toString()); BigInteger serial = issuerAndSerialNumber.getSerialNumber().getValue(); X509Certificate signerCertificate = null; for (X509Certificate x509Certificate : foundCertificates) { // TODO check issuer name if (serial.equals(x509Certificate.getSerialNumber())) { signerCertificate = x509Certificate; } } assertNotNull(signerCertificate); ASN1OctetString encryptedDigest = signedInfo.getEncryptedDigest(); logger.info("ENCRYPT DIGEST : " + encryptedDigest.toString()); ASN1Sequence seq = ASN1Sequence.getInstance(object); ASN1Integer version = ASN1Integer.getInstance(seq.getObjectAt(0)); logger.info("VERSION : " + version.toString()); ASN1Set digestManualSet = ASN1Set.getInstance(seq.getObjectAt(1)); logger.info("DIGEST SET : " + digestManualSet.toString()); assertEquals(digestAlgorithms, digestManualSet); ASN1Sequence seqDigest = ASN1Sequence.getInstance(digestManualSet.getObjectAt(0)); // assertEquals(1, seqDigest.size()); ASN1ObjectIdentifier oidDigestAlgo = ASN1ObjectIdentifier.getInstance(seqDigest.getObjectAt(0)); assertEquals(new ASN1ObjectIdentifier(DigestAlgorithm.SHA256.getOid()), oidDigestAlgo); ASN1Sequence seqEncapsulatedInfo = ASN1Sequence.getInstance(seq.getObjectAt(2)); logger.info("ENCAPSULATED INFO : " + seqEncapsulatedInfo.toString()); ASN1ObjectIdentifier oidContentType = ASN1ObjectIdentifier .getInstance(seqEncapsulatedInfo.getObjectAt(0)); logger.info("OID CONTENT TYPE : " + oidContentType.toString()); ASN1TaggedObject taggedContent = DERTaggedObject.getInstance(seqEncapsulatedInfo.getObjectAt(1)); ASN1OctetString contentOctetString = ASN1OctetString.getInstance(taggedContent.getObject()); String content = new String(contentOctetString.getOctets()); assertEquals(HELLO_WORLD, content); logger.info("CONTENT : " + content); byte[] digest = DSSUtils.digest(DigestAlgorithm.SHA256, HELLO_WORLD.getBytes()); String encodeHexDigest = Hex.toHexString(digest); logger.info("CONTENT DIGEST COMPUTED : " + encodeHexDigest); ASN1Set authenticatedAttributes = signedInfo.getAuthenticatedAttributes(); logger.info("AUTHENTICATED ATTRIBUTES : " + authenticatedAttributes.toString()); // ASN1Sequence seqAuthAttrib = ASN1Sequence.getInstance(authenticatedAttributes.getObjectAt(0)); logger.info("Nb Auth Attributes : " + authenticatedAttributes.size()); String embeddedDigest = StringUtils.EMPTY; for (int i = 0; i < authenticatedAttributes.size(); i++) { ASN1Sequence authAttrSeq = ASN1Sequence.getInstance(authenticatedAttributes.getObjectAt(i)); logger.info(authAttrSeq.toString()); ASN1ObjectIdentifier attrOid = ASN1ObjectIdentifier.getInstance(authAttrSeq.getObjectAt(0)); if (PKCSObjectIdentifiers.pkcs_9_at_messageDigest.equals(attrOid)) { ASN1Set setMessageDigest = ASN1Set.getInstance(authAttrSeq.getObjectAt(1)); ASN1OctetString asn1ObjString = ASN1OctetString.getInstance(setMessageDigest.getObjectAt(0)); embeddedDigest = Hex.toHexString(asn1ObjString.getOctets()); } } assertEquals(encodeHexDigest, embeddedDigest); ASN1OctetString encryptedInfoOctedString = signedInfo.getEncryptedDigest(); String signatureValue = Hex.toHexString(encryptedInfoOctedString.getOctets()); logger.info("SIGNATURE VALUE : " + signatureValue); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, signerCertificate); byte[] decrypted = cipher.doFinal(encryptedInfoOctedString.getOctets()); ASN1InputStream inputDecrypted = new ASN1InputStream(decrypted); ASN1Sequence seqDecrypt = (ASN1Sequence) inputDecrypted.readObject(); logger.info("Decrypted : " + seqDecrypt); DigestInfo digestInfo = new DigestInfo(seqDecrypt); assertEquals(oidDigestAlgo, digestInfo.getAlgorithmId().getAlgorithm()); String decryptedDigestEncodeBase64 = Base64.encodeBase64String(digestInfo.getDigest()); logger.info("Decrypted Base64 : " + decryptedDigestEncodeBase64); byte[] encoded = signedInfo.getAuthenticatedAttributes().getEncoded(); MessageDigest messageDigest = MessageDigest.getInstance(DigestAlgorithm.SHA256.getName()); byte[] digestOfAuthenticatedAttributes = messageDigest.digest(encoded); String computedDigestEncodeBase64 = Base64.encodeBase64String(digestOfAuthenticatedAttributes); logger.info("Computed Base64 : " + computedDigestEncodeBase64); assertEquals(decryptedDigestEncodeBase64, computedDigestEncodeBase64); IOUtils.closeQuietly(asn1sInput); IOUtils.closeQuietly(inputDecrypted); } catch (Exception e) { logger.error(e.getMessage(), e); fail(e.getMessage()); } }
From source file:org.icepdf.core.pobjects.acroform.signature.AbstractPkcsValidator.java
License:Apache License
/** * SignedData ::= SEQUENCE {//from w w w . j a v a 2 s . c om * 0, version CMSVersion, * 1, digestAlgorithms DigestAlgorithmIdentifiers, * 2, encapContentInfo EncapsulatedContentInfo, * 3, certificateChain [0] IMPLICIT CertificateSet OPTIONAL, * 4, crls [1] IMPLICIT RevocationInfoChoices OPTIONAL, * 5, signerInfos SignerInfos } * <p/> * DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier * SignerInfos ::= SET OF SignerInfo */ protected void parseSignerData(ASN1Sequence signedData, byte[] cmsData) throws SignatureIntegrityException { // digest algorithms ID, not currently using them but useful for debug. if (logger.isLoggable(Level.FINER)) { // should always be 1. int cmsVersion = ((ASN1Integer) signedData.getObjectAt(0)).getValue().intValue(); logger.finest("CMS version: " + cmsVersion); Enumeration<ASN1Sequence> enumeration = ((ASN1Set) signedData.getObjectAt(1)).getObjects(); while (enumeration.hasMoreElements()) { String objectId = ((ASN1ObjectIdentifier) enumeration.nextElement().getObjectAt(0)).getId(); try { String digestAlgorithmName = AlgorithmIdentifier.getDigestAlgorithmName(objectId); MessageDigest tmp = AlgorithmIdentifier.getDigestInstance(objectId, null); logger.finest("DigestAlgorithmIdentifiers: " + digestAlgorithmName + " " + objectId); logger.finest(tmp.toString()); } catch (Throwable ex) { logger.log(Level.WARNING, "Error finding iod: " + objectId, ex); } } } /** * EncapsulatedContentInfo ::= SEQUENCE { * eContentType ContentType, * eContent [0] EXPLICIT OCTET STRING OPTIONAL } * * ContentType ::= OBJECT IDENTIFIER */ encapsulatedContentInfoData = null; ASN1Sequence encapsulatedContentInfo = (ASN1Sequence) signedData.getObjectAt(2); // grab just the first definitions, as we are looking for encapuslated data for PKCS7.sha1. if (encapsulatedContentInfo.size() >= 2) { // should still be iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs7(7) 1 ... ASN1ObjectIdentifier eObjectIdentifier = (ASN1ObjectIdentifier) encapsulatedContentInfo.getObjectAt(0); String eObjectIdentifierId = eObjectIdentifier.getId(); if (logger.isLoggable(Level.FINER)) { logger.finest("EncapsulatedContentInfo: " + eObjectIdentifierId + " " + Pkcs7Validator.getObjectIdName(eObjectIdentifierId)); } // should be octets encode as pkcs#7 ASN1OctetString eContent = (ASN1OctetString) ((ASN1TaggedObject) encapsulatedContentInfo.getObjectAt(1)) .getObject(); // shows up in pkcs7.sha1 only encapsulatedContentInfoData = eContent.getOctets(); if (logger.isLoggable(Level.FINER)) { logger.finest("EncapsulatedContentInfo Data " + eContent.toString()); } } else if (encapsulatedContentInfo.size() == 1) { if (logger.isLoggable(Level.FINER)) { ASN1ObjectIdentifier eObjectIdentifier = (ASN1ObjectIdentifier) encapsulatedContentInfo .getObjectAt(0); String eObjectIdentifierId = eObjectIdentifier.getId(); logger.finest("EncapsulatedContentInfo size is 1: " + eObjectIdentifierId + " " + Pkcs7Validator.getObjectIdName(eObjectIdentifierId)); } } // grab the signer info. ASN1Sequence signerInfo = parseCertificateData(cmsData, signedData); // DigestAlgorithmIdentifier ::= AlgorithmIdentifier digestAlgorithmIdentifier = ((ASN1ObjectIdentifier) ((ASN1Sequence) signerInfo.getObjectAt(2)) .getObjectAt(0)).getId(); // signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL, // signedAttrs is optional so we look for the occurrence // // SignedAttributes ::= SET SIZE (1..MAX) OF Attribute // // Attribute ::= SEQUENCE { // attrType OBJECT IDENTIFIER, // attrValues SET OF AttributeValue } // // AttributeValue ::= ANY // SignatureValue ::= OCTET STRING int nextEntry = 3; messageDigest = null; ASN1TaggedObject signedAttributes; signedAttributesSequence = null; if (signerInfo.getObjectAt(nextEntry) instanceof ASN1TaggedObject) { signedAttributes = (ASN1TaggedObject) signerInfo.getObjectAt(nextEntry); signedAttributesSequence = ASN1Set.getInstance(signedAttributes, false); for (int i = 0, max = signedAttributesSequence.size(); i < max; ++i) { // attribute type/value pair. ASN1Sequence attributePair = (ASN1Sequence) signedAttributesSequence.getObjectAt(i); // mainly just looking for the message digest. if (((ASN1ObjectIdentifier) attributePair.getObjectAt(0)).getId() .equals(PKCSObjectIdentifiers.pkcs_9_at_messageDigest.getId())) { ASN1Set set = (ASN1Set) attributePair.getObjectAt(1); messageDigest = ((ASN1OctetString) set.getObjectAt(0)).getOctets(); } // try and pull out the signing time. // currently not using this time. // if (((ASN1ObjectIdentifier) attributePair.getObjectAt(0)).getId().equals( // PKCSObjectIdentifiers.pkcs_9_at_signingTime.getId())) { // ASN1Set set = (ASN1Set) attributePair.getObjectAt(1); // ASN1UTCTime signerTime = ((ASN1UTCTime) set.getObjectAt(0)); // try { // // see if the signer time matches the certificate validity times. // System.out.println(" SignatureSigner Time " + signerTime.getDate()); // } catch (ParseException e) { // e.printStackTrace(); // } // } // more attributes to come. } if (messageDigest == null) { throw new SignatureIntegrityException("Message Digest can nut be null"); } ++nextEntry; } // signatureAlgorithm SignatureAlgorithmIdentifier, signatureAlgorithmIdentifier = ((ASN1ObjectIdentifier) ((ASN1Sequence) signerInfo.getObjectAt(nextEntry)) .getObjectAt(0)).getId(); nextEntry++; // signature SignatureValue signatureValue = ((ASN1OctetString) signerInfo.getObjectAt(nextEntry)).getOctets(); nextEntry++; // unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL // once again optional so we check to see if the entry is available. if (nextEntry < signerInfo.size() && signerInfo.getObjectAt(nextEntry) instanceof ASN1TaggedObject) { ASN1TaggedObject unsignedAttributes = (ASN1TaggedObject) signerInfo.getObjectAt(nextEntry); ASN1Set unsignedAttributeSequence = ASN1Set.getInstance(unsignedAttributes, false); AttributeTable attributeTable = new AttributeTable(unsignedAttributeSequence); Attribute timeStamp = attributeTable.get(PKCSObjectIdentifiers.id_aa_signatureTimeStampToken); if (timeStamp != null && timeStamp.getAttrValues().size() > 0) { ASN1Set attributeValues = timeStamp.getAttrValues(); ASN1Sequence tokenSequence = ASN1Sequence.getInstance(attributeValues.getObjectAt(0)); ContentInfo contentInfo = ContentInfo.getInstance(tokenSequence); // if we can parse it we call it good, so cert has a embedded time but we don't do any validation on it try { new TimeStampToken(contentInfo); isEmbeddedTimeStamp = true; } catch (Throwable e1) { throw new SignatureIntegrityException("Valid TimeStamp could now be created"); } } } }