diff options
Diffstat (limited to 'pkix/src/main/java/org/spongycastle/cms/SignerInfoGeneratorBuilder.java')
-rw-r--r-- | pkix/src/main/java/org/spongycastle/cms/SignerInfoGeneratorBuilder.java | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/pkix/src/main/java/org/spongycastle/cms/SignerInfoGeneratorBuilder.java b/pkix/src/main/java/org/spongycastle/cms/SignerInfoGeneratorBuilder.java new file mode 100644 index 00000000..a33005e0 --- /dev/null +++ b/pkix/src/main/java/org/spongycastle/cms/SignerInfoGeneratorBuilder.java @@ -0,0 +1,139 @@ +package org.spongycastle.cms; + +import org.spongycastle.asn1.DEROctetString; +import org.spongycastle.asn1.cms.IssuerAndSerialNumber; +import org.spongycastle.asn1.cms.SignerIdentifier; +import org.spongycastle.cert.X509CertificateHolder; +import org.spongycastle.operator.ContentSigner; +import org.spongycastle.operator.DigestCalculatorProvider; +import org.spongycastle.operator.OperatorCreationException; + +/** + * Builder for SignerInfo generator objects. + */ +public class SignerInfoGeneratorBuilder +{ + private DigestCalculatorProvider digestProvider; + private boolean directSignature; + private CMSAttributeTableGenerator signedGen; + private CMSAttributeTableGenerator unsignedGen; + private CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder; + + /** + * Base constructor. + * + * @param digestProvider a provider of digest calculators for the algorithms required in the signature and attribute calculations. + */ + public SignerInfoGeneratorBuilder(DigestCalculatorProvider digestProvider) + { + this(digestProvider, new DefaultCMSSignatureEncryptionAlgorithmFinder()); + } + + /** + * Base constructor. + * + * @param digestProvider a provider of digest calculators for the algorithms required in the signature and attribute calculations. + */ + public SignerInfoGeneratorBuilder(DigestCalculatorProvider digestProvider, CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder) + { + this.digestProvider = digestProvider; + this.sigEncAlgFinder = sigEncAlgFinder; + } + + /** + * 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(boolean 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 setSignedAttributeGenerator(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 setUnsignedAttributeGenerator(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(ContentSigner contentSigner, X509CertificateHolder certHolder) + throws OperatorCreationException + { + SignerIdentifier sigId = new SignerIdentifier(new IssuerAndSerialNumber(certHolder.toASN1Structure())); + + SignerInfoGenerator sigInfoGen = createGenerator(contentSigner, sigId); + + sigInfoGen.setAssociatedCertificate(certHolder); + + 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(ContentSigner contentSigner, byte[] subjectKeyIdentifier) + throws OperatorCreationException + { + SignerIdentifier sigId = new SignerIdentifier(new DEROctetString(subjectKeyIdentifier)); + + return createGenerator(contentSigner, sigId); + } + + private SignerInfoGenerator createGenerator(ContentSigner contentSigner, SignerIdentifier sigId) + throws OperatorCreationException + { + if (directSignature) + { + return new SignerInfoGenerator(sigId, contentSigner, digestProvider, sigEncAlgFinder, true); + } + + if (signedGen != null || unsignedGen != null) + { + if (signedGen == null) + { + signedGen = new DefaultSignedAttributeTableGenerator(); + } + + return new SignerInfoGenerator(sigId, contentSigner, digestProvider, sigEncAlgFinder, signedGen, unsignedGen); + } + + return new SignerInfoGenerator(sigId, contentSigner, digestProvider, sigEncAlgFinder); + } +} |