private byte[] getTimeStampSignatureCertificate(byte[] tsResponse) { try { TimeStampResponse tsResp = new TimeStampResponse(tsResponse); TimeStampToken token = new TimeStampToken(new Org.BouncyCastle.Cms.CmsSignedData(tsResp.TimeStampToken.GetEncoded())); Org.BouncyCastle.X509.X509Certificate signerCert = null; Org.BouncyCastle.X509.Store.IX509Store x509Certs = tsResp.TimeStampToken.GetCertificates("Collection"); ArrayList certs = new ArrayList(x509Certs.GetMatches(null)); // nájdenie podpisového certifikátu tokenu v kolekcii foreach (Org.BouncyCastle.X509.X509Certificate cert in certs) { string cerIssuerName = cert.IssuerDN.ToString(true, new Hashtable()); string signerIssuerName = token.SignerID.Issuer.ToString(true, new Hashtable()); // kontrola issuer name a seriového čísla if (cerIssuerName == signerIssuerName && cert.SerialNumber.Equals(token.SignerID.SerialNumber)) { signerCert = cert; break; } } return signerCert.GetEncoded(); } catch (Exception ex) { //this.errorMessage = "Tsa.getTimeStampSignatureCertificate 9: " + ex.Message; return null; } }
public string Validate(byte[] tsr) { AppendLog("TimeStamp validating..."); Org.BouncyCastle.Tsp.TimeStampToken token; try { token = new Org.BouncyCastle.Tsp.TimeStampToken(new CmsSignedData(tsr)); } catch (Exception e) { AppendLog(e.Message); return("Invalid tsr"); } try { var certParser = new Org.BouncyCastle.X509.X509CertificateParser(); var bouncyCert = certParser.ReadCertificate(_authorityCert.GetRawCertData()); token.Validate(bouncyCert); return("Valid timestamp"); } catch (Exception e) { AppendLog(e.Message); return(e is TspValidationException || e is TspException ? e.Message : "Validation error"); } }
public TimeStampResponse( TimeStampResp resp) { this.resp = resp; if (resp.TimeStampToken != null) { timeStampToken = new TimeStampToken(resp.TimeStampToken); } }
/// <summary>The default constructor for TimestampToken.</summary> /// <remarks>The default constructor for TimestampToken.</remarks> /// <param name="timeStamp"></param> public TimestampToken(TimeStampToken timeStamp) { // CAdES: id-aa-ets-contentTimestamp, XAdES: AllDataObjectsTimeStamp, PAdES standard // timestamp // XAdES: IndividualDataObjectsTimeStamp // CAdES: id-aa-signatureTimeStampToken, XAdES: SignatureTimeStamp // CAdES: id-aa-ets-certCRLTimestamp, XAdES: RefsOnlyTimeStamp // CAdES: id-aa-ets-escTimeStamp, XAdES: SigAndRefsTimeStamp // CAdES: id-aa-ets-archiveTimestamp, XAdES: ArchiveTimeStamp, PAdES-LTV "document timestamp" this.timeStamp = timeStamp; }
/** * Fetches the signature time-stamp attributes from a SignerInformation object. * Checks that the MessageImprint for each time-stamp matches the signature field. * (see RFC 3161 Appendix A). * * @param signerInfo a SignerInformation to search for time-stamps * @return a collection of TimeStampToken objects * @throws TSPValidationException */ public static ICollection GetSignatureTimestamps( SignerInformation signerInfo) { IList timestamps = Platform.CreateArrayList(); Asn1.Cms.AttributeTable unsignedAttrs = signerInfo.UnsignedAttributes; if (unsignedAttrs != null) { foreach (Asn1.Cms.Attribute tsAttr in unsignedAttrs.GetAll( PkcsObjectIdentifiers.IdAASignatureTimeStampToken)) { foreach (Asn1Encodable asn1 in tsAttr.AttrValues) { try { Asn1.Cms.ContentInfo contentInfo = Asn1.Cms.ContentInfo.GetInstance( asn1.ToAsn1Object()); TimeStampToken timeStampToken = new TimeStampToken(contentInfo); TimeStampTokenInfo tstInfo = timeStampToken.TimeStampInfo; byte[] expectedDigest = DigestUtilities.CalculateDigest( GetDigestAlgName(tstInfo.MessageImprintAlgOid), signerInfo.GetSignature()); if (!Arrays.ConstantTimeAreEqual(expectedDigest, tstInfo.GetMessageImprintDigest())) throw new TspValidationException("Incorrect digest in message imprint"); timestamps.Add(timeStampToken); } catch (SecurityUtilityException) { throw new TspValidationException("Unknown hash algorithm specified in timestamp"); } catch (Exception) { throw new TspValidationException("Timestamp could not be parsed"); } } } } return timestamps; }
/** * Verifies a time stamp against a KeyStore. * @param ts the time stamp * @param keystore the <CODE>KeyStore</CODE> * @param provider the provider or <CODE>null</CODE> to use the BouncyCastle provider * @return <CODE>true</CODE> is a certificate was found */ public static bool VerifyTimestampCertificates(TimeStampToken ts, ICollection<X509Certificate> keystore) { try { foreach (X509Certificate certStoreX509 in keystore) { try { ts.Validate(certStoreX509); return true; } catch { } } } catch { } return false; }
/// <summary> /// Inserta y valida los certificados del servidor de sellado de tiempo. /// </summary> /// <param name="unsignedProperties"></param> private void AddTSACertificates(UnsignedProperties unsignedProperties) { TimeStampToken token = new TimeStampToken(new Org.BouncyCastle.Cms.CmsSignedData(unsignedProperties.UnsignedSignatureProperties.SignatureTimeStampCollection[0].EncapsulatedTimeStamp.PkiData)); IX509Store store = token.GetCertificates("Collection"); Org.BouncyCastle.Cms.SignerID signerId = token.SignerID; List<X509Certificate2> tsaCerts = new List<X509Certificate2>(); foreach (var tsaCert in store.GetMatches(null)) { X509Certificate2 cert = new X509Certificate2(((Org.BouncyCastle.X509.X509Certificate)tsaCert).GetEncoded()); tsaCerts.Add(cert); } X509Certificate2 startCert = DetermineStartCert(tsaCerts); AddCertificate(startCert, unsignedProperties, true, tsaCerts.ToArray()); }
/** * Verifies a signature using the sub-filter adbe.pkcs7.detached or * adbe.pkcs7.sha1. * @param contentsKey the /Contents key * @param provider the provider or <code>null</code> for the default provider * @throws SecurityException on error * @throws CRLException on error * @throws InvalidKeyException on error * @throws CertificateException on error * @throws NoSuchProviderException on error * @throws NoSuchAlgorithmException on error */ public PdfPKCS7(byte[] contentsKey) { Asn1InputStream din = new Asn1InputStream(new MemoryStream(contentsKey)); // // Basic checks to make sure it's a PKCS#7 SignedData Object // Asn1Object pkcs; try { pkcs = din.ReadObject(); } catch { throw new ArgumentException("can't decode PKCS7SignedData object"); } if (!(pkcs is Asn1Sequence)) { throw new ArgumentException("Not a valid PKCS#7 object - not a sequence"); } Asn1Sequence signedData = (Asn1Sequence)pkcs; DerObjectIdentifier objId = (DerObjectIdentifier)signedData[0]; if (!objId.Id.Equals(ID_PKCS7_SIGNED_DATA)) throw new ArgumentException("Not a valid PKCS#7 object - not signed data"); Asn1Sequence content = (Asn1Sequence)((DerTaggedObject)signedData[1]).GetObject(); // the positions that we care are: // 0 - version // 1 - digestAlgorithms // 2 - possible ID_PKCS7_DATA // (the certificates and crls are taken out by other means) // last - signerInfos // the version version = ((DerInteger)content[0]).Value.IntValue; // the digestAlgorithms digestalgos = new Hashtable(); IEnumerator e = ((Asn1Set)content[1]).GetEnumerator(); while (e.MoveNext()) { Asn1Sequence s = (Asn1Sequence)e.Current; DerObjectIdentifier o = (DerObjectIdentifier)s[0]; digestalgos[o.Id] = null; } // the certificates and crls X509CertificateParser cf = new X509CertificateParser(); certs = new ArrayList(); foreach (X509Certificate cc in cf.ReadCertificates(contentsKey)) { certs.Add(cc); } crls = new ArrayList(); // the possible ID_PKCS7_DATA Asn1Sequence rsaData = (Asn1Sequence)content[2]; if (rsaData.Count > 1) { DerOctetString rsaDataContent = (DerOctetString)((DerTaggedObject)rsaData[1]).GetObject(); RSAdata = rsaDataContent.GetOctets(); } // the signerInfos int next = 3; while (content[next] is DerTaggedObject) ++next; Asn1Set signerInfos = (Asn1Set)content[next]; if (signerInfos.Count != 1) throw new ArgumentException("This PKCS#7 object has multiple SignerInfos - only one is supported at this time"); Asn1Sequence signerInfo = (Asn1Sequence)signerInfos[0]; // the positions that we care are // 0 - version // 1 - the signing certificate serial number // 2 - the digest algorithm // 3 or 4 - digestEncryptionAlgorithm // 4 or 5 - encryptedDigest signerversion = ((DerInteger)signerInfo[0]).Value.IntValue; // Get the signing certificate Asn1Sequence issuerAndSerialNumber = (Asn1Sequence)signerInfo[1]; BigInteger serialNumber = ((DerInteger)issuerAndSerialNumber[1]).Value; foreach (X509Certificate cert in certs) { if (serialNumber.Equals(cert.SerialNumber)) { signCert = cert; break; } } if (signCert == null) { throw new ArgumentException("Can't find signing certificate with serial " + serialNumber.ToString(16)); } CalcSignCertificateChain(); digestAlgorithm = ((DerObjectIdentifier)((Asn1Sequence)signerInfo[2])[0]).Id; next = 3; if (signerInfo[next] is Asn1TaggedObject) { Asn1TaggedObject tagsig = (Asn1TaggedObject)signerInfo[next]; Asn1Set sseq = Asn1Set.GetInstance(tagsig, false); sigAttr = sseq.GetEncoded(Asn1Encodable.Der); for (int k = 0; k < sseq.Count; ++k) { Asn1Sequence seq2 = (Asn1Sequence)sseq[k]; if (((DerObjectIdentifier)seq2[0]).Id.Equals(ID_MESSAGE_DIGEST)) { Asn1Set sset = (Asn1Set)seq2[1]; digestAttr = ((DerOctetString)sset[0]).GetOctets(); } else if (((DerObjectIdentifier)seq2[0]).Id.Equals(ID_ADBE_REVOCATION)) { Asn1Set setout = (Asn1Set)seq2[1]; Asn1Sequence seqout = (Asn1Sequence)setout[0]; for (int j = 0; j < seqout.Count; ++j) { Asn1TaggedObject tg = (Asn1TaggedObject)seqout[j]; if (tg.TagNo != 1) continue; Asn1Sequence seqin = (Asn1Sequence)tg.GetObject(); FindOcsp(seqin); } } } if (digestAttr == null) throw new ArgumentException("Authenticated attribute is missing the digest."); ++next; } digestEncryptionAlgorithm = ((DerObjectIdentifier)((Asn1Sequence)signerInfo[next++])[0]).Id; digest = ((DerOctetString)signerInfo[next++]).GetOctets(); if (next < signerInfo.Count && (signerInfo[next] is DerTaggedObject)) { DerTaggedObject taggedObject = (DerTaggedObject) signerInfo[next]; Asn1Set unat = Asn1Set.GetInstance(taggedObject, false); Org.BouncyCastle.Asn1.Cms.AttributeTable attble = new Org.BouncyCastle.Asn1.Cms.AttributeTable(unat); Org.BouncyCastle.Asn1.Cms.Attribute ts = attble[PkcsObjectIdentifiers.IdAASignatureTimeStampToken]; if (ts != null) { Asn1Set attributeValues = ts.AttrValues; Asn1Sequence tokenSequence = Asn1Sequence.GetInstance(attributeValues[0]); Org.BouncyCastle.Asn1.Cms.ContentInfo contentInfo = Org.BouncyCastle.Asn1.Cms.ContentInfo.GetInstance(tokenSequence); this.timeStampToken = new TimeStampToken(contentInfo); } } if (RSAdata != null || digestAttr != null) { messageDigest = GetHashClass(); } sig = SignerUtilities.GetSigner(GetDigestAlgorithm()); sig.Init(false, signCert.GetPublicKey()); }
/** * Use this constructor if you want to verify a signature using * the sub-filter adbe.pkcs7.detached or adbe.pkcs7.sha1. * @param contentsKey the /Contents key * @param tsp set to true if there's a PAdES LTV time stamp. * @param provider the provider or <code>null</code> for the default provider */ public PdfPKCS7(byte[] contentsKey, bool tsp) { isTsp = tsp; Asn1InputStream din = new Asn1InputStream(new MemoryStream(contentsKey)); // // Basic checks to make sure it's a PKCS#7 SignedData Object // Asn1Object pkcs; try { pkcs = din.ReadObject(); } catch { throw new ArgumentException(MessageLocalization.GetComposedMessage("can.t.decode.pkcs7signeddata.object")); } if (!(pkcs is Asn1Sequence)) { throw new ArgumentException(MessageLocalization.GetComposedMessage("not.a.valid.pkcs.7.object.not.a.sequence")); } Asn1Sequence signedData = (Asn1Sequence)pkcs; DerObjectIdentifier objId = (DerObjectIdentifier)signedData[0]; if (!objId.Id.Equals(SecurityIDs.ID_PKCS7_SIGNED_DATA)) throw new ArgumentException(MessageLocalization.GetComposedMessage("not.a.valid.pkcs.7.object.not.signed.data")); Asn1Sequence content = (Asn1Sequence)((Asn1TaggedObject)signedData[1]).GetObject(); // the positions that we care are: // 0 - version // 1 - digestAlgorithms // 2 - possible ID_PKCS7_DATA // (the certificates and crls are taken out by other means) // last - signerInfos // the version version = ((DerInteger)content[0]).Value.IntValue; // the digestAlgorithms digestalgos = new Dictionary<string,object>(); IEnumerator e = ((Asn1Set)content[1]).GetEnumerator(); while (e.MoveNext()) { Asn1Sequence s = (Asn1Sequence)e.Current; DerObjectIdentifier o = (DerObjectIdentifier)s[0]; digestalgos[o.Id] = null; } // the certificates and crls X509CertificateParser cf = new X509CertificateParser(); certs = new List<X509Certificate>(); foreach (X509Certificate cc in cf.ReadCertificates(contentsKey)) { certs.Add(cc); } crls = new List<X509Crl>(); // the possible ID_PKCS7_DATA Asn1Sequence rsaData = (Asn1Sequence)content[2]; if (rsaData.Count > 1) { Asn1OctetString rsaDataContent = (Asn1OctetString)((Asn1TaggedObject)rsaData[1]).GetObject(); RSAdata = rsaDataContent.GetOctets(); } // the signerInfos int next = 3; while (content[next] is Asn1TaggedObject) ++next; Asn1Set signerInfos = (Asn1Set)content[next]; if (signerInfos.Count != 1) throw new ArgumentException(MessageLocalization.GetComposedMessage("this.pkcs.7.object.has.multiple.signerinfos.only.one.is.supported.at.this.time")); Asn1Sequence signerInfo = (Asn1Sequence)signerInfos[0]; // the positions that we care are // 0 - version // 1 - the signing certificate issuer and serial number // 2 - the digest algorithm // 3 or 4 - digestEncryptionAlgorithm // 4 or 5 - encryptedDigest signerversion = ((DerInteger)signerInfo[0]).Value.IntValue; // Get the signing certificate Asn1Sequence issuerAndSerialNumber = (Asn1Sequence)signerInfo[1]; Org.BouncyCastle.Asn1.X509.X509Name issuer = Org.BouncyCastle.Asn1.X509.X509Name.GetInstance(issuerAndSerialNumber[0]); BigInteger serialNumber = ((DerInteger)issuerAndSerialNumber[1]).Value; foreach (X509Certificate cert in certs) { if (issuer.Equivalent(cert.IssuerDN) && serialNumber.Equals(cert.SerialNumber)) { signCert = cert; break; } } if (signCert == null) { throw new ArgumentException(MessageLocalization.GetComposedMessage("can.t.find.signing.certificate.with.serial.1", issuer.ToString() + " / " + serialNumber.ToString(16))); } CalcSignCertificateChain(); digestAlgorithmOid = ((DerObjectIdentifier)((Asn1Sequence)signerInfo[2])[0]).Id; next = 3; if (signerInfo[next] is Asn1TaggedObject) { Asn1TaggedObject tagsig = (Asn1TaggedObject)signerInfo[next]; Asn1Set sseq = Asn1Set.GetInstance(tagsig, false); sigAttr = sseq.GetEncoded(Asn1Encodable.Der); for (int k = 0; k < sseq.Count; ++k) { Asn1Sequence seq2 = (Asn1Sequence)sseq[k]; if (((DerObjectIdentifier)seq2[0]).Id.Equals(SecurityIDs.ID_MESSAGE_DIGEST)) { Asn1Set sset = (Asn1Set)seq2[1]; digestAttr = ((DerOctetString)sset[0]).GetOctets(); } else if (((DerObjectIdentifier)seq2[0]).Id.Equals(SecurityIDs.ID_ADBE_REVOCATION)) { Asn1Set setout = (Asn1Set)seq2[1]; Asn1Sequence seqout = (Asn1Sequence)setout[0]; for (int j = 0; j < seqout.Count; ++j) { Asn1TaggedObject tg = (Asn1TaggedObject)seqout[j]; if (tg.TagNo == 1) { Asn1Sequence seqin = (Asn1Sequence)tg.GetObject(); FindOcsp(seqin); } if (tg.TagNo == 0) { Asn1Sequence seqin = (Asn1Sequence)tg.GetObject(); FindCRL(seqin); } } } } if (digestAttr == null) throw new ArgumentException(MessageLocalization.GetComposedMessage("authenticated.attribute.is.missing.the.digest")); ++next; } digestEncryptionAlgorithmOid = ((DerObjectIdentifier)((Asn1Sequence)signerInfo[next++])[0]).Id; digest = ((Asn1OctetString)signerInfo[next++]).GetOctets(); if (next < signerInfo.Count && (signerInfo[next] is DerTaggedObject)) { Asn1TaggedObject taggedObject = (Asn1TaggedObject) signerInfo[next]; Asn1Set unat = Asn1Set.GetInstance(taggedObject, false); Org.BouncyCastle.Asn1.Cms.AttributeTable attble = new Org.BouncyCastle.Asn1.Cms.AttributeTable(unat); Org.BouncyCastle.Asn1.Cms.Attribute ts = attble[PkcsObjectIdentifiers.IdAASignatureTimeStampToken]; if (ts != null && ts.AttrValues.Count > 0) { Asn1Set attributeValues = ts.AttrValues; Asn1Sequence tokenSequence = Asn1Sequence.GetInstance(attributeValues[0]); Org.BouncyCastle.Asn1.Cms.ContentInfo contentInfo = Org.BouncyCastle.Asn1.Cms.ContentInfo.GetInstance(tokenSequence); this.timeStampToken = new TimeStampToken(contentInfo); } } if (isTsp) { Org.BouncyCastle.Asn1.Cms.ContentInfo contentInfoTsp = Org.BouncyCastle.Asn1.Cms.ContentInfo.GetInstance(signedData); this.timeStampToken = new TimeStampToken(contentInfoTsp); TimeStampTokenInfo info = timeStampToken.TimeStampInfo; String algOID = info.MessageImprintAlgOid; messageDigest = DigestUtilities.GetDigest(algOID); } else { if (RSAdata != null || digestAttr != null) { messageDigest = GetHashClass(); encContDigest = GetHashClass(); } sig = SignerUtilities.GetSigner(GetDigestAlgorithm()); sig.Init(false, signCert.GetPublicKey()); } }
/// <summary>Constructor with an indication of the time-stamp type The default constructor for TimestampToken. /// </summary> /// <remarks>Constructor with an indication of the time-stamp type The default constructor for TimestampToken. /// </remarks> public TimestampToken(TimeStampToken timeStamp, TimestampToken.TimestampType type ) { this.timeStamp = timeStamp; this.timeStampType = type; }
/// <summary> /// Add the specified timestamp token to the validate request. /// </summary> /// <param name="validateRequest"></param> /// <param name="timeStampToken"></param> private void addTimeStampToken(ValidateRequestType validateRequest, TimeStampToken timeStampToken) { TSAMessageExtensionType tsaMessageExtension = new TSAMessageExtensionType(); EncapsulatedPKIDataType timeStampTokenValue = new EncapsulatedPKIDataType(); timeStampTokenValue.Value = timeStampToken.GetEncoded(); tsaMessageExtension.EncapsulatedTimeStamp = timeStampTokenValue; validateRequest.MessageExtension = new MessageExtensionAbstractType[] { tsaMessageExtension }; }
/* * Validation */ private void validate(List<Org.BouncyCastle.X509.X509Certificate> certificateChain, string trustDomain, bool returnRevocationData, DateTime validationDate, List<OcspResp> ocspResponses, List<X509Crl> crls, RevocationValuesType revocationValues, TimeStampToken timeStampToken, EncapsulatedPKIDataType[] attributeCertificates) { // setup the client setupClient(); // validate ValidateRequestType validateRequest = new ValidateRequestType(); QueryKeyBindingType queryKeyBinding = new QueryKeyBindingType(); KeyInfoType keyInfo = new KeyInfoType(); X509DataType x509Data = new X509DataType(); x509Data.Items = new object[certificateChain.Count]; x509Data.ItemsElementName = new ItemsChoiceType[certificateChain.Count]; int idx = 0; foreach (Org.BouncyCastle.X509.X509Certificate certificate in certificateChain) { x509Data.Items[idx] = certificate.GetEncoded(); x509Data.ItemsElementName[idx] = ItemsChoiceType.X509Certificate; idx++; } keyInfo.Items = new object[] { x509Data }; keyInfo.ItemsElementName = new ItemsChoiceType2[] { ItemsChoiceType2.X509Data }; queryKeyBinding.KeyInfo = keyInfo; validateRequest.QueryKeyBinding = queryKeyBinding; /* * Set optional trust domain */ if (null != trustDomain) { UseKeyWithType useKeyWith = new UseKeyWithType(); useKeyWith.Application = XkmsConstants.TRUST_DOMAIN_APPLICATION_URI; useKeyWith.Identifier = trustDomain; queryKeyBinding.UseKeyWith = new UseKeyWithType[] { useKeyWith }; } /* * Add timestamp token for TSA validation */ if (null != timeStampToken) { addTimeStampToken(validateRequest, timeStampToken); } /* * Add attribute certificates */ if (null != attributeCertificates) { addAttributeCertificates(validateRequest, attributeCertificates); } /* * Set if used revocation data should be returned or not */ if (returnRevocationData) { validateRequest.RespondWith = new string[] { XkmsConstants.RETURN_REVOCATION_DATA_URI }; } /* * Historical validation, add the revocation data to the request */ if (!validationDate.Equals(DateTime.MinValue)) { TimeInstantType timeInstant = new TimeInstantType(); timeInstant.Time = validationDate; queryKeyBinding.TimeInstant = timeInstant; addRevocationData(validateRequest, ocspResponses, crls, revocationValues); } /* * Validate */ ValidateResultType validateResult = client.Validate(validateRequest); /* * Check result */ checkResponse(validateResult); /* * Set the optionally requested revocation data */ if (returnRevocationData) { foreach (MessageExtensionAbstractType messageExtension in validateResult.MessageExtension) { if (messageExtension is RevocationDataMessageExtensionType) { this.revocationValues = ((RevocationDataMessageExtensionType)messageExtension).RevocationValues; } } if (null == this.revocationValues) { throw new RevocationDataNotFoundException(); } } /* * Store reason URIs */ foreach (KeyBindingType keyBinding in validateResult.KeyBinding) { if (KeyBindingEnum.httpwwww3org200203xkmsValid.Equals(keyBinding.Status.StatusValue)) { return; } foreach (string reason in keyBinding.Status.InvalidReason) { this.invalidReasonURIs.AddLast(reason); } throw new ValidationFailedException(this.invalidReasonURIs); } }
public void validate(string trustDomain, TimeStampToken timeStampToken) { validate(null, trustDomain, false, DateTime.MinValue, null, null, null, timeStampToken, null); }