internal SignerInformation( SignerInfo info, DerObjectIdentifier contentType, CmsProcessable content, IDigestCalculator digestCalculator) { this.info = info; this.sid = new SignerID(); this.contentType = contentType; this.isCounterSignature = contentType == null; try { SignerIdentifier s = info.SignerID; if (s.IsTagged) { Asn1OctetString octs = Asn1OctetString.GetInstance(s.ID); sid.SubjectKeyIdentifier = octs.GetEncoded(); } else { IssuerAndSerialNumber iAnds = IssuerAndSerialNumber.GetInstance(s.ID); sid.Issuer = iAnds.Name; sid.SerialNumber = 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.digestCalculator = digestCalculator; }
/** * 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 SignerInfo sInfo = signerInformation.info; 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.GetSigners()) { sigs.Add(sigInf.ToSignerInfo()); } v.Add(new Attribute(CmsAttributes.CounterSignature, new DerSet(sigs))); return(new SignerInformation( new 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, AttributeTable unsignedAttributes) { SignerInfo sInfo = signerInformation.info; Asn1Set unsignedAttr = null; if (unsignedAttributes != null) { unsignedAttr = new DerSet(unsignedAttributes.ToAsn1EncodableVector()); } return(new SignerInformation( new 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. */ AttributeTable unsignedAttributeTable = UnsignedAttributes; if (unsignedAttributeTable == null) { return(new SignerInformationStore(Platform.CreateArrayList(0))); } IList counterSignatures = Platform.CreateArrayList(); /* * 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 (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. */ SignerInfo si = SignerInfo.GetInstance(asn1Obj.ToAsn1Object()); string digestName = CmsSignedHelper.Instance.GetDigestAlgName(si.DigestAlgorithm.Algorithm.Id); counterSignatures.Add(new SignerInformation(si, null, null, new CounterSignatureDigestCalculator(digestName, GetSignature()))); } } return(new SignerInformationStore(counterSignatures)); }