[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [metrics-lib/master] Support (ntor-)onion-key crosscerts.
commit f4fca35135482979f85f7891b075b46a194ef37e
Author: Karsten Loesing <karsten.loesing@xxxxxxx>
Date: Wed Dec 16 16:09:17 2015 +0100
Support (ntor-)onion-key crosscerts.
---
CHANGELOG.md | 2 +
.../torproject/descriptor/ServerDescriptor.java | 17 +++++
.../descriptor/impl/ServerDescriptorImpl.java | 50 +++++++++++++-
.../descriptor/impl/ServerDescriptorImplTest.java | 73 ++++++++++++++++++++
4 files changed, 139 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bfda75e..73e9a1e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,8 @@
- Include RSA-1024 signatures of SHA-1 digests of extra-info
descriptors, which were parsed and discarded before.
- Support hidden-service statistics in extra-info descriptors.
+ - Support onion-key and ntor-onion-key cross certificates in server
+ descriptors.
# Changes in version 1.0.0 - 2015-12-05
diff --git a/src/org/torproject/descriptor/ServerDescriptor.java b/src/org/torproject/descriptor/ServerDescriptor.java
index 3266e9d..49eaa92 100644
--- a/src/org/torproject/descriptor/ServerDescriptor.java
+++ b/src/org/torproject/descriptor/ServerDescriptor.java
@@ -174,5 +174,22 @@ public interface ServerDescriptor extends Descriptor {
* the first space after the "router-sig-ed25519" string, prefixed with
* the string "Tor router descriptor signature v1". */
public String getRouterSignatureEd25519();
+
+ /* Return an RSA signature, generated using the onion-key, that proves
+ * that the party creating the descriptor had control over the secret
+ * key corresponding to the onion-key, or null if the descriptor does
+ * not contain such a signature. */
+ public String getOnionKeyCrosscert();
+
+ /* Return an Ed25519 signature, generated using the ntor-onion-key, that
+ * proves that the party creating the descriptor had control over the
+ * secret key corresponding to the ntor-onion-key, or null if the
+ * descriptor does not contain such a signature. */
+ public String getNtorOnionKeyCrosscert();
+
+ /* Return the sign of the Ed25519 public key corresponding to the ntor
+ * onion key as 0 or 1, or -1 if the descriptor does not contain this
+ * information. */
+ public int getNtorOnionKeyCrosscertSign();
}
diff --git a/src/org/torproject/descriptor/impl/ServerDescriptorImpl.java b/src/org/torproject/descriptor/impl/ServerDescriptorImpl.java
index 3dd6c40..1484866 100644
--- a/src/org/torproject/descriptor/impl/ServerDescriptorImpl.java
+++ b/src/org/torproject/descriptor/impl/ServerDescriptorImpl.java
@@ -37,9 +37,9 @@ public abstract class ServerDescriptorImpl extends DescriptorImpl
+ "hibernating,uptime,contact,family,read-history,write-history,"
+ "eventdns,caches-extra-info,extra-info-digest,"
+ "hidden-service-dir,protocols,allow-single-hop-exits,onion-key,"
- + "signing-key,ipv6-policy,ntor-onion-key,router-sig-ed25519,"
- + "router-signature,router-digest-sha256,router-digest").
- split(",")));
+ + "signing-key,ipv6-policy,ntor-onion-key,onion-key-crosscert,"
+ + "ntor-onion-key-crosscert,router-sig-ed25519,router-signature,"
+ + "router-digest-sha256,router-digest").split(",")));
this.checkAtMostOnceKeywords(atMostOnceKeywords);
this.checkFirstKeyword("router");
if (this.getKeywordCount("accept") == 0 &&
@@ -131,6 +131,12 @@ public abstract class ServerDescriptorImpl extends DescriptorImpl
this.parseMasterKeyEd25519Line(line, lineNoOpt, partsNoOpt);
} else if (keyword.equals("router-sig-ed25519")) {
this.parseRouterSigEd25519Line(line, lineNoOpt, partsNoOpt);
+ } else if (keyword.equals("onion-key-crosscert")) {
+ this.parseOnionKeyCrosscert(line, lineNoOpt, partsNoOpt);
+ nextCrypto = "onion-key-crosscert";
+ } else if (keyword.equals("ntor-onion-key-crosscert")) {
+ this.parseNtorOnionKeyCrosscert(line, lineNoOpt, partsNoOpt);
+ nextCrypto = "ntor-onion-key-crosscert";
} else if (line.startsWith("-----BEGIN")) {
cryptoLines = new ArrayList<String>();
cryptoLines.add(line);
@@ -150,6 +156,10 @@ public abstract class ServerDescriptorImpl extends DescriptorImpl
} else if ("identity-ed25519".equals(nextCrypto)) {
this.identityEd25519 = cryptoString;
this.parseIdentityEd25519CryptoBlock(cryptoString);
+ } else if ("onion-key-crosscert".equals(nextCrypto)) {
+ this.onionKeyCrosscert = cryptoString;
+ } else if ("ntor-onion-key-crosscert".equals(nextCrypto)) {
+ this.ntorOnionKeyCrosscert = cryptoString;
} else if (this.failUnrecognizedDescriptorLines) {
throw new DescriptorParseException("Unrecognized crypto "
+ "block '" + cryptoString + "' in server descriptor.");
@@ -534,6 +544,25 @@ public abstract class ServerDescriptorImpl extends DescriptorImpl
}
}
+ private void parseOnionKeyCrosscert(String line, String lineNoOpt,
+ String[] partsNoOpt) throws DescriptorParseException {
+ if (partsNoOpt.length != 1) {
+ throw new DescriptorParseException("Illegal line '" + line + "'.");
+ }
+ }
+
+ private void parseNtorOnionKeyCrosscert(String line, String lineNoOpt,
+ String[] partsNoOpt) throws DescriptorParseException {
+ if (partsNoOpt.length != 2) {
+ throw new DescriptorParseException("Illegal line '" + line + "'.");
+ }
+ try {
+ this.ntorOnionKeyCrosscertSign = Integer.parseInt(partsNoOpt[1]);
+ } catch (NumberFormatException e) {
+ throw new DescriptorParseException("Illegal line '" + line + "'.");
+ }
+ }
+
private void parseIdentityEd25519CryptoBlock(String cryptoString)
throws DescriptorParseException {
String masterKeyEd25519FromIdentityEd25519 =
@@ -834,5 +863,20 @@ public abstract class ServerDescriptorImpl extends DescriptorImpl
public String getRouterSignatureEd25519() {
return this.routerSignatureEd25519;
}
+
+ private String onionKeyCrosscert;
+ public String getOnionKeyCrosscert() {
+ return this.onionKeyCrosscert;
+ }
+
+ private String ntorOnionKeyCrosscert;
+ public String getNtorOnionKeyCrosscert() {
+ return this.ntorOnionKeyCrosscert;
+ }
+
+ private int ntorOnionKeyCrosscertSign = -1;
+ public int getNtorOnionKeyCrosscertSign() {
+ return ntorOnionKeyCrosscertSign;
+ }
}
diff --git a/test/org/torproject/descriptor/impl/ServerDescriptorImplTest.java b/test/org/torproject/descriptor/impl/ServerDescriptorImplTest.java
index a98df9f..56f1419 100644
--- a/test/org/torproject/descriptor/impl/ServerDescriptorImplTest.java
+++ b/test/org/torproject/descriptor/impl/ServerDescriptorImplTest.java
@@ -104,6 +104,20 @@ public class ServerDescriptorImplTest {
db.signingKeyLines = lines;
return new RelayServerDescriptorImpl(db.buildDescriptor(), true);
}
+ private String onionKeyCrosscertLines = null;
+ private static ServerDescriptor createWithOnionKeyCrosscertLines(
+ String lines) throws DescriptorParseException {
+ DescriptorBuilder db = new DescriptorBuilder();
+ db.onionKeyCrosscertLines = lines;
+ return new RelayServerDescriptorImpl(db.buildDescriptor(), true);
+ }
+ private String ntorOnionKeyCrosscertLines = null;
+ private static ServerDescriptor createWithNtorOnionKeyCrosscertLines(
+ String lines) throws DescriptorParseException {
+ DescriptorBuilder db = new DescriptorBuilder();
+ db.ntorOnionKeyCrosscertLines = lines;
+ return new RelayServerDescriptorImpl(db.buildDescriptor(), true);
+ }
private String exitPolicyLines = "reject *:*";
private static ServerDescriptor createWithExitPolicyLines(
String lines) throws DescriptorParseException {
@@ -274,6 +288,12 @@ public class ServerDescriptorImplTest {
if (this.signingKeyLines != null) {
sb.append(this.signingKeyLines + "\n");
}
+ if (this.onionKeyCrosscertLines != null) {
+ sb.append(this.onionKeyCrosscertLines + "\n");
+ }
+ if (this.ntorOnionKeyCrosscertLines != null) {
+ sb.append(this.ntorOnionKeyCrosscertLines + "\n");
+ }
if (this.exitPolicyLines != null) {
sb.append(this.exitPolicyLines + "\n");
}
@@ -1481,5 +1501,58 @@ public class ServerDescriptorImplTest {
MASTER_KEY_ED25519_LINE, ROUTER_SIG_ED25519_LINE + "\n"
+ ROUTER_SIG_ED25519_LINE);
}
+
+ private static final String ONION_KEY_CROSSCERT_LINES =
+ "onion-key-crosscert\n"
+ + "-----BEGIN CROSSCERT-----\n"
+ + "gVWpiNgG2FekW1uonr4KKoqykjr4bqUBKGZfu6s9rvsV1TThnquZNP6ZhX2IPdQA"
+ + "\nlfKtzFggGu/4BiJ5oTSDj2sK2DMjY3rjrMQZ3I/wJ25yhc9gxjqYqUYO9MmJwA"
+ + "Lp\nfYkqp/t4WchJpyva/4hK8vITsI6eT2BfY/DWMy/suIE=\n"
+ + "-----END CROSSCERT-----";
+
+ private static final String NTOR_ONION_KEY_CROSSCERT_LINES =
+ "ntor-onion-key-crosscert 1\n"
+ + "-----BEGIN ED25519 CERT-----\n"
+ + "AQoABiUeAdauu1MxYGMmGLTCPaoes0RvW7udeLc1t8LZ4P3CDo5bAN4nrRfbCfOt"
+ + "\nz2Nwqn8tER1a+Ry6Vs+ilMZA55Rag4+f6Zdb1fmHWknCxbQlLHpqHACMtemPda"
+ + "Ka\nErPtMuiEqAc=\n"
+ + "-----END ED25519 CERT-----";
+
+ @Test()
+ public void testOnionKeyCrosscert() throws DescriptorParseException {
+ ServerDescriptor descriptor =
+ DescriptorBuilder.createWithOnionKeyCrosscertLines(
+ ONION_KEY_CROSSCERT_LINES);
+ assertEquals(ONION_KEY_CROSSCERT_LINES.substring(
+ ONION_KEY_CROSSCERT_LINES.indexOf("\n") + 1),
+ descriptor.getOnionKeyCrosscert());
+ }
+
+ @Test(expected = DescriptorParseException.class)
+ public void testOnionKeyCrosscertDuplicate()
+ throws DescriptorParseException {
+ DescriptorBuilder.createWithOnionKeyCrosscertLines(
+ ONION_KEY_CROSSCERT_LINES + "\n" + ONION_KEY_CROSSCERT_LINES);
+ }
+
+ @Test()
+ public void testNtorOnionKeyCrosscert()
+ throws DescriptorParseException {
+ ServerDescriptor descriptor =
+ DescriptorBuilder.createWithNtorOnionKeyCrosscertLines(
+ NTOR_ONION_KEY_CROSSCERT_LINES);
+ assertEquals(NTOR_ONION_KEY_CROSSCERT_LINES.substring(
+ NTOR_ONION_KEY_CROSSCERT_LINES.indexOf("\n") + 1),
+ descriptor.getNtorOnionKeyCrosscert());
+ assertEquals(1, descriptor.getNtorOnionKeyCrosscertSign());
+ }
+
+ @Test(expected = DescriptorParseException.class)
+ public void testNtorOnionKeyCrosscertDuplicate()
+ throws DescriptorParseException {
+ DescriptorBuilder.createWithOnionKeyCrosscertLines(
+ NTOR_ONION_KEY_CROSSCERT_LINES + "\n"
+ + NTOR_ONION_KEY_CROSSCERT_LINES);
+ }
}
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits