aboutsummaryrefslogtreecommitdiffstats
path: root/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEUtil.java
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEUtil.java')
-rw-r--r--libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEUtil.java623
1 files changed, 0 insertions, 623 deletions
diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEUtil.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEUtil.java
deleted file mode 100644
index b2f36e6f0..000000000
--- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEUtil.java
+++ /dev/null
@@ -1,623 +0,0 @@
-package org.bouncycastle.mail.smime;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FilterOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.NoSuchProviderException;
-import java.security.Provider;
-import java.security.Security;
-import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.util.Enumeration;
-
-import javax.mail.BodyPart;
-import javax.mail.MessagingException;
-import javax.mail.internet.ContentType;
-import javax.mail.internet.MimeBodyPart;
-import javax.mail.internet.MimeMultipart;
-
-import org.bouncycastle.asn1.cms.IssuerAndSerialNumber;
-import org.bouncycastle.cms.CMSTypedStream;
-import org.bouncycastle.jce.PrincipalUtil;
-import org.bouncycastle.mail.smime.util.CRLFOutputStream;
-import org.bouncycastle.mail.smime.util.FileBackedMimeBodyPart;
-
-public class SMIMEUtil
-{
- private static final int BUF_SIZE = 32760;
-
- static boolean isCanonicalisationRequired(
- MimeBodyPart bodyPart,
- String defaultContentTransferEncoding)
- throws MessagingException
- {
- String[] cte = bodyPart.getHeader("Content-Transfer-Encoding");
- String contentTransferEncoding;
-
- if (cte == null)
- {
- contentTransferEncoding = defaultContentTransferEncoding;
- }
- else
- {
- contentTransferEncoding = cte[0];
- }
-
- return !contentTransferEncoding.equalsIgnoreCase("binary");
- }
-
- public static Provider getProvider(String providerName)
- throws NoSuchProviderException
- {
- if (providerName != null)
- {
- Provider prov = Security.getProvider(providerName);
-
- if (prov != null)
- {
- return prov;
- }
-
- throw new NoSuchProviderException("provider " + providerName + " not found.");
- }
-
- return null;
- }
-
- static class LineOutputStream extends FilterOutputStream
- {
- private static byte newline[];
-
- public LineOutputStream(OutputStream outputstream)
- {
- super(outputstream);
- }
-
- public void writeln(String s)
- throws MessagingException
- {
- try
- {
- byte abyte0[] = getBytes(s);
- super.out.write(abyte0);
- super.out.write(newline);
- }
- catch(Exception exception)
- {
- throw new MessagingException("IOException", exception);
- }
- }
-
- public void writeln()
- throws MessagingException
- {
- try
- {
- super.out.write(newline);
- }
- catch(Exception exception)
- {
- throw new MessagingException("IOException", exception);
- }
- }
-
- static
- {
- newline = new byte[2];
- newline[0] = 13;
- newline[1] = 10;
- }
-
- private static byte[] getBytes(String s)
- {
- char ac[] = s.toCharArray();
- int i = ac.length;
- byte abyte0[] = new byte[i];
- int j = 0;
-
- while (j < i)
- {
- abyte0[j] = (byte)ac[j++];
- }
-
- return abyte0;
- }
- }
-
- /**
- * internal preamble is generally included in signatures, while this is technically wrong,
- * if we find internal preamble we include it by default.
- */
- static void outputPreamble(LineOutputStream lOut, MimeBodyPart part, String boundary)
- throws MessagingException, IOException
- {
- InputStream in;
-
- try
- {
- in = part.getRawInputStream();
- }
- catch (MessagingException e)
- {
- return; // no underlying content rely on default generation
- }
-
- String line;
-
- while ((line = readLine(in)) != null)
- {
- if (line.equals(boundary))
- {
- break;
- }
-
- lOut.writeln(line);
- }
-
- in.close();
-
- if (line == null)
- {
- throw new MessagingException("no boundary found");
- }
- }
-
- /**
- * internal postamble is generally included in signatures, while this is technically wrong,
- * if we find internal postamble we include it by default.
- */
- static void outputPostamble(LineOutputStream lOut, MimeBodyPart part, int count, String boundary)
- throws MessagingException, IOException
- {
- InputStream in;
-
- try
- {
- in = part.getRawInputStream();
- }
- catch (MessagingException e)
- {
- return; // no underlying content rely on default generation
- }
-
- String line;
- int boundaries = count + 1;
-
- while ((line = readLine(in)) != null)
- {
- if (line.startsWith(boundary))
- {
- boundaries--;
-
- if (boundaries == 0)
- {
- break;
- }
- }
- }
-
- while ((line = readLine(in)) != null)
- {
- lOut.writeln(line);
- }
-
- in.close();
-
- if (boundaries != 0)
- {
- throw new MessagingException("all boundaries not found for: " + boundary);
- }
- }
-
- static void outputPostamble(LineOutputStream lOut, BodyPart parent, String parentBoundary, BodyPart part)
- throws MessagingException, IOException
- {
- InputStream in;
-
- try
- {
- in = ((MimeBodyPart)parent).getRawInputStream();
- }
- catch (MessagingException e)
- {
- return; // no underlying content rely on default generation
- }
-
-
- MimeMultipart multipart = (MimeMultipart)part.getContent();
- ContentType contentType = new ContentType(multipart.getContentType());
- String boundary = "--" + contentType.getParameter("boundary");
- int count = multipart.getCount() + 1;
- String line;
- while (count != 0 && (line = readLine(in)) != null)
- {
- if (line.startsWith(boundary))
- {
- count--;
- }
- }
-
- while ((line = readLine(in)) != null)
- {
- if (line.startsWith(parentBoundary))
- {
- break;
- }
- lOut.writeln(line);
- }
-
- in.close();
- }
-
- /*
- * read a line of input stripping of the tailing \r\n
- */
- private static String readLine(InputStream in)
- throws IOException
- {
- StringBuffer b = new StringBuffer();
-
- int ch;
- while ((ch = in.read()) >= 0 && ch != '\n')
- {
- if (ch != '\r')
- {
- b.append((char)ch);
- }
- }
-
- if (ch < 0 && b.length() == 0)
- {
- return null;
- }
-
- return b.toString();
- }
-
- static void outputBodyPart(
- OutputStream out,
- BodyPart bodyPart,
- String defaultContentTransferEncoding)
- throws MessagingException, IOException
- {
- if (bodyPart instanceof MimeBodyPart)
- {
- MimeBodyPart mimePart = (MimeBodyPart)bodyPart;
- String[] cte = mimePart.getHeader("Content-Transfer-Encoding");
- String contentTransferEncoding;
-
- if (mimePart.getContent() instanceof MimeMultipart)
- {
- MimeMultipart mp = (MimeMultipart)bodyPart.getContent();
- ContentType contentType = new ContentType(mp.getContentType());
- String boundary = "--" + contentType.getParameter("boundary");
-
- SMIMEUtil.LineOutputStream lOut = new SMIMEUtil.LineOutputStream(out);
-
- Enumeration headers = mimePart.getAllHeaderLines();
- while (headers.hasMoreElements())
- {
- String header = (String)headers.nextElement();
- lOut.writeln(header);
- }
-
- lOut.writeln(); // CRLF separator
-
- outputPreamble(lOut, mimePart, boundary);
-
- for (int i = 0; i < mp.getCount(); i++)
- {
- lOut.writeln(boundary);
- BodyPart part = mp.getBodyPart(i);
- outputBodyPart(out, part, defaultContentTransferEncoding);
- if (!(part.getContent() instanceof MimeMultipart))
- {
- lOut.writeln(); // CRLF terminator needed
- }
- else
- {
- outputPostamble(lOut, mimePart, boundary, part);
- }
- }
-
- lOut.writeln(boundary + "--");
-
- outputPostamble(lOut, mimePart, mp.getCount(), boundary);
-
- return;
- }
-
- if (cte == null)
- {
- contentTransferEncoding = defaultContentTransferEncoding;
- }
- else
- {
- contentTransferEncoding = cte[0];
- }
-
- if (!contentTransferEncoding.equalsIgnoreCase("base64")
- && !contentTransferEncoding.equalsIgnoreCase("quoted-printable"))
- {
- if (!contentTransferEncoding.equalsIgnoreCase("binary"))
- {
- out = new CRLFOutputStream(out);
- }
- bodyPart.writeTo(out);
- out.flush();
- return;
- }
-
- boolean base64 = contentTransferEncoding.equalsIgnoreCase("base64");
-
- //
- // Write raw content, performing canonicalization
- //
- InputStream inRaw;
-
- try
- {
- inRaw = mimePart.getRawInputStream();
- }
- catch (MessagingException e)
- {
- // this is less than ideal, but if the raw output stream is unavailable it's the
- // best option we've got.
- out = new CRLFOutputStream(out);
- bodyPart.writeTo(out);
- out.flush();
- return;
- }
-
- //
- // Write headers
- //
- LineOutputStream outLine = new LineOutputStream(out);
- for (Enumeration e = mimePart.getAllHeaderLines(); e.hasMoreElements();)
- {
- String header = (String)e.nextElement();
-
- outLine.writeln(header);
- }
-
- outLine.writeln();
- outLine.flush();
-
-
- OutputStream outCRLF;
-
- if (base64)
- {
- outCRLF = new Base64CRLFOutputStream(out);
- }
- else
- {
- outCRLF = new CRLFOutputStream(out);
- }
-
- byte[] buf = new byte[BUF_SIZE];
-
- int len;
- while ((len = inRaw.read(buf, 0, buf.length)) > 0)
- {
-
- outCRLF.write(buf, 0, len);
- }
-
- outCRLF.flush();
- }
- else
- {
- if (!defaultContentTransferEncoding.equalsIgnoreCase("binary"))
- {
- out = new CRLFOutputStream(out);
- }
-
- bodyPart.writeTo(out);
-
- out.flush();
- }
- }
-
- /**
- * return the MimeBodyPart described in the raw bytes provided in content
- */
- public static MimeBodyPart toMimeBodyPart(
- byte[] content)
- throws SMIMEException
- {
- return toMimeBodyPart(new ByteArrayInputStream(content));
- }
-
- /**
- * return the MimeBodyPart described in the input stream content
- */
- public static MimeBodyPart toMimeBodyPart(
- InputStream content)
- throws SMIMEException
- {
- try
- {
- return new MimeBodyPart(content);
- }
- catch (MessagingException e)
- {
- throw new SMIMEException("exception creating body part.", e);
- }
- }
-
- static FileBackedMimeBodyPart toWriteOnceBodyPart(
- CMSTypedStream content)
- throws SMIMEException
- {
- try
- {
- return new WriteOnceFileBackedMimeBodyPart(content.getContentStream(), File.createTempFile("bcMail", ".mime"));
- }
- catch (IOException e)
- {
- throw new SMIMEException("IOException creating tmp file:" + e.getMessage(), e);
- }
- catch (MessagingException e)
- {
- throw new SMIMEException("can't create part: " + e, e);
- }
- }
-
- /**
- * return a file backed MimeBodyPart described in {@link CMSTypedStream} content.
- * </p>
- */
- public static FileBackedMimeBodyPart toMimeBodyPart(
- CMSTypedStream content)
- throws SMIMEException
- {
- try
- {
- return toMimeBodyPart(content, File.createTempFile("bcMail", ".mime"));
- }
- catch (IOException e)
- {
- throw new SMIMEException("IOException creating tmp file:" + e.getMessage(), e);
- }
- }
-
- /**
- * Return a file based MimeBodyPart represented by content and backed
- * by the file represented by file.
- *
- * @param content content stream containing body part.
- * @param file file to store the decoded body part in.
- * @return the decoded body part.
- * @throws SMIMEException
- */
- public static FileBackedMimeBodyPart toMimeBodyPart(
- CMSTypedStream content,
- File file)
- throws SMIMEException
- {
- try
- {
- return new FileBackedMimeBodyPart(content.getContentStream(), file);
- }
- catch (IOException e)
- {
- throw new SMIMEException("can't save content to file: " + e, e);
- }
- catch (MessagingException e)
- {
- throw new SMIMEException("can't create part: " + e, e);
- }
- }
-
- /**
- * Return a CMS IssuerAndSerialNumber structure for the passed in X.509 certificate.
- *
- * @param cert the X.509 certificate to get the issuer and serial number for.
- * @return an IssuerAndSerialNumber structure representing the certificate.
- */
- public static IssuerAndSerialNumber createIssuerAndSerialNumberFor(
- X509Certificate cert)
- throws CertificateParsingException
- {
- try
- {
- return new IssuerAndSerialNumber(PrincipalUtil.getIssuerX509Principal(cert), cert.getSerialNumber());
- }
- catch (Exception e)
- {
- throw new CertificateParsingException("exception extracting issuer and serial number: " + e);
- }
- }
-
- private static class WriteOnceFileBackedMimeBodyPart
- extends FileBackedMimeBodyPart
- {
- public WriteOnceFileBackedMimeBodyPart(InputStream content, File file)
- throws MessagingException, IOException
- {
- super(content, file);
- }
-
- public void writeTo(OutputStream out)
- throws MessagingException, IOException
- {
- super.writeTo(out);
-
- this.dispose();
- }
- }
-
- static class Base64CRLFOutputStream extends FilterOutputStream
- {
- protected int lastb;
- protected static byte newline[];
- private boolean isCrlfStream;
-
- public Base64CRLFOutputStream(OutputStream outputstream)
- {
- super(outputstream);
- lastb = -1;
- }
-
- public void write(int i)
- throws IOException
- {
- if (i == '\r')
- {
- out.write(newline);
- }
- else if (i == '\n')
- {
- if (lastb != '\r')
- { // imagine my joy...
- if (!(isCrlfStream && lastb == '\n'))
- {
- out.write(newline);
- }
- }
- else
- {
- isCrlfStream = true;
- }
- }
- else
- {
- out.write(i);
- }
-
- lastb = i;
- }
-
- public void write(byte[] buf)
- throws IOException
- {
- this.write(buf, 0, buf.length);
- }
-
- public void write(byte buf[], int off, int len)
- throws IOException
- {
- for (int i = off; i != off + len; i++)
- {
- this.write(buf[i]);
- }
- }
-
- public void writeln()
- throws IOException
- {
- super.out.write(newline);
- }
-
- static
- {
- newline = new byte[2];
- newline[0] = '\r';
- newline[1] = '\n';
- }
- }
-}