[tor-commits] [metrics-lib/master] Move descriptor digest computation to DescriptorImpl.

karsten at torproject.org karsten at torproject.org
Tue Jun 6 13:12:31 UTC 2017


commit 74de0a5d7adf1346957fd17d2580199eb39c9712
Author: Karsten Loesing <karsten.loesing at gmx.net>
Date:   Mon May 29 14:10:19 2017 +0200

    Move descriptor digest computation to DescriptorImpl.
    
    The main intention behind this change is to reduce the number of
    places in the code where byte[] is converted to String.  But another
    reason is to reduce code duplication, which would have been sufficient
    to make this change.
---
 CHANGELOG.md                                       |  1 +
 .../torproject/descriptor/impl/DescriptorImpl.java | 84 +++++++++++++++++++
 .../impl/DirectoryKeyCertificateImpl.java          | 41 +---------
 .../descriptor/impl/ExtraInfoDescriptorImpl.java   | 93 ++-------------------
 .../descriptor/impl/MicrodescriptorImpl.java       | 39 +--------
 .../descriptor/impl/RelayDirectoryImpl.java        | 45 +----------
 .../impl/RelayNetworkStatusConsensusImpl.java      | 44 +---------
 .../descriptor/impl/RelayNetworkStatusImpl.java    | 45 +----------
 .../impl/RelayNetworkStatusVoteImpl.java           | 43 +---------
 .../descriptor/impl/ServerDescriptorImpl.java      | 94 ++--------------------
 .../impl/ExtraInfoDescriptorImplTest.java          | 10 ---
 11 files changed, 110 insertions(+), 429 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 61be7dc..85c9be8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@
    - Simplify and avoid repetition in parse helper methods.
    - Fix a bug where Microdescriptor's getDigestSha256Base64() returns
      a hex string rather than a base64 string.
+   - Move descriptor digest computation to DescriptorImpl.
 
 
 # Changes in version 1.7.0 - 2017-05-17
diff --git a/src/main/java/org/torproject/descriptor/impl/DescriptorImpl.java b/src/main/java/org/torproject/descriptor/impl/DescriptorImpl.java
index f963fef..d5d28c8 100644
--- a/src/main/java/org/torproject/descriptor/impl/DescriptorImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/DescriptorImpl.java
@@ -7,6 +7,9 @@ import org.torproject.descriptor.Descriptor;
 import org.torproject.descriptor.DescriptorParseException;
 
 import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
 import java.util.EnumMap;
 import java.util.List;
@@ -14,6 +17,8 @@ import java.util.Map;
 import java.util.Scanner;
 import java.util.Set;
 
+import javax.xml.bind.DatatypeConverter;
+
 public abstract class DescriptorImpl implements Descriptor {
 
   public static final String NL = "\n";
@@ -353,5 +358,84 @@ public abstract class DescriptorImpl implements Descriptor {
   protected void clearParsedKeys() {
     this.parsedKeys = null;
   }
+
+  private String digestSha1Hex;
+
+  protected void setDigestSha1Hex(String digestSha1Hex) {
+    this.digestSha1Hex = digestSha1Hex;
+  }
+
+  protected void calculateDigestSha1Hex(String startToken, String endToken)
+      throws DescriptorParseException {
+    if (null == this.digestSha1Hex) {
+      String ascii = new String(this.rawDescriptorBytes,
+          StandardCharsets.US_ASCII);
+      int start = ascii.indexOf(startToken);
+      int end = (null == endToken) ? ascii.length()
+          : (ascii.indexOf(endToken) + endToken.length());
+      if (start >= 0 && end >= 0 && end > start) {
+        byte[] forDigest = new byte[end - start];
+        System.arraycopy(this.rawDescriptorBytes, start, forDigest, 0,
+            end - start);
+        try {
+          this.digestSha1Hex = DatatypeConverter.printHexBinary(
+              MessageDigest.getInstance("SHA-1").digest(forDigest))
+              .toLowerCase();
+        } catch (NoSuchAlgorithmException e) {
+          /* Handle below. */
+        }
+      }
+    }
+    if (null == this.digestSha1Hex) {
+      throw new DescriptorParseException("Could not calculate descriptor "
+          + "digest.");
+    }
+  }
+
+  public String getDigestSha1Hex() {
+    return this.digestSha1Hex;
+  }
+
+  private String digestSha256Base64;
+
+  protected void setDigestSha256Base64(String digestSha256Base64) {
+    this.digestSha256Base64 = digestSha256Base64;
+  }
+
+  protected void calculateDigestSha256Base64(String startToken,
+      String endToken) throws DescriptorParseException {
+    if (null == this.digestSha256Base64) {
+      String ascii = new String(this.rawDescriptorBytes,
+          StandardCharsets.US_ASCII);
+      int start = ascii.indexOf(startToken);
+      int end = (null == endToken) ? ascii.length()
+          : (ascii.indexOf(endToken) + endToken.length());
+      if (start >= 0 && end >= 0 && end > start) {
+        byte[] forDigest = new byte[end - start];
+        System.arraycopy(this.rawDescriptorBytes, start, forDigest, 0,
+            end - start);
+        try {
+          this.digestSha256Base64 = DatatypeConverter.printBase64Binary(
+              MessageDigest.getInstance("SHA-256").digest(forDigest))
+              .replaceAll("=", "");
+        } catch (NoSuchAlgorithmException e) {
+          /* Handle below. */
+        }
+      }
+    }
+    if (null == this.digestSha256Base64) {
+      throw new DescriptorParseException("Could not calculate descriptor "
+          + "digest.");
+    }
+  }
+
+  protected void calculateDigestSha256Base64(String startToken)
+      throws DescriptorParseException {
+    this.calculateDigestSha256Base64(startToken, null);
+  }
+
+  public String getDigestSha256Base64() {
+    return this.digestSha256Base64;
+  }
 }
 
diff --git a/src/main/java/org/torproject/descriptor/impl/DirectoryKeyCertificateImpl.java b/src/main/java/org/torproject/descriptor/impl/DirectoryKeyCertificateImpl.java
index 0bb08fd..0ade2c9 100644
--- a/src/main/java/org/torproject/descriptor/impl/DirectoryKeyCertificateImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/DirectoryKeyCertificateImpl.java
@@ -6,17 +6,12 @@ package org.torproject.descriptor.impl;
 import org.torproject.descriptor.DescriptorParseException;
 import org.torproject.descriptor.DirectoryKeyCertificate;
 
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.List;
 import java.util.Scanner;
 import java.util.Set;
 
-import javax.xml.bind.DatatypeConverter;
-
 public class DirectoryKeyCertificateImpl extends DescriptorImpl
     implements DirectoryKeyCertificate {
 
@@ -41,7 +36,8 @@ public class DirectoryKeyCertificateImpl extends DescriptorImpl
       throws DescriptorParseException {
     super(rawDescriptorBytes, failUnrecognizedDescriptorLines, false);
     this.parseDescriptorBytes();
-    this.calculateDigest();
+    this.calculateDigestSha1Hex(Key.DIR_KEY_CERTIFICATE_VERSION.keyword + SP,
+        NL + Key.DIR_KEY_CERTIFICATION.keyword + NL);
     Set<Key> exactlyOnceKeys = EnumSet.of(
         Key.DIR_KEY_CERTIFICATE_VERSION, Key.FINGERPRINT, Key.DIR_IDENTITY_KEY,
         Key.DIR_KEY_PUBLISHED, Key.DIR_KEY_EXPIRES, Key.DIR_SIGNING_KEY,
@@ -211,32 +207,6 @@ public class DirectoryKeyCertificateImpl extends DescriptorImpl
     }
   }
 
-  private void calculateDigest() throws DescriptorParseException {
-    try {
-      String ascii = new String(this.getRawDescriptorBytes(), "US-ASCII");
-      String startToken = Key.DIR_KEY_CERTIFICATE_VERSION.keyword + SP;
-      String sigToken = NL + Key.DIR_KEY_CERTIFICATION.keyword + NL;
-      int start = ascii.indexOf(startToken);
-      int sig = ascii.indexOf(sigToken) + sigToken.length();
-      if (start >= 0 && sig >= 0 && sig > start) {
-        byte[] forDigest = new byte[sig - start];
-        System.arraycopy(this.getRawDescriptorBytes(), start,
-            forDigest, 0, sig - start);
-        this.certificateDigest = DatatypeConverter.printHexBinary(
-            MessageDigest.getInstance("SHA-1").digest(forDigest))
-            .toLowerCase();
-      }
-    } catch (UnsupportedEncodingException e) {
-      /* Handle below. */
-    } catch (NoSuchAlgorithmException e) {
-      /* Handle below. */
-    }
-    if (this.certificateDigest == null) {
-      throw new DescriptorParseException("Could not calculate "
-          + "certificate digest.");
-    }
-  }
-
   private int dirKeyCertificateVersion;
 
   @Override
@@ -307,16 +277,9 @@ public class DirectoryKeyCertificateImpl extends DescriptorImpl
     return this.dirKeyCertification;
   }
 
-  private String certificateDigest;
-
   @Override
   public String getCertificateDigest() {
     return this.getDigestSha1Hex();
   }
-
-  @Override
-  public String getDigestSha1Hex() {
-    return this.certificateDigest;
-  }
 }
 
diff --git a/src/main/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java b/src/main/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java
index fd55925..7b99114 100644
--- a/src/main/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java
@@ -7,9 +7,6 @@ import org.torproject.descriptor.BandwidthHistory;
 import org.torproject.descriptor.DescriptorParseException;
 import org.torproject.descriptor.ExtraInfoDescriptor;
 
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -23,8 +20,6 @@ import java.util.Set;
 import java.util.SortedMap;
 import java.util.TreeMap;
 
-import javax.xml.bind.DatatypeConverter;
-
 public abstract class ExtraInfoDescriptorImpl extends DescriptorImpl
     implements ExtraInfoDescriptor {
 
@@ -43,8 +38,10 @@ public abstract class ExtraInfoDescriptorImpl extends DescriptorImpl
       throws DescriptorParseException {
     super(descriptorBytes, failUnrecognizedDescriptorLines, false);
     this.parseDescriptorBytes();
-    this.calculateDigest();
-    this.calculateDigestSha256();
+    this.calculateDigestSha1Hex(Key.EXTRA_INFO.keyword + SP,
+        NL + Key.ROUTER_SIGNATURE.keyword + NL);
+    this.calculateDigestSha256Base64(Key.EXTRA_INFO.keyword + SP,
+        NL + "-----END SIGNATURE-----" + NL);
     this.checkExactlyOnceKeys(exactlyOnceKeys);
     Set<Key> dirreqStatsKeys = EnumSet.of(
         Key.DIRREQ_STATS_END, Key.DIRREQ_V2_IPS, Key.DIRREQ_V3_IPS,
@@ -784,8 +781,8 @@ public abstract class ExtraInfoDescriptorImpl extends DescriptorImpl
     if (partsNoOpt.length != 2) {
       throw new DescriptorParseException("Illegal line '" + line + "'.");
     }
-    this.extraInfoDigest = ParseHelper.parseTwentyByteHexString(line,
-        partsNoOpt[1]);
+    this.setDigestSha1Hex(ParseHelper.parseTwentyByteHexString(line,
+        partsNoOpt[1]));
   }
 
   private void parseIdentityEd25519Line(String line, String lineNoOpt,
@@ -836,95 +833,19 @@ public abstract class ExtraInfoDescriptorImpl extends DescriptorImpl
       throw new DescriptorParseException("Illegal line '" + line + "'.");
     }
     ParseHelper.parseThirtyTwoByteBase64String(line, partsNoOpt[1]);
-    this.extraInfoDigestSha256 = partsNoOpt[1];
-  }
-
-  private void calculateDigest() throws DescriptorParseException {
-    if (this.extraInfoDigest != null) {
-      /* We already learned the descriptor digest of this bridge
-       * descriptor from a "router-digest" line. */
-      return;
-    }
-    try {
-      String ascii = new String(this.getRawDescriptorBytes(), "US-ASCII");
-      String startToken = Key.EXTRA_INFO.keyword + SP;
-      String sigToken = NL + Key.ROUTER_SIGNATURE.keyword + NL;
-      int start = ascii.indexOf(startToken);
-      int sig = ascii.indexOf(sigToken) + sigToken.length();
-      if (start >= 0 && sig >= 0 && sig > start) {
-        byte[] forDigest = new byte[sig - start];
-        System.arraycopy(this.getRawDescriptorBytes(), start,
-            forDigest, 0, sig - start);
-        this.extraInfoDigest = DatatypeConverter.printHexBinary(
-            MessageDigest.getInstance("SHA-1").digest(forDigest))
-            .toLowerCase();
-      }
-    } catch (UnsupportedEncodingException e) {
-      /* Handle below. */
-    } catch (NoSuchAlgorithmException e) {
-      /* Handle below. */
-    }
-    if (this.extraInfoDigest == null) {
-      throw new DescriptorParseException("Could not calculate extra-info "
-          + "descriptor digest.");
-    }
-  }
-
-  private void calculateDigestSha256() throws DescriptorParseException {
-    if (this.extraInfoDigestSha256 != null) {
-      /* We already learned the descriptor digest of this bridge
-       * descriptor from a "router-digest-sha256" line. */
-      return;
-    }
-    try {
-      String ascii = new String(this.getRawDescriptorBytes(), "US-ASCII");
-      String startToken = Key.EXTRA_INFO.keyword + SP;
-      String sigToken = "\n-----END SIGNATURE-----\n";
-      int start = ascii.indexOf(startToken);
-      int sig = ascii.indexOf(sigToken) + sigToken.length();
-      if (start >= 0 && sig >= 0 && sig > start) {
-        byte[] forDigest = new byte[sig - start];
-        System.arraycopy(this.getRawDescriptorBytes(), start, forDigest,
-            0, sig - start);
-        this.extraInfoDigestSha256 = DatatypeConverter.printBase64Binary(
-            MessageDigest.getInstance("SHA-256").digest(forDigest))
-            .replaceAll("=", "");
-      }
-    } catch (UnsupportedEncodingException e) {
-      /* Handle below. */
-    } catch (NoSuchAlgorithmException e) {
-      /* Handle below. */
-    }
-    if (this.extraInfoDigestSha256 == null) {
-      throw new DescriptorParseException("Could not calculate extra-info "
-          + "descriptor SHA-256 digest.");
-    }
+    this.setDigestSha256Base64(partsNoOpt[1]);
   }
 
-  private String extraInfoDigest;
-
   @Override
   public String getExtraInfoDigest() {
     return this.getDigestSha1Hex();
   }
 
   @Override
-  public String getDigestSha1Hex() {
-    return this.extraInfoDigest;
-  }
-
-  private String extraInfoDigestSha256;
-
-  @Override
   public String getExtraInfoDigestSha256() {
     return this.getDigestSha256Base64();
   }
 
-  @Override
-  public String getDigestSha256Base64() {
-    return this.extraInfoDigestSha256;
-  }
-
   private String nickname;
 
   @Override
diff --git a/src/main/java/org/torproject/descriptor/impl/MicrodescriptorImpl.java b/src/main/java/org/torproject/descriptor/impl/MicrodescriptorImpl.java
index 522da05..e54b939 100644
--- a/src/main/java/org/torproject/descriptor/impl/MicrodescriptorImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/MicrodescriptorImpl.java
@@ -6,9 +6,6 @@ package org.torproject.descriptor.impl;
 import org.torproject.descriptor.DescriptorParseException;
 import org.torproject.descriptor.Microdescriptor;
 
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.EnumSet;
@@ -16,8 +13,6 @@ import java.util.List;
 import java.util.Scanner;
 import java.util.Set;
 
-import javax.xml.bind.DatatypeConverter;
-
 /* Contains a microdescriptor. */
 public class MicrodescriptorImpl extends DescriptorImpl
     implements Microdescriptor {
@@ -43,7 +38,7 @@ public class MicrodescriptorImpl extends DescriptorImpl
       throws DescriptorParseException {
     super(descriptorBytes, failUnrecognizedDescriptorLines, false);
     this.parseDescriptorBytes();
-    this.calculateDigest();
+    this.calculateDigestSha256Base64(Key.ONION_KEY.keyword + NL);
     this.checkExactlyOnceKeys(EnumSet.of(Key.ONION_KEY));
     Set<Key> atMostOnceKeys = EnumSet.of(
         Key.NTOR_ONION_KEY, Key.FAMILY, Key.P, Key.P6, Key.ID);
@@ -233,43 +228,11 @@ public class MicrodescriptorImpl extends DescriptorImpl
     }
   }
 
-  private void calculateDigest() throws DescriptorParseException {
-    try {
-      String ascii = new String(this.getRawDescriptorBytes(), "US-ASCII");
-      String startToken = "onion-key\n";
-      int start = ascii.indexOf(startToken);
-      int end = ascii.length();
-      if (start >= 0 && end > start) {
-        byte[] forDigest = new byte[end - start];
-        System.arraycopy(this.getRawDescriptorBytes(), start,
-            forDigest, 0, end - start);
-        this.microdescriptorDigest = DatatypeConverter.printBase64Binary(
-            MessageDigest.getInstance("SHA-256").digest(forDigest))
-            .replaceAll("=", "");
-      }
-    } catch (UnsupportedEncodingException e) {
-      /* Handle below. */
-    } catch (NoSuchAlgorithmException e) {
-      /* Handle below. */
-    }
-    if (this.microdescriptorDigest == null) {
-      throw new DescriptorParseException("Could not calculate "
-          + "microdescriptor digest.");
-    }
-  }
-
-  private String microdescriptorDigest;
-
   @Override
   public String getMicrodescriptorDigest() {
     return this.getDigestSha256Base64();
   }
 
-  @Override
-  public String getDigestSha256Base64() {
-    return this.microdescriptorDigest;
-  }
-
   private String onionKey;
 
   @Override
diff --git a/src/main/java/org/torproject/descriptor/impl/RelayDirectoryImpl.java b/src/main/java/org/torproject/descriptor/impl/RelayDirectoryImpl.java
index fae54f4..3c810e0 100644
--- a/src/main/java/org/torproject/descriptor/impl/RelayDirectoryImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/RelayDirectoryImpl.java
@@ -8,17 +8,12 @@ import org.torproject.descriptor.RelayDirectory;
 import org.torproject.descriptor.RouterStatusEntry;
 import org.torproject.descriptor.ServerDescriptor;
 
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.List;
 import java.util.Scanner;
 import java.util.Set;
 
-import javax.xml.bind.DatatypeConverter;
-
 public class RelayDirectoryImpl extends DescriptorImpl
     implements RelayDirectory {
 
@@ -43,7 +38,8 @@ public class RelayDirectoryImpl extends DescriptorImpl
       throws DescriptorParseException {
     super(directoryBytes, failUnrecognizedDescriptorLines, true);
     this.splitAndParseParts(rawDescriptorBytes);
-    this.calculateDigest();
+    this.calculateDigestSha1Hex(Key.SIGNED_DIRECTORY.keyword + NL,
+        NL + Key.DIRECTORY_SIGNATURE.keyword + SP);
     Set<Key> exactlyOnceKeys = EnumSet.of(
         Key.SIGNED_DIRECTORY, Key.RECOMMENDED_SOFTWARE,
         Key.DIRECTORY_SIGNATURE);
@@ -55,36 +51,6 @@ public class RelayDirectoryImpl extends DescriptorImpl
     this.clearParsedKeys();
   }
 
-  private void calculateDigest() throws DescriptorParseException {
-    try {
-      String ascii = new String(this.getRawDescriptorBytes(), "US-ASCII");
-      String startToken = Key.SIGNED_DIRECTORY.keyword + NL;
-      String sigToken = NL + Key.DIRECTORY_SIGNATURE.keyword + SP;
-      if (!ascii.contains(sigToken)) {
-        return;
-      }
-      int start = ascii.indexOf(startToken);
-      int sig = ascii.indexOf(sigToken) + sigToken.length();
-      sig = ascii.indexOf(NL, sig) + 1;
-      if (start >= 0 && sig >= 0 && sig > start) {
-        byte[] forDigest = new byte[sig - start];
-        System.arraycopy(this.getRawDescriptorBytes(), start,
-            forDigest, 0, sig - start);
-        this.directoryDigest = DatatypeConverter.printHexBinary(
-            MessageDigest.getInstance("SHA-1").digest(forDigest))
-            .toLowerCase();
-      }
-    } catch (UnsupportedEncodingException e) {
-      /* Handle below. */
-    } catch (NoSuchAlgorithmException e) {
-      /* Handle below. */
-    }
-    if (this.directoryDigest == null) {
-      throw new DescriptorParseException("Could not calculate v1 "
-          + "directory digest.");
-    }
-  }
-
   private void splitAndParseParts(byte[] rawDescriptorBytes)
       throws DescriptorParseException {
     if (this.rawDescriptorBytes.length == 0) {
@@ -553,16 +519,9 @@ public class RelayDirectoryImpl extends DescriptorImpl
     return this.nickname;
   }
 
-  private String directoryDigest;
-
   @Override
   public String getDirectoryDigest() {
     return this.getDigestSha1Hex();
   }
-
-  @Override
-  public String getDigestSha1Hex() {
-    return this.directoryDigest;
-  }
 }
 
diff --git a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java
index 43212f3..a90ae3e 100644
--- a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java
@@ -6,9 +6,6 @@ package org.torproject.descriptor.impl;
 import org.torproject.descriptor.DescriptorParseException;
 import org.torproject.descriptor.RelayNetworkStatusConsensus;
 
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.EnumSet;
@@ -20,8 +17,6 @@ import java.util.SortedSet;
 import java.util.TreeMap;
 import java.util.TreeSet;
 
-import javax.xml.bind.DatatypeConverter;
-
 /* Contains a network status consensus or microdesc consensus. */
 public class RelayNetworkStatusConsensusImpl extends NetworkStatusImpl
     implements RelayNetworkStatusConsensus {
@@ -60,36 +55,8 @@ public class RelayNetworkStatusConsensusImpl extends NetworkStatusImpl
     this.checkAtMostOnceKeys(atMostOnceKeys);
     this.checkFirstKey(Key.NETWORK_STATUS_VERSION);
     this.clearParsedKeys();
-    this.calculateDigest();
-  }
-
-  private void calculateDigest() throws DescriptorParseException {
-    try {
-      String ascii = new String(this.getRawDescriptorBytes(), "US-ASCII");
-      String startToken = Key.NETWORK_STATUS_VERSION.keyword + SP;
-      String sigToken = NL + Key.DIRECTORY_SIGNATURE.keyword + SP;
-      if (!ascii.contains(sigToken)) {
-        return;
-      }
-      int start = ascii.indexOf(startToken);
-      int sig = ascii.indexOf(sigToken) + sigToken.length();
-      if (start >= 0 && sig >= 0 && sig > start) {
-        byte[] forDigest = new byte[sig - start];
-        System.arraycopy(this.getRawDescriptorBytes(), start,
-            forDigest, 0, sig - start);
-        this.consensusDigest = DatatypeConverter.printHexBinary(
-            MessageDigest.getInstance("SHA-1").digest(forDigest))
-            .toLowerCase();
-      }
-    } catch (UnsupportedEncodingException e) {
-      /* Handle below. */
-    } catch (NoSuchAlgorithmException e) {
-      /* Handle below. */
-    }
-    if (this.consensusDigest == null) {
-      throw new DescriptorParseException("Could not calculate consensus "
-          + "digest.");
-    }
+    this.calculateDigestSha1Hex(Key.NETWORK_STATUS_VERSION.keyword + SP,
+        NL + Key.DIRECTORY_SIGNATURE.keyword + SP);
   }
 
   protected void parseHeader(byte[] headerBytes)
@@ -393,18 +360,11 @@ public class RelayNetworkStatusConsensusImpl extends NetworkStatusImpl
         parts, 1);
   }
 
-  private String consensusDigest;
-
   @Override
   public String getConsensusDigest() {
     return this.getDigestSha1Hex();
   }
 
-  @Override
-  public String getDigestSha1Hex() {
-    return this.consensusDigest;
-  }
-
   private int networkStatusVersion;
 
   @Override
diff --git a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusImpl.java b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusImpl.java
index 121cdc9..cc84ebd 100644
--- a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusImpl.java
@@ -6,9 +6,6 @@ package org.torproject.descriptor.impl;
 import org.torproject.descriptor.DescriptorParseException;
 import org.torproject.descriptor.RelayNetworkStatus;
 
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.EnumSet;
@@ -18,8 +15,6 @@ import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
 
-import javax.xml.bind.DatatypeConverter;
-
 public class RelayNetworkStatusImpl extends NetworkStatusImpl
     implements RelayNetworkStatus {
 
@@ -51,37 +46,8 @@ public class RelayNetworkStatusImpl extends NetworkStatusImpl
     this.checkAtMostOnceKeys(atMostOnceKeys);
     this.checkFirstKey(Key.NETWORK_STATUS_VERSION);
     this.clearParsedKeys();
-    this.calculateDigest();
-  }
-
-  private void calculateDigest() throws DescriptorParseException {
-    try {
-      String ascii = new String(this.getRawDescriptorBytes(), "US-ASCII");
-      String startToken = Key.NETWORK_STATUS_VERSION.keyword + SP;
-      String sigToken = NL + Key.DIRECTORY_SIGNATURE.keyword + SP;
-      if (!ascii.contains(sigToken)) {
-        return;
-      }
-      int start = ascii.indexOf(startToken);
-      int sig = ascii.indexOf(sigToken) + sigToken.length();
-      sig = ascii.indexOf(NL, sig) + 1;
-      if (start >= 0 && sig >= 0 && sig > start) {
-        byte[] forDigest = new byte[sig - start];
-        System.arraycopy(this.getRawDescriptorBytes(), start,
-            forDigest, 0, sig - start);
-        this.statusDigest = DatatypeConverter.printHexBinary(
-            MessageDigest.getInstance("SHA-1").digest(forDigest))
-            .toLowerCase();
-      }
-    } catch (UnsupportedEncodingException e) {
-      /* Handle below. */
-    } catch (NoSuchAlgorithmException e) {
-      /* Handle below. */
-    }
-    if (this.statusDigest == null) {
-      throw new DescriptorParseException("Could not calculate status "
-          + "digest.");
-    }
+    this.calculateDigestSha1Hex(Key.NETWORK_STATUS_VERSION.keyword + SP,
+        NL + Key.DIRECTORY_SIGNATURE.keyword + SP);
   }
 
   protected void parseHeader(byte[] headerBytes)
@@ -295,18 +261,11 @@ public class RelayNetworkStatusImpl extends NetworkStatusImpl
     this.nickname = ParseHelper.parseNickname(line, parts[1]);
   }
 
-  private String statusDigest;
-
   @Override
   public String getStatusDigest() {
     return this.getDigestSha1Hex();
   }
 
-  @Override
-  public String getDigestSha1Hex() {
-    return this.statusDigest;
-  }
-
   private int networkStatusVersion;
 
   @Override
diff --git a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java
index e5bd052..b694b5a 100644
--- a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java
@@ -7,9 +7,6 @@ import org.torproject.descriptor.DescriptorParseException;
 import org.torproject.descriptor.DirectorySignature;
 import org.torproject.descriptor.RelayNetworkStatusVote;
 
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.EnumSet;
@@ -21,7 +18,6 @@ import java.util.SortedMap;
 import java.util.SortedSet;
 import java.util.TreeMap;
 import java.util.TreeSet;
-import javax.xml.bind.DatatypeConverter;
 
 /* Contains a network status vote. */
 public class RelayNetworkStatusVoteImpl extends NetworkStatusImpl
@@ -66,36 +62,8 @@ public class RelayNetworkStatusVoteImpl extends NetworkStatusImpl
     this.checkAtLeastOnceKeys(EnumSet.of(Key.DIRECTORY_SIGNATURE));
     this.checkFirstKey(Key.NETWORK_STATUS_VERSION);
     this.clearParsedKeys();
-    this.calculateDigest();
-  }
-
-  private void calculateDigest() throws DescriptorParseException {
-    try {
-      String ascii = new String(this.getRawDescriptorBytes(), "US-ASCII");
-      String startToken = "network-status-version ";
-      String sigToken = "\ndirectory-signature ";
-      if (!ascii.contains(sigToken)) {
-        return;
-      }
-      int start = ascii.indexOf(startToken);
-      int sig = ascii.indexOf(sigToken) + sigToken.length();
-      if (start >= 0 && sig >= 0 && sig > start) {
-        byte[] forDigest = new byte[sig - start];
-        System.arraycopy(this.getRawDescriptorBytes(), start,
-            forDigest, 0, sig - start);
-        this.digestSha1Hex = DatatypeConverter.printHexBinary(
-            MessageDigest.getInstance("SHA-1").digest(forDigest))
-            .toLowerCase();
-      }
-    } catch (UnsupportedEncodingException e) {
-      /* Handle below. */
-    } catch (NoSuchAlgorithmException e) {
-      /* Handle below. */
-    }
-    if (this.digestSha1Hex == null) {
-      throw new DescriptorParseException("Could not calculate vote "
-          + "digest.");
-    }
+    this.calculateDigestSha1Hex(Key.NETWORK_STATUS_VERSION.keyword + SP,
+        NL + Key.DIRECTORY_SIGNATURE.keyword + SP);
   }
 
   protected void parseHeader(byte[] headerBytes)
@@ -647,13 +615,6 @@ public class RelayNetworkStatusVoteImpl extends NetworkStatusImpl
     }
   }
 
-  private String digestSha1Hex;
-
-  @Override
-  public String getDigestSha1Hex() {
-    return this.digestSha1Hex;
-  }
-
   private String nickname;
 
   @Override
diff --git a/src/main/java/org/torproject/descriptor/impl/ServerDescriptorImpl.java b/src/main/java/org/torproject/descriptor/impl/ServerDescriptorImpl.java
index 70bd42c..9241fcf 100644
--- a/src/main/java/org/torproject/descriptor/impl/ServerDescriptorImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/ServerDescriptorImpl.java
@@ -7,9 +7,6 @@ import org.torproject.descriptor.BandwidthHistory;
 import org.torproject.descriptor.DescriptorParseException;
 import org.torproject.descriptor.ServerDescriptor;
 
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.EnumSet;
@@ -19,8 +16,6 @@ import java.util.Set;
 import java.util.SortedMap;
 import java.util.SortedSet;
 
-import javax.xml.bind.DatatypeConverter;
-
 /* Contains a server descriptor. */
 public abstract class ServerDescriptorImpl extends DescriptorImpl
     implements ServerDescriptor {
@@ -44,8 +39,10 @@ public abstract class ServerDescriptorImpl extends DescriptorImpl
       throws DescriptorParseException {
     super(descriptorBytes, failUnrecognizedDescriptorLines, false);
     this.parseDescriptorBytes();
-    this.calculateDigest();
-    this.calculateDigestSha256();
+    this.calculateDigestSha1Hex(Key.ROUTER.keyword + SP,
+        NL + Key.ROUTER_SIGNATURE.keyword + NL);
+    this.calculateDigestSha256Base64(Key.ROUTER.keyword + SP,
+        NL + "-----END SIGNATURE-----" + NL);
     this.checkExactlyOnceKeys(exactlyOnce);
     this.checkAtMostOnceKeys(atMostOnce);
     this.checkFirstKey(Key.ROUTER);
@@ -563,8 +560,8 @@ public abstract class ServerDescriptorImpl extends DescriptorImpl
     if (partsNoOpt.length != 2) {
       throw new DescriptorParseException("Illegal line '" + line + "'.");
     }
-    this.serverDescriptorDigest = ParseHelper.parseTwentyByteHexString(
-        line, partsNoOpt[1]);
+    this.setDigestSha1Hex(ParseHelper.parseTwentyByteHexString(
+        line, partsNoOpt[1]));
   }
 
   private void parseIpv6PolicyLine(String line, String lineNoOpt,
@@ -679,96 +676,19 @@ public abstract class ServerDescriptorImpl extends DescriptorImpl
       throw new DescriptorParseException("Illegal line '" + line + "'.");
     }
     ParseHelper.parseThirtyTwoByteBase64String(line, partsNoOpt[1]);
-    this.serverDescriptorDigestSha256 = partsNoOpt[1];
-  }
-
-  private void calculateDigest() throws DescriptorParseException {
-    if (this.serverDescriptorDigest != null) {
-      /* We already learned the descriptor digest of this bridge
-       * descriptor from a "router-digest" line. */
-      return;
-    }
-    try {
-      String ascii = new String(this.getRawDescriptorBytes(), "US-ASCII");
-      String startToken = Key.ROUTER.keyword + SP;
-      String sigToken = NL + Key.ROUTER_SIGNATURE.keyword + NL;
-      int start = ascii.indexOf(startToken);
-      int sig = ascii.indexOf(sigToken) + sigToken.length();
-      if (start >= 0 && sig >= 0 && sig > start) {
-        byte[] forDigest = new byte[sig - start];
-        System.arraycopy(this.getRawDescriptorBytes(), start,
-            forDigest, 0, sig - start);
-        this.serverDescriptorDigest = DatatypeConverter.printHexBinary(
-            MessageDigest.getInstance("SHA-1").digest(forDigest))
-            .toLowerCase();
-      }
-    } catch (UnsupportedEncodingException e) {
-      /* Handle below. */
-    } catch (NoSuchAlgorithmException e) {
-      /* Handle below. */
-    }
-    if (this.serverDescriptorDigest == null) {
-      throw new DescriptorParseException("Could not calculate server "
-          + "descriptor digest.");
-    }
+    this.setDigestSha256Base64(partsNoOpt[1]);
   }
 
-  private void calculateDigestSha256() throws DescriptorParseException {
-    if (this.serverDescriptorDigestSha256 != null) {
-      /* We already learned the descriptor digest of this bridge
-       * descriptor from a "router-digest-sha256" line. */
-      return;
-    }
-    try {
-      String ascii = new String(this.getRawDescriptorBytes(), "US-ASCII");
-      String startToken = Key.ROUTER.keyword + SP;
-      String sigToken = "\n-----END SIGNATURE-----\n";
-      int start = ascii.indexOf(startToken);
-      int sig = ascii.indexOf(sigToken) + sigToken.length();
-      if (start >= 0 && sig >= 0 && sig > start) {
-        byte[] forDigest = new byte[sig - start];
-        System.arraycopy(this.getRawDescriptorBytes(), start, forDigest,
-            0, sig - start);
-        this.serverDescriptorDigestSha256 =
-            DatatypeConverter.printBase64Binary(
-            MessageDigest.getInstance("SHA-256").digest(forDigest))
-            .replaceAll("=", "");
-      }
-    } catch (UnsupportedEncodingException e) {
-      /* Handle below. */
-    } catch (NoSuchAlgorithmException e) {
-      /* Handle below. */
-    }
-    if (this.serverDescriptorDigestSha256 == null) {
-      throw new DescriptorParseException("Could not calculate server "
-          + "descriptor SHA-256 digest.");
-    }
-  }
-
-  private String serverDescriptorDigest;
-
   @Override
   public String getServerDescriptorDigest() {
     return this.getDigestSha1Hex();
   }
 
   @Override
-  public String getDigestSha1Hex() {
-    return this.serverDescriptorDigest;
-  }
-
-  private String serverDescriptorDigestSha256;
-
-  @Override
   public String getServerDescriptorDigestSha256() {
     return this.getDigestSha256Base64();
   }
 
-  @Override
-  public String getDigestSha256Base64() {
-    return this.serverDescriptorDigestSha256;
-  }
-
   private String nickname;
 
   @Override
diff --git a/src/test/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImplTest.java b/src/test/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImplTest.java
index 3d8c033..d1e38d6 100644
--- a/src/test/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImplTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImplTest.java
@@ -1969,16 +1969,6 @@ public class ExtraInfoDescriptorImplTest {
         "hidserv-dir-onions-seen -3 delta_f=8 epsilon=0.30 bin_size=8 pi=3");
   }
 
-  @Test()
-  public void testRouterSignatureOpt()
-      throws DescriptorParseException {
-    DescriptorBuilder.createWithRouterSignatureLines("opt "
-        + "router-signature\n"
-        + "-----BEGIN SIGNATURE-----\n"
-        + "crypto lines are ignored anyway\n"
-        + "-----END SIGNATURE-----");
-  }
-
   @Test(expected = DescriptorParseException.class)
   public void testRouterSignatureNotLastLine()
       throws DescriptorParseException {





More information about the tor-commits mailing list