| 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<String, String> 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; |
| } |
| } |