2
0

Clean up now that implementation is Native only.

This commit is contained in:
Maarten Billemont 2019-10-23 09:25:57 -04:00
parent aec5e371b8
commit 023749049a
18 changed files with 314 additions and 481 deletions

View File

@ -5,6 +5,10 @@ add_library( mpw SHARED
"${PROJECT_SOURCE_DIR}/../platform-independent/c/core/src/base64.c"
"${PROJECT_SOURCE_DIR}/../platform-independent/c/core/src/aes.c"
"${PROJECT_SOURCE_DIR}/../platform-independent/c/core/src/mpw-algorithm.c"
"${PROJECT_SOURCE_DIR}/../platform-independent/c/core/src/mpw-algorithm_v0.c"
"${PROJECT_SOURCE_DIR}/../platform-independent/c/core/src/mpw-algorithm_v1.c"
"${PROJECT_SOURCE_DIR}/../platform-independent/c/core/src/mpw-algorithm_v2.c"
"${PROJECT_SOURCE_DIR}/../platform-independent/c/core/src/mpw-algorithm_v3.c"
"${PROJECT_SOURCE_DIR}/../platform-independent/c/core/src/mpw-types.c"
"${PROJECT_SOURCE_DIR}/../platform-independent/c/core/src/mpw-util.c"
"${PROJECT_SOURCE_DIR}/../platform-independent/c/core/src/mpw-marshal-util.c"

View File

@ -316,8 +316,8 @@ public class EmergencyActivity extends Activity {
@Override
public void run() {
try {
sitePassword = masterKey.siteResult( siteName, version.getAlgorithm(), counter,
MPKeyPurpose.Authentication, null, type, null );
sitePassword = masterKey.siteResult(
siteName, version, counter, MPKeyPurpose.Authentication, null, type, null );
runOnUiThread( new Runnable() {
@Override

View File

@ -149,7 +149,7 @@ public final class Preferences {
@Nonnull
public MPResultType getDefaultResultType() {
return MPResultType.values()[
prefs().getInt( PREF_RESULT_TYPE, getDefaultVersion().getAlgorithm().mpw_default_result_type().ordinal() )];
prefs().getInt( PREF_RESULT_TYPE, getDefaultVersion().mpw_default_result_type().ordinal() )];
}
public boolean setDefaultVersion(final MPAlgorithm.Version value) {

View File

@ -0,0 +1,47 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_lyndir_masterpassword_MPAlgorithm_Version */
#ifndef _Included_com_lyndir_masterpassword_MPAlgorithm_Version
#define _Included_com_lyndir_masterpassword_MPAlgorithm_Version
#ifdef __cplusplus
extern "C" {
#endif
#undef com_lyndir_masterpassword_MPAlgorithm_Version_AES_BLOCKSIZE
#define com_lyndir_masterpassword_MPAlgorithm_Version_AES_BLOCKSIZE 128L
/*
* Class: com_lyndir_masterpassword_MPAlgorithm_Version
* Method: _masterKey
* Signature: (Ljava/lang/String;[BI)[B
*/
JNIEXPORT jbyteArray JNICALL Java_com_lyndir_masterpassword_MPAlgorithm_00024Version__1masterKey
(JNIEnv *, jobject, jstring, jbyteArray, jint);
/*
* Class: com_lyndir_masterpassword_MPAlgorithm_Version
* Method: _siteKey
* Signature: ([BLjava/lang/String;JILjava/lang/String;I)[B
*/
JNIEXPORT jbyteArray JNICALL Java_com_lyndir_masterpassword_MPAlgorithm_00024Version__1siteKey
(JNIEnv *, jobject, jbyteArray, jstring, jlong, jint, jstring, jint);
/*
* Class: com_lyndir_masterpassword_MPAlgorithm_Version
* Method: _siteResult
* Signature: ([B[BLjava/lang/String;JILjava/lang/String;ILjava/lang/String;I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_lyndir_masterpassword_MPAlgorithm_00024Version__1siteResult
(JNIEnv *, jobject, jbyteArray, jbyteArray, jstring, jlong, jint, jstring, jint, jstring, jint);
/*
* Class: com_lyndir_masterpassword_MPAlgorithm_Version
* Method: _siteState
* Signature: ([B[BLjava/lang/String;JILjava/lang/String;ILjava/lang/String;I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_lyndir_masterpassword_MPAlgorithm_00024Version__1siteState
(JNIEnv *, jobject, jbyteArray, jbyteArray, jstring, jlong, jint, jstring, jint, jstring, jint);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,47 +0,0 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_lyndir_masterpassword_impl_MPAlgorithmV0 */
#ifndef _Included_com_lyndir_masterpassword_impl_MPAlgorithmV0
#define _Included_com_lyndir_masterpassword_impl_MPAlgorithmV0
#ifdef __cplusplus
extern "C" {
#endif
#undef com_lyndir_masterpassword_impl_MPAlgorithmV0_AES_BLOCKSIZE
#define com_lyndir_masterpassword_impl_MPAlgorithmV0_AES_BLOCKSIZE 128L
/*
* Class: com_lyndir_masterpassword_impl_MPAlgorithmV0
* Method: _masterKey
* Signature: (Ljava/lang/String;[BI)[B
*/
JNIEXPORT jbyteArray JNICALL Java_com_lyndir_masterpassword_impl_MPAlgorithmV0__1masterKey
(JNIEnv *, jobject, jstring, jbyteArray, jint);
/*
* Class: com_lyndir_masterpassword_impl_MPAlgorithmV0
* Method: _siteKey
* Signature: ([BLjava/lang/String;JILjava/lang/String;I)[B
*/
JNIEXPORT jbyteArray JNICALL Java_com_lyndir_masterpassword_impl_MPAlgorithmV0__1siteKey
(JNIEnv *, jobject, jbyteArray, jstring, jlong, jint, jstring, jint);
/*
* Class: com_lyndir_masterpassword_impl_MPAlgorithmV0
* Method: _siteResult
* Signature: ([B[BLjava/lang/String;JILjava/lang/String;ILjava/lang/String;I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_lyndir_masterpassword_impl_MPAlgorithmV0__1siteResult
(JNIEnv *, jobject, jbyteArray, jbyteArray, jstring, jlong, jint, jstring, jint, jstring, jint);
/*
* Class: com_lyndir_masterpassword_impl_MPAlgorithmV0
* Method: _siteState
* Signature: ([B[BLjava/lang/String;JILjava/lang/String;ILjava/lang/String;I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_lyndir_masterpassword_impl_MPAlgorithmV0__1siteState
(JNIEnv *, jobject, jbyteArray, jbyteArray, jstring, jlong, jint, jstring, jint, jstring, jint);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,6 +1,6 @@
#include <string.h>
#include "java/com_lyndir_masterpassword_impl_MPAlgorithmV0.h"
#include "java/com_lyndir_masterpassword_MPAlgorithm_Version.h"
#include "mpw-algorithm.h"
#include "mpw-util.h"

View File

@ -22,12 +22,15 @@ import static com.lyndir.lhunath.opal.system.util.StringUtils.strf;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import com.google.common.base.Charsets;
import com.google.common.primitives.UnsignedInteger;
import com.lyndir.lhunath.opal.system.MessageAuthenticationDigests;
import com.lyndir.lhunath.opal.system.MessageDigests;
import com.lyndir.lhunath.opal.system.logging.Logger;
import com.lyndir.masterpassword.impl.*;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.nio.*;
import java.nio.charset.*;
import java.util.Arrays;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -36,7 +39,7 @@ import javax.annotation.Nullable;
* @see Version
*/
@SuppressWarnings({ "FieldMayBeStatic", "NewMethodNamingConvention", "MethodReturnAlwaysConstant" })
public abstract class MPAlgorithm {
public interface MPAlgorithm {
/**
* Derive a master key that describes a user's identity.
@ -45,7 +48,7 @@ public abstract class MPAlgorithm {
* @param masterPassword The user's secret that authenticates his access to the identity.
*/
@Nullable
public abstract byte[] masterKey(String fullName, char[] masterPassword);
byte[] masterKey(String fullName, char[] masterPassword);
/**
* Derive a site key that describes a user's access to a specific entity.
@ -57,8 +60,8 @@ public abstract class MPAlgorithm {
* @param keyContext An action-specific context within which to scope the key.
*/
@Nullable
public abstract byte[] siteKey(byte[] masterKey, String siteName, UnsignedInteger siteCounter,
MPKeyPurpose keyPurpose, @Nullable String keyContext);
byte[] siteKey(byte[] masterKey, String siteName, UnsignedInteger siteCounter,
MPKeyPurpose keyPurpose, @Nullable String keyContext);
/**
* Encode a templated result for a site key.
@ -67,9 +70,9 @@ public abstract class MPAlgorithm {
* @param resultParam A parameter that provides contextual data specific to the type template.
*/
@Nullable
public abstract String siteResult(byte[] masterKey, byte[] siteKey, String siteName, UnsignedInteger siteCounter,
MPKeyPurpose keyPurpose, @Nullable String keyContext,
MPResultType resultType, @Nullable String resultParam);
String siteResult(byte[] masterKey, byte[] siteKey, String siteName, UnsignedInteger siteCounter,
MPKeyPurpose keyPurpose, @Nullable String keyContext,
MPResultType resultType, @Nullable String resultParam);
/**
* For {@link MPResultTypeClass#Stateful} {@code resultType}s, generate the {@code resultParam} to use with the
@ -80,9 +83,9 @@ public abstract class MPAlgorithm {
* @param resultParam A parameter that provides contextual data specific to the type template.
*/
@Nullable
public abstract String siteState(byte[] masterKey, byte[] siteKey, String siteName, UnsignedInteger siteCounter,
MPKeyPurpose keyPurpose, @Nullable String keyContext,
MPResultType resultType, String resultParam);
String siteState(byte[] masterKey, byte[] siteKey, String siteName, UnsignedInteger siteCounter,
MPKeyPurpose keyPurpose, @Nullable String keyContext,
MPResultType resultType, String resultParam);
// Configuration
@ -90,115 +93,105 @@ public abstract class MPAlgorithm {
* The linear version identifier of this algorithm's implementation.
*/
@Nonnull
public abstract Version version();
Version version();
/**
* mpw: defaults: initial counter value.
*/
@Nonnull
public abstract UnsignedInteger mpw_default_counter();
UnsignedInteger mpw_default_counter();
/**
* mpw: defaults: password result type.
*/
@Nonnull
public abstract MPResultType mpw_default_result_type();
MPResultType mpw_default_result_type();
/**
* mpw: defaults: login result type.
*/
@Nonnull
public abstract MPResultType mpw_default_login_type();
MPResultType mpw_default_login_type();
/**
* mpw: defaults: answer result type.
*/
@Nonnull
public abstract MPResultType mpw_default_answer_type();
MPResultType mpw_default_answer_type();
/**
* mpw: Input character encoding.
*/
@Nonnull
public abstract Charset mpw_charset();
Charset mpw_charset();
/**
* mpw: Platform-agnostic byte order.
*/
@Nonnull
public abstract ByteOrder mpw_byteOrder();
ByteOrder mpw_byteOrder();
/**
* mpw: Key ID hash.
*/
@Nonnull
public abstract MessageDigests mpw_hash();
MessageDigests mpw_hash();
/**
* mpw: Site digest.
*/
@Nonnull
public abstract MessageAuthenticationDigests mpw_digest();
MessageAuthenticationDigests mpw_digest();
/**
* mpw: Master key size (byte).
*/
public abstract int mpw_dkLen();
int mpw_dkLen();
/**
* mpw: Minimum size for derived keys (bit).
*/
public abstract int mpw_keySize_min();
int mpw_keySize_min();
/**
* mpw: Maximum size for derived keys (bit).
*/
public abstract int mpw_keySize_max();
int mpw_keySize_max();
/**
* mpw: validity for the time-based rolling counter (s).
*/
public abstract long mpw_otp_window();
long mpw_otp_window();
/**
* scrypt: CPU cost parameter.
*/
public abstract int scrypt_N();
int scrypt_N();
/**
* scrypt: Memory cost parameter.
*/
public abstract int scrypt_r();
int scrypt_r();
/**
* scrypt: Parallelization parameter.
*/
public abstract int scrypt_p();
int scrypt_p();
// Utilities
@Nonnull
protected abstract byte[] toBytes(int number);
byte[] toBytes(final int number);
@Nonnull
protected abstract byte[] toBytes(UnsignedInteger number);
byte[] toBytes(final UnsignedInteger number);
@Nonnull
protected abstract byte[] toBytes(char[] characters);
byte[] toBytes(final char[] characters);
@Nonnull
protected abstract byte[] toID(byte[] bytes);
@Override
public String toString() {
return strf( "%d, %s", version().toInt(), getClass().getSimpleName() );
}
byte[] toID(final byte[] bytes);
/**
* The algorithm iterations.
*/
public enum Version {
enum Version implements MPAlgorithm {
/**
* bugs:
@ -206,38 +199,38 @@ public abstract class MPAlgorithm {
* - miscounted the byte-length for multi-byte site names.
* - miscounted the byte-length for multi-byte user names.
*/
V0( new MPAlgorithmV0() ),
V0,
/**
* bugs:
* - miscounted the byte-length for multi-byte site names.
* - miscounted the byte-length for multi-byte user names.
*/
V1( new MPAlgorithmV1() ),
V1,
/**
* bugs:
* - miscounted the byte-length for multi-byte user names.
*/
V2( new MPAlgorithmV2() ),
V2,
/**
* bugs:
* - no known issues.
*/
V3( new MPAlgorithmV3() );
V3;
public static final Version CURRENT = V3;
private final MPAlgorithm algorithm;
@SuppressWarnings("HardcodedFileSeparator")
private static final String AES_TRANSFORMATION = "AES/CBC/PKCS5Padding";
private static final int AES_BLOCKSIZE = 128 /* bit */;
Version(final MPAlgorithm algorithm) {
this.algorithm = algorithm;
static {
Native.load( MPAlgorithm.class, "mpw" );
}
public MPAlgorithm getAlgorithm() {
return algorithm;
}
protected final Logger logger = Logger.get( getClass() );
@JsonCreator
public static Version fromInt(final int algorithmVersion) {
@ -250,5 +243,207 @@ public abstract class MPAlgorithm {
return ordinal();
}
@Override
public String toString() {
return strf( "%d, %s", version().toInt(), getClass().getSimpleName() );
}
@Nullable
@Override
public byte[] masterKey(final String fullName, final char[] masterPassword) {
// Create a memory-safe NUL-terminated UTF-8 C-string byte array variant of masterPassword.
CharsetEncoder encoder = mpw_charset().newEncoder();
byte[] masterPasswordBytes = new byte[(int) (masterPassword.length * (double) encoder.maxBytesPerChar()) + 1];
try {
Arrays.fill( masterPasswordBytes, (byte) 0 );
ByteBuffer masterPasswordBuffer = ByteBuffer.wrap( masterPasswordBytes );
CoderResult result = encoder.encode( CharBuffer.wrap( masterPassword ), masterPasswordBuffer, true );
if (result.isError())
throw new IllegalStateException( result.toString() );
result = encoder.flush( masterPasswordBuffer );
if (result.isError())
throw new IllegalStateException( result.toString() );
return _masterKey( fullName, masterPasswordBytes, version().toInt() );
}
finally {
Arrays.fill( masterPasswordBytes, (byte) 0 );
}
}
@Nullable
protected native byte[] _masterKey(final String fullName, final byte[] masterPassword, final int algorithmVersion);
@Nullable
@Override
public byte[] siteKey(final byte[] masterKey, final String siteName, final UnsignedInteger siteCounter,
final MPKeyPurpose keyPurpose, @Nullable final String keyContext) {
return _siteKey( masterKey, siteName, siteCounter.longValue(), keyPurpose.toInt(), keyContext, version().toInt() );
}
@Nullable
protected native byte[] _siteKey(final byte[] masterKey, final String siteName, final long siteCounter,
final int keyPurpose, @Nullable final String keyContext, final int version);
@Nullable
@Override
public String siteResult(final byte[] masterKey, final byte[] siteKey, final String siteName, final UnsignedInteger siteCounter,
final MPKeyPurpose keyPurpose, @Nullable final String keyContext,
final MPResultType resultType, @Nullable final String resultParam) {
return _siteResult( masterKey, siteKey, siteName, siteCounter.longValue(),
keyPurpose.toInt(), keyContext, resultType.getType(), resultParam, version().toInt() );
}
@Nullable
protected native String _siteResult(final byte[] masterKey, final byte[] siteKey, final String siteName, final long siteCounter,
final int keyPurpose, @Nullable final String keyContext,
final int resultType, @Nullable final String resultParam, final int algorithmVersion);
@Nullable
@Override
public String siteState(final byte[] masterKey, final byte[] siteKey, final String siteName, final UnsignedInteger siteCounter,
final MPKeyPurpose keyPurpose, @Nullable final String keyContext,
final MPResultType resultType, final String resultParam) {
return _siteState( masterKey, siteKey, siteName, siteCounter.longValue(),
keyPurpose.toInt(), keyContext, resultType.getType(), resultParam, version().toInt() );
}
@Nullable
protected native String _siteState(final byte[] masterKey, final byte[] siteKey, final String siteName, final long siteCounter,
final int keyPurpose, @Nullable final String keyContext,
final int resultType, final String resultParam, final int algorithmVersion);
// Configuration
@Nonnull
@Override
public Version version() {
return MPAlgorithm.Version.V0;
}
@Nonnull
@Override
public UnsignedInteger mpw_default_counter() {
return UnsignedInteger.ONE;
}
@Nonnull
@Override
public MPResultType mpw_default_result_type() {
return MPResultType.GeneratedLong;
}
@Nonnull
@Override
public MPResultType mpw_default_login_type() {
return MPResultType.GeneratedName;
}
@Nonnull
@Override
public MPResultType mpw_default_answer_type() {
return MPResultType.GeneratedPhrase;
}
@Nonnull
@Override
public Charset mpw_charset() {
return Charsets.UTF_8;
}
@Nonnull
@Override
public ByteOrder mpw_byteOrder() {
return ByteOrder.BIG_ENDIAN;
}
@Nonnull
@Override
public MessageDigests mpw_hash() {
return MessageDigests.SHA256;
}
@Nonnull
@Override
public MessageAuthenticationDigests mpw_digest() {
return MessageAuthenticationDigests.HmacSHA256;
}
@Override
@SuppressWarnings("MagicNumber")
public int mpw_dkLen() {
return 64;
}
@Override
@SuppressWarnings("MagicNumber")
public int mpw_keySize_min() {
return 128;
}
@Override
@SuppressWarnings("MagicNumber")
public int mpw_keySize_max() {
return 512;
}
@Override
@SuppressWarnings("MagicNumber")
public long mpw_otp_window() {
return 5 * 60 /* s */;
}
@Override
@SuppressWarnings("MagicNumber")
public int scrypt_N() {
return 32768;
}
@Override
@SuppressWarnings("MagicNumber")
public int scrypt_r() {
return 8;
}
@Override
@SuppressWarnings("MagicNumber")
public int scrypt_p() {
return 2;
}
// Utilities
@Nonnull
public byte[] toBytes(final int number) {
return ByteBuffer.allocate( Integer.SIZE / Byte.SIZE ).order( mpw_byteOrder() ).putInt( number ).array();
}
@Nonnull
public byte[] toBytes(final UnsignedInteger number) {
return ByteBuffer.allocate( Integer.SIZE / Byte.SIZE ).order( mpw_byteOrder() ).putInt( number.intValue() ).array();
}
@Nonnull
public byte[] toBytes(final char[] characters) {
ByteBuffer byteBuffer = mpw_charset().encode( CharBuffer.wrap( characters ) );
byte[] bytes = new byte[byteBuffer.remaining()];
byteBuffer.get( bytes );
Arrays.fill( byteBuffer.array(), (byte) 0 );
return bytes;
}
@Nonnull
public byte[] toID(final byte[] bytes) {
return mpw_hash().of( bytes );
}
}
}

View File

@ -1,250 +0,0 @@
//==============================================================================
// This file is part of Master Password.
// Copyright (c) 2011-2017, Maarten Billemont.
//
// Master Password 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.
//
// Master Password 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 can find a copy of the GNU General Public License in the
// LICENSE file. Alternatively, see <http://www.gnu.org/licenses/>.
//==============================================================================
package com.lyndir.masterpassword.impl;
import com.google.common.base.Charsets;
import com.google.common.primitives.UnsignedInteger;
import com.lyndir.lhunath.opal.system.MessageAuthenticationDigests;
import com.lyndir.lhunath.opal.system.MessageDigests;
import com.lyndir.lhunath.opal.system.logging.Logger;
import com.lyndir.masterpassword.*;
import java.nio.*;
import java.nio.charset.*;
import java.util.Arrays;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* @author lhunath, 2014-08-30
* @see MPAlgorithm.Version#V0
*/
@SuppressWarnings("NewMethodNamingConvention")
public class MPAlgorithmV0 extends MPAlgorithm {
@SuppressWarnings("HardcodedFileSeparator")
protected static final String AES_TRANSFORMATION = "AES/CBC/PKCS5Padding";
protected static final int AES_BLOCKSIZE = 128 /* bit */;
static {
Native.load( MPAlgorithmV0.class, "mpw" );
}
protected final Logger logger = Logger.get( getClass() );
@Nullable
@Override
public byte[] masterKey(final String fullName, final char[] masterPassword) {
// Create a memory-safe NUL-terminated UTF-8 C-string byte array variant of masterPassword.
CharsetEncoder encoder = mpw_charset().newEncoder();
byte[] masterPasswordBytes = new byte[(int) (masterPassword.length * (double) encoder.maxBytesPerChar()) + 1];
try {
Arrays.fill( masterPasswordBytes, (byte) 0 );
ByteBuffer masterPasswordBuffer = ByteBuffer.wrap( masterPasswordBytes );
CoderResult result = encoder.encode( CharBuffer.wrap( masterPassword ), masterPasswordBuffer, true );
if (result.isError())
throw new IllegalStateException( result.toString() );
result = encoder.flush( masterPasswordBuffer );
if (result.isError())
throw new IllegalStateException( result.toString() );
return _masterKey( fullName, masterPasswordBytes, version().toInt() );
}
finally {
Arrays.fill( masterPasswordBytes, (byte) 0 );
}
}
@Nullable
protected native byte[] _masterKey(final String fullName, final byte[] masterPassword, final int algorithmVersion);
@Nullable
@Override
public byte[] siteKey(final byte[] masterKey, final String siteName, final UnsignedInteger siteCounter,
final MPKeyPurpose keyPurpose, @Nullable final String keyContext) {
return _siteKey( masterKey, siteName, siteCounter.longValue(), keyPurpose.toInt(), keyContext, version().toInt() );
}
@Nullable
protected native byte[] _siteKey(final byte[] masterKey, final String siteName, final long siteCounter,
final int keyPurpose, @Nullable final String keyContext, final int version);
@Nullable
@Override
public String siteResult(final byte[] masterKey, final byte[] siteKey, final String siteName, final UnsignedInteger siteCounter,
final MPKeyPurpose keyPurpose, @Nullable final String keyContext,
final MPResultType resultType, @Nullable final String resultParam) {
return _siteResult( masterKey, siteKey, siteName, siteCounter.longValue(),
keyPurpose.toInt(), keyContext, resultType.getType(), resultParam, version().toInt() );
}
@Nullable
protected native String _siteResult(final byte[] masterKey, final byte[] siteKey, final String siteName, final long siteCounter,
final int keyPurpose, @Nullable final String keyContext,
final int resultType, @Nullable final String resultParam, final int algorithmVersion);
@Nullable
@Override
public String siteState(final byte[] masterKey, final byte[] siteKey, final String siteName, final UnsignedInteger siteCounter,
final MPKeyPurpose keyPurpose, @Nullable final String keyContext,
final MPResultType resultType, final String resultParam) {
return _siteState( masterKey, siteKey, siteName, siteCounter.longValue(),
keyPurpose.toInt(), keyContext, resultType.getType(), resultParam, version().toInt() );
}
@Nullable
protected native String _siteState(final byte[] masterKey, final byte[] siteKey, final String siteName, final long siteCounter,
final int keyPurpose, @Nullable final String keyContext,
final int resultType, final String resultParam, final int algorithmVersion);
// Configuration
@Nonnull
@Override
public Version version() {
return MPAlgorithm.Version.V0;
}
@Nonnull
@Override
public UnsignedInteger mpw_default_counter() {
return UnsignedInteger.ONE;
}
@Nonnull
@Override
public MPResultType mpw_default_result_type() {
return MPResultType.GeneratedLong;
}
@Nonnull
@Override
public MPResultType mpw_default_login_type() {
return MPResultType.GeneratedName;
}
@Nonnull
@Override
public MPResultType mpw_default_answer_type() {
return MPResultType.GeneratedPhrase;
}
@Nonnull
@Override
public Charset mpw_charset() {
return Charsets.UTF_8;
}
@Nonnull
@Override
public ByteOrder mpw_byteOrder() {
return ByteOrder.BIG_ENDIAN;
}
@Nonnull
@Override
public MessageDigests mpw_hash() {
return MessageDigests.SHA256;
}
@Nonnull
@Override
public MessageAuthenticationDigests mpw_digest() {
return MessageAuthenticationDigests.HmacSHA256;
}
@Override
@SuppressWarnings("MagicNumber")
public int mpw_dkLen() {
return 64;
}
@Override
@SuppressWarnings("MagicNumber")
public int mpw_keySize_min() {
return 128;
}
@Override
@SuppressWarnings("MagicNumber")
public int mpw_keySize_max() {
return 512;
}
@Override
@SuppressWarnings("MagicNumber")
public long mpw_otp_window() {
return 5 * 60 /* s */;
}
@Override
@SuppressWarnings("MagicNumber")
public int scrypt_N() {
return 32768;
}
@Override
@SuppressWarnings("MagicNumber")
public int scrypt_r() {
return 8;
}
@Override
@SuppressWarnings("MagicNumber")
public int scrypt_p() {
return 2;
}
// Utilities
@Nonnull
@Override
public byte[] toBytes(final int number) {
return ByteBuffer.allocate( Integer.SIZE / Byte.SIZE ).order( mpw_byteOrder() ).putInt( number ).array();
}
@Nonnull
@Override
public byte[] toBytes(final UnsignedInteger number) {
return ByteBuffer.allocate( Integer.SIZE / Byte.SIZE ).order( mpw_byteOrder() ).putInt( number.intValue() ).array();
}
@Nonnull
@Override
public byte[] toBytes(final char[] characters) {
ByteBuffer byteBuffer = mpw_charset().encode( CharBuffer.wrap( characters ) );
byte[] bytes = new byte[byteBuffer.remaining()];
byteBuffer.get( bytes );
Arrays.fill( byteBuffer.array(), (byte) 0 );
return bytes;
}
@Nonnull
@Override
public byte[] toID(final byte[] bytes) {
return mpw_hash().of( bytes );
}
}

View File

@ -1,38 +0,0 @@
//==============================================================================
// This file is part of Master Password.
// Copyright (c) 2011-2017, Maarten Billemont.
//
// Master Password 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.
//
// Master Password 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 can find a copy of the GNU General Public License in the
// LICENSE file. Alternatively, see <http://www.gnu.org/licenses/>.
//==============================================================================
package com.lyndir.masterpassword.impl;
import com.lyndir.masterpassword.*;
import javax.annotation.Nonnull;
/**
* @author lhunath, 2014-08-30
* @see Version#V1
*/
public class MPAlgorithmV1 extends MPAlgorithmV0 {
// Configuration
@Nonnull
@Override
public Version version() {
return MPAlgorithm.Version.V1;
}
}

View File

@ -1,38 +0,0 @@
//==============================================================================
// This file is part of Master Password.
// Copyright (c) 2011-2017, Maarten Billemont.
//
// Master Password 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.
//
// Master Password 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 can find a copy of the GNU General Public License in the
// LICENSE file. Alternatively, see <http://www.gnu.org/licenses/>.
//==============================================================================
package com.lyndir.masterpassword.impl;
import com.lyndir.masterpassword.MPAlgorithm;
import javax.annotation.Nonnull;
/**
* @author lhunath, 2014-08-30
* @see Version#V2
*/
public class MPAlgorithmV2 extends MPAlgorithmV1 {
// Configuration
@Nonnull
@Override
public Version version() {
return MPAlgorithm.Version.V2;
}
}

View File

@ -1,38 +0,0 @@
//==============================================================================
// This file is part of Master Password.
// Copyright (c) 2011-2017, Maarten Billemont.
//
// Master Password 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.
//
// Master Password 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 can find a copy of the GNU General Public License in the
// LICENSE file. Alternatively, see <http://www.gnu.org/licenses/>.
//==============================================================================
package com.lyndir.masterpassword.impl;
import com.lyndir.masterpassword.MPAlgorithm;
import javax.annotation.Nonnull;
/**
* @author lhunath, 2014-08-30
* @see Version#V3
*/
public class MPAlgorithmV3 extends MPAlgorithmV2 {
// Configuration
@Nonnull
@Override
public Version version() {
return MPAlgorithm.Version.V3;
}
}

View File

@ -30,7 +30,7 @@ import javax.annotation.Nullable;
public class MPIncognitoUser extends MPBasicUser<MPIncognitoSite> {
public MPIncognitoUser(final String fullName) {
super( fullName, MPAlgorithm.Version.CURRENT.getAlgorithm() );
super( fullName, MPAlgorithm.Version.CURRENT );
}
@Nullable

View File

@ -577,7 +577,7 @@ public class UserContentPanel extends JPanel implements State.Listener, MPUser.L
components.add( Components.label( "Default Algorithm:" ),
Components.comboBox( MPAlgorithm.Version.values(), MPAlgorithm.Version::name,
user.getAlgorithm().version(), version -> user.setAlgorithm( version.getAlgorithm() ) ) );
user.getAlgorithm().version(), user::setAlgorithm ) );
components.add( Components.label( "Default Password Type:" ),
Components.comboBox( MPResultType.values(), MPResultType::getLongName,
@ -614,7 +614,7 @@ public class UserContentPanel extends JPanel implements State.Listener, MPUser.L
components.add( Components.label( "Algorithm:" ),
Components.comboBox( MPAlgorithm.Version.values(), MPAlgorithm.Version::name,
site.getAlgorithm().version(),
version -> site.setAlgorithm( version.getAlgorithm() ) ) );
site::setAlgorithm ) );
components.add( Components.label( "Counter:" ),
Components.spinner( new UnsignedIntegerModel( site.getCounter(), UnsignedInteger.ONE )

View File

@ -59,7 +59,7 @@ public class MPFileUser extends MPBasicUser<MPFileSite> {
}
public MPFileUser(final String fullName, final File location) {
this( fullName, null, MPAlgorithm.Version.CURRENT.getAlgorithm(), location );
this( fullName, null, MPAlgorithm.Version.CURRENT, location );
}
public MPFileUser(final String fullName, @Nullable final byte[] keyID, final MPAlgorithm algorithm, final File location) {

View File

@ -68,7 +68,7 @@ public class MPFlatUnmarshaller implements MPUnmarshaller {
else if ((fullName != null) && (keyID != null))
// Ends the header.
return new MPFileUser(
fullName, keyID, MPAlgorithm.Version.fromInt( mpVersion ).getAlgorithm(), avatar, defaultType,
fullName, keyID, MPAlgorithm.Version.fromInt( mpVersion ), avatar, defaultType,
date, false, clearContent? MPMarshaller.ContentMode.VISIBLE: MPMarshaller.ContentMode.PROTECTED,
MPMarshalFormat.Flat, file
);
@ -157,7 +157,7 @@ public class MPFlatUnmarshaller implements MPUnmarshaller {
site = new MPFileSite(
user, siteMatcher.group( 5 ),
MPAlgorithm.Version.fromInt( ConversionUtils.toIntegerNN(
colon.matcher( siteMatcher.group( 4 ) ).replaceAll( "" ) ) ).getAlgorithm(),
colon.matcher( siteMatcher.group( 4 ) ).replaceAll( "" ) ) ),
user.getAlgorithm().mpw_default_counter(),
MPResultType.forType( ConversionUtils.toIntegerNN( siteMatcher.group( 3 ) ) ),
clearContent? null: siteMatcher.group( 6 ),
@ -171,7 +171,7 @@ public class MPFlatUnmarshaller implements MPUnmarshaller {
site = new MPFileSite(
user, siteMatcher.group( 7 ),
MPAlgorithm.Version.fromInt( ConversionUtils.toIntegerNN(
colon.matcher( siteMatcher.group( 4 ) ).replaceAll( "" ) ) ).getAlgorithm(),
colon.matcher( siteMatcher.group( 4 ) ).replaceAll( "" ) ) ),
UnsignedInteger.valueOf(
colon.matcher( siteMatcher.group( 5 ) ).replaceAll( "" ) ),
MPResultType.forType( ConversionUtils.toIntegerNN( siteMatcher.group( 3 ) ) ),

View File

@ -128,7 +128,7 @@ public class MPJSONFile extends MPJSONAnyObject {
}
MPFileUser readUser(final File file) {
MPAlgorithm algorithm = ifNotNullElse( user.algorithm, MPAlgorithm.Version.CURRENT ).getAlgorithm();
MPAlgorithm algorithm = ifNotNullElse( user.algorithm, MPAlgorithm.Version.CURRENT );
return new MPFileUser(
user.full_name, CodeUtils.decodeHex( user.key_id ), algorithm, user.avatar,
@ -146,7 +146,7 @@ public class MPJSONFile extends MPJSONAnyObject {
String siteName = siteEntry.getKey();
Site fileSite = siteEntry.getValue();
MPFileSite site = new MPFileSite(
user, siteName, fileSite.algorithm.getAlgorithm(), UnsignedInteger.valueOf( fileSite.counter ),
user, siteName, fileSite.algorithm, UnsignedInteger.valueOf( fileSite.counter ),
fileSite.type, export.redacted? fileSite.password: null,
fileSite.login_type, export.redacted? fileSite.login_name: null,
(fileSite._ext_mpw != null)? fileSite._ext_mpw.url: null, fileSite.uses,

View File

@ -191,7 +191,7 @@ public class MPTests {
@Nonnull
public MPAlgorithm getAlgorithm() {
return MPAlgorithm.Version.fromInt( checkNotNull( algorithm ) ).getAlgorithm();
return MPAlgorithm.Version.fromInt( checkNotNull( algorithm ) );
}
@Nonnull

View File

@ -106,9 +106,7 @@ public class MPMasterKeyTest {
String password = randomString( 8 );
MPResultType resultType = MPResultType.StoredPersonal;
for (final MPAlgorithm.Version version : MPAlgorithm.Version.values()) {
MPAlgorithm algorithm = version.getAlgorithm();
for (final MPAlgorithm.Version algorithm : MPAlgorithm.Version.values()) {
// Test site state
String state = masterKey.siteState( testCase.getSiteName(), algorithm, testCase.getSiteCounter(), testCase.getKeyPurpose(),
testCase.getKeyContext(), resultType, password );