From 12784931c8ae440fec10dfd6ea97e7b16ba64988 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Sun, 28 Apr 2019 18:11:30 +0200 Subject: [PATCH] bugfixes --- src/be/nikiroo/utils/Base64.java | 13 +- src/be/nikiroo/utils/CryptUtils.java | 120 ++++++++++++++++-- .../utils/streams/BufferedOutputStream.java | 7 +- .../utils/streams/NextableInputStream.java | 16 ++- .../utils/streams/ReplaceOutputStream.java | 2 +- 5 files changed, 139 insertions(+), 19 deletions(-) diff --git a/src/be/nikiroo/utils/Base64.java b/src/be/nikiroo/utils/Base64.java index 4761601..784fc92 100644 --- a/src/be/nikiroo/utils/Base64.java +++ b/src/be/nikiroo/utils/Base64.java @@ -1,5 +1,7 @@ package be.nikiroo.utils; +import java.io.IOException; + /** *

Encodes and decodes to and from Base64 notation.

*

Homepage: http://iharder.net/base64.

@@ -2029,7 +2031,9 @@ class Base64 @Override public void close() throws java.io.IOException { // 1. Ensure that pending characters are written - flushBase64(); + + // niki: removed since it is now in flush() + //flushBase64(); // 2. Actually close the stream // Base class both flushes and closes. @@ -2066,7 +2070,12 @@ class Base64 this.suspendEncoding = false; } // end resumeEncoding - + @Override + // added by niki + public void flush() throws IOException { + flushBase64(); + super.flush(); + } } // end inner class OutputStream diff --git a/src/be/nikiroo/utils/CryptUtils.java b/src/be/nikiroo/utils/CryptUtils.java index ed6f9e0..74b85c2 100644 --- a/src/be/nikiroo/utils/CryptUtils.java +++ b/src/be/nikiroo/utils/CryptUtils.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; +import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; @@ -14,6 +15,7 @@ import javax.crypto.CipherOutputStream; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import javax.net.ssl.SSLException; @@ -31,14 +33,15 @@ import javax.net.ssl.SSLException; * @author niki */ public class CryptUtils { - static private final String AES_NAME = "AES/ECB/PKCS5Padding"; - + static private final String AES_NAME = "AES/CFB8/NoPadding"; + private Cipher ecipher; private Cipher dcipher; private SecretKey key; /** - * Small and lazy-easy way to initialize a 128 bits key with {@link CryptUtils}. + * Small and lazy-easy way to initialize a 128 bits key with + * {@link CryptUtils}. *

* Some part of the key will be used to generate a 128 bits key and * initialize the {@link CryptUtils}; even NULL will generate something. @@ -81,50 +84,136 @@ public class CryptUtils { * the {@link InputStream} to wrap * @return the auto-encode {@link InputStream} */ - public InputStream encryptInputStream(InputStream in) { + public InputStream encrypt(InputStream in) { Cipher ecipher = newCipher(Cipher.ENCRYPT_MODE); return new CipherInputStream(in, ecipher); } + /** + * Wrap the given {@link InputStream} so it is transparently encrypted by + * the current {@link CryptUtils} and encoded in base64. + * + * @param in + * the {@link InputStream} to wrap + * @param zip + * TRUE to also uncompress the data from a GZIP format; take care + * about this flag, as it could easily cause errors in the + * returned content or an {@link IOException} + * + * @return the auto-encode {@link InputStream} + * + * @throws IOException + * in case of I/O error + */ + public InputStream encrypt64(InputStream in, boolean zip) + throws IOException { + return StringUtils.base64(encrypt(in), zip, false); + } + /** * Wrap the given {@link OutputStream} so it is transparently encrypted by * the current {@link CryptUtils}. * - * @param in + * @param out * the {@link OutputStream} to wrap + * * @return the auto-encode {@link OutputStream} */ - public OutputStream encryptOutpuStream(OutputStream out) { + public OutputStream encrypt(OutputStream out) { Cipher ecipher = newCipher(Cipher.ENCRYPT_MODE); return new CipherOutputStream(out, ecipher); } /** - * Wrap the given {@link OutStream} so it is transparently decoded by the + * Wrap the given {@link OutputStream} so it is transparently encrypted by + * the current {@link CryptUtils} and encoded in base64. + * + * @param out + * the {@link OutputStream} to wrap + * @param zip + * TRUE to also uncompress the data from a GZIP format; take care + * about this flag, as it could easily cause errors in the + * returned content or an {@link IOException} + * + * @return the auto-encode {@link OutputStream} + * + * @throws IOException + * in case of I/O error + */ + public OutputStream encrypt64(OutputStream out, boolean zip) + throws IOException { + return encrypt(StringUtils.base64(out, zip, false)); + } + + /** + * Wrap the given {@link OutputStream} so it is transparently decoded by the * current {@link CryptUtils}. * * @param in * the {@link InputStream} to wrap + * * @return the auto-decode {@link InputStream} */ - public InputStream decryptInputStream(InputStream in) { + public InputStream decrypt(InputStream in) { Cipher dcipher = newCipher(Cipher.DECRYPT_MODE); return new CipherInputStream(in, dcipher); } /** - * Wrap the given {@link OutStream} so it is transparently decoded by the + * Wrap the given {@link OutputStream} so it is transparently decoded by the + * current {@link CryptUtils} and decoded from base64. + * + * @param in + * the {@link InputStream} to wrap + * @param zip + * TRUE to also uncompress the data from a GZIP format; take care + * about this flag, as it could easily cause errors in the + * returned content or an {@link IOException} + * + * @return the auto-decode {@link InputStream} + * + * @throws IOException + * in case of I/O error + */ + public InputStream decrypt64(InputStream in, boolean zip) + throws IOException { + return decrypt(StringUtils.unbase64(in, zip)); + } + + /** + * Wrap the given {@link OutputStream} so it is transparently decoded by the * current {@link CryptUtils}. * * @param out * the {@link OutputStream} to wrap * @return the auto-decode {@link OutputStream} */ - public OutputStream decryptOutputStream(OutputStream out) { + public OutputStream decrypt(OutputStream out) { Cipher dcipher = newCipher(Cipher.DECRYPT_MODE); return new CipherOutputStream(out, dcipher); } + /** + * Wrap the given {@link OutputStream} so it is transparently decoded by the + * current {@link CryptUtils} and decoded from base64. + * + * @param out + * the {@link OutputStream} to wrap + * @param zip + * TRUE to also uncompress the data from a GZIP format; take care + * about this flag, as it could easily cause errors in the + * returned content or an {@link IOException} + * + * @return the auto-decode {@link OutputStream} + * + * @throws IOException + * in case of I/O error + */ + public OutputStream decrypt64(OutputStream out, boolean zip) + throws IOException { + return StringUtils.unbase64(decrypt(out), zip); + } + /** * This method required an array of 128 bytes. * @@ -146,7 +235,7 @@ public class CryptUtils { ecipher = newCipher(Cipher.ENCRYPT_MODE); dcipher = newCipher(Cipher.DECRYPT_MODE); } - + /** * Create a new {@link Cipher}of the given mode (see * {@link Cipher#ENCRYPT_MODE} and {@link Cipher#ENCRYPT_MODE}). @@ -159,8 +248,10 @@ public class CryptUtils { */ private Cipher newCipher(int mode) { try { + byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + IvParameterSpec ivspec = new IvParameterSpec(iv); Cipher cipher = Cipher.getInstance(AES_NAME); - cipher.init(mode, key); + cipher.init(mode, key, ivspec); return cipher; } catch (NoSuchAlgorithmException e) { // Every implementation of the Java platform is required to support @@ -174,8 +265,11 @@ public class CryptUtils { // Every implementation of the Java platform is required to support // this standard Cipher transformation with 128 bits keys e.printStackTrace(); + } catch (InvalidAlgorithmParameterException e) { + // Woops? + e.printStackTrace(); } - + return null; } diff --git a/src/be/nikiroo/utils/streams/BufferedOutputStream.java b/src/be/nikiroo/utils/streams/BufferedOutputStream.java index 2071d0c..1442534 100644 --- a/src/be/nikiroo/utils/streams/BufferedOutputStream.java +++ b/src/be/nikiroo/utils/streams/BufferedOutputStream.java @@ -177,13 +177,18 @@ public class BufferedOutputStream extends OutputStream { *

* If {@link BufferedOutputStream#bypassFlush} is false, all writes to the * under-laying stream are done in this method. + *

+ * This can be used if you want to write some data in the under-laying + * stream yourself (in that case, flush this {@link BufferedOutputStream} + * with or without flushing the under-laying stream, then you can write to + * the under-laying stream). * * @param includingSubStream * also flush the under-laying stream * @throws IOException * in case of I/O error */ - protected void flush(boolean includingSubStream) throws IOException { + public void flush(boolean includingSubStream) throws IOException { if (stop > start) { out.write(buffer, start, stop - start); bytesWritten += (stop - start); diff --git a/src/be/nikiroo/utils/streams/NextableInputStream.java b/src/be/nikiroo/utils/streams/NextableInputStream.java index b8c3fe8..62156e3 100644 --- a/src/be/nikiroo/utils/streams/NextableInputStream.java +++ b/src/be/nikiroo/utils/streams/NextableInputStream.java @@ -2,6 +2,8 @@ package be.nikiroo.utils.streams; import java.io.IOException; import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.util.Arrays; /** * This {@link InputStream} can be separated into sub-streams (you can process @@ -245,10 +247,20 @@ public class NextableInputStream extends BufferedInputStream { } public String DEBUG() { + String data = ""; + if (stop > 0) { + try { + data = new String(Arrays.copyOfRange(buffer, 0, stop), "UTF-8"); + } catch (UnsupportedEncodingException e) { + } + if (data.length() > 50) { + data = data.substring(0, 47) + "..."; + } + } String rep = String.format( - "Nextable %s: %d -> %d [eof: %s] [more data: %s]", + "Nextable %s: %d -> %d [eof: %s] [more data: %s]: %s", (stopped ? "stopped" : "running"), start, stop, "" + eof, "" - + hasMoreData()); + + hasMoreData(), data); return rep; } diff --git a/src/be/nikiroo/utils/streams/ReplaceOutputStream.java b/src/be/nikiroo/utils/streams/ReplaceOutputStream.java index dcb0207..ff871eb 100644 --- a/src/be/nikiroo/utils/streams/ReplaceOutputStream.java +++ b/src/be/nikiroo/utils/streams/ReplaceOutputStream.java @@ -89,7 +89,7 @@ public class ReplaceOutputStream extends BufferedOutputStream { } @Override - protected void flush(boolean includingSubStream) throws IOException { + public void flush(boolean includingSubStream) throws IOException { // Note: very simple, not efficient implementation, sorry. while (start < stop) { boolean replaced = false; -- 2.27.0