diff --git a/app/src/androidTest/java/com/keepassdroid/tests/database/SprEngineTest.java b/app/src/androidTest/java/com/keepassdroid/tests/database/SprEngineTest.java index 7e166c45c..2434d2da1 100644 --- a/app/src/androidTest/java/com/keepassdroid/tests/database/SprEngineTest.java +++ b/app/src/androidTest/java/com/keepassdroid/tests/database/SprEngineTest.java @@ -19,16 +19,12 @@ */ package com.keepassdroid.tests.database; -import java.io.InputStream; -import java.util.UUID; - import android.content.Context; import android.content.res.AssetManager; +import android.util.Base64; import androidx.test.platform.app.InstrumentationRegistry; -import biz.source_code.base64Coder.Base64Coder; - import com.keepassdroid.database.PwDatabaseV4; import com.keepassdroid.database.PwEntryV4; import com.keepassdroid.database.load.ImporterV4; @@ -38,6 +34,9 @@ import org.junit.Before; import org.junit.Test; +import java.io.InputStream; +import java.util.UUID; + import static org.junit.Assert.assertEquals; public class SprEngineTest { @@ -78,7 +77,7 @@ private UUID decodeUUID(String encoded) { return PwDatabaseV4.UUID_ZERO; } - byte[] buf = Base64Coder.decode(encoded); + byte[] buf = Base64.decode(encoded, Base64.DEFAULT); return Types.bytestoUUID(buf); } diff --git a/app/src/main/java/biz/source_code/base64Coder/Base64Coder.java b/app/src/main/java/biz/source_code/base64Coder/Base64Coder.java deleted file mode 100644 index 9054587d5..000000000 --- a/app/src/main/java/biz/source_code/base64Coder/Base64Coder.java +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright 2003-2010 Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland -// www.source-code.biz, www.inventec.ch/chdh -// -// This module is multi-licensed and may be used under the terms -// of any of the following licenses: -// -// EPL, Eclipse Public License, http://www.eclipse.org/legal -// LGPL, GNU Lesser General Public License, http://www.gnu.org/licenses/lgpl.html -// AL, Apache License, http://www.apache.org/licenses -// BSD, BSD License, http://www.opensource.org/licenses/bsd-license.php -// -// Please contact the author if you need another license. -// This module is provided "as is", without warranties of any kind. - -package biz.source_code.base64Coder; - -/** -* A Base64 encoder/decoder. -* -*

-* This class is used to encode and decode data in Base64 format as described in RFC 1521. -* -*

-* Project home page: www.source-code.biz/base64coder/java
-* Author: Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland
-* Multi-licensed: EPL / LGPL / AL / BSD. -*/ -public class Base64Coder { - -// The line separator string of the operating system. -private static final String systemLineSeparator = System.getProperty("line.separator"); - -// Mapping table from 6-bit nibbles to Base64 characters. -private static char[] map1 = new char[64]; - static { - int i=0; - for (char c='A'; c<='Z'; c++) map1[i++] = c; - for (char c='a'; c<='z'; c++) map1[i++] = c; - for (char c='0'; c<='9'; c++) map1[i++] = c; - map1[i++] = '+'; map1[i++] = '/'; } - -// Mapping table from Base64 characters to 6-bit nibbles. -private static byte[] map2 = new byte[128]; - static { - for (int i=0; isun.misc.BASE64Encoder.encodeBuffer(byte[]). -* @param in An array containing the data bytes to be encoded. -* @return A String containing the Base64 encoded data, broken into lines. -*/ -public static String encodeLines (byte[] in) { - return encodeLines(in, 0, in.length, 76, systemLineSeparator); } - -/** -* Encodes a byte array into Base 64 format and breaks the output into lines. -* @param in An array containing the data bytes to be encoded. -* @param iOff Offset of the first byte in in to be processed. -* @param iLen Number of bytes to be processed in in, starting at iOff. -* @param lineLen Line length for the output data. Should be a multiple of 4. -* @param lineSeparator The line separator to be used to separate the output lines. -* @return A String containing the Base64 encoded data, broken into lines. -*/ -public static String encodeLines (byte[] in, int iOff, int iLen, int lineLen, String lineSeparator) { - int blockLen = (lineLen*3) / 4; - if (blockLen <= 0) throw new IllegalArgumentException(); - int lines = (iLen+blockLen-1) / blockLen; - int bufLen = ((iLen+2)/3)*4 + lines*lineSeparator.length(); - StringBuilder buf = new StringBuilder(bufLen); - int ip = 0; - while (ip < iLen) { - int l = Math.min(iLen-ip, blockLen); - buf.append (encode(in, iOff+ip, l)); - buf.append (lineSeparator); - ip += l; } - return buf.toString(); } - -/** -* Encodes a byte array into Base64 format. -* No blanks or line breaks are inserted in the output. -* @param in An array containing the data bytes to be encoded. -* @return A character array containing the Base64 encoded data. -*/ -public static char[] encode (byte[] in) { - return encode(in, 0, in.length); } - -/** -* Encodes a byte array into Base64 format. -* No blanks or line breaks are inserted in the output. -* @param in An array containing the data bytes to be encoded. -* @param iLen Number of bytes to process in in. -* @return A character array containing the Base64 encoded data. -*/ -public static char[] encode (byte[] in, int iLen) { - return encode(in, 0, iLen); } - -/** -* Encodes a byte array into Base64 format. -* No blanks or line breaks are inserted in the output. -* @param in An array containing the data bytes to be encoded. -* @param iOff Offset of the first byte in in to be processed. -* @param iLen Number of bytes to process in in, starting at iOff. -* @return A character array containing the Base64 encoded data. -*/ -public static char[] encode (byte[] in, int iOff, int iLen) { - int oDataLen = (iLen*4+2)/3; // output length without padding - int oLen = ((iLen+2)/3)*4; // output length including padding - char[] out = new char[oLen]; - int ip = iOff; - int iEnd = iOff + iLen; - int op = 0; - while (ip < iEnd) { - int i0 = in[ip++] & 0xff; - int i1 = ip < iEnd ? in[ip++] & 0xff : 0; - int i2 = ip < iEnd ? in[ip++] & 0xff : 0; - int o0 = i0 >>> 2; - int o1 = ((i0 & 3) << 4) | (i1 >>> 4); - int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6); - int o3 = i2 & 0x3F; - out[op++] = map1[o0]; - out[op++] = map1[o1]; - out[op] = op < oDataLen ? map1[o2] : '='; op++; - out[op] = op < oDataLen ? map1[o3] : '='; op++; } - return out; } - -/** -* Decodes a string from Base64 format. -* No blanks or line breaks are allowed within the Base64 encoded input data. -* @param s A Base64 String to be decoded. -* @return A String containing the decoded data. -* @throws IllegalArgumentException If the input is not valid Base64 encoded data. -*/ -public static String decodeString (String s) { - return new String(decode(s)); } - -/** -* Decodes a byte array from Base64 format and ignores line separators, tabs and blanks. -* CR, LF, Tab and Space characters are ignored in the input data. -* This method is compatible with sun.misc.BASE64Decoder.decodeBuffer(String). -* @param s A Base64 String to be decoded. -* @return An array containing the decoded data bytes. -* @throws IllegalArgumentException If the input is not valid Base64 encoded data. -*/ -public static byte[] decodeLines (String s) { - char[] buf = new char[s.length()]; - int p = 0; - for (int ip = 0; ip < s.length(); ip++) { - char c = s.charAt(ip); - if (c != ' ' && c != '\r' && c != '\n' && c != '\t') - buf[p++] = c; } - return decode(buf, 0, p); } - -/** -* Decodes a byte array from Base64 format. -* No blanks or line breaks are allowed within the Base64 encoded input data. -* @param s A Base64 String to be decoded. -* @return An array containing the decoded data bytes. -* @throws IllegalArgumentException If the input is not valid Base64 encoded data. -*/ -public static byte[] decode (String s) { - return decode(s.toCharArray()); } - -/** -* Decodes a byte array from Base64 format. -* No blanks or line breaks are allowed within the Base64 encoded input data. -* @param in A character array containing the Base64 encoded data. -* @return An array containing the decoded data bytes. -* @throws IllegalArgumentException If the input is not valid Base64 encoded data. -*/ -public static byte[] decode (char[] in) { - return decode(in, 0, in.length); } - -/** -* Decodes a byte array from Base64 format. -* No blanks or line breaks are allowed within the Base64 encoded input data. -* @param in A character array containing the Base64 encoded data. -* @param iOff Offset of the first character in in to be processed. -* @param iLen Number of characters to process in in, starting at iOff. -* @return An array containing the decoded data bytes. -* @throws IllegalArgumentException If the input is not valid Base64 encoded data. -*/ -public static byte[] decode (char[] in, int iOff, int iLen) { - if (iLen%4 != 0) throw new IllegalArgumentException ("Length of Base64 encoded input string is not a multiple of 4."); - while (iLen > 0 && in[iOff+iLen-1] == '=') iLen--; - int oLen = (iLen*3) / 4; - byte[] out = new byte[oLen]; - int ip = iOff; - int iEnd = iOff + iLen; - int op = 0; - while (ip < iEnd) { - int i0 = in[ip++]; - int i1 = in[ip++]; - int i2 = ip < iEnd ? in[ip++] : 'A'; - int i3 = ip < iEnd ? in[ip++] : 'A'; - if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127) - throw new IllegalArgumentException ("Illegal character in Base64 encoded data."); - int b0 = map2[i0]; - int b1 = map2[i1]; - int b2 = map2[i2]; - int b3 = map2[i3]; - if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0) - throw new IllegalArgumentException ("Illegal character in Base64 encoded data."); - int o0 = ( b0 <<2) | (b1>>>4); - int o1 = ((b1 & 0xf)<<4) | (b2>>>2); - int o2 = ((b2 & 3)<<6) | b3; - out[op++] = (byte)o0; - if (op 0 ) { - customIconData = Base64Coder.decode(strData); + customIconData = Base64.decode(strData, Base64.DEFAULT); } else { assert(false); } @@ -923,7 +924,7 @@ private Date ReadTime(XmlPullParser xpp) throws IOException, XmlPullParserExcept Date utcDate = null; if (version >= PwDbHeaderV4.FILE_VERSION_32_4) { - byte[] buf = Base64Coder.decode(sDate); + byte[] buf = Base64.decode(sDate, Base64.DEFAULT); if (buf.length != 8) { byte[] buf8 = new byte[8]; System.arraycopy(buf, 0, buf8, 0, Math.min(buf.length, 8)); @@ -988,8 +989,7 @@ private UUID ReadUuid(XmlPullParser xpp) throws IOException, XmlPullParserExcept return PwDatabaseV4.UUID_ZERO; } - // TODO: Switch to framework Base64 once API level 8 is the minimum - byte[] buf = Base64Coder.decode(encoded); + byte[] buf = Base64.decode(encoded, Base64.DEFAULT); return Types.bytestoUUID(buf); } @@ -1081,7 +1081,7 @@ private ProtectedBinary ReadProtectedBinary(XmlPullParser xpp) throws XmlPullPar String base64 = ReadString(xpp); if ( base64.length() == 0 ) return ProtectedBinary.EMPTY; - byte[] data = Base64Coder.decode(base64); + byte[] data = Base64.decode(base64, Base64.DEFAULT); if (compressed) { data = MemUtil.decompress(data); @@ -1123,7 +1123,7 @@ private byte[] ProcessNode(XmlPullParser xpp) throws XmlPullParserException, IOE String encrypted = ReadStringRaw(xpp); if ( encrypted.length() > 0 ) { - buf = Base64Coder.decode(encrypted); + buf = Base64.decode(encrypted, Base64.DEFAULT); byte[] plainText = new byte[buf.length]; randomStream.processBytes(buf, 0, buf.length, plainText, 0); diff --git a/app/src/main/java/com/keepassdroid/database/save/PwDbV4Output.java b/app/src/main/java/com/keepassdroid/database/save/PwDbV4Output.java index 2cb350801..60ff9e852 100644 --- a/app/src/main/java/com/keepassdroid/database/save/PwDbV4Output.java +++ b/app/src/main/java/com/keepassdroid/database/save/PwDbV4Output.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2017 Brian Pellin. + * Copyright 2013-2020 Brian Pellin. * * This file is part of KeePassDroid. * @@ -19,6 +19,7 @@ */ package com.keepassdroid.database.save; +import android.util.Base64; import android.util.Xml; import com.keepassdroid.crypto.CipherFactory; @@ -74,8 +75,6 @@ import javax.crypto.Cipher; import javax.crypto.CipherOutputStream; -import biz.source_code.base64Coder.Base64Coder; - import static com.keepassdroid.database.PwDatabaseV4XML.AttrCompressed; import static com.keepassdroid.database.PwDatabaseV4XML.AttrId; import static com.keepassdroid.database.PwDatabaseV4XML.AttrProtected; @@ -322,7 +321,7 @@ private void writeMeta() throws IllegalArgumentException, IllegalStateException, writeObject(ElemGenerator, mPM.localizedAppName); if (hashOfHeader != null) { - writeObject(ElemHeaderHash, String.valueOf(Base64Coder.encode(hashOfHeader))); + writeObject(ElemHeaderHash, Base64.encodeToString(hashOfHeader, Base64.DEFAULT)); } writeObject(ElemDbName, mPM.name, true); @@ -527,15 +526,15 @@ private void subWriteValue(ProtectedBinary value) throws IllegalArgumentExceptio byte[] encoded = new byte[valLength]; randomStream.processBytes(buffer, 0, valLength, encoded, 0); - xml.text(String.valueOf(Base64Coder.encode(encoded))); + xml.text(Base64.encodeToString(encoded, Base64.DEFAULT)); } else { if (mPM.compressionAlgorithm == PwCompressionAlgorithm.Gzip) { xml.attribute(null, AttrCompressed, ValTrue); byte[] compressData = MemUtil.compress(buffer); - xml.text(String.valueOf(Base64Coder.encode(compressData))); + xml.text(Base64.encodeToString(compressData, Base64.DEFAULT)); } else { - xml.text(String.valueOf(Base64Coder.encode(buffer))); + xml.text(Base64.encodeToString(buffer, Base64.DEFAULT)); } } @@ -566,7 +565,7 @@ private void writeObject(String name, Date value) throws IllegalArgumentExceptio DateTime dt = new DateTime(value); long seconds = DateUtil.convertDateToKDBX4Time(dt); byte[] buf = LEDataOutputStream.writeLongBuf(seconds); - String b64 = new String(Base64Coder.encode(buf)); + String b64 = Base64.encodeToString(buf, Base64.DEFAULT); writeObject(name, b64); } @@ -593,7 +592,7 @@ else if (value) { private void writeObject(String name, UUID uuid) throws IllegalArgumentException, IllegalStateException, IOException { byte[] data = Types.UUIDtoBytes(uuid); - writeObject(name, String.valueOf(Base64Coder.encode(data))); + writeObject(name, Base64.encodeToString(data, Base64.DEFAULT)); } private void writeObject(String name, String keyName, String keyValue, String valueName, String valueValue) throws IllegalArgumentException, IllegalStateException, IOException { @@ -677,7 +676,7 @@ else if (key.equals(PwDefsV4.NOTES_FIELD)) { if (valLength > 0) { byte[] encoded = new byte[valLength]; randomStream.processBytes(data, 0, valLength, encoded, 0); - xml.text(String.valueOf(Base64Coder.encode(encoded))); + xml.text(Base64.encodeToString(encoded, Base64.DEFAULT)); } } else { @@ -790,7 +789,7 @@ private void writeCustomIconList() throws IllegalArgumentException, IllegalState xml.startTag(null, ElemCustomIconItem); writeObject(ElemCustomIconItemID, icon.uuid); - writeObject(ElemCustomIconItemData, String.valueOf(Base64Coder.encode(icon.imageData))); + writeObject(ElemCustomIconItemData, Base64.encodeToString(icon.imageData, Base64.DEFAULT)); xml.endTag(null, ElemCustomIconItem); }