diff options
author | David Hook <dgh@bouncycastle.org> | 2015-10-17 11:59:05 +1100 |
---|---|---|
committer | David Hook <dgh@bouncycastle.org> | 2015-10-17 11:59:05 +1100 |
commit | 8a5abb409a84e6d2ec42d0ea8a626ef054474d5c (patch) | |
tree | 60907a8cfea42ca96d43585aacadd696f129869b /crypto/src/cms/SignerInfoGenerator.cs | |
parent | Further work of signature/verification calculators. (diff) | |
download | BouncyCastle.NET-ed25519-8a5abb409a84e6d2ec42d0ea8a626ef054474d5c.tar.xz |
Initial cut of SignerInfoGenerator
Diffstat (limited to 'crypto/src/cms/SignerInfoGenerator.cs')
-rw-r--r-- | crypto/src/cms/SignerInfoGenerator.cs | 163 |
1 files changed, 158 insertions, 5 deletions
diff --git a/crypto/src/cms/SignerInfoGenerator.cs b/crypto/src/cms/SignerInfoGenerator.cs index f78cf2c01..62db40ad8 100644 --- a/crypto/src/cms/SignerInfoGenerator.cs +++ b/crypto/src/cms/SignerInfoGenerator.cs @@ -3,12 +3,165 @@ using System; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cms; using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.X509; namespace Org.BouncyCastle.Cms { - internal interface SignerInfoGenerator - { - SignerInfo Generate(DerObjectIdentifier contentType, AlgorithmIdentifier digestAlgorithm, - byte[] calculatedDigest); - } + internal interface ISignerInfoGenerator + { + SignerInfo Generate(DerObjectIdentifier contentType, AlgorithmIdentifier digestAlgorithm, + byte[] calculatedDigest); + } + + public class SignerInfoGenerator + { + internal X509Certificate certificate; + internal ISignatureCalculator contentSigner; + internal SignerIdentifier sigId; + internal CmsAttributeTableGenerator signedGen; + internal CmsAttributeTableGenerator unsignedGen; + private bool isDirectSignature; + + internal SignerInfoGenerator(SignerIdentifier sigId, ISignatureCalculator contentSigner): this(sigId, contentSigner, false) + { + + } + + internal SignerInfoGenerator(SignerIdentifier sigId, ISignatureCalculator contentSigner, bool isDirectSignature) + { + this.sigId = sigId; + this.contentSigner = contentSigner; + this.isDirectSignature = isDirectSignature; + if (this.isDirectSignature) + { + this.signedGen = null; + this.unsignedGen = null; + } + else + { + this.signedGen = new DefaultSignedAttributeTableGenerator(); + this.unsignedGen = null; + } + } + + internal SignerInfoGenerator(SignerIdentifier sigId, ISignatureCalculator contentSigner, CmsAttributeTableGenerator signedGen, CmsAttributeTableGenerator unsignedGen) + { + this.sigId = sigId; + this.contentSigner = contentSigner; + this.signedGen = signedGen; + this.unsignedGen = unsignedGen; + this.isDirectSignature = false; + } + + internal void setAssociatedCertificate(X509Certificate certificate) + { + this.certificate = certificate; + } + } + + public class SignerInfoGeneratorBuilder + { + private bool directSignature; + private CmsAttributeTableGenerator signedGen; + private CmsAttributeTableGenerator unsignedGen; + + public SignerInfoGeneratorBuilder() + { + } + + /** + * If the passed in flag is true, the signer signature will be based on the data, not + * a collection of signed attributes, and no signed attributes will be included. + * + * @return the builder object + */ + public SignerInfoGeneratorBuilder SetDirectSignature(bool hasNoSignedAttributes) + { + this.directSignature = hasNoSignedAttributes; + + return this; + } + + /** + * Provide a custom signed attribute generator. + * + * @param signedGen a generator of signed attributes. + * @return the builder object + */ + public SignerInfoGeneratorBuilder WithSignedAttributeGenerator(CmsAttributeTableGenerator signedGen) + { + this.signedGen = signedGen; + + return this; + } + + /** + * Provide a generator of unsigned attributes. + * + * @param unsignedGen a generator for signed attributes. + * @return the builder object + */ + public SignerInfoGeneratorBuilder WithUnsignedAttributeGenerator(CmsAttributeTableGenerator unsignedGen) + { + this.unsignedGen = unsignedGen; + + return this; + } + + /** + * Build a generator with the passed in certHolder issuer and serial number as the signerIdentifier. + * + * @param contentSigner operator for generating the final signature in the SignerInfo with. + * @param certHolder carrier for the X.509 certificate related to the contentSigner. + * @return a SignerInfoGenerator + * @throws OperatorCreationException if the generator cannot be built. + */ + public SignerInfoGenerator Build(ISignatureCalculator contentSigner, X509Certificate certificate) + { + SignerIdentifier sigId = new SignerIdentifier(new IssuerAndSerialNumber(certificate.IssuerDN, new DerInteger(certificate.SerialNumber))); + + SignerInfoGenerator sigInfoGen = CreateGenerator(contentSigner, sigId); + + sigInfoGen.setAssociatedCertificate(certificate); + + return sigInfoGen; + } + + /** + * Build a generator with the passed in subjectKeyIdentifier as the signerIdentifier. If used you should + * try to follow the calculation described in RFC 5280 section 4.2.1.2. + * + * @param contentSigner operator for generating the final signature in the SignerInfo with. + * @param subjectKeyIdentifier key identifier to identify the public key for verifying the signature. + * @return a SignerInfoGenerator + * @throws OperatorCreationException if the generator cannot be built. + */ + public SignerInfoGenerator Build(ISignatureCalculator contentSigner, byte[] subjectKeyIdentifier) + { + SignerIdentifier sigId = new SignerIdentifier(new DerOctetString(subjectKeyIdentifier)); + + return CreateGenerator(contentSigner, sigId); + } + + private SignerInfoGenerator CreateGenerator(ISignatureCalculator contentSigner, SignerIdentifier sigId) + { + if (directSignature) + { + return new SignerInfoGenerator(sigId, contentSigner, true); + } + + if (signedGen != null || unsignedGen != null) + { + if (signedGen == null) + { + signedGen = new DefaultSignedAttributeTableGenerator(); + } + + return new SignerInfoGenerator(sigId, contentSigner, signedGen, unsignedGen); + } + + return new SignerInfoGenerator(sigId, contentSigner); + } + } } |