]> WPIA git - gigi.git/blobdiff - src/org/cacert/gigi/crypto/SMIME.java
fix: S/MIME signature
[gigi.git] / src / org / cacert / gigi / crypto / SMIME.java
index f3ac0f766b6f00e9eff6960abdf675f592e0f9ff..de39f5a190793e267e16828f027d9cbcba86e220 100644 (file)
@@ -8,9 +8,10 @@ import java.security.GeneralSecurityException;
 import java.security.PrivateKey;
 import java.security.Signature;
 import java.security.cert.X509Certificate;
-import java.util.Base64;
 import java.util.Random;
 
+import org.cacert.gigi.util.PEM;
+
 import sun.security.pkcs.ContentInfo;
 import sun.security.pkcs.PKCS7;
 import sun.security.pkcs.SignerInfo;
@@ -44,6 +45,7 @@ public class SMIME {
     }
 
     public static void smime(String contents, PrivateKey pKey, X509Certificate c, PrintWriter to) throws IOException, GeneralSecurityException {
+        contents = normalizeNewlinesToCRLF(contents);
 
         Signature signature = Signature.getInstance("SHA1WithRSA");
         signature.initSign(pKey);
@@ -61,38 +63,42 @@ public class SMIME {
 
         // Create PKCS7 Signed data
         PKCS7 p7 = new PKCS7(new AlgorithmId[] {
-            new AlgorithmId(AlgorithmId.SHA_oid)
+                new AlgorithmId(AlgorithmId.SHA_oid)
         }, cInfo, new java.security.cert.X509Certificate[] {
-            c
+                c
         }, new SignerInfo[] {
-            sInfo
+                sInfo
         });
 
         ByteArrayOutputStream bOut = new DerOutputStream();
         p7.encodeSignedData(bOut);
 
-        mimeEncode(contents, Base64.getEncoder().encodeToString(bOut.toByteArray()).replaceAll("(.{64})(?=.)", "$1\n"), to);
+        mimeEncode(contents, PEM.formatBase64(bOut.toByteArray()), to);
+    }
+
+    private static String normalizeNewlinesToCRLF(String contents) {
+        return contents.replace("\r\n", "\r").replace("\r", "\n").replace("\n", "\r\n");
     }
 
-    static Random r = new Random();
+    private static Random r = new Random();
 
     private static void mimeEncode(String contents, String signature, PrintWriter to) {
         String boundary = generateBoundary(contents, null);
-        to.println("MIME-Version: 1.0");
-        to.println("Content-Type: multipart/signed; protocol=\"application/x-pkcs7-signature\"; micalg=\"sha1\"; boundary=\"" + boundary + "\"");
-        to.println("");
-        to.println("This is an S/MIME signed message");
-        to.println("");
-        to.println("--" + boundary);
-        to.println(contents);
-        to.println("--" + boundary);
-        to.println("Content-Type: application/x-pkcs7-signature; name=\"smime.p7s\"");
-        to.println("Content-Transfer-Encoding: base64");
-        to.println("Content-Disposition: attachment; filename=\"smime.p7s\"");
-        to.println("");
-        to.println(signature);
-        to.println();
-        to.println("--" + boundary + "--");
+        to.print("MIME-Version: 1.0\r\n");
+        to.print("Content-Type: multipart/signed; protocol=\"application/x-pkcs7-signature\"; micalg=\"sha1\"; boundary=\"" + boundary + "\"\r\n");
+        to.print("\r\n");
+        to.print("This is an S/MIME signed message\r\n");
+        to.print("\r\n");
+        to.print("--" + boundary + "\r\n");
+        to.print(contents + "\r\n");
+        to.print("--" + boundary + "\r\n");
+        to.print("Content-Type: application/x-pkcs7-signature; name=\"smime.p7s\"\r\n");
+        to.print("Content-Transfer-Encoding: base64\r\n");
+        to.print("Content-Disposition: attachment; filename=\"smime.p7s\"\r\n");
+        to.print("\r\n");
+        to.print(signature + "\r\n");
+        to.print("\r\n");
+        to.print("--" + boundary + "--\r\n");
     }
 
     private static String generateBoundary(String contents, String contents2) {