internal SignerInformation( Asn1.Cms.SignerInfo info, DerObjectIdentifier contentType, ICmsTypedData content, byte[] digest) { this.info = info; this.contentType = contentType; this.isCounterSignature = contentType == null; try { SignerIdentifier s = info.SignerID; if (s.IsTagged) { Asn1OctetString octs = Asn1OctetString.GetInstance(s.ID); this.sid = new SignerID(octs.GetEncoded()); } else { Asn1.Cms.IssuerAndSerialNumber iAnds = Asn1.Cms.IssuerAndSerialNumber.GetInstance(s.ID); this.sid = new SignerID(iAnds.Name, iAnds.SerialNumber.Value); } } catch (IOException) { throw new ArgumentException("invalid sid in SignerInfo"); } this.digestAlgorithm = info.DigestAlgorithm; this.signedAttributeSet = info.AuthenticatedAttributes; this.unsignedAttributeSet = info.UnauthenticatedAttributes; this.encryptionAlgorithm = info.DigestEncryptionAlgorithm; this.signature = info.EncryptedDigest.GetOctets(); this.content = content; this.resultDigest = digest; }
/** * Return a signer information object with passed in SignerInformationStore representing counter * signatures attached as an unsigned attribute. * * @param signerInformation the signerInfo to be used as the basis. * @param counterSigners signer info objects carrying counter signature. * @return a copy of the original SignerInformationObject with the changed attributes. */ public static SignerInformation AddCounterSigners( SignerInformation signerInformation, SignerInformationStore counterSigners) { // TODO Perform checks from RFC 3852 11.4 Asn1.Cms.SignerInfo sInfo = signerInformation.info; Asn1.Cms.AttributeTable unsignedAttr = signerInformation.UnsignedAttributes; Asn1EncodableVector v; if (unsignedAttr != null) { v = unsignedAttr.ToAsn1EncodableVector(); } else { v = new Asn1EncodableVector(); } Asn1EncodableVector sigs = new Asn1EncodableVector(); foreach (SignerInformation sigInf in counterSigners.GetAll()) { sigs.Add(sigInf.ToAsn1Structure()); } v.Add(new Asn1.Cms.Attribute(CmsAttributes.CounterSignature, new DerSet(sigs))); return(new SignerInformation( new Asn1.Cms.SignerInfo( sInfo.SignerID, sInfo.DigestAlgorithm, sInfo.AuthenticatedAttributes, sInfo.DigestEncryptionAlgorithm, sInfo.EncryptedDigest, new DerSet(v)), signerInformation.contentType, signerInformation.content, null)); }
/** * Return a signer information object with the passed in unsigned * attributes replacing the ones that are current associated with * the object passed in. * * @param signerInformation the signerInfo to be used as the basis. * @param unsignedAttributes the unsigned attributes to add. * @return a copy of the original SignerInformationObject with the changed attributes. */ public static SignerInformation ReplaceUnsignedAttributes( SignerInformation signerInformation, Asn1.Cms.AttributeTable unsignedAttributes) { Asn1.Cms.SignerInfo sInfo = signerInformation.info; Asn1Set unsignedAttr = null; if (unsignedAttributes != null) { unsignedAttr = new DerSet(unsignedAttributes.ToAsn1EncodableVector()); } return(new SignerInformation( new Asn1.Cms.SignerInfo( sInfo.SignerID, sInfo.DigestAlgorithm, sInfo.AuthenticatedAttributes, sInfo.DigestEncryptionAlgorithm, sInfo.EncryptedDigest, unsignedAttr), signerInformation.contentType, signerInformation.content, null)); }
/** * Return a SignerInformationStore containing the counter signatures attached to this * signer. If no counter signatures are present an empty store is returned. */ public SignerInformationStore GetCounterSignatures() { // TODO There are several checks implied by the RFC3852 comments that are missing /* * The countersignature attribute MUST be an unsigned attribute; it MUST * NOT be a signed attribute, an authenticated attribute, an * unauthenticated attribute, or an unprotected attribute. */ Asn1.Cms.AttributeTable unsignedAttributeTable = UnsignedAttributes; if (unsignedAttributeTable == null) { return(new SignerInformationStore(new List <SignerInformation>(0))); } IList <SignerInformation> counterSignatures = new List <SignerInformation>(); /* * The UnsignedAttributes syntax is defined as a SET OF Attributes. The * UnsignedAttributes in a signerInfo may include multiple instances of * the countersignature attribute. */ Asn1EncodableVector allCSAttrs = unsignedAttributeTable.GetAll(CmsAttributes.CounterSignature); foreach (Asn1.Cms.Attribute counterSignatureAttribute in allCSAttrs) { /* * A countersignature attribute can have multiple attribute values. The * syntax is defined as a SET OF AttributeValue, and there MUST be one * or more instances of AttributeValue present. */ Asn1Set values = counterSignatureAttribute.AttrValues; if (values.Count < 1) { // TODO Throw an appropriate exception? } foreach (Asn1Encodable asn1Obj in values) { /* * Countersignature values have the same meaning as SignerInfo values * for ordinary signatures, except that: * * 1. The signedAttributes field MUST NOT contain a content-type * attribute; there is no content type for countersignatures. * * 2. The signedAttributes field MUST contain a message-digest * attribute if it contains any other attributes. * * 3. The input to the message-digesting process is the contents * octets of the DER encoding of the signatureValue field of the * SignerInfo value with which the attribute is associated. */ Asn1.Cms.SignerInfo si = Asn1.Cms.SignerInfo.GetInstance(asn1Obj.ToAsn1Object()); string digestName = CmsSignedHelper.Instance.GetDigestAlgName(si.DigestAlgorithm.Algorithm.Id); // TODO: //counterSignatures.Add(new SignerInformation(si, null, null, new CounterSignatureDigestCalculator(digestName, GetSignature()))); } } return(new SignerInformationStore(counterSignatures)); }