Merge remote-tracking branch 'origin/signature-implementation' into Bulletin_Board_Server_phase_1

Bulletin_Board_Server_phase_1
Arbel Deutsch Peled 2015-11-12 21:32:09 +02:00
commit a5eabe4b28
51 changed files with 995 additions and 7 deletions

4
.gitignore vendored
View File

@ -1,6 +1,10 @@
.gradle
.idea
build
bin
.settings
.classpath
.project
out
*.iml
*.ipr

View File

@ -45,6 +45,10 @@ dependencies {
// Google protobufs
compile 'com.google.protobuf:protobuf-java:3.+'
// Crypto
compile 'org.bouncycastle:bcprov-jdk15on:1.53'
compile 'org.bouncycastle:bcpkix-jdk15on:1.53'
testCompile 'junit:junit:4.+'
runtime 'org.codehaus.groovy:groovy:2.4.+'

View File

@ -2,16 +2,92 @@ package meerkat.crypto;
import com.google.protobuf.Message;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.PasswordCallback;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.SignatureException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.List;
import static meerkat.protobuf.Crypto.*;
/**
* Created by talm on 25/10/15.
*
* Sign arrays of messages
* Sign and verifyarrays of messages
*/
public interface DigitalSignature { // Extends SCAPI DigitalSignature
public Signature sign(List<Message> msg);
public interface DigitalSignature {
final public static String CERTIFICATE_ENCODING_X509 = "X.509";
/**
* Load a set of certificates from an input stream.
* This will consume the entire stream.
* Certificates can be either DER-encoded (binary) or PEM (base64) encoded.
* This may be called multiple times to load several different certificates.
* It must be called before calling {@link #verify()}.
* @param certStream source from which certificates are loaded
* @throws CertificateException on parsing errors
*/
public void loadVerificationCertificates(InputStream certStream)
throws CertificateException;
/**
* Clear the loaded verification certificates.
*/
public void clearVerificationCertificates();
/**
* Add msg to the content stream to be verified / signed. Each message is always (automatically)
* prepended with its length as a 32-bit unsigned integer in network byte order.
*
* @param msg
* @throws SignatureException
*/
public void updateContent(Message msg) throws SignatureException;
/**
* Sign the content that was added.
* @return
* @throws SignatureException
*/
Signature sign() throws SignatureException;
/**
* Initialize the verifier with the certificate whose Id is in sig.
* @param sig
* @throws CertificateException
* @throws InvalidKeyException
*/
void initVerify(Signature sig)
throws CertificateException, InvalidKeyException;
/**
* Verify the updated content using the initialized signature.
* @return
*/
public boolean verify();
/**
* Loads a private signing key. The keystore must include both the public and private
* key parts.
* This method must be called before calling {@link #sign(List)}
* Calling this method again will replace the key.
*
* @param keyStoreBuilder A keystore builder that can be used to load a keystore.
*/
public void loadSigningCertificate(KeyStore.Builder keyStoreBuilder)
throws IOException, CertificateException, UnrecoverableKeyException;
/**
* Clear the signing key (will require authentication to use again).
*/
public void clearSigningKey();
public boolean verify(Signature sig, List<Message> msgs);
}

View File

@ -0,0 +1,272 @@
package meerkat.crypto.concrete;
import java.io.IOException;
import java.io.InputStream;
import java.security.*;
import java.security.cert.*;
import java.security.cert.Certificate;
import java.util.*;
import com.google.protobuf.ByteString;
import meerkat.crypto.Digest;
import meerkat.protobuf.Crypto;
import meerkat.util.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.protobuf.Message;
import meerkat.crypto.DigitalSignature;
import meerkat.protobuf.Crypto.Signature;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
/**
* Sign and verify digital signatures.
* <p/>
* This class is not thread-safe (each thread should have its own instance).
*/
public class ECDSASignature extends GlobalCryptoSetup implements DigitalSignature {
final Logger logger = LoggerFactory.getLogger(getClass());
final public static String KEYSTORE_TYPE = "PKCS12";
final public static String DEFAULT_SIGNATURE_ALGORITHM = "SHA256withECDSA";
SHA256Digest digest = new SHA256Digest();
Map<ByteString, Certificate> loadedCertificates = new HashMap<>();
/**
* Signature currently loaded (will be used in calls to {@link #verify()}).
*/
ByteString loadedSignature = null;
ByteString loadedSigningKeyId = null;
/**
* The actual signing implementation. (used for both signing and verifying)
*/
java.security.Signature signer;
/**
* Compute a fingerprint of a cert as a SHA256 hash.
*
* @param cert
* @return
*/
public ByteString computeCertificateFingerprint(Certificate cert) {
try {
digest.reset();
byte[] data = cert.getEncoded();
digest.update(data);
return ByteString.copyFrom(digest.digest());
} catch (CertificateEncodingException e) {
// Shouldn't happen
logger.error("Certificate encoding error", e);
return ByteString.EMPTY;
}
}
public ECDSASignature(java.security.Signature signer) {
this.signer = signer;
}
public ECDSASignature() {
try {
this.signer = java.security.Signature.getInstance(DEFAULT_SIGNATURE_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
// Should never happen
logger.error("Couldn't find implementation for " + DEFAULT_SIGNATURE_ALGORITHM + " signatures", e);
}
}
@Override
public void loadVerificationCertificates(InputStream certStream)
throws CertificateException {
CertificateFactory certificateFactory = CertificateFactory.getInstance(CERTIFICATE_ENCODING_X509);
Collection<? extends Certificate> certs = certificateFactory.generateCertificates(certStream);
for (Certificate cert : certs) {
// Just checking
if (!(cert instanceof X509Certificate)) {
logger.error("Certificate must be in X509 format; got {} instead!", cert.getClass().getCanonicalName());
continue;
}
PublicKey pubKey = cert.getPublicKey();
ByteString keyId = computeCertificateFingerprint(cert);
loadedCertificates.put(keyId, cert);
}
}
@Override
public void clearVerificationCertificates() {
loadedCertificates.clear();
}
/**
* Add the list of messages to the stream that is being verified/signed.
* Messages are separated with {@link Digest#CONCAT_MARKER}
*
* @param msg
* @throws SignatureException
*/
@Override
public void updateContent(Message msg) throws SignatureException {
assert msg != null;
int len = msg.getSerializedSize();
byte[] lenBytes = { (byte) ((len >>> 24) & 0xff), (byte) ((len >>> 16) & 0xff), (byte) ((len >>> 8) & 0xff), (byte) (len & 0xff) };
signer.update(lenBytes);
signer.update(msg.toByteString().asReadOnlyByteBuffer());
}
public void updateSigner(InputStream in) throws IOException, SignatureException {
ByteString inStr = ByteString.readFrom(in);
signer.update(inStr.asReadOnlyByteBuffer());
}
@Override
public Signature sign() throws SignatureException {
Signature.Builder sig = Signature.newBuilder();
sig.setType(Crypto.SignatureType.ECDSA);
sig.setData(ByteString.copyFrom(signer.sign()));
sig.setSignerId(loadedSigningKeyId);
return sig.build();
}
@Override
public void initVerify(Signature sig)
throws CertificateException, InvalidKeyException {
Certificate cert = loadedCertificates.get(sig.getSignerId());
if (cert == null) {
logger.warn("No certificate loaded for ID {}!", sig.getSignerId());
throw new CertificateException("No certificate loaded for " + sig.getSignerId());
}
signer.initVerify(cert.getPublicKey());
loadedSignature = sig.getData();
loadedSigningKeyId = null;
}
@Override
public boolean verify() {
try {
return signer.verify(loadedSignature.toByteArray());
} catch (SignatureException e) {
// Happens only if signature is invalid!
logger.error("Signature exception", e);
return false;
}
}
/**
* Utility method to more easily deal with simple password-protected files.
*
* @param password
* @return
*/
public CallbackHandler getFixedPasswordHandler(final char[] password) {
return new CallbackHandler() {
@Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (Callback callback : callbacks) {
if (callback instanceof PasswordCallback) {
PasswordCallback passwordCallback = (PasswordCallback) callback;
logger.debug("Requested password ({})", passwordCallback.getPrompt());
passwordCallback.setPassword(password);
}
}
}
};
}
/**
* Load a keystore from an input stream in PKCS12 format.
*
* @param keyStream
* @param password
* @return
* @throws IOException
* @throws CertificateException
* @throws KeyStoreException
* @throws NoSuchAlgorithmException
*/
public KeyStore.Builder getPKCS12KeyStoreBuilder(InputStream keyStream, char[] password)
throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException {
KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE);
keyStore.load(keyStream, password);
return KeyStore.Builder.newInstance(keyStore, new KeyStore.CallbackHandlerProtection(getFixedPasswordHandler(password)));
}
/**
* For now we only support PKCS12.
* TODO: Support for PKCS11 as well.
*
* @param keyStoreBuilder
* @throws IOException
* @throws CertificateException
* @throws UnrecoverableKeyException
*/
@Override
public void loadSigningCertificate(KeyStore.Builder keyStoreBuilder)
throws IOException, CertificateException, UnrecoverableKeyException {
try {
KeyStore keyStore = keyStoreBuilder.getKeyStore();
// Iterate through all aliases until we find the first privatekey
Enumeration<String> aliases = keyStore.aliases();
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
logger.trace("Testing keystore entry {}", alias);
try {
Certificate cert = keyStore.getCertificate(alias);
logger.trace("keystore entry {}, has cert type {}", alias, cert.getClass());
Key key = keyStore.getKey(alias, null);
logger.trace("keystore entry {}, has key type {}", alias, key.getClass());
if (key instanceof PrivateKey) {
loadedSigningKeyId = computeCertificateFingerprint(cert);
signer.initSign((PrivateKey) key);
logger.debug("Loaded signing key with ID {}", Hex.encode(loadedSigningKeyId));
return;
} else {
logger.info("Certificate {} in keystore does not have a private key", cert.toString());
}
} catch(InvalidKeyException e) {
logger.info("Read invalid key", e);
} catch(UnrecoverableEntryException e) {
logger.info("Read unrecoverable entry", e);
}
}
} catch (KeyStoreException e) {
logger.error("Keystore exception", e);
} catch (NoSuchAlgorithmException e) {
logger.error("NoSuchAlgorithmException exception", e);
throw new CertificateException(e);
}
logger.error("Didn't find valid private key entry in keystore");
throw new UnrecoverableKeyException("Didn't find valid private key entry in keystore!");
}
public void clearSigningKey() {
try {
// TODO: Check if this really clears the key from memory
if (loadedSigningKeyId != null)
signer.initSign(null);
loadedSigningKeyId = null;
} catch (InvalidKeyException e) {
// Do nothing
}
}
}

View File

@ -0,0 +1,38 @@
package meerkat.crypto.concrete;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.security.Security;
/**
* A class that performs required crypto setup
*/
public class GlobalCryptoSetup {
final static Logger logger = LoggerFactory.getLogger(GlobalCryptoSetup.class);
static boolean loadedBouncyCastle = false;
public static boolean hasSecp256k1Curve() {
// For now we just check if the java version is at least 8
String[] version = System.getProperty("java.version").split("\\.");
int major = Integer.parseInt(version[0]);
int minor = Integer.parseInt(version[1]);
return ((major > 1) || ((major > 0) && (minor > 7)));
}
public static void doSetup() {
// Make bouncycastle our default provider if we're running on a JVM version < 8
// (earlier version don't support the EC curve we use for signatures)
if (!hasSecp256k1Curve() && !loadedBouncyCastle) {
loadedBouncyCastle = true;
Security.insertProviderAt(new BouncyCastleProvider(), 1);
logger.info("Using BouncyCastle instead of native provider to support secp256k1 named curve");
}
}
public GlobalCryptoSetup() {
doSetup();
}
}

View File

@ -1,5 +1,6 @@
package meerkat.crypto.concrete;
import com.google.protobuf.ByteString;
import com.google.protobuf.Message;
import meerkat.crypto.Digest;
import org.slf4j.Logger;
@ -11,7 +12,7 @@ import java.security.NoSuchAlgorithmException;
/**
* Created by talm on 11/9/15.
*/
public class SHA256Digest implements Digest {
public class SHA256Digest extends GlobalCryptoSetup implements Digest {
final Logger logger = LoggerFactory.getLogger(getClass());
public static final String SHA256 = "SHA-256";
@ -32,7 +33,7 @@ public class SHA256Digest implements Digest {
public SHA256Digest() { this(true); }
/**
/**SHA
* Instantiate with the default (SHA-256) algorithm,
* or create an empty class (for cloning)
*/
@ -58,6 +59,14 @@ public class SHA256Digest implements Digest {
hash.update(msg.toByteString().asReadOnlyByteBuffer());
}
final public void update(ByteString msg) {
hash.update(msg.asReadOnlyByteBuffer());
}
final public void update(byte[] msg) {
hash.update(msg);
}
@Override
public void reset() {
hash.reset();

View File

@ -0,0 +1,26 @@
package meerkat.util;
import com.google.protobuf.ByteString;
/**
* Convert to/from Hex
*/
public class Hex {
/**
* Encode a {@link ByteString} as a hex string.
* @param str
* @return
*/
public static String encode(ByteString str) {
StringBuilder s = new StringBuilder();
for (byte b : str) {
s.append(Integer.toHexString(((int) b) & 0xff));
}
return s.toString();
}
public static String encode(byte[] bytes) {
return encode(ByteString.copyFrom(bytes));
}
}

View File

@ -13,14 +13,18 @@ enum SignatureType {
message Signature {
SignatureType type = 1;
// Data encoding depends on type; default is x509 BER-encoded
// Data encoding depends on type; default is DER-encoded
bytes data = 2;
// ID of the signer (should be the fingerprint of the signature verification key)
bytes signer_id = 3;
}
// Public key used to verify signatures
message SignatureVerificationKey {
SignatureType type = 1;
// Data encoding depends on type; default is x509 DER-encoded
bytes data = 2;
}

View File

@ -0,0 +1,46 @@
import ch.qos.logback.classic.encoder.PatternLayoutEncoder
import ch.qos.logback.classic.filter.ThresholdFilter
import ch.qos.logback.core.ConsoleAppender
import ch.qos.logback.core.util.Duration
import static ch.qos.logback.classic.Level.*
if (System.getProperty("log.debug") != null) {
println "Logback configuration debugging enabled"
statusListener(OnConsoleStatusListener)
}
def LOG_LEVEL = toLevel(System.getProperty("log.level"), INFO)
def haveBeagle = System.getProperty("log.beagle") != null
def logOps = System.getProperty("log.ops") != null
appender("CONSOLE", ConsoleAppender) {
filter(ThresholdFilter) {
level = toLevel(System.getProperty("log.level"), TRACE)
}
encoder(PatternLayoutEncoder) {
pattern = "%d{HH:mm:ss.SSS} [%thread %file:%line] %-5level %logger{0} - %msg%n"
}
}
def appenders = [ "CONSOLE" ]
if (haveBeagle) {
appender("SOCKET", SocketAppender) {
includeCallerData = true
remoteHost = "localhost"
port = 4321
reconnectionDelay = new Duration(10000)
}
appenders += ["SOCKET"]
}
root(LOG_LEVEL, appenders)

View File

@ -0,0 +1,172 @@
package meerkat.crypto.concrete;
import com.google.protobuf.ByteString;
import meerkat.protobuf.Crypto;
import meerkat.protobuf.Voting;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.util.Arrays;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* Created by talm on 12/11/15.
*/
public class TestECDSASignature {
public static String KEYFILE_EXAMPLE = "/certs/enduser-certs/user1-key-with-password-secret.p12";
public static String KEYFILE_PASSWORD = "secret";
public static String CERT1_PEM_EXAMPLE = "/certs/enduser-certs/user1.crt";
public static String CERT2_DER_EXAMPLE = "/certs/enduser-certs/user2.der";
public static String MSG_PLAINTEXT_EXAMPLE = "/certs/signed-messages/helloworld.txt";
public static String MSG_SIG_EXAMPLE = "/certs/signed-messages/helloworld.txt.sha256sig";
public static String HELLO_WORLD = "hello world!";
@Test
public void loadSignatureKey() throws Exception {
InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE);
char[] password = KEYFILE_PASSWORD.toCharArray();
ECDSASignature sig = new ECDSASignature();
KeyStore.Builder keyStore = sig.getPKCS12KeyStoreBuilder(keyStream, password);
sig.loadSigningCertificate(keyStore);
keyStream.close();
}
@Test
public void loadPEMVerificationKey() throws Exception {
InputStream certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE);
ECDSASignature sig = new ECDSASignature();
sig.loadVerificationCertificates(certStream);
certStream.close();
}
@Test
public void loadDERVerificationKey() throws Exception {
InputStream certStream = getClass().getResourceAsStream(CERT2_DER_EXAMPLE);
ECDSASignature sig = new ECDSASignature();
sig.loadVerificationCertificates(certStream);
certStream.close();
}
@Test
public void verifyValidSig() throws Exception {
InputStream certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE);
InputStream msgStream = getClass().getResourceAsStream(MSG_PLAINTEXT_EXAMPLE);
InputStream sigStream = getClass().getResourceAsStream(MSG_SIG_EXAMPLE);
ECDSASignature signer = new ECDSASignature();
signer.loadVerificationCertificates(certStream);
certStream.close();
Crypto.Signature.Builder sig = Crypto.Signature.newBuilder();
sig.setType(Crypto.SignatureType.ECDSA);
sig.setSignerId(signer.loadedCertificates.entrySet().iterator().next().getKey());
sig.setData(ByteString.readFrom(sigStream));
Crypto.Signature builtSig = sig.build();
signer.initVerify(builtSig);
signer.updateSigner(msgStream);
assertTrue("Signature did not verify!", signer.verify());
}
@Test
public void verifyInvalidSig() throws Exception {
InputStream certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE);
InputStream msgStream = getClass().getResourceAsStream(MSG_PLAINTEXT_EXAMPLE);
InputStream sigStream = getClass().getResourceAsStream(MSG_SIG_EXAMPLE);
ECDSASignature signer = new ECDSASignature();
signer.loadVerificationCertificates(certStream);
certStream.close();
Crypto.Signature.Builder sig = Crypto.Signature.newBuilder();
sig.setType(Crypto.SignatureType.ECDSA);
sig.setSignerId(signer.loadedCertificates.entrySet().iterator().next().getKey());
byte[] sigData = ByteString.readFrom(sigStream).toByteArray();
++sigData[0];
sig.setData(ByteString.copyFrom(sigData));
Crypto.Signature builtSig = sig.build();
signer.initVerify(builtSig);
signer.updateSigner(msgStream);
assertFalse("Bad Signature passed verification!", signer.verify());
}
@Test
public void verifyInvalidMsg() throws Exception {
InputStream certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE);
InputStream msgStream = getClass().getResourceAsStream(MSG_PLAINTEXT_EXAMPLE);
InputStream sigStream = getClass().getResourceAsStream(MSG_SIG_EXAMPLE);
ECDSASignature signer = new ECDSASignature();
signer.loadVerificationCertificates(certStream);
certStream.close();
Crypto.Signature.Builder sig = Crypto.Signature.newBuilder();
sig.setType(Crypto.SignatureType.ECDSA);
sig.setSignerId(signer.loadedCertificates.entrySet().iterator().next().getKey());
sig.setData(ByteString.readFrom(sigStream));
byte[] msgData = ByteString.readFrom(msgStream).toByteArray();
++msgData[0];
Crypto.Signature builtSig = sig.build();
signer.initVerify(builtSig);
signer.updateSigner(msgStream);
assertFalse("Signature doesn't match message but passed verification!", signer.verify());
}
@Test
public void signAndVerify() throws Exception {
InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE);
char[] password = KEYFILE_PASSWORD.toCharArray();
ECDSASignature signer = new ECDSASignature();
KeyStore.Builder keyStore = signer.getPKCS12KeyStoreBuilder(keyStream, password);
signer.loadSigningCertificate(keyStore);
Voting.UnsignedBulletinBoardMessage.Builder unsignedMsgBuilder = Voting.UnsignedBulletinBoardMessage.newBuilder();
unsignedMsgBuilder.setData(ByteString.copyFromUtf8(HELLO_WORLD));
unsignedMsgBuilder.addTags("Tag1");
unsignedMsgBuilder.addTags("Tag2");
unsignedMsgBuilder.addTags("Tag3");
Voting.UnsignedBulletinBoardMessage usMsg = unsignedMsgBuilder.build();
signer.updateContent(usMsg);
Crypto.Signature sig = signer.sign();
signer.loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE));
signer.initVerify(sig);
signer.updateContent(usMsg);
assertTrue("Couldn't verify signature on ", signer.verify());
}
}

View File

@ -0,0 +1,6 @@
Certs and private keys for testing generated using OpenSSL
.crt and .pem files are in PEM format
.der files are in binary DER format
files that have a name of the form *-with-password-xxxx.pem are encrypted with the password xxxx

View File

@ -0,0 +1,8 @@
-----BEGIN EC PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,243D718A0D80C59590E582A26E87A49C
RG6ITUTIdbJdWYX57oMn3tTCzHJSTjXAIZLjoVxy/v4UFYjluaFhGonIlbH1q2pP
ueu29Q3eT6144ypB8ARUJ1x0kRX1OL9zNHgdF9ulrCf9/nhGyC2nL+tHZ0YPbxoQ
+6yCQcRWvjUXLVzPEUnwMuHXJDpaXES8X0R4CISQKIA=
-----END EC PRIVATE KEY-----

View File

@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQge8JqCoaLoZq61aQki5Xm
GppcfAAkhHDGNQw/wLof5LmhRANCAAQJD1kW6BsNkRY9tslaugpOJOaoKX4uBz4S
Q96lPaPWkatNVgQchwNeB/hdjZwNuwE7A7XAwr69HFmhXRhsM005
-----END PRIVATE KEY-----

View File

@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAECQ9ZFugbDZEWPbbJWroKTiTmqCl+Lgc+
EkPepT2j1pGrTVYEHIcDXgf4XY2cDbsBOwO1wMK+vRxZoV0YbDNNOQ==
-----END PUBLIC KEY-----

View File

@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDFjCCArygAwIBAgICEAAwCgYIKoZIzj0EAwIwgYIxKTAnBgNVBAMMIE1lZXJr
YXQgVm90aW5nIEludGVybWVkaWF0ZSBDQSAxMRMwEQYDVQQIDApTb21lLVN0YXRl
MQswCQYDVQQGEwJJTDEVMBMGA1UECgwMSURDIEhlcnpsaXlhMRwwGgYDVQQLDBNN
ZWVya2F0IFZvdGluZyBUZWFtMB4XDTE1MTExMTE2MTM1NFoXDTI1MTEwODE2MTM1
NFowbjEaMBgGA1UEAwwRUG9sbGluZyBTdGF0aW9uIDExEzARBgNVBAgMClNvbWUt
U3RhdGUxCzAJBgNVBAYTAklMMRUwEwYDVQQKDAxJREMgSGVyemxpeWExFzAVBgNV
BAsMDk1lZXJrYXQgVm90aW5nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAECQ9ZFugb
DZEWPbbJWroKTiTmqCl+Lgc+EkPepT2j1pGrTVYEHIcDXgf4XY2cDbsBOwO1wMK+
vRxZoV0YbDNNOaOCATYwggEyMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFLamS8o2
hFNd0vWy/irEBNWVNwFXMB8GA1UdIwQYMBaAFBeyv0c75eT6PNumHo9TZ2B9vtcp
MAsGA1UdDwQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATBEBgNVHR8EPTA7MDmg
N6A1hjNodHRwOi8vY3JsLmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRp
YXRlMS5jcmwwegYIKwYBBQUHAQEEbjBsMEEGCCsGAQUFBzAChjVodHRwOi8vcGtp
LmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRpYXRlLWNhLmNydDAnBggr
BgEFBQcwAYYbaHR0cDovL29jc3AuZmFjdGNlbnRlci5vcmcvMAoGCCqGSM49BAMC
A0gAMEUCIQD6QbhNNmB3AVVqhmXuiLA7WF6raShw6n0g/VloVGQebQIgEvxYclpO
MMynt5wH6X65rtn4Q1EGaDMvNbFweCDsldk=
-----END CERTIFICATE-----

View File

@ -0,0 +1,9 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIBOjCB4QIBADCBgTELMAkGA1UEBhMCSUwxEzARBgNVBAgMClNvbWUtU3RhdGUx
ETAPBgNVBAcMCEhlcnpsaXlhMRUwEwYDVQQKDAxJREMgSGVyemxpeWExFzAVBgNV
BAsMDk1lZXJrYXQgVm90aW5nMRowGAYDVQQDDBFQb2xsaW5nIFN0YXRpb24gMTBW
MBAGByqGSM49AgEGBSuBBAAKA0IABAkPWRboGw2RFj22yVq6Ck4k5qgpfi4HPhJD
3qU9o9aRq01WBByHA14H+F2NnA27ATsDtcDCvr0cWaFdGGwzTTmgADAKBggqhkjO
PQQDAgNIADBFAiEA8gmIhALr7O5M1QLReGH3jheildTIr1mDWl14WyMf9U4CIF23
mInyo4VqNHLzxMLg5Cn3Oddokng3OXa63y4nTfv+
-----END CERTIFICATE REQUEST-----

View File

@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgYpBEO+XWm/n6VPeMVK76
mrZkDTpiwLsDykG7M4fU5RKhRANCAAR71/kVGyA3hdxcLBBT3NPQF6R3LholmLRN
qhnvHqzJWuy7ev+Xbuxtt9AN0ajyeFDy8Oe1bUSidnLyQi+nXC0f
-----END PRIVATE KEY-----

View File

@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEe9f5FRsgN4XcXCwQU9zT0Bekdy4aJZi0
TaoZ7x6syVrsu3r/l27sbbfQDdGo8nhQ8vDntW1EonZy8kIvp1wtHw==
-----END PUBLIC KEY-----

View File

@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDFjCCArygAwIBAgICEAEwCgYIKoZIzj0EAwIwgYIxKTAnBgNVBAMMIE1lZXJr
YXQgVm90aW5nIEludGVybWVkaWF0ZSBDQSAxMRMwEQYDVQQIDApTb21lLVN0YXRl
MQswCQYDVQQGEwJJTDEVMBMGA1UECgwMSURDIEhlcnpsaXlhMRwwGgYDVQQLDBNN
ZWVya2F0IFZvdGluZyBUZWFtMB4XDTE1MTExMTE2MjAzM1oXDTI1MTEwODE2MjAz
M1owbjEaMBgGA1UEAwwRUG9sbGluZyBTdGF0aW9uIDIxEzARBgNVBAgMClNvbWUt
U3RhdGUxCzAJBgNVBAYTAklMMRUwEwYDVQQKDAxJREMgSGVyemxpeWExFzAVBgNV
BAsMDk1lZXJrYXQgVm90aW5nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEe9f5FRsg
N4XcXCwQU9zT0Bekdy4aJZi0TaoZ7x6syVrsu3r/l27sbbfQDdGo8nhQ8vDntW1E
onZy8kIvp1wtH6OCATYwggEyMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFKCdquYj
DGHqAHt+4PIDlw0h2UvuMB8GA1UdIwQYMBaAFBeyv0c75eT6PNumHo9TZ2B9vtcp
MAsGA1UdDwQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATBEBgNVHR8EPTA7MDmg
N6A1hjNodHRwOi8vY3JsLmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRp
YXRlMS5jcmwwegYIKwYBBQUHAQEEbjBsMEEGCCsGAQUFBzAChjVodHRwOi8vcGtp
LmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRpYXRlLWNhLmNydDAnBggr
BgEFBQcwAYYbaHR0cDovL29jc3AuZmFjdGNlbnRlci5vcmcvMAoGCCqGSM49BAMC
A0gAMEUCIQDpo5B0vvEJSax3YzOMfE8l0pfDUIKLdBWJVGeq0VLtIgIgVr0+4/0e
n+R+l1OVOLh2GirloOgbv5Ch5BQ2pQNAG2Y=
-----END CERTIFICATE-----

View File

@ -0,0 +1,9 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIBOzCB4QIBADCBgTELMAkGA1UEBhMCSUwxEzARBgNVBAgMClNvbWUtU3RhdGUx
ETAPBgNVBAcMCEhlcnpsaXlhMRUwEwYDVQQKDAxJREMgSGVyemxpeWExFzAVBgNV
BAsMDk1lZXJrYXQgVm90aW5nMRowGAYDVQQDDBFQb2xsaW5nIFN0YXRpb24gMjBW
MBAGByqGSM49AgEGBSuBBAAKA0IABHvX+RUbIDeF3FwsEFPc09AXpHcuGiWYtE2q
Ge8erMla7Lt6/5du7G230A3RqPJ4UPLw57VtRKJ2cvJCL6dcLR+gADAKBggqhkjO
PQQDAgNJADBGAiEA6Ls/ojRaZT+u4YeOBYcPbRcJE3jSTe1Sm/lR7fDyEhMCIQCk
UOca+e2b8+CqM3CURBv6TqUMmZ3HeMRvEAxFPqOWSw==
-----END CERTIFICATE REQUEST-----

View File

@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDFjCCArygAwIBAgICEAAwCgYIKoZIzj0EAwIwgYIxKTAnBgNVBAMMIE1lZXJr
YXQgVm90aW5nIEludGVybWVkaWF0ZSBDQSAxMRMwEQYDVQQIDApTb21lLVN0YXRl
MQswCQYDVQQGEwJJTDEVMBMGA1UECgwMSURDIEhlcnpsaXlhMRwwGgYDVQQLDBNN
ZWVya2F0IFZvdGluZyBUZWFtMB4XDTE1MTExMTE2MTM1NFoXDTI1MTEwODE2MTM1
NFowbjEaMBgGA1UEAwwRUG9sbGluZyBTdGF0aW9uIDExEzARBgNVBAgMClNvbWUt
U3RhdGUxCzAJBgNVBAYTAklMMRUwEwYDVQQKDAxJREMgSGVyemxpeWExFzAVBgNV
BAsMDk1lZXJrYXQgVm90aW5nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAECQ9ZFugb
DZEWPbbJWroKTiTmqCl+Lgc+EkPepT2j1pGrTVYEHIcDXgf4XY2cDbsBOwO1wMK+
vRxZoV0YbDNNOaOCATYwggEyMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFLamS8o2
hFNd0vWy/irEBNWVNwFXMB8GA1UdIwQYMBaAFBeyv0c75eT6PNumHo9TZ2B9vtcp
MAsGA1UdDwQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATBEBgNVHR8EPTA7MDmg
N6A1hjNodHRwOi8vY3JsLmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRp
YXRlMS5jcmwwegYIKwYBBQUHAQEEbjBsMEEGCCsGAQUFBzAChjVodHRwOi8vcGtp
LmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRpYXRlLWNhLmNydDAnBggr
BgEFBQcwAYYbaHR0cDovL29jc3AuZmFjdGNlbnRlci5vcmcvMAoGCCqGSM49BAMC
A0gAMEUCIQD6QbhNNmB3AVVqhmXuiLA7WF6raShw6n0g/VloVGQebQIgEvxYclpO
MMynt5wH6X65rtn4Q1EGaDMvNbFweCDsldk=
-----END CERTIFICATE-----

View File

@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDFjCCArygAwIBAgICEAEwCgYIKoZIzj0EAwIwgYIxKTAnBgNVBAMMIE1lZXJr
YXQgVm90aW5nIEludGVybWVkaWF0ZSBDQSAxMRMwEQYDVQQIDApTb21lLVN0YXRl
MQswCQYDVQQGEwJJTDEVMBMGA1UECgwMSURDIEhlcnpsaXlhMRwwGgYDVQQLDBNN
ZWVya2F0IFZvdGluZyBUZWFtMB4XDTE1MTExMTE2MjAzM1oXDTI1MTEwODE2MjAz
M1owbjEaMBgGA1UEAwwRUG9sbGluZyBTdGF0aW9uIDIxEzARBgNVBAgMClNvbWUt
U3RhdGUxCzAJBgNVBAYTAklMMRUwEwYDVQQKDAxJREMgSGVyemxpeWExFzAVBgNV
BAsMDk1lZXJrYXQgVm90aW5nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEe9f5FRsg
N4XcXCwQU9zT0Bekdy4aJZi0TaoZ7x6syVrsu3r/l27sbbfQDdGo8nhQ8vDntW1E
onZy8kIvp1wtH6OCATYwggEyMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFKCdquYj
DGHqAHt+4PIDlw0h2UvuMB8GA1UdIwQYMBaAFBeyv0c75eT6PNumHo9TZ2B9vtcp
MAsGA1UdDwQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATBEBgNVHR8EPTA7MDmg
N6A1hjNodHRwOi8vY3JsLmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRp
YXRlMS5jcmwwegYIKwYBBQUHAQEEbjBsMEEGCCsGAQUFBzAChjVodHRwOi8vcGtp
LmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRpYXRlLWNhLmNydDAnBggr
BgEFBQcwAYYbaHR0cDovL29jc3AuZmFjdGNlbnRlci5vcmcvMAoGCCqGSM49BAMC
A0gAMEUCIQDpo5B0vvEJSax3YzOMfE8l0pfDUIKLdBWJVGeq0VLtIgIgVr0+4/0e
n+R+l1OVOLh2GirloOgbv5Ch5BQ2pQNAG2Y=
-----END CERTIFICATE-----

View File

@ -0,0 +1,2 @@
V 251108161354Z 1000 unknown /CN=Polling Station 1/ST=Some-State/C=IL/O=IDC Herzliya/OU=Meerkat Voting
V 251108162033Z 1001 unknown /CN=Polling Station 2/ST=Some-State/C=IL/O=IDC Herzliya/OU=Meerkat Voting

View File

@ -0,0 +1 @@
unique_subject = no

View File

@ -0,0 +1 @@
unique_subject = no

View File

@ -0,0 +1 @@
V 251108161354Z 1000 unknown /CN=Polling Station 1/ST=Some-State/C=IL/O=IDC Herzliya/OU=Meerkat Voting

View File

@ -0,0 +1 @@
1000

View File

@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgJvMhOfcQfdK/42QlBbri
IYXLM/gVHq/yppOykDqB3s6hRANCAAQoShAtCGW5c9pk/4/sKN1qjCgDKngqJpba
kku6cIDqXDr+aHsl+/KdSHd46OI3fEynl+/Pc85wRsaY6Z7b1PdS
-----END PRIVATE KEY-----

View File

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDfDCCAyGgAwIBAgICEAAwCgYIKoZIzj0EAwIwgbAxCzAJBgNVBAYTAklMMRMw
EQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQHDAhIZXJ6bGl5YTEUMBIGA1UECgwL
SURDIEhlcmxpeWExHzAdBgNVBAsMFk1lZXJrYXQgVm90aW5nIFByb2plY3QxGDAW
BgNVBAMMD1Rlc3RpbmcgUm9vdCBDQTEoMCYGCSqGSIb3DQEJARYZdGVzdGluZy1j
YUBmYWN0Y2VudGVyLm9yZzAeFw0xNTExMTExNjA4MDJaFw0yNTExMDgxNjA4MDJa
MIGCMSkwJwYDVQQDDCBNZWVya2F0IFZvdGluZyBJbnRlcm1lZGlhdGUgQ0EgMTET
MBEGA1UECAwKU29tZS1TdGF0ZTELMAkGA1UEBhMCSUwxFTATBgNVBAoMDElEQyBI
ZXJ6bGl5YTEcMBoGA1UECwwTTWVlcmthdCBWb3RpbmcgVGVhbTBWMBAGByqGSM49
AgEGBSuBBAAKA0IABChKEC0IZblz2mT/j+wo3WqMKAMqeComltqSS7pwgOpcOv5o
eyX78p1Id3jo4jd8TKeX789zznBGxpjpntvU91KjggFYMIIBVDAPBgNVHRMBAf8E
BTADAQH/MB0GA1UdDgQWBBQXsr9HO+Xk+jzbph6PU2dgfb7XKTAfBgNVHSMEGDAW
gBSJD9L1fLmX4A9CBoLsYXn3OPy1ojALBgNVHQ8EBAMCAaYwEwYDVR0lBAwwCgYI
KwYBBQUHAwEwPgYDVR0fBDcwNTAzoDGgL4YtaHR0cDovL2NybC5mYWN0Y2VudGVy
Lm9yZy9tZWVya2F0LXJvb3QtY2EuY3JsMCsGA1UdEQQkMCKCIE1lZXJrYXQgVm90
aW5nIEludGVybWVkaWF0ZSBDQSAxMHIGCCsGAQUFBwEBBGYwZDA5BggrBgEFBQcw
AoYtaHR0cDovL3BraS5mYWN0Y2VudGVyLm9yZy9tZWVya2F0LXJvb3QtY2EuY3J0
MCcGCCsGAQUFBzABhhtodHRwOi8vb2NzcC5mYWN0Y2VudGVyLm9yZy8wCgYIKoZI
zj0EAwIDSQAwRgIhALEMHq2ssC9rLXiG8v6NcZetwwxdu3B3LW9s0KeGoNIEAiEA
skA56tMnhiZe38msyanRyRrAHyBI2fGs6GP3UBrg2P8=
-----END CERTIFICATE-----

View File

@ -0,0 +1,10 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIBTTCB9QIBADCBlTELMAkGA1UEBhMCSUwxEzARBgNVBAgMClNvbWUtU3RhdGUx
ETAPBgNVBAcMCEhlcnpsaXlhMRUwEwYDVQQKDAxJREMgSGVyemxpeWExHDAaBgNV
BAsME01lZXJrYXQgVm90aW5nIFRlYW0xKTAnBgNVBAMMIE1lZXJrYXQgVm90aW5n
IEludGVybWVkaWF0ZSBDQSAxMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEKEoQLQhl
uXPaZP+P7CjdaowoAyp4KiaW2pJLunCA6lw6/mh7JfvynUh3eOjiN3xMp5fvz3PO
cEbGmOme29T3UqAAMAoGCCqGSM49BAMCA0cAMEQCIFlyJO5NFqnMUu5hOlQa872E
yy0V3zkqeN6Aly+LtEQqAiAfHwbi1lkJOZT2tOX8gfJzcac2jKmbgIhmITNq7uma
Wg==
-----END CERTIFICATE REQUEST-----

View File

@ -0,0 +1,46 @@
[ ca ]
default_ca = myca
[ crl_ext ]
issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always
[ myca ]
dir = ./
new_certs_dir = $dir
unique_subject = no
certificate = $dir/intermediate-ca-1.crt
database = $dir/certindex
private_key = $dir/intermediate-ca-1-private-key.pem
serial = $dir/certserial
default_days = 3650
default_md = sha256
policy = myca_policy
x509_extensions = myca_extensions
crlnumber = $dir/crlnumber
default_crl_days = 3650
[ myca_policy ]
commonName = supplied
stateOrProvinceName = optional
countryName = optional
emailAddress = optional
organizationName = supplied
organizationalUnitName = optional
[ myca_extensions ]
basicConstraints = critical,CA:FALSE
keyUsage = critical,any
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
keyUsage = digitalSignature,keyEncipherment
extendedKeyUsage = serverAuth
crlDistributionPoints = @crl_section
authorityInfoAccess = @ocsp_section
[crl_section]
URI.0 = http://crl.factcenter.org/meerkat-intermediate1.crl
[ocsp_section]
caIssuers;URI.0 = http://pki.factcenter.org/meerkat-intermediate-ca.crt
OCSP;URI.0 = http://ocsp.factcenter.org/

View File

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDfDCCAyGgAwIBAgICEAAwCgYIKoZIzj0EAwIwgbAxCzAJBgNVBAYTAklMMRMw
EQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQHDAhIZXJ6bGl5YTEUMBIGA1UECgwL
SURDIEhlcmxpeWExHzAdBgNVBAsMFk1lZXJrYXQgVm90aW5nIFByb2plY3QxGDAW
BgNVBAMMD1Rlc3RpbmcgUm9vdCBDQTEoMCYGCSqGSIb3DQEJARYZdGVzdGluZy1j
YUBmYWN0Y2VudGVyLm9yZzAeFw0xNTExMTExNjA4MDJaFw0yNTExMDgxNjA4MDJa
MIGCMSkwJwYDVQQDDCBNZWVya2F0IFZvdGluZyBJbnRlcm1lZGlhdGUgQ0EgMTET
MBEGA1UECAwKU29tZS1TdGF0ZTELMAkGA1UEBhMCSUwxFTATBgNVBAoMDElEQyBI
ZXJ6bGl5YTEcMBoGA1UECwwTTWVlcmthdCBWb3RpbmcgVGVhbTBWMBAGByqGSM49
AgEGBSuBBAAKA0IABChKEC0IZblz2mT/j+wo3WqMKAMqeComltqSS7pwgOpcOv5o
eyX78p1Id3jo4jd8TKeX789zznBGxpjpntvU91KjggFYMIIBVDAPBgNVHRMBAf8E
BTADAQH/MB0GA1UdDgQWBBQXsr9HO+Xk+jzbph6PU2dgfb7XKTAfBgNVHSMEGDAW
gBSJD9L1fLmX4A9CBoLsYXn3OPy1ojALBgNVHQ8EBAMCAaYwEwYDVR0lBAwwCgYI
KwYBBQUHAwEwPgYDVR0fBDcwNTAzoDGgL4YtaHR0cDovL2NybC5mYWN0Y2VudGVy
Lm9yZy9tZWVya2F0LXJvb3QtY2EuY3JsMCsGA1UdEQQkMCKCIE1lZXJrYXQgVm90
aW5nIEludGVybWVkaWF0ZSBDQSAxMHIGCCsGAQUFBwEBBGYwZDA5BggrBgEFBQcw
AoYtaHR0cDovL3BraS5mYWN0Y2VudGVyLm9yZy9tZWVya2F0LXJvb3QtY2EuY3J0
MCcGCCsGAQUFBzABhhtodHRwOi8vb2NzcC5mYWN0Y2VudGVyLm9yZy8wCgYIKoZI
zj0EAwIDSQAwRgIhALEMHq2ssC9rLXiG8v6NcZetwwxdu3B3LW9s0KeGoNIEAiEA
skA56tMnhiZe38msyanRyRrAHyBI2fGs6GP3UBrg2P8=
-----END CERTIFICATE-----

View File

@ -0,0 +1 @@
V 251108160802Z 1000 unknown /CN=Meerkat Voting Intermediate CA 1/ST=Some-State/C=IL/O=IDC Herzliya/OU=Meerkat Voting Team

View File

@ -0,0 +1 @@
unique_subject = no

View File

@ -0,0 +1 @@
1001

View File

@ -0,0 +1 @@
1000

View File

@ -0,0 +1 @@
1000

View File

@ -0,0 +1,61 @@
[ ca ]
default_ca = myca
[ crl_ext ]
issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always
[ myca ]
dir = ./
new_certs_dir = $dir
unique_subject = no
certificate = $dir/root-ca.crt
database = $dir/certindex
private_key = $dir/root-ca-private-key.pem
serial = $dir/certserial
default_days = 3650
default_md = sha256
policy = myca_policy
x509_extensions = myca_extensions
crlnumber = $dir/crlnumber
default_crl_days = 3650
[ myca_policy ]
commonName = supplied
stateOrProvinceName = optional
countryName = optional
emailAddress = optional
organizationName = supplied
organizationalUnitName = optional
[ myca_extensions ]
basicConstraints = critical,CA:TRUE
keyUsage = critical,any
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
keyUsage = digitalSignature,keyEncipherment,cRLSign,keyCertSign
extendedKeyUsage = serverAuth
crlDistributionPoints = @crl_section
subjectAltName = @alt_names
authorityInfoAccess = @ocsp_section
[ v3_ca ]
basicConstraints = critical,CA:TRUE,pathlen:0
keyUsage = critical,any
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
keyUsage = digitalSignature,keyEncipherment,cRLSign,keyCertSign
extendedKeyUsage = serverAuth
crlDistributionPoints = @crl_section
subjectAltName = @alt_names
authorityInfoAccess = @ocsp_section
[alt_names]
DNS.0 = Meerkat Voting Intermediate CA 1
[crl_section]
URI.0 = http://crl.factcenter.org/meerkat-root-ca.crl
[ocsp_section]
caIssuers;URI.0 = http://pki.factcenter.org/meerkat-root-ca.crt
OCSP;URI.0 = http://ocsp.factcenter.org/

View File

@ -0,0 +1,8 @@
-----BEGIN EC PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,B8CA131346FD6C9568A6C80935F2AF14
8q1seEln39/tQTo5KqN+qNRhd0fQ0oC71dYpfTHsP0NlNmjMtwKo2niFwzjxnSyP
vpJjGzUlnq30ucbeJA7CDm/1cmYAU5gGQ7gldgpi2TQVS+EBjqi/Y5P9AlrgLv6K
tKe4AvkqQcpi4ZvlUL9xmNaM9jEH4syopR9YClEMfa8=
-----END EC PRIVATE KEY-----

View File

@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIEi9y6pSKu1kDZcIfQQAnojl1iFxm32W0DVCp2P6HRrkoAcGBSuBBAAK
oUQDQgAEoijIYF12bpA0tcjyQnWZGQ4lzdBGR+hK/5al/M+zFgFwvWHoWf6yJsSB
ymviB5yUaH+cE+/3LXlGbpRzYKLBYQ==
-----END EC PRIVATE KEY-----

View File

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICpTCCAkygAwIBAgIJAJoVb07aGgNaMAoGCCqGSM49BAMCMIGwMQswCQYDVQQG
EwJJTDETMBEGA1UECAwKU29tZS1TdGF0ZTERMA8GA1UEBwwISGVyemxpeWExFDAS
BgNVBAoMC0lEQyBIZXJsaXlhMR8wHQYDVQQLDBZNZWVya2F0IFZvdGluZyBQcm9q
ZWN0MRgwFgYDVQQDDA9UZXN0aW5nIFJvb3QgQ0ExKDAmBgkqhkiG9w0BCQEWGXRl
c3RpbmctY2FAZmFjdGNlbnRlci5vcmcwHhcNMTUxMTExMTUzODE4WhcNMjUxMTA4
MTUzODE4WjCBsDELMAkGA1UEBhMCSUwxEzARBgNVBAgMClNvbWUtU3RhdGUxETAP
BgNVBAcMCEhlcnpsaXlhMRQwEgYDVQQKDAtJREMgSGVybGl5YTEfMB0GA1UECwwW
TWVlcmthdCBWb3RpbmcgUHJvamVjdDEYMBYGA1UEAwwPVGVzdGluZyBSb290IENB
MSgwJgYJKoZIhvcNAQkBFhl0ZXN0aW5nLWNhQGZhY3RjZW50ZXIub3JnMFYwEAYH
KoZIzj0CAQYFK4EEAAoDQgAEoijIYF12bpA0tcjyQnWZGQ4lzdBGR+hK/5al/M+z
FgFwvWHoWf6yJsSBymviB5yUaH+cE+/3LXlGbpRzYKLBYaNQME4wHQYDVR0OBBYE
FIkP0vV8uZfgD0IGguxhefc4/LWiMB8GA1UdIwQYMBaAFIkP0vV8uZfgD0IGguxh
efc4/LWiMAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgNftHrW30Git8
VFQKyMCkasauSpEHpAGdcRAhRHqUQMUCIDxw++trz/Iv8818xVB1ARr9EQAmH0aC
7MHETGuiBC7L
-----END CERTIFICATE-----

View File

@ -0,0 +1,3 @@
-----BEGIN EC PARAMETERS-----
BgUrgQQACg==
-----END EC PARAMETERS-----