001: //The contents of this file are subject to the Mozilla Public License Version 1.1
002: //(the "License"); you may not use this file except in compliance with the
003: //License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
004: //
005: //Software distributed under the License is distributed on an "AS IS" basis,
006: //WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
007: //for the specific language governing rights and
008: //limitations under the License.
009: //
010: //The Original Code is "The Columba Project"
011: //
012: //The Initial Developers of the Original Code are Frederik Dietz and Timo Stich.
013: //Portions created by Frederik Dietz and Timo Stich are Copyright (C) 2003.
014: //
015: //All Rights Reserved.
016: package org.columba.mail.pgp;
017:
018: import java.io.ByteArrayInputStream;
019: import java.io.InputStream;
020: import java.util.Vector;
021:
022: import org.columba.core.io.CloneStreamMaster;
023: import org.columba.ristretto.composer.MimePartRenderer;
024: import org.columba.ristretto.composer.MimeTreeRenderer;
025: import org.columba.ristretto.io.SequenceInputStream;
026: import org.columba.ristretto.message.InputStreamMimePart;
027: import org.columba.ristretto.message.MimeHeader;
028: import org.columba.ristretto.message.MimePart;
029: import org.columba.ristretto.message.StreamableMimePart;
030: import org.waffel.jscf.JSCFConnection;
031: import org.waffel.jscf.JSCFResultSet;
032: import org.waffel.jscf.JSCFStatement;
033:
034: /**
035: * @author waffel
036: *
037: * This class renders a message to be a signed message. The class supports
038: * currently only pgp as method.
039: */
040: public class MultipartSignedRenderer extends MimePartRenderer {
041: private MimeHeader signatureHeader;
042:
043: /**
044: * Creates a new Instance to render a message which should be signed. This
045: * constructor initialize the header for the signature with new mime header
046: * <code>application</code> and the value <code>pgp-signature</code>
047: */
048: public MultipartSignedRenderer() {
049: this .signatureHeader = new MimeHeader("application",
050: "pgp-signature");
051: }
052:
053: /*
054: * (non-Javadoc)
055: *
056: * @see org.columba.ristretto.composer.MimePartRenderer#getRegisterString()
057: */
058: public String getRegisterString() {
059: return "multipart/signed";
060: }
061:
062: /*
063: * (non-Javadoc)
064: *
065: * @see org.columba.ristretto.composer.MimePartRenderer#render(org.columba.ristretto.message.StreamableMimePart)
066: */
067: public InputStream render(MimePart part) throws Exception {
068: Vector streams = new Vector((2 * 2) + 3);
069:
070: MimeHeader header = part.getHeader();
071:
072: // Create boundary to separate the mime-parts
073: String boundary = createUniqueBoundary().toString();
074: header.putContentParameter("boundary", boundary);
075:
076: byte[] startBoundary = ("\r\n--" + boundary + "\r\n")
077: .getBytes();
078: byte[] endBoundary = ("\r\n--" + boundary + "--\r\n")
079: .getBytes();
080:
081: // Add pgp-specific content-parameters
082: // we take as default hash-algo SHA1
083: header.putContentParameter("micalg", "pgp-sha1");
084: header.putContentParameter("protocol",
085: "application/pgp-signature");
086:
087: // Create the header and body of the multipart
088: streams.add(header.getHeader().getInputStream());
089:
090: // Add the MimePart that will be signed
091: streams.add(new ByteArrayInputStream(startBoundary));
092:
093: CloneStreamMaster signedPartCloneModel = new CloneStreamMaster(
094: MimeTreeRenderer.getInstance().renderMimePart(
095: part.getChild(0)));
096:
097: streams.add(signedPartCloneModel.getClone());
098:
099: // Add the signature
100: streams.add(new ByteArrayInputStream(startBoundary));
101:
102: StreamableMimePart signatureMimePart;
103:
104: signatureMimePart = null;
105:
106: JSCFController controller = JSCFController.getInstance();
107: JSCFConnection con = controller.getConnection();
108:
109: PGPPassChecker passCheck = PGPPassChecker.getInstance();
110: boolean check = passCheck.checkPassphrase(con);
111:
112: if (!check) {
113: throw new WrongPassphraseException("wrong passphrase");
114: }
115:
116: JSCFStatement stmt = con.createStatement();
117: JSCFResultSet res = stmt.executeSign(signedPartCloneModel
118: .getClone());
119:
120: signatureMimePart = new InputStreamMimePart(
121: this .signatureHeader, res.getResultStream());
122:
123: streams.add(MimeTreeRenderer.getInstance().renderMimePart(
124: signatureMimePart));
125:
126: // Create the closing boundary
127: streams.add(new ByteArrayInputStream(endBoundary));
128:
129: return new SequenceInputStream(streams);
130: }
131: }
|