org.jdownloader.container.C.java Source code

Java tutorial

Introduction

Here is the source code for org.jdownloader.container.C.java

Source

//    jDownloader - Downloadmanager
//    Copyright (C) 2008  JD-Team jdownloader@freenet.de
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.

package org.jdownloader.container;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;

import jd.controlling.linkcrawler.CrawledLink;
import jd.parser.Regex;
import jd.plugins.ContainerStatus;
import jd.plugins.PluginsC;

import org.appwork.utils.StringUtils;
import org.appwork.utils.formatter.HexFormatter;
import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.engines.RijndaelEngine;
import org.bouncycastle.crypto.io.CipherInputStream;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.seamless.util.io.IO;

public class C extends PluginsC {

    public C() {
        super("CFF", "file:/.+\\.ccf$", "$Revision$");
    }

    public C newPluginInstance() {
        return new C();
    }

    private String decryptCCF5(InputStream inputStream) throws Exception {
        final String[][] CCF50 = (String[][]) getClass().forName(new String(
                HexFormatter.hexToByteArray("6F72672E6A646F776E6C6F616465722E636F6E7461696E65722E436F6E666967"),
                "UTF-8")).getMethod("CCF50").invoke(null);
        final KeyParameter keyParam1 = new KeyParameter(HexFormatter.hexToByteArray(CCF50[0][0]));
        final CipherParameters cipherParams1 = new ParametersWithIV(keyParam1,
                HexFormatter.hexToByteArray(CCF50[0][1]));
        final BufferedBlockCipher cipher1 = new BufferedBlockCipher(new CBCBlockCipher(new RijndaelEngine()));
        cipher1.reset();
        cipher1.init(false, cipherParams1);

        final KeyParameter keyParam11 = new KeyParameter(HexFormatter.hexToByteArray(CCF50[0][0]));
        final CipherParameters cipherParams11 = new ParametersWithIV(keyParam11,
                HexFormatter.hexToByteArray(CCF50[0][1]));
        final BufferedBlockCipher cipher11 = new BufferedBlockCipher(new CBCBlockCipher(new RijndaelEngine()));
        cipher11.reset();
        cipher11.init(false, cipherParams11);

        final KeyParameter keyParam2 = new KeyParameter(HexFormatter.hexToByteArray(CCF50[1][0]));
        final CipherParameters cipherParams2 = new ParametersWithIV(keyParam2,
                HexFormatter.hexToByteArray(CCF50[1][1]));
        final BufferedBlockCipher cipher2 = new BufferedBlockCipher(new CBCBlockCipher(new RijndaelEngine()));
        cipher2.reset();
        cipher2.init(false, cipherParams2);

        final InputStream is = new CipherInputStream(
                new CipherInputStream(new CipherInputStream(inputStream, cipher11), cipher2), cipher1);
        String d = new String(IO.readBytes(is), "UTF-8");
        return d;
    }

    private String decryptCCF07_10(InputStream inputStream, String key, String iv) throws Exception {
        final KeyParameter keyParam1 = new KeyParameter(HexFormatter.hexToByteArray(key));
        final CipherParameters cipherParams1 = new ParametersWithIV(keyParam1, HexFormatter.hexToByteArray(iv));
        final BufferedBlockCipher cipher1 = new BufferedBlockCipher(new CBCBlockCipher(new RijndaelEngine()));
        cipher1.reset();
        cipher1.init(false, cipherParams1);

        final InputStream is = new CipherInputStream(inputStream, cipher1);
        String d = new String(IO.readBytes(is), "UTF-8");
        return d;
    }

    private static byte[] byteBox(final byte[] buf) {
        final byte[] ret = new byte[64];
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                ret[i * 8 + j] = buf[j * 8 + i];
            }
        }
        return ret;
    }

    private static byte[] bitBox(final byte[] buf) {
        final byte[] mask = new byte[] { 1, 2, 4, 8, 16, 32, 64, (byte) 128 };
        final byte[] ret = new byte[8];
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if ((buf[i] & mask[j]) != 0) {
                    ret[j] |= mask[i];
                }
            }
        }
        return ret;
    }

    private static long rotateLeft(long l, long steps) {
        if (steps <= 0) {
            return l;
        }
        String bits = Long.toBinaryString(l);
        if (bits.length() < 32) {
            bits = String.format("%32s", bits).replace(' ', '0');
        }
        bits = bits.substring((int) steps) + (bits.substring(0, (int) steps));
        return Long.parseLong(bits, 2);
    }

    private static long rotateRight(long l, long steps) {
        if (steps <= 0) {
            return l;
        }
        String bits = Long.toBinaryString(l);
        if (bits.length() < 32) {
            bits = String.format("%32s", bits).replace(' ', '0');
        }
        bits = bits.substring(bits.length() - (int) steps) + (bits.substring(0, bits.length() - (int) steps));
        return Long.parseLong(bits, 2);
    }

    private String decryptCCF30(byte[] ccfBytes) throws Exception {
        final byte[] magic = new byte[8];
        System.arraycopy(ccfBytes, 6, magic, 0, 4);
        long key = ByteBuffer.wrap(magic).order(ByteOrder.LITTLE_ENDIAN).getLong();
        final int padding = 64 - ccfBytes[10];
        final byte[] result = new byte[ccfBytes.length - 11];
        byte[] buf = new byte[64];
        int resultIndex = 0;
        int ccfIndex = 11;
        while (ccfIndex < ccfBytes.length) {
            System.arraycopy(ccfBytes, ccfIndex, buf, 0, 64);
            ccfIndex += 64;
            for (int index = 0; index < 64; index++) {
                if ((key & 1) != 0) {
                    key = rotateRight(key, (key & 0xFF) % 12);
                } else {
                    key = rotateLeft(key, (key & 0xFF) % 9);
                }
                buf[index] ^= key & 0xFF;
                buf = byteBox(buf);
            }
            for (int n = 0; n < 8; n++) {
                byte[] tmp = new byte[8];
                System.arraycopy(buf, 8 * n, tmp, 0, 8);
                for (int m = 0; m < 8; m++) {
                    tmp[m] ^= (key & 0xFF);
                    tmp = bitBox(tmp);
                    if ((key & 1) != 0) {
                        key = rotateRight(key, key & 12);
                    } else {
                        key = rotateLeft(key, key & 9);
                    }
                }
                System.arraycopy(tmp, 0, buf, n * 8, 8);
            }
            System.arraycopy(buf, 0, result, resultIndex, 64);
            resultIndex += 64;
        }
        final int len = result.length - padding;
        return new String(result, 0, len, "UTF-8");
    }

    public ContainerStatus callDecryption(File ccfFile) throws Exception {
        final ContainerStatus cs = new ContainerStatus(ccfFile);
        if (ccfFile.exists()) {
            String ccfContent = null;
            final byte[] ccfBytes = IO.readBytes(ccfFile);
            if (ccfBytes[0] == 'C' && ccfBytes[1] == 'C' && ccfBytes[2] == 'F' && ccfBytes[3] == '3'
                    && ccfBytes[4] == '.' && ccfBytes[5] == '0') {
                /**
                 * CCF3.0
                 */
                final String check = decryptCCF30(ccfBytes);
                if (StringUtils.contains(check, "CryptLoad")) {
                    ccfContent = check;
                }
            } else {
                final ByteArrayInputStream is = new ByteArrayInputStream(ccfBytes);
                is.reset();
                for (String ccf[] : (String[][]) getClass()
                        .forName(new String(
                                HexFormatter.hexToByteArray(
                                        "6F72672E6A646F776E6C6F616465722E636F6E7461696E65722E436F6E666967"),
                                "UTF-8"))
                        .getMethod("CCF0710").invoke(null)) {
                    /**
                     * CCF0.7-CCF1.0
                     */

                    is.reset();
                    final String check = decryptCCF07_10(is, ccf[0], ccf[1]);
                    if (StringUtils.contains(check, "CryptLoad")) {
                        ccfContent = check;
                        break;
                    }
                }
                if (ccfContent == null) {
                    /**
                     * CCF5.0
                     */
                    is.reset();
                    final String check = decryptCCF5(is);
                    if (StringUtils.contains(check, "CryptLoad")) {
                        ccfContent = check;
                    }
                }
            }
            if (ccfContent != null) {
                final String urls[] = new Regex(ccfContent, "<url>(.*?)</url>").getColumn(0);
                cls = new ArrayList<CrawledLink>();
                for (String url : urls) {
                    if (!StringUtils.isEmpty(url)) {
                        cls.add(new CrawledLink(url));
                    }
                }
                if (cls.size() > 0) {
                    cs.setStatus(ContainerStatus.STATUS_FINISHED);
                    return cs;
                }
            }
        }
        cs.setStatus(ContainerStatus.STATUS_FAILED);
        return cs;

    }

    public String[] encrypt(String plain) {
        return null;
    }

}