org.bouncycastle.mime.smime.SMimeMultipartContext Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bcpkix-jdk15to18 Show documentation
Show all versions of bcpkix-jdk15to18 Show documentation
The Bouncy Castle Java APIs for CMS, PKCS, EAC, TSP, CMP, CRMF, OCSP, and certificate generation. This jar contains APIs for JDK 1.5 to JDK 1.8. The APIs can be used in conjunction with a JCE/JCA provider such as the one provided with the Bouncy Castle Cryptography APIs.
package org.bouncycastle.mime.smime;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.mime.CanonicalOutputStream;
import org.bouncycastle.mime.Headers;
import org.bouncycastle.mime.MimeContext;
import org.bouncycastle.mime.MimeMultipartContext;
import org.bouncycastle.mime.MimeParserContext;
import org.bouncycastle.operator.DigestCalculator;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.util.io.TeeInputStream;
import org.bouncycastle.util.io.TeeOutputStream;
public class SMimeMultipartContext
implements MimeMultipartContext
{
private final SMimeParserContext parserContext;
private DigestCalculator[] calculators;
public SMimeMultipartContext(MimeParserContext parserContext, Headers headers)
{
this.parserContext = (SMimeParserContext)parserContext;
this.calculators = createDigestCalculators(headers);
}
DigestCalculator[] getDigestCalculators()
{
return calculators;
}
OutputStream getDigestOutputStream()
{
if (calculators.length == 1)
{
return calculators[0].getOutputStream();
}
else
{
OutputStream compoundStream = calculators[0].getOutputStream();
for (int i = 1; i < calculators.length; i++)
{
compoundStream = new TeeOutputStream(calculators[i].getOutputStream(), compoundStream);
}
return compoundStream;
}
}
private DigestCalculator[] createDigestCalculators(Headers headers)
{
try
{
Map contentTypeFields = headers.getContentTypeAttributes();
String micalgs = (String)contentTypeFields.get("micalg");
if (micalgs == null)
{
throw new IllegalStateException("No micalg field on content-type header");
}
String[] algs = micalgs.substring(micalgs.indexOf('=') + 1).split(",");
DigestCalculator[] dcOut = new DigestCalculator[algs.length];
for (int t = 0; t < algs.length; t++)
{
// Deal with possibility of quoted parts, eg "SHA1","SHA256" etc
String alg = SMimeUtils.lessQuotes(algs[t]).trim();
dcOut[t] = parserContext.getDigestCalculatorProvider().get(
new AlgorithmIdentifier(SMimeUtils.getDigestOID(alg)));
}
return dcOut;
}
catch (OperatorCreationException e)
{
return null;
}
}
public MimeContext createContext(final int partNo)
throws IOException
{
return new MimeContext()
{
public InputStream applyContext(Headers headers, InputStream contentStream)
throws IOException
{
if (partNo == 0)
{
OutputStream digestOut = getDigestOutputStream();
headers.dumpHeaders(digestOut);
digestOut.write('\r');
digestOut.write('\n');
return new TeeInputStream(contentStream, new CanonicalOutputStream(parserContext, headers, digestOut));
}
return contentStream;
}
};
}
public InputStream applyContext(Headers headers, InputStream contentStream)
throws IOException
{
return contentStream;
}
}