All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.siisise.security.block.DecodeStream Maven / Gradle / Ivy

/*
 * Copyright 2023 Siisise Net.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.siisise.security.block;

import java.io.IOException;
import java.io.OutputStream;
import net.siisise.security.PacketS;
import net.siisise.security.io.BlockIOListener;

/**
 *
 */
class DecodeStream implements BlockIOListener {

    private final Block block;
    private final boolean pad;
    private final PacketS pac = new PacketS();
    private final OutputStream out;
    private final int bsize;
    private byte[] buffer;

    /**
     * 
     * @param block ブロック暗号アルゴリズムとモードを組み合わせたもの
     * @param out
     * @param padding paddingを付与する?
     */
    DecodeStream(Block block, OutputStream out, boolean padding) {
        this.block = block;
        this.pad = padding;
        pac.setDirect(false);
        this.out = out;
        bsize = block.getBlockLength() / 8;
    }

    @Override
    public int getBitBlockLength() {
        return block.getBlockLength();
    }

    @Override
    public void blockWrite(byte[] src, int offset, int length) throws IOException {
        if (pad) {
            if (buffer != null) {
                pac.write(buffer);
            }
            if (length > bsize) {
                pac.write(block.decrypt(src, offset, length - bsize));
                offset += length - bsize;
                length = bsize;
            }
            buffer = block.decrypt(src, offset);
        } else {
            pac.write(block.decrypt(src, offset, length));
        }
    }

    @Override
    public void blockFlush(byte[] buf, int size) throws IOException {
        if (pad) {
            // サイズは0かmaxのはず
            if (buffer != null) {
                int len = buffer[buffer.length - 1] & 0xff;
                // ToDo: 他のパディングもチェック
                if (len == 0) {
                    len = 256;
                }
                // len = 1 ~ 256
                if (buffer.length > len) {
                    pac.write(buffer, 0, buffer.length - len);
                }
            } else {
                throw new UnsupportedOperationException();
            }
        } else { // CFB / OFB / Stream タイプ
            byte[] dec = block.decrypt(buf, 0);
            if (buffer != null) {
                pac.write(dec, 0, size);
            }
        }
    }

    @Override
    public void flush() throws IOException {
        if (pac.size() > 0) {
            out.write(pac.toByteArray());
        }
        out.flush();
    }

    @Override
    public void close() throws IOException {
        out.close();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy