Merge remote-tracking branch 'origin/master' into Bulletin_Board_Server_phase_1
commit
a11f78aa59
|
@ -57,6 +57,15 @@ dependencies {
|
||||||
|
|
||||||
/*==== You probably don't have to edit below this line =======*/
|
/*==== You probably don't have to edit below this line =======*/
|
||||||
|
|
||||||
|
// The run task added by the application plugin
|
||||||
|
// is also of type JavaExec.
|
||||||
|
tasks.withType(JavaExec) {
|
||||||
|
// Assign all Java system properties from
|
||||||
|
// the command line to the JavaExec task.
|
||||||
|
systemProperties System.properties
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protobuf {
|
protobuf {
|
||||||
// Configure the protoc executable
|
// Configure the protoc executable
|
||||||
protoc {
|
protoc {
|
||||||
|
|
|
@ -57,6 +57,16 @@ dependencies {
|
||||||
|
|
||||||
/*==== You probably don't have to edit below this line =======*/
|
/*==== You probably don't have to edit below this line =======*/
|
||||||
|
|
||||||
|
|
||||||
|
// The run task added by the application plugin
|
||||||
|
// is also of type JavaExec.
|
||||||
|
tasks.withType(JavaExec) {
|
||||||
|
// Assign all Java system properties from
|
||||||
|
// the command line to the JavaExec task.
|
||||||
|
systemProperties System.properties
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protobuf {
|
protobuf {
|
||||||
// Configure the protoc executable
|
// Configure the protoc executable
|
||||||
protoc {
|
protoc {
|
||||||
|
@ -91,33 +101,6 @@ idea {
|
||||||
* "Fat" Build targets
|
* "Fat" Build targets
|
||||||
*===================================*/
|
*===================================*/
|
||||||
|
|
||||||
task fatjar(type: Jar) {
|
|
||||||
description = "Generate a single jar containing everything. Use -Pfatmain=... to override main class"
|
|
||||||
|
|
||||||
destinationDir = buildDir
|
|
||||||
|
|
||||||
def fatMain = hasProperty('fatmain') ? fatmain : mainClassName
|
|
||||||
def testJar = hasProperty('test')
|
|
||||||
|
|
||||||
appendix = "${fatMain}-fat"
|
|
||||||
|
|
||||||
if (testJar) {
|
|
||||||
from sourceSets.test.output
|
|
||||||
from configurations.testRuntime.collect { it.isDirectory() ? it : zipTree(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
from sourceSets.main.output // that's it
|
|
||||||
from { configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) } }
|
|
||||||
|
|
||||||
exclude 'META-INF/MANIFEST.MF'
|
|
||||||
exclude 'META-INF/*.SF'
|
|
||||||
exclude 'META-INF/*.DSA'
|
|
||||||
exclude 'META-INF/*.RSA'
|
|
||||||
|
|
||||||
|
|
||||||
manifest { attributes 'Main-Class': fatMain }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
task mavenCapsule(type: MavenCapsule){
|
task mavenCapsule(type: MavenCapsule){
|
||||||
description = "Generate a capsule jar that automatically downloads and caches dependencies when run."
|
description = "Generate a capsule jar that automatically downloads and caches dependencies when run."
|
||||||
|
|
|
@ -8,13 +8,6 @@ import java.security.MessageDigest;
|
||||||
* Created by talm on 11/9/15.
|
* Created by talm on 11/9/15.
|
||||||
*/
|
*/
|
||||||
public interface Digest {
|
public interface Digest {
|
||||||
|
|
||||||
/**
|
|
||||||
* Marker between messages
|
|
||||||
*/
|
|
||||||
public static final byte[] CONCAT_MARKER = {(byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef,
|
|
||||||
(byte) 0xba, (byte) 0x1d, (byte) 0xfa, (byte) 0xce};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Completes the hash computation by performing final operations such as padding.
|
* Completes the hash computation by performing final operations such as padding.
|
||||||
* (copied from {@link MessageDigest#digest()})
|
* (copied from {@link MessageDigest#digest()})
|
||||||
|
@ -25,9 +18,7 @@ public interface Digest {
|
||||||
/**
|
/**
|
||||||
* Updates the digest using the specified message (in serialized wire form)
|
* Updates the digest using the specified message (in serialized wire form)
|
||||||
*
|
*
|
||||||
* Includes a special message concatenation marker (the 64 bit message {@link #CONCAT_MARKER}) in the digest (digesting a single message
|
* Each message is (automatically) prepended with its length as a 32-bit big-endian unsigned integer.
|
||||||
* will give a different result than the same message split into two messages).
|
|
||||||
* Messages must not contain the {@link #CONCAT_MARKER}) marker.
|
|
||||||
* @param msg
|
* @param msg
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -41,8 +41,8 @@ public interface DigitalSignature {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add msg to the content stream to be verified / signed. Each message is always (automatically)
|
* Add msg to the content stream to be verified / signed. Each message is (automatically)
|
||||||
* prepended with its length as a 32-bit unsigned integer in network byte order.
|
* prepended with its length as a 32-bit big-endian unsigned integer.
|
||||||
*
|
*
|
||||||
* @param msg
|
* @param msg
|
||||||
* @throws SignatureException
|
* @throws SignatureException
|
||||||
|
|
|
@ -2,13 +2,13 @@ package meerkat.crypto.concrete;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
import java.security.cert.*;
|
import java.security.cert.*;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
import meerkat.crypto.Digest;
|
|
||||||
import meerkat.protobuf.Crypto;
|
import meerkat.protobuf.Crypto;
|
||||||
import meerkat.util.Hex;
|
import meerkat.util.Hex;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -27,7 +27,7 @@ import javax.security.auth.callback.UnsupportedCallbackException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sign and verify digital signatures.
|
* Sign and verify digital signatures.
|
||||||
* <p/>
|
*
|
||||||
* This class is not thread-safe (each thread should have its own instance).
|
* This class is not thread-safe (each thread should have its own instance).
|
||||||
*/
|
*/
|
||||||
public class ECDSASignature extends GlobalCryptoSetup implements DigitalSignature {
|
public class ECDSASignature extends GlobalCryptoSetup implements DigitalSignature {
|
||||||
|
@ -38,6 +38,12 @@ public class ECDSASignature extends GlobalCryptoSetup implements DigitalSignatur
|
||||||
|
|
||||||
SHA256Digest digest = new SHA256Digest();
|
SHA256Digest digest = new SHA256Digest();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buffer used to hold length in for hash update
|
||||||
|
*/
|
||||||
|
ByteBuffer lenBuf = ByteBuffer.allocate(4);
|
||||||
|
|
||||||
|
|
||||||
Map<ByteString, Certificate> loadedCertificates = new HashMap<>();
|
Map<ByteString, Certificate> loadedCertificates = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -111,7 +117,7 @@ public class ECDSASignature extends GlobalCryptoSetup implements DigitalSignatur
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add the list of messages to the stream that is being verified/signed.
|
* Add the list of messages to the stream that is being verified/signed.
|
||||||
* Messages are separated with {@link Digest#CONCAT_MARKER}
|
* Messages are prepended with their length in 32-bit big-endian format.
|
||||||
*
|
*
|
||||||
* @param msg
|
* @param msg
|
||||||
* @throws SignatureException
|
* @throws SignatureException
|
||||||
|
@ -119,10 +125,11 @@ public class ECDSASignature extends GlobalCryptoSetup implements DigitalSignatur
|
||||||
@Override
|
@Override
|
||||||
public void updateContent(Message msg) throws SignatureException {
|
public void updateContent(Message msg) throws SignatureException {
|
||||||
assert msg != null;
|
assert msg != null;
|
||||||
int len = msg.getSerializedSize();
|
|
||||||
|
|
||||||
byte[] lenBytes = { (byte) ((len >>> 24) & 0xff), (byte) ((len >>> 16) & 0xff), (byte) ((len >>> 8) & 0xff), (byte) (len & 0xff) };
|
lenBuf.clear();
|
||||||
signer.update(lenBytes);
|
lenBuf.putInt(msg.getSerializedSize());
|
||||||
|
lenBuf.flip();
|
||||||
|
signer.update(lenBuf);
|
||||||
signer.update(msg.toByteString().asReadOnlyByteBuffer());
|
signer.update(msg.toByteString().asReadOnlyByteBuffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,7 +237,34 @@ public class ECDSASignature extends GlobalCryptoSetup implements DigitalSignatur
|
||||||
try {
|
try {
|
||||||
Certificate cert = keyStore.getCertificate(alias);
|
Certificate cert = keyStore.getCertificate(alias);
|
||||||
logger.trace("keystore entry {}, has cert type {}", alias, cert.getClass());
|
logger.trace("keystore entry {}, has cert type {}", alias, cert.getClass());
|
||||||
Key key = keyStore.getKey(alias, null);
|
Key key;
|
||||||
|
try {
|
||||||
|
key = keyStore.getKey(alias, null);
|
||||||
|
} catch (UnrecoverableKeyException e) {
|
||||||
|
// This might be a keystore that doesn't support callback handlers
|
||||||
|
// (e.g., Java 8 PKCS12)
|
||||||
|
// Manually extract password using callback handler
|
||||||
|
char[] password = null;
|
||||||
|
KeyStore.ProtectionParameter prot = keyStoreBuilder.getProtectionParameter(alias);
|
||||||
|
|
||||||
|
if (prot instanceof KeyStore.PasswordProtection) {
|
||||||
|
password = ((KeyStore.PasswordProtection) prot).getPassword();
|
||||||
|
} else if (prot instanceof KeyStore.CallbackHandlerProtection) {
|
||||||
|
PasswordCallback callback = new PasswordCallback("Password for " + alias + "?", false);
|
||||||
|
Callback[] callbacks = { callback };
|
||||||
|
try {
|
||||||
|
((KeyStore.CallbackHandlerProtection) prot).getCallbackHandler().handle(callbacks);
|
||||||
|
password = callback.getPassword();
|
||||||
|
} catch (UnsupportedCallbackException e1) {
|
||||||
|
logger.error("PasswordCallback fallback not supported!", e1);
|
||||||
|
throw new UnrecoverableKeyException("Couldn't use password callback to get key");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.error("Unrecognized protection handler for keystore: {}", prot.getClass());
|
||||||
|
throw new UnrecoverableKeyException("Unrecognized protection handler for keystore");
|
||||||
|
}
|
||||||
|
key = keyStore.getKey(alias, password);
|
||||||
|
}
|
||||||
logger.trace("keystore entry {}, has key type {}", alias, key.getClass());
|
logger.trace("keystore entry {}, has key type {}", alias, key.getClass());
|
||||||
if (key instanceof PrivateKey) {
|
if (key instanceof PrivateKey) {
|
||||||
loadedSigningKeyId = computeCertificateFingerprint(cert);
|
loadedSigningKeyId = computeCertificateFingerprint(cert);
|
||||||
|
|
|
@ -6,6 +6,7 @@ import meerkat.crypto.Digest;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
@ -18,6 +19,11 @@ public class SHA256Digest extends GlobalCryptoSetup implements Digest {
|
||||||
|
|
||||||
MessageDigest hash;
|
MessageDigest hash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to convert length to bytes in proper order.
|
||||||
|
*/
|
||||||
|
ByteBuffer lenBuf = ByteBuffer.allocate(4);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate with a specified algorithm.
|
* Instantiate with a specified algorithm.
|
||||||
* @param algorithm
|
* @param algorithm
|
||||||
|
@ -56,6 +62,11 @@ public class SHA256Digest extends GlobalCryptoSetup implements Digest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Message msg) {
|
public void update(Message msg) {
|
||||||
|
|
||||||
|
lenBuf.clear();
|
||||||
|
lenBuf.putInt(msg.getSerializedSize());
|
||||||
|
lenBuf.flip();
|
||||||
|
hash.update(lenBuf);
|
||||||
hash.update(msg.toByteString().asReadOnlyByteBuffer());
|
hash.update(msg.toByteString().asReadOnlyByteBuffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
signed-messages/* -text
|
Loading…
Reference in New Issue