mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Start combining functionality.
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2009 Brian Pellin.
|
||||
*
|
||||
* This file is part of KeePassDroid.
|
||||
*
|
||||
* KeePassDroid 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* KeePassDroid 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 KeePassDroid. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.android.keepass.keepasslib;
|
||||
|
||||
import java.io.FilterOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.bouncycastle.crypto.DataLengthException;
|
||||
import org.bouncycastle.crypto.InvalidCipherTextException;
|
||||
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
|
||||
|
||||
public class BufferedBlockCipherOutputStream extends FilterOutputStream {
|
||||
|
||||
OutputStream mOS;
|
||||
PaddedBufferedBlockCipher mCipher;
|
||||
|
||||
public BufferedBlockCipherOutputStream(OutputStream out) {
|
||||
super(out);
|
||||
mOS = out;
|
||||
}
|
||||
|
||||
public BufferedBlockCipherOutputStream(OutputStream out, PaddedBufferedBlockCipher cipher) {
|
||||
super(out);
|
||||
mOS = out;
|
||||
mCipher = cipher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
byte[] block = new byte[2*mCipher.getBlockSize()];
|
||||
int bytes;
|
||||
try {
|
||||
bytes = mCipher.doFinal(block, 0);
|
||||
} catch (DataLengthException e) {
|
||||
throw new IOException(e.getMessage());
|
||||
} catch (IllegalStateException e) {
|
||||
throw new IOException("IllegalStateException.");
|
||||
} catch (InvalidCipherTextException e) {
|
||||
throw new IOException("InvalidCipherText.");
|
||||
}
|
||||
if ( bytes > 0 ) {
|
||||
mOS.write(block, 0, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] buffer, int offset, int count) throws IOException {
|
||||
int outputLen = mCipher.getUpdateOutputSize(count);
|
||||
|
||||
if ( outputLen > 0 ) {
|
||||
byte[] block = new byte[outputLen];
|
||||
int bytes = mCipher.processBytes(buffer, offset, count, block, 0);
|
||||
if ( bytes > 0 ) {
|
||||
mOS.write(block, 0, bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] buffer) throws IOException {
|
||||
int length = buffer.length;
|
||||
int outputLen = mCipher.getUpdateOutputSize(length);
|
||||
|
||||
if ( outputLen > 0 ) {
|
||||
byte[] block = new byte[outputLen];
|
||||
int bytes = mCipher.processBytes(buffer, 0, length, block, 0);
|
||||
|
||||
if ( bytes > 0 ) {
|
||||
mOS.write(block, 0, bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int oneByte) throws IOException {
|
||||
int outputLen = mCipher.getUpdateOutputSize(1);
|
||||
|
||||
if ( outputLen > 0 ) {
|
||||
byte[] block = new byte[outputLen];
|
||||
int bytes = mCipher.processByte((byte)oneByte, block, 0);
|
||||
|
||||
if ( bytes > 0 ) {
|
||||
mOS.write(block, 0, bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
51
src/com/android/keepass/keepasslib/NullOutputStream.java
Normal file
51
src/com/android/keepass/keepasslib/NullOutputStream.java
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2009 Brian Pellin.
|
||||
*
|
||||
* This file is part of KeePassDroid.
|
||||
*
|
||||
* KeePassDroid 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* KeePassDroid 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 KeePassDroid. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.android.keepass.keepasslib;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class NullOutputStream extends OutputStream {
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
super.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] buffer, int offset, int count) throws IOException {
|
||||
super.write(buffer, offset, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] buffer) throws IOException {
|
||||
super.write(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int oneByte) throws IOException {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -57,43 +57,20 @@ public class PwManagerOutput {
|
||||
mDebug = debug;
|
||||
}
|
||||
|
||||
/*
|
||||
public void close() throws PwManagerOutputException {
|
||||
try {
|
||||
mOS.close();
|
||||
} catch (IOException e) {
|
||||
throw new PwManagerOutputException("Failed to close stream.");
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
public byte[] getFinalKey(PwDbHeader header) throws PwManagerOutputException {
|
||||
|
||||
// Write checksum Checksum
|
||||
MessageDigest md = null;
|
||||
try {
|
||||
md = MessageDigest.getInstance("SHA-256");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
assert true;
|
||||
throw new PwManagerOutputException("SHA-256 not implemented here.");
|
||||
return ImporterV3.makeFinalKey(header.masterSeed, header.masterSeed2, mPM.masterKey, mPM.numKeyEncRounds);
|
||||
} catch (IOException e) {
|
||||
throw new PwManagerOutputException("Key creation failed: " + e.getMessage());
|
||||
}
|
||||
NullOutputStream nos = new NullOutputStream();
|
||||
DigestOutputStream dos = new DigestOutputStream(nos, md);
|
||||
|
||||
byte[] transformedMasterKey = ImporterV3.transformMasterKey(header.masterSeed2, mPM.masterKey, mPM.numKeyEncRounds);
|
||||
try {
|
||||
dos.write(header.masterSeed);
|
||||
dos.write(transformedMasterKey);
|
||||
} catch ( IOException e ) {
|
||||
throw new PwManagerOutputException("Failed to build final key.");
|
||||
}
|
||||
|
||||
return md.digest();
|
||||
|
||||
}
|
||||
|
||||
public byte[] getFinalKey2(PwDbHeader header) {
|
||||
return ImporterV3.makeFinalKey(header.masterSeed, header.masterSeed2, mPM.masterKey, mPM.numKeyEncRounds);
|
||||
public byte[] getFinalKey2(PwDbHeader header) throws PwManagerOutputException {
|
||||
try {
|
||||
return ImporterV3.makeFinalKey(header.masterSeed, header.masterSeed2, mPM.masterKey, mPM.numKeyEncRounds);
|
||||
} catch (IOException e) {
|
||||
throw new PwManagerOutputException("Key creation failed: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void output() throws PwManagerOutputException, IOException {
|
||||
@@ -151,7 +128,7 @@ public class PwManagerOutput {
|
||||
}
|
||||
|
||||
try {
|
||||
cipher.init( Cipher.ENCRYPT_MODE, new SecretKeySpec(mPM.finalKey, "AES" ), new IvParameterSpec(header.encryptionIV) );
|
||||
cipher.init( Cipher.ENCRYPT_MODE, new SecretKeySpec(finalKey, "AES" ), new IvParameterSpec(header.encryptionIV) );
|
||||
CipherOutputStream cos = new CipherOutputStream(mOS, cipher);
|
||||
outputPlanGroupAndEntries(cos);
|
||||
cos.close();
|
||||
|
||||
@@ -27,8 +27,10 @@ package org.phoneid.keepassj2me;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.DigestOutputStream;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
@@ -49,6 +51,8 @@ import org.phoneid.PhoneIDUtil;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.keepass.keepasslib.InvalidKeyFileException;
|
||||
import com.android.keepass.keepasslib.NullOutputStream;
|
||||
import com.android.keepass.keepasslib.PwManagerOutput.PwManagerOutputException;
|
||||
|
||||
/**
|
||||
* Load a v3 database file.
|
||||
@@ -267,17 +271,23 @@ public class ImporterV3 {
|
||||
return newManager;
|
||||
}
|
||||
|
||||
public static byte[] makeFinalKey(byte[] masterSeed, byte[] masterSeed2, byte[] masterKey, int numRounds) {
|
||||
byte[] transformedMasterKey = transformMasterKey(masterSeed2, masterKey, numRounds );
|
||||
public static byte[] makeFinalKey(byte[] masterSeed, byte[] masterSeed2, byte[] masterKey, int numRounds) throws IOException {
|
||||
|
||||
// Hash the master password with the salt in the file
|
||||
SHA256Digest md = new SHA256Digest();
|
||||
md.update( masterSeed, 0, masterSeed.length );
|
||||
md.update( transformedMasterKey, 0, transformedMasterKey.length );
|
||||
byte[] finalKey = new byte[md.getDigestSize()];
|
||||
md.doFinal(finalKey, 0);
|
||||
|
||||
return finalKey;
|
||||
// Write checksum Checksum
|
||||
MessageDigest md = null;
|
||||
try {
|
||||
md = MessageDigest.getInstance("SHA-256");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new IOException("SHA-256 not implemented here.");
|
||||
}
|
||||
NullOutputStream nos = new NullOutputStream();
|
||||
DigestOutputStream dos = new DigestOutputStream(nos, md);
|
||||
|
||||
byte[] transformedMasterKey = ImporterV3.transformMasterKey(masterSeed2, masterKey, numRounds);
|
||||
dos.write(masterSeed);
|
||||
dos.write(transformedMasterKey);
|
||||
|
||||
return md.digest();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user