1 /*
2  * reserved comment block
3  * DO NOT REMOVE OR ALTER!
4  */
5 /**
6  * Licensed to the Apache Software Foundation (ASF) under one
7  * or more contributor license agreements. See the NOTICE file
8  * distributed with this work for additional information
9  * regarding copyright ownership. The ASF licenses this file
10  * to you under the Apache License, Version 2.0 (the
11  * "License"); you may not use this file except in compliance
12  * with the License. You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing,
17  * software distributed under the License is distributed on an
18  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19  * KIND, either express or implied. See the License for the
20  * specific language governing permissions and limitations
21  * under the License.
22  */
23 /*
24  * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
25  */
26 package org.jcp.xml.dsig.internal;
27 
28 import java.io.ByteArrayInputStream;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.OutputStream;
32 import java.security.MessageDigest;
33 
34 import com.sun.org.apache.xml.internal.security.utils.UnsyncByteArrayOutputStream;
35 
36 /**
37  * This class has been modified slightly to use java.security.MessageDigest
38  * objects as input, rather than
39  * com.sun.org.apache.xml.internal.security.algorithms.MessageDigestAlgorithm objects.
40  * It also optionally caches the input bytes.
41  *
42  */
43 public class DigesterOutputStream extends OutputStream {
44     private static final com.sun.org.slf4j.internal.Logger LOG =
45         com.sun.org.slf4j.internal.LoggerFactory.getLogger(DigesterOutputStream.class);
46 
47     private final boolean buffer;
48     private UnsyncByteArrayOutputStream bos;
49     private final MessageDigest md;
50 
51     /**
52      * Creates a DigesterOutputStream.
53      *
54      * @param md the MessageDigest
55      */
DigesterOutputStream(MessageDigest md)56     public DigesterOutputStream(MessageDigest md) {
57         this(md, false);
58     }
59 
60     /**
61      * Creates a DigesterOutputStream.
62      *
63      * @param md the MessageDigest
64      * @param buffer if true, caches the input bytes
65      */
DigesterOutputStream(MessageDigest md, boolean buffer)66     public DigesterOutputStream(MessageDigest md, boolean buffer) {
67         this.md = md;
68         this.buffer = buffer;
69         if (buffer) {
70             bos = new UnsyncByteArrayOutputStream();
71         }
72     }
73 
write(int input)74     public void write(int input) {
75         if (buffer) {
76             bos.write(input);
77         }
78         md.update((byte)input);
79     }
80 
81     @Override
write(byte[] input, int offset, int len)82     public void write(byte[] input, int offset, int len) {
83         if (buffer) {
84             bos.write(input, offset, len);
85         }
86         if (LOG.isDebugEnabled()) {
87             LOG.debug("Pre-digested input:");
88             StringBuilder sb = new StringBuilder(len);
89             for (int i = offset; i < (offset + len); i++) {
90                 sb.append((char)input[i]);
91             }
92             LOG.debug(sb.toString());
93         }
94         md.update(input, offset, len);
95     }
96 
97     /**
98      * @return the digest value
99      */
getDigestValue()100     public byte[] getDigestValue() {
101          return md.digest();
102     }
103 
104     /**
105      * @return an input stream containing the cached bytes, or
106      *    null if not cached
107      */
getInputStream()108     public InputStream getInputStream() {
109         if (buffer) {
110             return new ByteArrayInputStream(bos.toByteArray());
111         } else {
112             return null;
113         }
114     }
115 
116     @Override
close()117     public void close() throws IOException {
118         if (buffer) {
119             bos.close();
120         }
121     }
122 }
123