1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.kuali.rice.ksb.security;
18
19 import java.io.BufferedOutputStream;
20 import java.io.ByteArrayOutputStream;
21 import java.io.IOException;
22 import java.io.OutputStream;
23 import java.security.GeneralSecurityException;
24
25 import javax.servlet.ServletOutputStream;
26
27
28
29
30
31
32
33
34
35 public class SignatureSigningOutputStream extends ServletOutputStream {
36
37 private boolean delayWrite;
38 private DigitalSigner signer;
39 private BufferedOutputStream bufferedDataHoldingStream;
40 private ByteArrayOutputStream dataHoldingStream;
41 private OutputStream wrappedOutputStream;
42
43
44
45
46
47
48
49 public SignatureSigningOutputStream(DigitalSigner signer, OutputStream wrappedOutputStream, boolean delayWrite) {
50 super();
51 this.delayWrite = delayWrite;
52 if (delayWrite) {
53 this.dataHoldingStream = new ByteArrayOutputStream();
54 this.bufferedDataHoldingStream = new BufferedOutputStream(this.dataHoldingStream);
55 }
56 this.wrappedOutputStream = wrappedOutputStream;
57 this.signer = signer;
58 }
59
60 public void write(int data) throws IOException {
61 if (this.delayWrite) {
62 this.bufferedDataHoldingStream.write(data);
63 } else {
64 this.wrappedOutputStream.write(data);
65 }
66 try {
67 this.signer.getSignature().update((byte)data);
68 } catch (GeneralSecurityException e) {
69 IOException exception = new IOException("Error updating signature.");
70 exception.initCause(e);
71 throw exception;
72 }
73 }
74
75 @Override
76 public void close() throws IOException {
77
78 try {
79 this.signer.sign();
80 if (this.delayWrite) {
81 this.bufferedDataHoldingStream.close();
82 byte[] data = this.dataHoldingStream.toByteArray();
83 for (int index = 0; index < data.length; index++) {
84 this.wrappedOutputStream.write(data[index]);
85 }
86 }
87 this.wrappedOutputStream.close();
88 } catch (Exception e) {
89 IOException exception = new IOException("Error attaching digital signature to outbound response.");
90 exception.initCause(e);
91 throw exception;
92 } finally {
93 super.close();
94 }
95 }
96
97 }