/** * Create a standard attribute table from the passed in parameters - this will * normally include contentType, signingTime, and messageDigest. If the constructor * using an AttributeTable was used, entries in it for contentType, signingTime, and * messageDigest will override the generated ones. * * @param parameters source parameters for table generation. * * @return a filled in Hashtable of attributes. */ protected virtual Hashtable createStandardAttributeTable( IDictionary parameters) { Hashtable std = (Hashtable)table.Clone(); if (!std.ContainsKey(CmsAttributes.ContentType)) { DerObjectIdentifier contentType = (DerObjectIdentifier) parameters[CmsAttributeTableParameter.ContentType]; Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.ContentType, new DerSet(contentType)); std[attr.AttrType] = attr; } if (!std.ContainsKey(CmsAttributes.SigningTime)) { Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.SigningTime, new DerSet(new Time(DateTime.UtcNow))); std[attr.AttrType] = attr; } if (!std.ContainsKey(CmsAttributes.MessageDigest)) { byte[] messageDigest = (byte[])parameters[CmsAttributeTableParameter.Digest]; Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.MessageDigest, new DerSet(new DerOctetString(messageDigest))); std[attr.AttrType] = attr; } return std; }
/** * Create a standard attribute table from the passed in parameters - this will * normally include contentType, signingTime, and messageDigest. If the constructor * using an AttributeTable was used, entries in it for contentType, signingTime, and * messageDigest will override the generated ones. * * @param parameters source parameters for table generation. * * @return a filled in Hashtable of attributes. */ protected virtual Hashtable createStandardAttributeTable( IDictionary parameters) { Hashtable std = (Hashtable)table.Clone(); if (!std.ContainsKey(CmsAttributes.ContentType)) { DerObjectIdentifier contentType = (DerObjectIdentifier) parameters[CmsAttributeTableParameter.ContentType]; Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.ContentType, new DerSet(contentType)); std[attr.AttrType] = attr; } if (!std.ContainsKey(CmsAttributes.SigningTime)) { Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.SigningTime, new DerSet(new Time(DateTime.UtcNow))); std[attr.AttrType] = attr; } if (!std.ContainsKey(CmsAttributes.MessageDigest)) { byte[] messageDigest = (byte[])parameters[CmsAttributeTableParameter.Digest]; Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.MessageDigest, new DerSet(new DerOctetString(messageDigest))); std[attr.AttrType] = attr; } return(std); }
private void DoCreateStandardAttributeTable(IDictionary parameters, IDictionary std) { // contentType will be absent if we're trying to generate a counter signature. if (parameters.Contains(CmsAttributeTableParameter.ContentType)) { if (!std.Contains(CmsAttributes.ContentType)) { DerObjectIdentifier contentType = (DerObjectIdentifier) parameters[CmsAttributeTableParameter.ContentType]; Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.ContentType, new DerSet(contentType)); std[attr.AttrType] = attr; } } if (!std.Contains(CmsAttributes.SigningTime)) { Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.SigningTime, new DerSet(new Time(DateTime.UtcNow))); std[attr.AttrType] = attr; } if (!std.Contains(CmsAttributes.MessageDigest)) { byte[] messageDigest = (byte[])parameters[CmsAttributeTableParameter.Digest]; Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.MessageDigest, new DerSet(new DerOctetString(messageDigest))); std[attr.AttrType] = attr; } }
private void checkAttribute( byte[] expected, Asn1.Cms.Attribute attr) { DerOctetString value = (DerOctetString)attr.AttrValues[0]; Assert.AreEqual(new DerOctetString(expected), value); }
public AttributeTable GetAttributes( IDictionary parameters) { DerOctetString val = new DerOctetString((byte[])parameters[CmsAttributeTableParameter.Signature]); Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(dummyOid2, new DerSet(val)); return(new AttributeTable(new DerSet(attr))); }
public void TestSha1WithRsaEncapsulatedSubjectKeyID() { MemoryStream bOut = new MemoryStream(); IX509Store x509Certs = CmsTestUtil.MakeCertStore(OrigCert, SignCert); CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator(); gen.AddSigner(OrigKP.Private, CmsTestUtil.CreateSubjectKeyId(OrigCert.GetPublicKey()).GetKeyIdentifier(), CmsSignedDataStreamGenerator.DigestSha1); gen.AddCertificates(x509Certs); byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage); Stream sigOut = gen.Open(bOut, true); sigOut.Write(testBytes, 0, testBytes.Length); sigOut.Close(); CmsSignedDataParser sp = new CmsSignedDataParser(bOut.ToArray()); sp.GetSignedContent().Drain(); VerifySignatures(sp); byte[] contentDigest = (byte[])gen.GetGeneratedDigests()[CmsSignedGenerator.DigestSha1]; ArrayList signers = new ArrayList(sp.GetSignerInfos().GetSigners()); AttributeTable table = ((SignerInformation)signers[0]).SignedAttributes; Asn1.Cms.Attribute hash = table[CmsAttributes.MessageDigest]; Assert.IsTrue(Arrays.AreEqual(contentDigest, ((Asn1OctetString)hash.AttrValues[0]).GetOctets())); // // try using existing signer // gen = new CmsSignedDataStreamGenerator(); gen.AddSigners(sp.GetSignerInfos()); // gen.AddCertificatesAndCRLs(sp.GetCertificatesAndCrls("Collection", "BC")); gen.AddCertificates(sp.GetCertificates("Collection")); bOut.SetLength(0); sigOut = gen.Open(bOut, true); sigOut.Write(testBytes, 0, testBytes.Length); sigOut.Close(); CmsSignedData sd = new CmsSignedData(new CmsProcessableByteArray(testBytes), bOut.ToArray()); Assert.AreEqual(1, sd.GetSignerInfos().GetSigners().Count); VerifyEncodedData(bOut); }
/** * Check this response against to see if it a well formed response for * the passed in request. Validation will include checking the time stamp * token if the response status is GRANTED or GRANTED_WITH_MODS. * * @param request the request to be checked against * @throws TspException if the request can not match this response. */ public void Validate( TimeStampRequest request) { TimeStampToken tok = this.TimeStampToken; if (tok != null) { TimeStampTokenInfo tstInfo = tok.TimeStampInfo; if (request.Nonce != null && !request.Nonce.Equals(tstInfo.Nonce)) { throw new TspValidationException("response contains wrong nonce value."); } if (this.Status != (int)PkiStatus.Granted && this.Status != (int)PkiStatus.GrantedWithMods) { throw new TspValidationException("time stamp token found in failed request."); } if (!Arrays.ConstantTimeAreEqual(request.GetMessageImprintDigest(), tstInfo.GetMessageImprintDigest())) { throw new TspValidationException("response for different message imprint digest."); } if (!tstInfo.MessageImprintAlgOid.Equals(request.MessageImprintAlgOid)) { throw new TspValidationException("response for different message imprint algorithm."); } Asn1.Cms.Attribute scV1 = tok.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificate]; Asn1.Cms.Attribute scV2 = tok.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificateV2]; if (scV1 == null && scV2 == null) { throw new TspValidationException("no signing certificate attribute present."); } if (scV1 != null && scV2 != null) { /* * RFC 5035 5.4. If both attributes exist in a single message, * they are independently evaluated. */ } if (request.ReqPolicy != null && !request.ReqPolicy.Equals(tstInfo.Policy)) { throw new TspValidationException("TSA policy wrong for request."); } } else if (this.Status == (int)PkiStatus.Granted || this.Status == (int)PkiStatus.GrantedWithMods) { throw new TspValidationException("no time stamp token found and one expected."); } }
public TimeStampToken( CmsSignedData signedData) { this.tsToken = signedData; if (!this.tsToken.SignedContentTypeOid.Equals(PkcsObjectIdentifiers.IdCTTstInfo.Id)) { throw new TspValidationException("ContentInfo object not for a time stamp."); } ICollection signers = tsToken.GetSignerInfos().GetSigners(); if (signers.Count != 1) { throw new ArgumentException("Time-stamp token signed by " + signers.Count + " signers, but it must contain just the TSA signature."); } IEnumerator signerEnum = signers.GetEnumerator(); signerEnum.MoveNext(); tsaSignerInfo = (SignerInformation)signerEnum.Current; try { CmsProcessable content = tsToken.SignedContent; MemoryStream bOut = new MemoryStream(); content.Write(bOut); this.tstInfo = new TimeStampTokenInfo( TstInfo.GetInstance( Asn1Object.FromByteArray(bOut.ToArray()))); Asn1.Cms.Attribute attr = tsaSignerInfo.SignedAttributes[ PkcsObjectIdentifiers.IdAASigningCertificate]; if (attr == null) { throw new TspValidationException( "no signing certificate attribute found, time stamp invalid."); } SigningCertificate signCert = SigningCertificate.GetInstance( attr.AttrValues[0]); this.certID = EssCertID.GetInstance(signCert.GetCerts()[0]); } catch (CmsException e) { throw new TspException(e.Message, e.InnerException); } }
/** * create with a signer with extra signed/unsigned attributes. */ public TimeStampTokenGenerator( AsymmetricKeyParameter key, X509Certificate cert, string digestOID, string tsaPolicyOID, Asn1.Cms.AttributeTable signedAttr, Asn1.Cms.AttributeTable unsignedAttr) { this.key = key; this.cert = cert; this.digestOID = digestOID; this.tsaPolicyOID = tsaPolicyOID; this.unsignedAttr = unsignedAttr; TspUtil.ValidateCertificate(cert); // // Add the ESSCertID attribute // IDictionary signedAttrs; if (signedAttr != null) { signedAttrs = signedAttr.ToDictionary(); } else { signedAttrs = Platform.CreateHashtable(); } try { byte[] hash = DigestUtilities.CalculateDigest("SHA-1", cert.GetEncoded()); EssCertID essCertid = new EssCertID(hash); Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute( PkcsObjectIdentifiers.IdAASigningCertificate, new DerSet(new SigningCertificate(essCertid))); signedAttrs[attr.AttrType] = attr; } catch (CertificateEncodingException e) { throw new TspException("Exception processing certificate.", e); } catch (SecurityUtilityException e) { throw new TspException("Can't find a SHA-1 implementation.", e); } this.signedAttr = new Asn1.Cms.AttributeTable(signedAttrs); }
/** * Create a standard attribute table from the passed in parameters - this will * normally include contentType, signingTime, and messageDigest. If the constructor * using an AttributeTable was used, entries in it for contentType, signingTime, and * messageDigest will override the generated ones. * * @param parameters source parameters for table generation. * * @return a filled in Hashtable of attributes. */ protected Hashtable createStandardAttributeTable( IDictionary parameters) { Hashtable std = (Hashtable)table.Clone(); if (table.ContainsKey(CmsAttributes.ContentType)) { std[CmsAttributes.ContentType] = table[CmsAttributes.ContentType]; } else { Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.ContentType, new DerSet((DerObjectIdentifier)parameters[CmsAttributeTableParameter.ContentType])); std[attr.AttrType] = attr; } if (table.ContainsKey(CmsAttributes.SigningTime)) { std[CmsAttributes.SigningTime] = table[CmsAttributes.SigningTime]; } else { Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute( CmsAttributes.SigningTime, new DerSet(new Time(DateTime.UtcNow))); std[attr.AttrType] = attr; } if (table.ContainsKey(CmsAttributes.MessageDigest)) { std[CmsAttributes.MessageDigest] = table[CmsAttributes.MessageDigest]; } else { byte[] hash = (byte[])parameters[CmsAttributeTableParameter.Digest]; Asn1.Cms.Attribute attr; if (hash != null) { attr = new Asn1.Cms.Attribute( CmsAttributes.MessageDigest, new DerSet(new DerOctetString(hash))); } else { attr = new Asn1.Cms.Attribute( CmsAttributes.MessageDigest, new DerSet(DerNull.Instance)); } std[attr.AttrType] = attr; } return(std); }
/** * Create a standard attribute table from the passed in parameters - this will * normally include contentType, signingTime, and messageDigest. If the constructor * using an AttributeTable was used, entries in it for contentType, signingTime, and * messageDigest will override the generated ones. * * @param parameters source parameters for table generation. * * @return a filled in Hashtable of attributes. */ protected Hashtable createStandardAttributeTable( IDictionary parameters) { Hashtable std = (Hashtable)table.Clone(); if (table.ContainsKey(CmsAttributes.ContentType)) { std[CmsAttributes.ContentType] = table[CmsAttributes.ContentType]; } else { Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.ContentType, new DerSet((DerObjectIdentifier)parameters[CmsAttributeTableParameter.ContentType])); std[attr.AttrType] = attr; } if (table.ContainsKey(CmsAttributes.SigningTime)) { std[CmsAttributes.SigningTime] = table[CmsAttributes.SigningTime]; } else { Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute( CmsAttributes.SigningTime, new DerSet(new Time(DateTime.UtcNow))); std[attr.AttrType] = attr; } if (table.ContainsKey(CmsAttributes.MessageDigest)) { std[CmsAttributes.MessageDigest] = table[CmsAttributes.MessageDigest]; } else { byte[] hash = (byte[])parameters[CmsAttributeTableParameter.Digest]; Asn1.Cms.Attribute attr; if (hash != null) { attr = new Asn1.Cms.Attribute( CmsAttributes.MessageDigest, new DerSet(new DerOctetString(hash))); } else { attr = new Asn1.Cms.Attribute( CmsAttributes.MessageDigest, new DerSet(DerNull.Instance)); } std[attr.AttrType] = attr; } return std; }
public override AttributeTable GetAttributes( IDictionary parameters) { IDictionary table = createStandardAttributeTable(parameters); DerOctetString val = new DerOctetString((byte[])parameters[CmsAttributeTableParameter.Digest]); Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(dummyOid1, new DerSet(val)); table[attr.AttrType] = attr; return(new AttributeTable(table)); }
private void VerifyContentHint(SignerInformation signInfo) { Asn1.Cms.AttributeTable attrTable = signInfo.UnsignedAttributes; Asn1.Cms.Attribute attr = attrTable[CmsAttributes.ContentHint]; Assert.AreEqual(1, attr.AttrValues.Count); Asn1EncodableVector v = new Asn1EncodableVector( new DerUtf8String("Content Hints Description Buffer"), CmsObjectIdentifiers.Data); Assert.IsTrue(attr.AttrValues[0].Equals(new DerSequence(v))); }
/** * verify that the given certificate succesfully handles and confirms * the signature associated with this signer and, if a signingTime * attribute is available, that the certificate was valid at the time the * signature was generated. */ public bool Verify( X509Certificate cert) { Asn1.Cms.AttributeTable attr = this.SignedAttributes; if (attr != null) { Asn1.Cms.Attribute t = attr[CmsAttributes.SigningTime]; if (t != null) { Asn1.Cms.Time time = Asn1.Cms.Time.GetInstance( t.AttrValues[0].ToAsn1Object()); cert.CheckValidity(time.Date); } } return(DoVerify(cert.GetPublicKey(), attr)); }
private Asn1Object GetSingleValuedSignedAttribute( DerObjectIdentifier attrOID, string printableName) { Asn1.Cms.AttributeTable unsignedAttrTable = this.UnsignedAttributes; if (unsignedAttrTable != null && unsignedAttrTable.GetAll(attrOID).Count > 0) { throw new CmsException("The " + printableName + " attribute MUST NOT be an unsigned attribute"); } Asn1.Cms.AttributeTable signedAttrTable = this.SignedAttributes; if (signedAttrTable == null) { return(null); } Asn1EncodableVector v = signedAttrTable.GetAll(attrOID); switch (v.Count) { case 0: return(null); case 1: Asn1.Cms.Attribute t = (Asn1.Cms.Attribute)v[0]; Asn1Set attrValues = t.AttrValues; if (attrValues.Count != 1) { throw new CmsException("A " + printableName + " attribute MUST have a single attribute value"); } return(attrValues[0].ToAsn1Object()); default: throw new CmsException("The SignedAttributes in a signerInfo MUST NOT include multiple instances of the " + printableName + " attribute"); } }
public void TestBasicSha256() { SignerInfoGenerator sInfoGenerator = MakeInfoGenerator(privateKey, cert, TspAlgorithms.Sha256, null, null); TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator( sInfoGenerator, Asn1DigestFactory.Get(NistObjectIdentifiers.IdSha256), new DerObjectIdentifier("1.2"), true); tsTokenGen.SetCertificates(certs); TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); TimeStampRequest request = reqGen.Generate(TspAlgorithms.Sha256, new byte[32]); Assert.IsFalse(request.CertReq); TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TspAlgorithms.Allowed); TimeStampResponse tsResp = tsRespGen.Generate(request, BigInteger.ValueOf(23), DateTime.UtcNow); tsResp = new TimeStampResponse(tsResp.GetEncoded()); TimeStampToken tsToken = tsResp.TimeStampToken; tsToken.Validate(cert); TimeStampTokenInfo tstInfo = tsToken.TimeStampInfo; AttributeTable table = tsToken.SignedAttributes; Asn1.Cms.Attribute r = table[PkcsObjectIdentifiers.IdAASigningCertificateV2]; Assert.NotNull(r); Assert.AreEqual(PkcsObjectIdentifiers.IdAASigningCertificateV2, r.AttrType); Asn1Set set = r.AttrValues; SigningCertificateV2 sCert = SigningCertificateV2.GetInstance(set[0]); Asn1.X509.IssuerSerial issSerNum = sCert.GetCerts()[0].IssuerSerial; Assert.AreEqual(cert.SerialNumber, issSerNum.Serial.Value); }
/** * verify that the given certificate successfully handles and confirms * the signature associated with this signer and, if a signingTime * attribute is available, that the certificate was valid at the time the * signature was generated. */ public bool Verify( X509Certificate cert) { Asn1.Cms.AttributeTable attr = this.SignedAttributes; if (attr != null) { Asn1EncodableVector v = attr.GetAll(CmsAttributes.SigningTime); switch (v.Count) { case 0: break; case 1: { Asn1.Cms.Attribute t = (Asn1.Cms.Attribute)v[0]; Debug.Assert(t != null); Asn1Set attrValues = t.AttrValues; if (attrValues.Count != 1) { throw new CmsException("A signing-time attribute MUST have a single attribute value"); } Asn1.Cms.Time time = Asn1.Cms.Time.GetInstance(attrValues[0].ToAsn1Object()); cert.CheckValidity(time.Date); break; } default: throw new CmsException("The SignedAttributes in a signerInfo MUST NOT include multiple instances of the signing-time attribute"); } } return(DoVerify(cert.GetPublicKey(), attr)); }
/** * Create a standard attribute table from the passed in parameters - this will * normally include contentType and messageDigest. If the constructor * using an AttributeTable was used, entries in it for contentType and * messageDigest will override the generated ones. * * @param parameters source parameters for table generation. * * @return a filled in IDictionary of attributes. */ protected virtual IDictionary CreateStandardAttributeTable( IDictionary parameters) { IDictionary std = Platform.CreateHashtable(table); if (!std.Contains(CmsAttributes.ContentType)) { DerObjectIdentifier contentType = (DerObjectIdentifier) parameters[CmsAttributeTableParameter.ContentType]; Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.ContentType, new DerSet(contentType)); std[attr.AttrType] = attr; } if (!std.Contains(CmsAttributes.MessageDigest)) { byte[] messageDigest = (byte[])parameters[CmsAttributeTableParameter.Digest]; Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.MessageDigest, new DerSet(new DerOctetString(messageDigest))); std[attr.AttrType] = attr; } return(std); }
/** * Create a standard attribute table from the passed in parameters - this will * normally include contentType and messageDigest. If the constructor * using an AttributeTable was used, entries in it for contentType and * messageDigest will override the generated ones. * * @param parameters source parameters for table generation. * * @return a filled in IDictionary of attributes. */ protected virtual IDictionary CreateStandardAttributeTable( IDictionary parameters) { IDictionary std = Platform.CreateHashtable(table); if (!std.Contains(CmsAttributes.ContentType)) { DerObjectIdentifier contentType = (DerObjectIdentifier) parameters[CmsAttributeTableParameter.ContentType]; Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.ContentType, new DerSet(contentType)); std[attr.AttrType] = attr; } if (!std.Contains(CmsAttributes.MessageDigest)) { byte[] messageDigest = (byte[])parameters[CmsAttributeTableParameter.Digest]; Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.MessageDigest, new DerSet(new DerOctetString(messageDigest))); std[attr.AttrType] = attr; } return std; }
public void TestSha1WithRsaAndAttributeTable() { byte[] testBytes = Encoding.ASCII.GetBytes("Hello world!"); IList certList = new ArrayList(); CmsProcessable msg = new CmsProcessableByteArray(testBytes); certList.Add(OrigCert); certList.Add(SignCert); IX509Store x509Certs = X509StoreFactory.Create( "Certificate/Collection", new X509CollectionStoreParameters(certList)); CmsSignedDataGenerator gen = new CmsSignedDataGenerator(); IDigest md = DigestUtilities.GetDigest("SHA1"); md.BlockUpdate(testBytes, 0, testBytes.Length); byte[] hash = DigestUtilities.DoFinal(md); Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.MessageDigest, new DerSet(new DerOctetString(hash))); Asn1EncodableVector v = new Asn1EncodableVector(attr); gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataGenerator.DigestSha1, new AttributeTable(v), null); gen.AddCertificates(x509Certs); CmsSignedData s = gen.Generate(CmsSignedDataGenerator.Data, null, false); // // the signature is detached, so need to add msg before passing on // s = new CmsSignedData(msg, s.GetEncoded()); // // compute expected content digest // VerifySignatures(s, hash); }
public AttributeTable GetAttributes( IDictionary parameters) { DerOctetString val = new DerOctetString((byte[])parameters[CmsAttributeTableParameter.Signature]); Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(dummyOid2, new DerSet(val)); return new AttributeTable(new DerSet(attr)); }
public override AttributeTable GetAttributes( IDictionary parameters) { IDictionary table = createStandardAttributeTable(parameters); DerOctetString val = new DerOctetString((byte[])parameters[CmsAttributeTableParameter.Digest]); Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(dummyOid1, new DerSet(val)); table[attr.AttrType] = attr; return new AttributeTable(table); }
private bool doVerify(bool isRawVerifier, IVerifierFactory <AlgorithmIdentifier> verifierFactory, IDigestFactory <AlgorithmIdentifier> digestFactory) { IStreamCalculator <IVerifier> contentVerifier = verifierFactory.CreateCalculator(); Stream sigOut = contentVerifier.Stream; try { if (resultDigest == null) { IStreamCalculator <IBlockResult> calc = digestFactory.CreateCalculator(); if (content != null) { Stream digOut = calc.Stream; if (signedAttributeSet == null) { if (isRawVerifier) { content.Write(digOut); } else { Stream cOut = new TeeOutputStream(digOut, sigOut); content.Write(cOut); cOut.Close(); } } else { content.Write(digOut); byte[] enc = this.GetEncodedSignedAttributes(); sigOut.Write(enc, 0, enc.Length); } digOut.Close(); } else if (signedAttributeSet != null) { byte[] enc = this.GetEncodedSignedAttributes(); sigOut.Write(enc, 0, enc.Length); } else { // TODO Get rid of this exception and just treat content==null as empty not missing? throw new CmsException("data not encapsulated in signature - use detached constructor."); } resultDigest = calc.GetResult().Collect(); } else { if (signedAttributeSet == null) { if (content != null) { content.Write(sigOut); } } else { byte[] enc = this.GetEncodedSignedAttributes(); sigOut.Write(enc, 0, enc.Length); } } sigOut.Close(); } catch (Exception e) { throw new CmsException("can't process object to create signature.", e); } // RFC 3852 11.1 Check the content-type attribute is correct { Asn1Object validContentType = GetSingleValuedSignedAttribute( CmsAttributes.ContentType, "content-type"); if (validContentType == null) { if (!isCounterSignature && signedAttributeSet != null) { throw new CmsException("The content-type attribute type MUST be present whenever signed attributes are present in signed-data"); } } else { if (isCounterSignature) { throw new CmsException("[For counter signatures,] the signedAttributes field MUST NOT contain a content-type attribute"); } if (!(validContentType is DerObjectIdentifier)) { throw new CmsException("content-type attribute value not of ASN.1 type 'OBJECT IDENTIFIER'"); } DerObjectIdentifier signedContentType = (DerObjectIdentifier)validContentType; if (!signedContentType.Equals(contentType)) { throw new CmsException("content-type attribute value does not match eContentType"); } } } Asn1.Cms.AttributeTable signedAttrTable = this.SignedAttributes; // RFC 6211 Validate Algorithm Identifier protection attribute if present { Asn1.Cms.AttributeTable unsignedAttrTable = this.UnsignedAttributes; if (unsignedAttrTable != null && unsignedAttrTable.GetAll(CmsAttributes.CmsAlgorithmProtect).Count > 0) { throw new CmsException("A cmsAlgorithmProtect attribute MUST be a signed attribute"); } if (signedAttrTable != null) { Asn1EncodableVector protectionAttributes = signedAttrTable.GetAll(CmsAttributes.CmsAlgorithmProtect); if (protectionAttributes.Count > 1) { throw new CmsException("Only one instance of a cmsAlgorithmProtect attribute can be present"); } if (protectionAttributes.Count > 0) { Asn1.Cms.Attribute attr = Asn1.Cms.Attribute.GetInstance(protectionAttributes[0]); if (attr.AttrValues.Count != 1) { throw new CmsException("A cmsAlgorithmProtect attribute MUST contain exactly one value"); } CmsAlgorithmProtection algorithmProtection = CmsAlgorithmProtection.GetInstance(attr.AttrValues[0]); if (!CmsUtilities.IsEquivalent(algorithmProtection.DigestAlgorithm, info.DigestAlgorithm)) { throw new CmsException("CMS Algorithm Identifier Protection check failed for digestAlgorithm"); } if (!CmsUtilities.IsEquivalent(algorithmProtection.SignatureAlgorithm, info.DigestEncryptionAlgorithm)) { throw new CmsException("CMS Algorithm Identifier Protection check failed for signatureAlgorithm"); } } } } // RFC 3852 11.2 Check the message-digest attribute is correct { Asn1Encodable validMessageDigest = GetSingleValuedSignedAttribute( CmsAttributes.MessageDigest, "message-digest"); if (validMessageDigest == null) { if (signedAttributeSet != null) { throw new CmsException("the message-digest signed attribute type MUST be present when there are any signed attributes present"); } } else { if (!(validMessageDigest is Asn1OctetString)) { throw new CmsException("message-digest attribute value not of ASN.1 type 'OCTET STRING'"); } Asn1OctetString signedMessageDigest = (Asn1OctetString)validMessageDigest; if (!Arrays.ConstantTimeAreEqual(resultDigest, signedMessageDigest.GetOctets())) { throw new CmsSignerDigestMismatchException("message-digest attribute value does not match calculated value"); } } } // RFC 3852 11.4 Validate countersignature attribute(s) { if (signedAttrTable != null && signedAttrTable.GetAll(CmsAttributes.CounterSignature).Count > 0) { throw new CmsException("A countersignature attribute MUST NOT be a signed attribute"); } Asn1.Cms.AttributeTable unsignedAttrTable = this.UnsignedAttributes; if (unsignedAttrTable != null) { Asn1EncodableVector csAttrs = unsignedAttrTable.GetAll(CmsAttributes.CounterSignature); for (int i = 0; i < csAttrs.Count; ++i) { Asn1.Cms.Attribute csAttr = Asn1.Cms.Attribute.GetInstance(csAttrs[i]); if (csAttr.AttrValues.Count < 1) { throw new CmsException("A countersignature attribute MUST contain at least one AttributeValue"); } // Note: We don't recursively validate the countersignature value } } } try { if (signedAttributeSet == null && resultDigest != null) { if (isRawVerifier) { if (SignatureAlgorithmID.Algorithm.Equals(PkcsObjectIdentifiers.RsaEncryption)) { DigestInfo digInfo = new DigestInfo(new AlgorithmIdentifier(digestAlgorithm.Algorithm, DerNull.Instance), resultDigest); byte[] data = digInfo.GetEncoded(Asn1Encodable.Der); sigOut.Write(data, 0, data.Length); sigOut.Close(); return(contentVerifier.GetResult().IsVerified(this.GetSignature())); } sigOut.Write(resultDigest, 0, resultDigest.Length); sigOut.Close(); return(contentVerifier.GetResult().IsVerified(this.GetSignature())); } } sigOut.Close(); return(contentVerifier.GetResult().IsVerified(this.GetSignature())); } catch (IOException e) { throw new CmsException("can't process mime object to create signature.", e); } }
public void TestSha1WithRsaAndAttributeTable() { byte[] testBytes = Encoding.ASCII.GetBytes("Hello world!"); CmsProcessable msg = new CmsProcessableByteArray(testBytes); IX509Store x509Certs = CmsTestUtil.MakeCertStore(OrigCert, SignCert); byte[] hash = DigestUtilities.CalculateDigest("SHA1", testBytes); Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.MessageDigest, new DerSet(new DerOctetString(hash))); Asn1EncodableVector v = new Asn1EncodableVector(attr); CmsSignedDataGenerator gen = new CmsSignedDataGenerator(); gen.AddSigner(SignKP.Private, SignCert, CmsSignedDataGenerator.DigestSha1, new AttributeTable(v), null); gen.AddCertificates(x509Certs); CmsSignedData s = gen.Generate(CmsSignedDataGenerator.Data, null, false); // // the signature is detached, so need to add msg before passing on // s = new CmsSignedData(msg, s.GetEncoded()); // // compute expected content digest // VerifySignatures(s, hash); }
private bool DoVerify( AsymmetricKeyParameter key, Asn1.Cms.AttributeTable signedAttrTable) { string digestName = Helper.GetDigestAlgName(this.DigestAlgOid); IDigest digest = Helper.GetDigestInstance(digestName); DerObjectIdentifier sigAlgOid = this.encryptionAlgorithm.ObjectID; Asn1Encodable sigParams = this.encryptionAlgorithm.Parameters; ISigner sig; if (sigAlgOid.Equals(Asn1.Pkcs.PkcsObjectIdentifiers.IdRsassaPss)) { // RFC 4056 2.2 // When the id-RSASSA-PSS algorithm identifier is used for a signature, // the AlgorithmIdentifier parameters field MUST contain RSASSA-PSS-params. if (sigParams == null) { throw new CmsException("RSASSA-PSS signature must specify algorithm parameters"); } try { // TODO Provide abstract configuration mechanism Asn1.Pkcs.RsassaPssParameters pss = Asn1.Pkcs.RsassaPssParameters.GetInstance( sigParams.ToAsn1Object()); if (!pss.HashAlgorithm.ObjectID.Equals(this.digestAlgorithm.ObjectID)) { throw new CmsException("RSASSA-PSS signature parameters specified incorrect hash algorithm"); } if (!pss.MaskGenAlgorithm.ObjectID.Equals(Asn1.Pkcs.PkcsObjectIdentifiers.IdMgf1)) { throw new CmsException("RSASSA-PSS signature parameters specified unknown MGF"); } IDigest pssDigest = DigestUtilities.GetDigest(pss.HashAlgorithm.ObjectID); int saltLength = pss.SaltLength.Value.IntValue; byte trailerField = (byte)pss.TrailerField.Value.IntValue; // RFC 4055 3.1 // The value MUST be 1, which represents the trailer field with hexadecimal value 0xBC if (trailerField != 1) { throw new CmsException("RSASSA-PSS signature parameters must have trailerField of 1"); } sig = new PssSigner(new RsaBlindedEngine(), pssDigest, saltLength); } catch (Exception e) { throw new CmsException("failed to set RSASSA-PSS signature parameters", e); } } else { // TODO Probably too strong a check at the moment // if (sigParams != null) // throw new CmsException("unrecognised signature parameters provided"); string signatureName = digestName + "with" + Helper.GetEncryptionAlgName(this.EncryptionAlgOid); sig = Helper.GetSignatureInstance(signatureName); } try { sig.Init(false, key); if (signedAttributes == null) { if (content != null) { content.Write(new CmsSignedDataGenerator.SigOutputStream(sig)); content.Write(new CmsSignedDataGenerator.DigOutputStream(digest)); resultDigest = DigestUtilities.DoFinal(digest); } else { resultDigest = digestCalculator.GetDigest(); // need to decrypt signature and check message bytes return(VerifyDigest(resultDigest, key, this.GetSignature())); } } else { byte[] hash; if (content != null) { content.Write( new CmsSignedDataGenerator.DigOutputStream(digest)); hash = DigestUtilities.DoFinal(digest); } else if (digestCalculator != null) { hash = digestCalculator.GetDigest(); } else { hash = null; } resultDigest = hash; Asn1.Cms.Attribute dig = signedAttrTable[Asn1.Cms.CmsAttributes.MessageDigest]; Asn1.Cms.Attribute type = signedAttrTable[Asn1.Cms.CmsAttributes.ContentType]; if (dig == null) { throw new SignatureException("no hash for content found in signed attributes"); } if (type == null && !contentType.Equals(CmsAttributes.CounterSignature)) { throw new SignatureException("no content type id found in signed attributes"); } Asn1Object hashObj = dig.AttrValues[0].ToAsn1Object(); if (hashObj is Asn1OctetString) { byte[] signedHash = ((Asn1OctetString)hashObj).GetOctets(); if (!Arrays.AreEqual(hash, signedHash)) { throw new SignatureException("content hash found in signed attributes different"); } } else if (hashObj is DerNull) { if (hash != null) { throw new SignatureException("NULL hash found in signed attributes when one expected"); } } if (type != null) { DerObjectIdentifier typeOID = (DerObjectIdentifier)type.AttrValues[0]; if (!typeOID.Equals(contentType)) { throw new SignatureException("contentType in signed attributes different"); } } byte[] tmp = this.GetEncodedSignedAttributes(); sig.BlockUpdate(tmp, 0, tmp.Length); } return(sig.VerifySignature(this.GetSignature())); } catch (InvalidKeyException e) { throw new CmsException( "key not appropriate to signature in message.", e); } catch (IOException e) { throw new CmsException( "can't process mime object to create signature.", e); } catch (SignatureException e) { throw new CmsException( "invalid signature format in message: " + e.Message, e); } }
/** * create with a signer with extra signed/unsigned attributes. */ public TimeStampTokenGenerator( AsymmetricKeyParameter key, X509Certificate cert, string digestOID, string tsaPolicyOID, Asn1.Cms.AttributeTable signedAttr, Asn1.Cms.AttributeTable unsignedAttr) { this.key = key; this.cert = cert; this.digestOID = digestOID; this.tsaPolicyOID = tsaPolicyOID; this.unsignedAttr = unsignedAttr; TspUtil.ValidateCertificate(cert); // // add the essCertid // Hashtable signedAttrs; if (signedAttr != null) { signedAttrs = signedAttr.ToHashtable(); } else { signedAttrs = new Hashtable(); } IDigest digest; try { digest = DigestUtilities.GetDigest("SHA-1"); } catch (Exception e) { throw new TspException("Can't find a SHA-1 implementation.", e); } try { byte[] certEncoded = cert.GetEncoded(); digest.BlockUpdate(certEncoded, 0, certEncoded.Length); byte[] hash = DigestUtilities.DoFinal(digest); EssCertID essCertid = new EssCertID(hash); Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute( PkcsObjectIdentifiers.IdAASigningCertificate, new DerSet(new SigningCertificate(essCertid))); signedAttrs[attr.AttrType] = attr; } catch (CertificateEncodingException e) { throw new TspException("Exception processing certificate.", e); } this.signedAttr = new Asn1.Cms.AttributeTable(signedAttrs); }
private bool DoVerify( AsymmetricKeyParameter key, Asn1.Cms.AttributeTable signedAttrTable) { string digestName = Helper.GetDigestAlgName(this.DigestAlgOid); string signatureName = digestName + "with" + Helper.GetEncryptionAlgName(this.EncryptionAlgOid); ISigner sig = Helper.GetSignatureInstance(signatureName); IDigest digest = Helper.GetDigestInstance(digestName); try { sig.Init(false, key); if (signedAttributes == null) { if (content != null) { content.Write(new CmsSignedDataGenerator.SigOutputStream(sig)); content.Write(new CmsSignedDataGenerator.DigOutputStream(digest)); _resultDigest = DigestUtilities.DoFinal(digest); } else { _resultDigest = _digest; // need to decrypt signature and check message bytes return(VerifyDigest(_digest, key, this.GetSignature())); } } else { byte[] hash; if (content != null) { content.Write( new CmsSignedDataGenerator.DigOutputStream(digest)); hash = DigestUtilities.DoFinal(digest); } else { hash = _digest; } _resultDigest = hash; Asn1.Cms.Attribute dig = signedAttrTable[Asn1.Cms.CmsAttributes.MessageDigest]; Asn1.Cms.Attribute type = signedAttrTable[Asn1.Cms.CmsAttributes.ContentType]; if (dig == null) { throw new SignatureException("no hash for content found in signed attributes"); } if (type == null) { throw new SignatureException("no content type id found in signed attributes"); } Asn1Object hashObj = dig.AttrValues[0].ToAsn1Object(); if (hashObj is Asn1OctetString) { byte[] signedHash = ((Asn1OctetString)hashObj).GetOctets(); if (!Arrays.AreEqual(hash, signedHash)) { throw new SignatureException("content hash found in signed attributes different"); } } else if (hashObj is DerNull) { if (hash != null) { throw new SignatureException("NULL hash found in signed attributes when one expected"); } } DerObjectIdentifier typeOID = (DerObjectIdentifier)type.AttrValues[0]; if (!typeOID.Equals(contentType)) { throw new SignatureException("contentType in signed attributes different"); } { byte[] tmp = this.GetEncodedSignedAttributes(); sig.BlockUpdate(tmp, 0, tmp.Length); } } return(sig.VerifySignature(this.GetSignature())); } catch (InvalidKeyException e) { throw new CmsException( "key not appropriate to signature in message.", e); } catch (IOException e) { throw new CmsException( "can't process mime object to create signature.", e); } catch (SignatureException e) { throw new CmsException( "invalid signature format in message: " + e.Message, e); } }