1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.james.jdkim.impl;
21
22 import java.io.OutputStream;
23 import java.security.MessageDigest;
24 import java.security.NoSuchAlgorithmException;
25
26 import org.apache.james.jdkim.api.BodyHasher;
27 import org.apache.james.jdkim.api.SignatureRecord;
28 import org.apache.james.jdkim.canon.DebugOutputStream;
29 import org.apache.james.jdkim.canon.DigestOutputStream;
30 import org.apache.james.jdkim.canon.LimitedOutputStream;
31 import org.apache.james.jdkim.canon.RelaxedBodyCanonicalizer;
32 import org.apache.james.jdkim.canon.SimpleBodyCanonicalizer;
33 import org.apache.james.jdkim.exceptions.PermFailException;
34
35 public class BodyHasherImpl implements BodyHasher {
36
37 private static final boolean DEEP_DEBUG = false;
38 private SignatureRecord sign;
39 private DigestOutputStream digesterOS;
40 private OutputStream out;
41
42 public BodyHasherImpl(SignatureRecord sign) throws PermFailException {
43 MessageDigest md;
44 try {
45 md = MessageDigest.getInstance(sign.getHashAlgo().toString());
46 } catch (NoSuchAlgorithmException e) {
47 throw new PermFailException("Unsupported algorythm: "
48 + sign.getHashAlgo(), e);
49 }
50
51 int limit = sign.getBodyHashLimit();
52
53
54 boolean relaxedBody = SignatureRecord.RELAXED.equals(sign
55 .getBodyCanonicalisationMethod());
56
57 if (!relaxedBody
58 && !SignatureRecord.SIMPLE.equals(sign
59 .getBodyCanonicalisationMethod())) {
60 throw new PermFailException(
61 "Unsupported body canonicalization method: "
62 + sign.getBodyCanonicalisationMethod());
63 }
64
65 DigestOutputStream dout = new DigestOutputStream(md);
66
67 OutputStream out = dout;
68 if (DEEP_DEBUG)
69 out = new DebugOutputStream(out);
70 out = prepareCanonicalizerOutputStream(limit, relaxedBody, out);
71
72 setSignatureRecord(sign);
73 setDigestOutputStream(dout);
74 setOutputStream(out);
75 }
76
77 static OutputStream prepareCanonicalizerOutputStream(int limit,
78 boolean relaxedBody, OutputStream dout) {
79 OutputStream out = dout;
80 if (limit != -1)
81 out = new LimitedOutputStream(out, limit);
82 if (relaxedBody)
83 out = new RelaxedBodyCanonicalizer(out);
84 else
85 out = new SimpleBodyCanonicalizer(out);
86 return out;
87 }
88
89
90
91
92 public OutputStream getOutputStream() {
93 return out;
94 }
95
96
97
98
99 public SignatureRecord getSignatureRecord() {
100 return sign;
101 }
102
103 private DigestOutputStream getDigesterOutputStream() {
104 return digesterOS;
105 }
106
107
108
109
110 public byte[] getDigest() {
111 return getDigesterOutputStream().getDigest();
112 }
113
114 public void setSignatureRecord(SignatureRecord sign) {
115 this.sign = sign;
116 }
117
118 public void setDigestOutputStream(DigestOutputStream dout) {
119 this.digesterOS = dout;
120 }
121
122 public void setOutputStream(OutputStream out) {
123 this.out = out;
124 }
125
126 }