Fix V0 in Java and support for testing algorithms.
This commit is contained in:
parent
563aab9a81
commit
779d2776a0
@ -6,6 +6,7 @@ import com.lyndir.lhunath.opal.system.logging.Logger;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,6 +148,7 @@ public enum MPSiteType {
|
|||||||
*
|
*
|
||||||
* @return The type registered with the given name.
|
* @return The type registered with the given name.
|
||||||
*/
|
*/
|
||||||
|
@Contract("!null -> !null, null -> null")
|
||||||
public static MPSiteType forName(@Nullable final String name) {
|
public static MPSiteType forName(@Nullable final String name) {
|
||||||
|
|
||||||
if (name == null)
|
if (name == null)
|
||||||
|
@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableList;
|
|||||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,6 +67,7 @@ public enum MPSiteVariant {
|
|||||||
*
|
*
|
||||||
* @return The variant registered with the given name.
|
* @return The variant registered with the given name.
|
||||||
*/
|
*/
|
||||||
|
@Contract("!null -> !null, null -> null")
|
||||||
public static MPSiteVariant forName(@Nullable final String name) {
|
public static MPSiteVariant forName(@Nullable final String name) {
|
||||||
|
|
||||||
if (name == null)
|
if (name == null)
|
||||||
|
@ -89,29 +89,37 @@ public class MasterKeyV0 extends MasterKey {
|
|||||||
byte[] siteNameBytes = siteName.getBytes( MP_charset );
|
byte[] siteNameBytes = siteName.getBytes( MP_charset );
|
||||||
byte[] siteNameLengthBytes = bytesForInt( siteName.length() );
|
byte[] siteNameLengthBytes = bytesForInt( siteName.length() );
|
||||||
byte[] siteCounterBytes = bytesForInt( siteCounter );
|
byte[] siteCounterBytes = bytesForInt( siteCounter );
|
||||||
byte[] siteContextBytes = siteContext == null? null: siteContext.getBytes( MP_charset );
|
byte[] siteContextBytes = siteContext == null || siteContext.isEmpty()? null: siteContext.getBytes( MP_charset );
|
||||||
byte[] siteContextLengthBytes = bytesForInt( siteContextBytes == null? 0: siteContextBytes.length );
|
byte[] siteContextLengthBytes = bytesForInt( siteContextBytes == null? 0: siteContextBytes.length );
|
||||||
logger.trc( "site scope: %s, context: %s", siteScope, siteContext == null? "<empty>": siteContext );
|
logger.trc( "site scope: %s, context: %s", siteScope, siteContextBytes == null? "<empty>": siteContext );
|
||||||
logger.trc( "seed from: hmac-sha256(masterKey, %s | %s | %s | %s | %s | %s)", siteScope, CodeUtils.encodeHex( siteNameLengthBytes ),
|
logger.trc( "seed from: hmac-sha256(masterKey, %s | %s | %s | %s | %s | %s)", siteScope, CodeUtils.encodeHex( siteNameLengthBytes ),
|
||||||
siteName, CodeUtils.encodeHex( siteCounterBytes ), CodeUtils.encodeHex( siteContextLengthBytes ),
|
siteName, CodeUtils.encodeHex( siteCounterBytes ), CodeUtils.encodeHex( siteContextLengthBytes ),
|
||||||
siteContext == null? "(null)": siteContext );
|
siteContextBytes == null? "(null)": siteContext );
|
||||||
|
|
||||||
byte[] sitePasswordInfo = Bytes.concat( siteScope.getBytes( MP_charset ), siteNameLengthBytes, siteNameBytes, siteCounterBytes );
|
byte[] sitePasswordInfo = Bytes.concat( siteScope.getBytes( MP_charset ), siteNameLengthBytes, siteNameBytes, siteCounterBytes );
|
||||||
if (siteContextBytes != null)
|
if (siteContextBytes != null)
|
||||||
sitePasswordInfo = Bytes.concat( sitePasswordInfo, siteContextLengthBytes, siteContextBytes );
|
sitePasswordInfo = Bytes.concat( sitePasswordInfo, siteContextLengthBytes, siteContextBytes );
|
||||||
logger.trc( "sitePasswordInfo ID: %s", CodeUtils.encodeHex( idForBytes( sitePasswordInfo ) ) );
|
logger.trc( "sitePasswordInfo ID: %s", CodeUtils.encodeHex( idForBytes( sitePasswordInfo ) ) );
|
||||||
|
|
||||||
byte[] sitePasswordSeed = MP_mac.of( getKey(), sitePasswordInfo );
|
byte[] sitePasswordSeedBytes = MP_mac.of( getKey(), sitePasswordInfo );
|
||||||
logger.trc( "sitePasswordSeed ID: %s", CodeUtils.encodeHex( idForBytes( sitePasswordSeed ) ) );
|
int[] sitePasswordSeed = new int[sitePasswordSeedBytes.length];
|
||||||
|
for (int i = 0; i < sitePasswordSeedBytes.length; ++i) {
|
||||||
|
ByteBuffer buf = ByteBuffer.allocate( Integer.SIZE / Byte.SIZE ).order( ByteOrder.BIG_ENDIAN );
|
||||||
|
Arrays.fill( buf.array(), sitePasswordSeedBytes[i] > 0? (byte)0x00: (byte) 0xFF );
|
||||||
|
buf.position( 2 );
|
||||||
|
buf.put( sitePasswordSeedBytes[i] ).rewind();
|
||||||
|
sitePasswordSeed[i] = buf.getInt() & 0xFFFF;
|
||||||
|
}
|
||||||
|
logger.trc( "sitePasswordSeed ID: %s", CodeUtils.encodeHex( idForBytes( sitePasswordSeedBytes ) ) );
|
||||||
|
|
||||||
Preconditions.checkState( sitePasswordSeed.length > 0 );
|
Preconditions.checkState( sitePasswordSeed.length > 0 );
|
||||||
int templateIndex = sitePasswordSeed[0] & 0xFFFF;
|
int templateIndex = sitePasswordSeed[0];
|
||||||
MPTemplate template = siteType.getTemplateAtRollingIndex( templateIndex );
|
MPTemplate template = siteType.getTemplateAtRollingIndex( templateIndex );
|
||||||
logger.trc( "type %s, template: %s", siteType, template.getTemplateString() );
|
logger.trc( "type %s, template: %s", siteType, template.getTemplateString() );
|
||||||
|
|
||||||
StringBuilder password = new StringBuilder( template.length() );
|
StringBuilder password = new StringBuilder( template.length() );
|
||||||
for (int i = 0; i < template.length(); ++i) {
|
for (int i = 0; i < template.length(); ++i) {
|
||||||
int characterIndex = sitePasswordSeed[i + 1] & 0xFFFF;
|
int characterIndex = sitePasswordSeed[i + 1];
|
||||||
MPTemplateCharacterClass characterClass = template.getCharacterClassAtIndex( i );
|
MPTemplateCharacterClass characterClass = template.getCharacterClassAtIndex( i );
|
||||||
char passwordCharacter = characterClass.getCharacterAtRollingIndex( characterIndex );
|
char passwordCharacter = characterClass.getCharacterAtRollingIndex( characterIndex );
|
||||||
logger.trc( "class %c, index %d (0x%02X) -> character: %c", characterClass.getIdentifier(), characterIndex,
|
logger.trc( "class %c, index %d (0x%02X) -> character: %c", characterClass.getIdentifier(), characterIndex,
|
||||||
|
@ -46,12 +46,12 @@ public class MasterKeyV1 extends MasterKeyV0 {
|
|||||||
byte[] siteNameBytes = siteName.getBytes( MP_charset );
|
byte[] siteNameBytes = siteName.getBytes( MP_charset );
|
||||||
byte[] siteNameLengthBytes = bytesForInt( siteName.length() );
|
byte[] siteNameLengthBytes = bytesForInt( siteName.length() );
|
||||||
byte[] siteCounterBytes = bytesForInt( siteCounter );
|
byte[] siteCounterBytes = bytesForInt( siteCounter );
|
||||||
byte[] siteContextBytes = siteContext == null? null: siteContext.getBytes( MP_charset );
|
byte[] siteContextBytes = siteContext == null || siteContext.isEmpty()? null: siteContext.getBytes( MP_charset );
|
||||||
byte[] siteContextLengthBytes = bytesForInt( siteContextBytes == null? 0: siteContextBytes.length );
|
byte[] siteContextLengthBytes = bytesForInt( siteContextBytes == null? 0: siteContextBytes.length );
|
||||||
logger.trc( "site scope: %s, context: %s", siteScope, siteContext == null? "<empty>": siteContext );
|
logger.trc( "site scope: %s, context: %s", siteScope, siteContextBytes == null? "<empty>": siteContext );
|
||||||
logger.trc( "seed from: hmac-sha256(masterKey, %s | %s | %s | %s | %s | %s)", siteScope, CodeUtils.encodeHex( siteNameLengthBytes ),
|
logger.trc( "seed from: hmac-sha256(masterKey, %s | %s | %s | %s | %s | %s)", siteScope, CodeUtils.encodeHex( siteNameLengthBytes ),
|
||||||
siteName, CodeUtils.encodeHex( siteCounterBytes ), CodeUtils.encodeHex( siteContextLengthBytes ),
|
siteName, CodeUtils.encodeHex( siteCounterBytes ), CodeUtils.encodeHex( siteContextLengthBytes ),
|
||||||
siteContext == null? "(null)": siteContext );
|
siteContextBytes == null? "(null)": siteContext );
|
||||||
|
|
||||||
byte[] sitePasswordInfo = Bytes.concat( siteScope.getBytes( MP_charset ), siteNameLengthBytes, siteNameBytes, siteCounterBytes );
|
byte[] sitePasswordInfo = Bytes.concat( siteScope.getBytes( MP_charset ), siteNameLengthBytes, siteNameBytes, siteCounterBytes );
|
||||||
if (siteContextBytes != null)
|
if (siteContextBytes != null)
|
||||||
|
@ -45,12 +45,12 @@ public class MasterKeyV2 extends MasterKeyV1 {
|
|||||||
byte[] siteNameBytes = siteName.getBytes( MP_charset );
|
byte[] siteNameBytes = siteName.getBytes( MP_charset );
|
||||||
byte[] siteNameLengthBytes = bytesForInt( siteNameBytes.length );
|
byte[] siteNameLengthBytes = bytesForInt( siteNameBytes.length );
|
||||||
byte[] siteCounterBytes = bytesForInt( siteCounter );
|
byte[] siteCounterBytes = bytesForInt( siteCounter );
|
||||||
byte[] siteContextBytes = siteContext == null? null: siteContext.getBytes( MP_charset );
|
byte[] siteContextBytes = siteContext == null || siteContext.isEmpty()? null: siteContext.getBytes( MP_charset );
|
||||||
byte[] siteContextLengthBytes = bytesForInt( siteContextBytes == null? 0: siteContextBytes.length );
|
byte[] siteContextLengthBytes = bytesForInt( siteContextBytes == null? 0: siteContextBytes.length );
|
||||||
logger.trc( "site scope: %s, context: %s", siteScope, siteContext == null? "<empty>": siteContext );
|
logger.trc( "site scope: %s, context: %s", siteScope, siteContextBytes == null? "<empty>": siteContext );
|
||||||
logger.trc( "seed from: hmac-sha256(masterKey, %s | %s | %s | %s | %s | %s)", siteScope, CodeUtils.encodeHex( siteNameLengthBytes ),
|
logger.trc( "seed from: hmac-sha256(masterKey, %s | %s | %s | %s | %s | %s)", siteScope, CodeUtils.encodeHex( siteNameLengthBytes ),
|
||||||
siteName, CodeUtils.encodeHex( siteCounterBytes ), CodeUtils.encodeHex( siteContextLengthBytes ),
|
siteName, CodeUtils.encodeHex( siteCounterBytes ), CodeUtils.encodeHex( siteContextLengthBytes ),
|
||||||
siteContext == null? "(null)": siteContext );
|
siteContextBytes == null? "(null)": siteContext );
|
||||||
|
|
||||||
byte[] sitePasswordInfo = Bytes.concat( siteScope.getBytes( MP_charset ), siteNameLengthBytes, siteNameBytes, siteCounterBytes );
|
byte[] sitePasswordInfo = Bytes.concat( siteScope.getBytes( MP_charset ), siteNameLengthBytes, siteNameBytes, siteCounterBytes );
|
||||||
if (siteContextBytes != null)
|
if (siteContextBytes != null)
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package com.lyndir.masterpassword;
|
package com.lyndir.masterpassword;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.lyndir.lhunath.opal.system.util.ObjectUtils.*;
|
import static com.lyndir.lhunath.opal.system.util.ObjectUtils.*;
|
||||||
|
|
||||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||||
import com.lyndir.lhunath.opal.system.util.NNSupplier;
|
import com.lyndir.lhunath.opal.system.util.*;
|
||||||
import com.lyndir.lhunath.opal.system.util.NSupplier;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@ -25,8 +25,9 @@ public class MPWTests {
|
|||||||
@XmlElement(name = "case")
|
@XmlElement(name = "case")
|
||||||
private List<Case> cases;
|
private List<Case> cases;
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public List<Case> getCases() {
|
public List<Case> getCases() {
|
||||||
return cases;
|
return checkNotNull( cases );
|
||||||
}
|
}
|
||||||
|
|
||||||
public Case getCase(String identifier) {
|
public Case getCase(String identifier) {
|
||||||
@ -45,6 +46,8 @@ public class MPWTests {
|
|||||||
@XmlAttribute
|
@XmlAttribute
|
||||||
private String parent;
|
private String parent;
|
||||||
@XmlElement
|
@XmlElement
|
||||||
|
private String algorithm;
|
||||||
|
@XmlElement
|
||||||
private String fullName;
|
private String fullName;
|
||||||
@XmlElement
|
@XmlElement
|
||||||
private String masterPassword;
|
private String masterPassword;
|
||||||
@ -65,76 +68,86 @@ public class MPWTests {
|
|||||||
|
|
||||||
private transient Case parentCase;
|
private transient Case parentCase;
|
||||||
|
|
||||||
public void setTests(MPWTests tests) {
|
public void initializeParentHierarchy(MPWTests tests) {
|
||||||
|
|
||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
parentCase = tests.getCase( parent );
|
parentCase = tests.getCase( parent );
|
||||||
|
parentCase.initializeParentHierarchy( tests );
|
||||||
|
}
|
||||||
|
|
||||||
|
algorithm = ifNotNullElse( algorithm, new NNSupplier<String>() {
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public String get() {
|
||||||
|
return checkNotNull( parentCase.algorithm );
|
||||||
|
}
|
||||||
|
} );
|
||||||
fullName = ifNotNullElse( fullName, new NNSupplier<String>() {
|
fullName = ifNotNullElse( fullName, new NNSupplier<String>() {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String get() {
|
public String get() {
|
||||||
return parentCase.getFullName();
|
return checkNotNull( parentCase.fullName );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
masterPassword = ifNotNullElse( masterPassword, new NNSupplier<String>() {
|
masterPassword = ifNotNullElse( masterPassword, new NNSupplier<String>() {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String get() {
|
public String get() {
|
||||||
return new String( parentCase.getMasterPassword() );
|
return checkNotNull( parentCase.masterPassword );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
keyID = ifNotNullElse( keyID, new NNSupplier<String>() {
|
keyID = ifNotNullElse( keyID, new NNSupplier<String>() {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String get() {
|
public String get() {
|
||||||
return parentCase.getKeyID();
|
return checkNotNull( parentCase.keyID );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
siteName = ifNotNullElse( siteName, new NNSupplier<String>() {
|
siteName = ifNotNullElse( siteName, new NNSupplier<String>() {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String get() {
|
public String get() {
|
||||||
return parentCase.getSiteName();
|
return checkNotNull( parentCase.siteName );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
siteCounter = ifNotNullElse( siteCounter, new NNSupplier<Integer>() {
|
siteCounter = ifNotNullElse( siteCounter, new NNSupplier<Integer>() {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Integer get() {
|
public Integer get() {
|
||||||
return parentCase.getSiteCounter();
|
return checkNotNull( parentCase.siteCounter );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
siteType = ifNotNullElse( siteType, new NNSupplier<String>() {
|
siteType = ifNotNullElse( siteType, new NNSupplier<String>() {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String get() {
|
public String get() {
|
||||||
return parentCase.getSiteType().name();
|
return checkNotNull( parentCase.siteType );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
siteVariant = ifNotNullElse( siteVariant, new NNSupplier<String>() {
|
siteVariant = ifNotNullElse( siteVariant, new NNSupplier<String>() {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String get() {
|
public String get() {
|
||||||
return parentCase.getSiteVariant().name();
|
return checkNotNull( parentCase.siteVariant );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
siteContext = ifNotNullElseNullable( siteContext, new NSupplier<String>() {
|
siteContext = ifNotNullElse( siteContext, new NNSupplier<String>() {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String get() {
|
public String get() {
|
||||||
return parentCase.getSiteContext();
|
return parentCase == null? "": checkNotNull( parentCase.siteContext );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
result = ifNotNullElse( result, new NNSupplier<String>() {
|
result = ifNotNullElse( result, new NNSupplier<String>() {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String get() {
|
public String get() {
|
||||||
return parentCase.getResult();
|
return parentCase == null? "": checkNotNull( parentCase.result );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public String getIdentifier() {
|
public String getIdentifier() {
|
||||||
return identifier;
|
return identifier;
|
||||||
}
|
}
|
||||||
@ -144,40 +157,53 @@ public class MPWTests {
|
|||||||
return parentCase;
|
return parentCase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public MasterKey.Version getAlgorithm() {
|
||||||
|
return MasterKey.Version.fromInt( ConversionUtils.toIntegerNN( algorithm ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public String getFullName() {
|
public String getFullName() {
|
||||||
return fullName;
|
return checkNotNull( fullName );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public char[] getMasterPassword() {
|
public char[] getMasterPassword() {
|
||||||
return masterPassword == null? null: masterPassword.toCharArray();
|
return checkNotNull( masterPassword ).toCharArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public String getKeyID() {
|
public String getKeyID() {
|
||||||
return keyID;
|
return checkNotNull( keyID );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public String getSiteName() {
|
public String getSiteName() {
|
||||||
return siteName;
|
return checkNotNull( siteName );
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSiteCounter() {
|
public int getSiteCounter() {
|
||||||
return ifNotNullElse( siteCounter, 1 );
|
return ifNotNullElse( siteCounter, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public MPSiteType getSiteType() {
|
public MPSiteType getSiteType() {
|
||||||
return MPSiteType.forName( siteType );
|
return MPSiteType.forName( checkNotNull( siteType ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public MPSiteVariant getSiteVariant() {
|
public MPSiteVariant getSiteVariant() {
|
||||||
return MPSiteVariant.forName( siteVariant );
|
return MPSiteVariant.forName( checkNotNull( siteVariant ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public String getSiteContext() {
|
public String getSiteContext() {
|
||||||
return siteContext;
|
return checkNotNull( siteContext );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public String getResult() {
|
public String getResult() {
|
||||||
return result;
|
return checkNotNull( result );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -5,6 +5,7 @@ import static org.testng.Assert.*;
|
|||||||
import com.google.common.io.Resources;
|
import com.google.common.io.Resources;
|
||||||
import com.lyndir.lhunath.opal.system.CodeUtils;
|
import com.lyndir.lhunath.opal.system.CodeUtils;
|
||||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||||
|
import com.lyndir.lhunath.opal.system.util.StringUtils;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import javax.xml.bind.JAXBContext;
|
import javax.xml.bind.JAXBContext;
|
||||||
import org.testng.annotations.BeforeMethod;
|
import org.testng.annotations.BeforeMethod;
|
||||||
@ -26,7 +27,7 @@ public class MasterKeyTest {
|
|||||||
URL testCasesResource = Resources.getResource( "mpw_tests.xml" );
|
URL testCasesResource = Resources.getResource( "mpw_tests.xml" );
|
||||||
tests = (MPWTests) JAXBContext.newInstance( MPWTests.class ).createUnmarshaller().unmarshal( testCasesResource );
|
tests = (MPWTests) JAXBContext.newInstance( MPWTests.class ).createUnmarshaller().unmarshal( testCasesResource );
|
||||||
for (MPWTests.Case testCase : tests.getCases())
|
for (MPWTests.Case testCase : tests.getCases())
|
||||||
testCase.setTests( tests );
|
testCase.initializeParentHierarchy( tests );
|
||||||
defaultCase = tests.getCase( MPWTests.ID_DEFAULT );
|
defaultCase = tests.getCase( MPWTests.ID_DEFAULT );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,10 +36,15 @@ public class MasterKeyTest {
|
|||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
||||||
for (MPWTests.Case testCase : tests.getCases()) {
|
for (MPWTests.Case testCase : tests.getCases()) {
|
||||||
MasterKey masterKey = MasterKey.create( testCase.getFullName(), testCase.getMasterPassword() );
|
if (testCase.getResult().isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
logger.inf( "Running test case: %s [testEncode]", testCase.getIdentifier() );
|
||||||
|
MasterKey masterKey = MasterKey.create( testCase.getAlgorithm(), testCase.getFullName(), testCase.getMasterPassword() );
|
||||||
assertEquals(
|
assertEquals(
|
||||||
masterKey.encode( testCase.getSiteName(), testCase.getSiteType(), testCase.getSiteCounter(), testCase.getSiteVariant(),
|
masterKey.encode( testCase.getSiteName(), testCase.getSiteType(), testCase.getSiteCounter(), testCase.getSiteVariant(),
|
||||||
testCase.getSiteContext() ), testCase.getResult(), "Failed test case: " + testCase );
|
testCase.getSiteContext() ), testCase.getResult(), "Failed test case: " + testCase );
|
||||||
|
logger.inf( "passed!" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,8 +61,13 @@ public class MasterKeyTest {
|
|||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
||||||
for (MPWTests.Case testCase : tests.getCases()) {
|
for (MPWTests.Case testCase : tests.getCases()) {
|
||||||
|
if (testCase.getResult().isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
logger.inf( "Running test case: %s [testGetKeyID]", testCase.getIdentifier() );
|
||||||
MasterKey masterKey = MasterKey.create( testCase.getFullName(), testCase.getMasterPassword() );
|
MasterKey masterKey = MasterKey.create( testCase.getFullName(), testCase.getMasterPassword() );
|
||||||
assertEquals( CodeUtils.encodeHex( masterKey.getKeyID() ), testCase.getKeyID(), "Failed test case: " + testCase );
|
assertEquals( CodeUtils.encodeHex( masterKey.getKeyID() ), testCase.getKeyID(), "Failed test case: " + testCase );
|
||||||
|
logger.inf( "passed!" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
<tests>
|
<tests>
|
||||||
|
<!-- Default values for all parameters. -->
|
||||||
<case id="default">
|
<case id="default">
|
||||||
|
<algorithm><!-- current --></algorithm>
|
||||||
<fullName>Robert Lee Mitchell</fullName>
|
<fullName>Robert Lee Mitchell</fullName>
|
||||||
<masterPassword>banana colored duckling</masterPassword>
|
<masterPassword>banana colored duckling</masterPassword>
|
||||||
<keyID>98EEF4D1DF46D849574A82A03C3177056B15DFFCA29BB3899DE4628453675302</keyID>
|
<keyID>98EEF4D1DF46D849574A82A03C3177056B15DFFCA29BB3899DE4628453675302</keyID>
|
||||||
@ -7,67 +9,271 @@
|
|||||||
<siteCounter>1</siteCounter>
|
<siteCounter>1</siteCounter>
|
||||||
<siteType>GeneratedLong</siteType>
|
<siteType>GeneratedLong</siteType>
|
||||||
<siteVariant>Password</siteVariant>
|
<siteVariant>Password</siteVariant>
|
||||||
|
<result><!-- abstract --></result>
|
||||||
|
</case>
|
||||||
|
|
||||||
|
<!-- Algorithm 3 -->
|
||||||
|
<case id="v3" parent="default">
|
||||||
|
<algorithm>3</algorithm>
|
||||||
<result>Jejr5[RepuSosp</result>
|
<result>Jejr5[RepuSosp</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="mb_fullName" parent="default">
|
<case id="v3_mb_fullName" parent="v3">
|
||||||
<fullName>⛄</fullName>
|
<fullName>⛄</fullName>
|
||||||
<keyID>1717AA1F9BF5BA56CD0965CDA3D78E6D2E6A1EA8C067A8EA621F3DDAD4A87EB8</keyID>
|
<keyID>1717AA1F9BF5BA56CD0965CDA3D78E6D2E6A1EA8C067A8EA621F3DDAD4A87EB8</keyID>
|
||||||
<result>NopaDajh8=Fene</result>
|
<result>NopaDajh8=Fene</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="mb_masterPassword" parent="default">
|
<case id="v3_mb_masterPassword" parent="v3">
|
||||||
<masterPassword>⛄</masterPassword>
|
<masterPassword>⛄</masterPassword>
|
||||||
<keyID>351432B8528A5ABECAB768CA95015097DE76FE14C41E10AF36C67DCFB8917E08</keyID>
|
<keyID>351432B8528A5ABECAB768CA95015097DE76FE14C41E10AF36C67DCFB8917E08</keyID>
|
||||||
<result>QesuHirv5-Xepl</result>
|
<result>QesuHirv5-Xepl</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="mb_siteName" parent="default">
|
<case id="v3_mb_siteName" parent="v3">
|
||||||
<siteName>⛄</siteName>
|
<siteName>⛄</siteName>
|
||||||
<result>LiheCuwhSerz6)</result>
|
<result>LiheCuwhSerz6)</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="loginName" parent="default">
|
<case id="v3_loginName" parent="v3">
|
||||||
<siteVariant>Login</siteVariant>
|
<siteVariant>Login</siteVariant>
|
||||||
<siteType>GeneratedName</siteType>
|
<siteType>GeneratedName</siteType>
|
||||||
<result>wohzaqage</result>
|
<result>wohzaqage</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="securityAnswer" parent="default">
|
<case id="v3_securityAnswer" parent="v3">
|
||||||
<siteVariant>Answer</siteVariant>
|
<siteVariant>Answer</siteVariant>
|
||||||
<siteType>GeneratedPhrase</siteType>
|
<siteType>GeneratedPhrase</siteType>
|
||||||
<result>xin diyjiqoja hubu</result>
|
<result>xin diyjiqoja hubu</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="securityAnswer_context" parent="securityAnswer">
|
<case id="v3_securityAnswer_context" parent="v3_securityAnswer">
|
||||||
<siteContext>question</siteContext>
|
<siteContext>question</siteContext>
|
||||||
<result>xogx tem cegyiva jab</result>
|
<result>xogx tem cegyiva jab</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="type_maximum" parent="default">
|
<case id="v3_type_maximum" parent="v3">
|
||||||
<siteType>GeneratedMaximum</siteType>
|
<siteType>GeneratedMaximum</siteType>
|
||||||
<result>W6@692^B1#&@gVdSdLZ@</result>
|
<result>W6@692^B1#&@gVdSdLZ@</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="type_medium" parent="default">
|
<case id="v3_type_medium" parent="v3">
|
||||||
<siteType>GeneratedMedium</siteType>
|
<siteType>GeneratedMedium</siteType>
|
||||||
<result>Jej2$Quv</result>
|
<result>Jej2$Quv</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="type_basic" parent="default">
|
<case id="v3_type_basic" parent="v3">
|
||||||
<siteType>GeneratedBasic</siteType>
|
<siteType>GeneratedBasic</siteType>
|
||||||
<result>WAo2xIg6</result>
|
<result>WAo2xIg6</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="type_short" parent="default">
|
<case id="v3_type_short" parent="v3">
|
||||||
<siteType>GeneratedShort</siteType>
|
<siteType>GeneratedShort</siteType>
|
||||||
<result>Jej2</result>
|
<result>Jej2</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="type_pin" parent="default">
|
<case id="v3_type_pin" parent="v3">
|
||||||
<siteType>GeneratedPIN</siteType>
|
<siteType>GeneratedPIN</siteType>
|
||||||
<result>7662</result>
|
<result>7662</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="type_name" parent="default">
|
<case id="v3_type_name" parent="v3">
|
||||||
<siteType>GeneratedName</siteType>
|
<siteType>GeneratedName</siteType>
|
||||||
<result>jejraquvo</result>
|
<result>jejraquvo</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="type_phrase" parent="default">
|
<case id="v3_type_phrase" parent="v3">
|
||||||
<siteType>GeneratedPhrase</siteType>
|
<siteType>GeneratedPhrase</siteType>
|
||||||
<result>jejr quv cabsibu tam</result>
|
<result>jejr quv cabsibu tam</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="counter_ceiling" parent="default">
|
<case id="v3_counter_ceiling" parent="v3">
|
||||||
<siteCounter>4294967295</siteCounter>
|
<siteCounter>4294967295</siteCounter>
|
||||||
<result>XambHoqo6[Peni</result>
|
<result>XambHoqo6[Peni</result>
|
||||||
</case>
|
</case>
|
||||||
|
|
||||||
|
<!-- Algorithm 2 -->
|
||||||
|
<case id="v2" parent="default">
|
||||||
|
<algorithm>2</algorithm>
|
||||||
|
<result>Jejr5[RepuSosp</result>
|
||||||
|
</case>
|
||||||
|
<case id="v2_mb_fullName" parent="v2">
|
||||||
|
<fullName>⛄</fullName>
|
||||||
|
<keyID>1717AA1F9BF5BA56CD0965CDA3D78E6D2E6A1EA8C067A8EA621F3DDAD4A87EB8</keyID>
|
||||||
|
<result>WaqoGuho2[Xaxw</result>
|
||||||
|
</case>
|
||||||
|
<case id="v2_mb_masterPassword" parent="v2">
|
||||||
|
<masterPassword>⛄</masterPassword>
|
||||||
|
<keyID>351432B8528A5ABECAB768CA95015097DE76FE14C41E10AF36C67DCFB8917E08</keyID>
|
||||||
|
<result>QesuHirv5-Xepl</result>
|
||||||
|
</case>
|
||||||
|
<case id="v2_mb_siteName" parent="v2">
|
||||||
|
<siteName>⛄</siteName>
|
||||||
|
<result>LiheCuwhSerz6)</result>
|
||||||
|
</case>
|
||||||
|
<case id="v2_loginName" parent="v2">
|
||||||
|
<siteVariant>Login</siteVariant>
|
||||||
|
<siteType>GeneratedName</siteType>
|
||||||
|
<result>wohzaqage</result>
|
||||||
|
</case>
|
||||||
|
<case id="v2_securityAnswer" parent="v2">
|
||||||
|
<siteVariant>Answer</siteVariant>
|
||||||
|
<siteType>GeneratedPhrase</siteType>
|
||||||
|
<result>xin diyjiqoja hubu</result>
|
||||||
|
</case>
|
||||||
|
<case id="v2_securityAnswer_context" parent="v2_securityAnswer">
|
||||||
|
<siteContext>question</siteContext>
|
||||||
|
<result>xogx tem cegyiva jab</result>
|
||||||
|
</case>
|
||||||
|
<case id="v2_type_maximum" parent="v2">
|
||||||
|
<siteType>GeneratedMaximum</siteType>
|
||||||
|
<result>W6@692^B1#&@gVdSdLZ@</result>
|
||||||
|
</case>
|
||||||
|
<case id="v2_type_medium" parent="v2">
|
||||||
|
<siteType>GeneratedMedium</siteType>
|
||||||
|
<result>Jej2$Quv</result>
|
||||||
|
</case>
|
||||||
|
<case id="v2_type_basic" parent="v2">
|
||||||
|
<siteType>GeneratedBasic</siteType>
|
||||||
|
<result>WAo2xIg6</result>
|
||||||
|
</case>
|
||||||
|
<case id="v2_type_short" parent="v2">
|
||||||
|
<siteType>GeneratedShort</siteType>
|
||||||
|
<result>Jej2</result>
|
||||||
|
</case>
|
||||||
|
<case id="v2_type_pin" parent="v2">
|
||||||
|
<siteType>GeneratedPIN</siteType>
|
||||||
|
<result>7662</result>
|
||||||
|
</case>
|
||||||
|
<case id="v2_type_name" parent="v2">
|
||||||
|
<siteType>GeneratedName</siteType>
|
||||||
|
<result>jejraquvo</result>
|
||||||
|
</case>
|
||||||
|
<case id="v2_type_phrase" parent="v2">
|
||||||
|
<siteType>GeneratedPhrase</siteType>
|
||||||
|
<result>jejr quv cabsibu tam</result>
|
||||||
|
</case>
|
||||||
|
<case id="v2_counter_ceiling" parent="v2">
|
||||||
|
<siteCounter>4294967295</siteCounter>
|
||||||
|
<result>XambHoqo6[Peni</result>
|
||||||
|
</case>
|
||||||
|
|
||||||
|
<!-- Algorithm 1 -->
|
||||||
|
<case id="v1" parent="default">
|
||||||
|
<algorithm>1</algorithm>
|
||||||
|
<result>Jejr5[RepuSosp</result>
|
||||||
|
</case>
|
||||||
|
<case id="v1_mb_fullName" parent="v1">
|
||||||
|
<fullName>⛄</fullName>
|
||||||
|
<keyID>1717AA1F9BF5BA56CD0965CDA3D78E6D2E6A1EA8C067A8EA621F3DDAD4A87EB8</keyID>
|
||||||
|
<result>WaqoGuho2[Xaxw</result>
|
||||||
|
</case>
|
||||||
|
<case id="v1_mb_masterPassword" parent="v1">
|
||||||
|
<masterPassword>⛄</masterPassword>
|
||||||
|
<keyID>351432B8528A5ABECAB768CA95015097DE76FE14C41E10AF36C67DCFB8917E08</keyID>
|
||||||
|
<result>QesuHirv5-Xepl</result>
|
||||||
|
</case>
|
||||||
|
<case id="v1_mb_siteName" parent="v1">
|
||||||
|
<siteName>⛄</siteName>
|
||||||
|
<result>WawiYarp2@Kodh</result>
|
||||||
|
</case>
|
||||||
|
<case id="v1_loginName" parent="v1">
|
||||||
|
<siteVariant>Login</siteVariant>
|
||||||
|
<siteType>GeneratedName</siteType>
|
||||||
|
<result>wohzaqage</result>
|
||||||
|
</case>
|
||||||
|
<case id="v1_securityAnswer" parent="v1">
|
||||||
|
<siteVariant>Answer</siteVariant>
|
||||||
|
<siteType>GeneratedPhrase</siteType>
|
||||||
|
<result>xin diyjiqoja hubu</result>
|
||||||
|
</case>
|
||||||
|
<case id="v1_securityAnswer_context" parent="v1_securityAnswer">
|
||||||
|
<siteContext>question</siteContext>
|
||||||
|
<result>xogx tem cegyiva jab</result>
|
||||||
|
</case>
|
||||||
|
<case id="v1_type_maximum" parent="v1">
|
||||||
|
<siteType>GeneratedMaximum</siteType>
|
||||||
|
<result>W6@692^B1#&@gVdSdLZ@</result>
|
||||||
|
</case>
|
||||||
|
<case id="v1_type_medium" parent="v1">
|
||||||
|
<siteType>GeneratedMedium</siteType>
|
||||||
|
<result>Jej2$Quv</result>
|
||||||
|
</case>
|
||||||
|
<case id="v1_type_basic" parent="v1">
|
||||||
|
<siteType>GeneratedBasic</siteType>
|
||||||
|
<result>WAo2xIg6</result>
|
||||||
|
</case>
|
||||||
|
<case id="v1_type_short" parent="v1">
|
||||||
|
<siteType>GeneratedShort</siteType>
|
||||||
|
<result>Jej2</result>
|
||||||
|
</case>
|
||||||
|
<case id="v1_type_pin" parent="v1">
|
||||||
|
<siteType>GeneratedPIN</siteType>
|
||||||
|
<result>7662</result>
|
||||||
|
</case>
|
||||||
|
<case id="v1_type_name" parent="v1">
|
||||||
|
<siteType>GeneratedName</siteType>
|
||||||
|
<result>jejraquvo</result>
|
||||||
|
</case>
|
||||||
|
<case id="v1_type_phrase" parent="v1">
|
||||||
|
<siteType>GeneratedPhrase</siteType>
|
||||||
|
<result>jejr quv cabsibu tam</result>
|
||||||
|
</case>
|
||||||
|
<case id="v1_counter_ceiling" parent="v1">
|
||||||
|
<siteCounter>4294967295</siteCounter>
|
||||||
|
<result>XambHoqo6[Peni</result>
|
||||||
|
</case>
|
||||||
|
|
||||||
|
<!-- Algorithm 0 -->
|
||||||
|
<case id="v0" parent="default">
|
||||||
|
<algorithm>0</algorithm>
|
||||||
|
<result>Feji5@ReduWosh</result>
|
||||||
|
</case>
|
||||||
|
<case id="v0_mb_fullName" parent="v0">
|
||||||
|
<fullName>⛄</fullName>
|
||||||
|
<keyID>1717AA1F9BF5BA56CD0965CDA3D78E6D2E6A1EA8C067A8EA621F3DDAD4A87EB8</keyID>
|
||||||
|
<result>HajrYudo7@Mamh</result>
|
||||||
|
</case>
|
||||||
|
<case id="v0_mb_masterPassword" parent="v0">
|
||||||
|
<masterPassword>⛄</masterPassword>
|
||||||
|
<keyID>351432B8528A5ABECAB768CA95015097DE76FE14C41E10AF36C67DCFB8917E08</keyID>
|
||||||
|
<result>MewmDini0]Meho</result>
|
||||||
|
</case>
|
||||||
|
<case id="v0_mb_siteName" parent="v0">
|
||||||
|
<siteName>⛄</siteName>
|
||||||
|
<result>HahiVana2@Nole</result>
|
||||||
|
</case>
|
||||||
|
<case id="v0_loginName" parent="v0">
|
||||||
|
<siteVariant>Login</siteVariant>
|
||||||
|
<siteType>GeneratedName</siteType>
|
||||||
|
<result>lozwajave</result>
|
||||||
|
</case>
|
||||||
|
<case id="v0_securityAnswer" parent="v0">
|
||||||
|
<siteVariant>Answer</siteVariant>
|
||||||
|
<siteType>GeneratedPhrase</siteType>
|
||||||
|
<result>miy lirfijoja dubu</result>
|
||||||
|
</case>
|
||||||
|
<case id="v0_securityAnswer_context" parent="v0_securityAnswer">
|
||||||
|
<siteContext>question</siteContext>
|
||||||
|
<result>movm bex gevrica jaf</result>
|
||||||
|
</case>
|
||||||
|
<case id="v0_type_maximum" parent="v0">
|
||||||
|
<siteType>GeneratedMaximum</siteType>
|
||||||
|
<result>w1!3bA3icmRAc)SS@lwl</result>
|
||||||
|
</case>
|
||||||
|
<case id="v0_type_medium" parent="v0">
|
||||||
|
<siteType>GeneratedMedium</siteType>
|
||||||
|
<result>Fej7]Jug</result>
|
||||||
|
</case>
|
||||||
|
<case id="v0_type_basic" parent="v0">
|
||||||
|
<siteType>GeneratedBasic</siteType>
|
||||||
|
<result>wvH7irC1</result>
|
||||||
|
</case>
|
||||||
|
<case id="v0_type_short" parent="v0">
|
||||||
|
<siteType>GeneratedShort</siteType>
|
||||||
|
<result>Fej7</result>
|
||||||
|
</case>
|
||||||
|
<case id="v0_type_pin" parent="v0">
|
||||||
|
<siteType>GeneratedPIN</siteType>
|
||||||
|
<result>2117</result>
|
||||||
|
</case>
|
||||||
|
<case id="v0_type_name" parent="v0">
|
||||||
|
<siteType>GeneratedName</siteType>
|
||||||
|
<result>fejrajugo</result>
|
||||||
|
</case>
|
||||||
|
<case id="v0_type_phrase" parent="v0">
|
||||||
|
<siteType>GeneratedPhrase</siteType>
|
||||||
|
<result>fejr jug gabsibu bax</result>
|
||||||
|
</case>
|
||||||
|
<case id="v0_counter_ceiling" parent="v0">
|
||||||
|
<siteCounter>4294967295</siteCounter>
|
||||||
|
<result>QateDojh1@Hecn</result>
|
||||||
|
</case>
|
||||||
</tests>
|
</tests>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user