[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r22089: {projects} Fix digests for bridge descriptors with non-ASCII characters (projects/archives/trunk/bridge-desc-sanitizer)



Author: kloesing
Date: 2010-03-29 17:06:34 +0000 (Mon, 29 Mar 2010)
New Revision: 22089

Modified:
   projects/archives/trunk/bridge-desc-sanitizer/ConvertBridgeDescs.java
Log:
Fix digests for bridge descriptors with non-ASCII characters in them.


Modified: projects/archives/trunk/bridge-desc-sanitizer/ConvertBridgeDescs.java
===================================================================
--- projects/archives/trunk/bridge-desc-sanitizer/ConvertBridgeDescs.java	2010-03-29 16:59:37 UTC (rev 22088)
+++ projects/archives/trunk/bridge-desc-sanitizer/ConvertBridgeDescs.java	2010-03-29 17:06:34 UTC (rev 22089)
@@ -1,9 +1,8 @@
 import java.io.*;
 import java.util.*;
-import com.maxmind.geoip.LookupService;
-import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.commons.codec.binary.Hex;
-import org.apache.commons.codec.binary.Base64;
+import com.maxmind.geoip.*;
+import org.apache.commons.codec.digest.*;
+import org.apache.commons.codec.binary.*;
 
 public class ConvertBridgeDescs {
 
@@ -136,16 +135,30 @@
         System.out.print(".");
         parsed = 0;
       }
-      BufferedReader br = new BufferedReader(new FileReader(file));
+      FileInputStream fis = new FileInputStream(file);
+      BufferedInputStream bis = new BufferedInputStream(fis);
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      int len;
+      byte[] data = new byte[1024];
+      while ((len = bis.read(data, 0, 1024)) >= 0) {
+        baos.write(data, 0, len);
+      }
+      bis.close();
+      byte[] allData = baos.toByteArray();
+      int startDescriptorIndex = -1, endDescriptorIndex = -1;
+      String asciiString = new String(allData, "US-ASCII");
+      BufferedReader br = new BufferedReader(new StringReader(
+          asciiString));
       String line = null;
-      StringBuilder original = null, scrubbed = null;
+      StringBuilder scrubbed = null;
       boolean skipSignature = false;
       boolean skipDescriptor = false;
       while ((line = br.readLine()) != null) {
         if (skipSignature && !line.equals("-----END SIGNATURE-----")) {
           continue;
         } else if (line.startsWith("extra-info ")) {
-          original = new StringBuilder(line + "\n");
+          endDescriptorIndex = startDescriptorIndex =
+              asciiString.indexOf(line, startDescriptorIndex + 1);
           scrubbed = new StringBuilder(DigestUtils.shaHex(Hex.decodeHex(
               line.split(" ")[2].toCharArray())).toUpperCase() + "\n");
         } else if (line.startsWith("published ")
@@ -155,15 +168,19 @@
             || line.startsWith("geoip-client-origins ")
             || line.startsWith("bridge-stats-end ") 
             || line.startsWith("bridge-ips ")) {
-          original.append(line + "\n");
           scrubbed.append(line + "\n");
         } else if (line.startsWith("router-signature")) {
           if (skipDescriptor) {
             System.out.println("Skipping!");
             skipDescriptor = false;
           } else {
-            String originalDesc = original.toString() + line + "\n";
-            String originalHash = DigestUtils.shaHex(originalDesc);
+            endDescriptorIndex = asciiString.indexOf(line,
+                endDescriptorIndex + 1) + line.length() + 1;
+            byte[] forDigest = new byte[endDescriptorIndex -
+                startDescriptorIndex];
+            System.arraycopy(allData, startDescriptorIndex, forDigest, 0,
+                endDescriptorIndex - startDescriptorIndex);
+            String originalHash = DigestUtils.shaHex(forDigest);
             String countryCode = "ZZ";
             if (bridgeCountries.containsKey(originalHash.toUpperCase())) {
               countryCode = bridgeCountries.get(originalHash.toUpperCase());
@@ -175,8 +192,9 @@
                 !extrainfoMapping.get(originalHash).equals(scrubbedHash)) {
               System.out.println("We already have an extra-info mapping "
                   + "from " + originalHash + " to "
-                  + extrainfoMapping.get(originalHash) + ", but we now want "
-                  + "to add a mapping to " + scrubbedHash + ". Exiting");
+                  + extrainfoMapping.get(originalHash) + ", but we now "
+                  + "want to add a mapping to " + scrubbedHash
+                  + ". Exiting");
               System.exit(1);
             }
             extrainfoMapping.put(originalHash, scrubbedHash);
@@ -196,7 +214,7 @@
           skipSignature = false;
         } else if (line.startsWith("dirreq-") || line.startsWith("cell-")
             || line.startsWith("exit-")) {
-          original.append(line + "\n");
+          continue;
         } else {
           System.out.println("Unrecognized line '" + line + "'. Skipping");
           skipDescriptor = true;
@@ -222,16 +240,29 @@
         System.out.print(".");
         parsed = 0;
       }
-      BufferedReader br = new BufferedReader(new FileReader(file));
+      FileInputStream fis = new FileInputStream(file);
+      BufferedInputStream bis = new BufferedInputStream(fis);
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      int len;
+      byte[] data = new byte[1024];
+      while ((len = bis.read(data, 0, 1024)) >= 0) {
+        baos.write(data, 0, len);
+      }
+      bis.close();
+      byte[] allData = baos.toByteArray();
+      int startDescriptorIndex = -1, endDescriptorIndex = -1;
+      String asciiString = new String(allData, "US-ASCII");
+      BufferedReader br = new BufferedReader(new StringReader(
+          asciiString));
       String line = null, country = null;
-      StringBuilder original = null, scrubbed = null;
+      StringBuilder scrubbed = null;
       boolean skipCrypto = false, contactWritten = false;
       while ((line = br.readLine()) != null) {
         if (skipCrypto && !line.startsWith("-----END ")) {
-          original.append(line + "\n");
           continue;
         } else if (line.startsWith("router ")) {
-          original = new StringBuilder(line + "\n");
+          endDescriptorIndex = startDescriptorIndex =
+              asciiString.indexOf(line, startDescriptorIndex + 1);
           country = cl.getCountry(line.split(" ")[2]).getCode().
               toLowerCase();
           if (unresolved.contains(country)) {
@@ -244,22 +275,26 @@
           contactWritten = false;
           haveExtraInfo = null;
         } else if (line.startsWith("opt fingerprint ")) {
-          original.append(line + "\n");
           scrubbed.append("opt fingerprint");
           String fingerprint = DigestUtils.shaHex(Hex.decodeHex(
               line.substring(16).replaceAll(" ", "").toCharArray())).
               toUpperCase();
           for (int i = 0; i < fingerprint.length() / 4; i++)
-            scrubbed.append(" " + fingerprint.substring(4 * i, 4 * (i + 1)));
+            scrubbed.append(" " + fingerprint.substring(4 * i,
+                4 * (i + 1)));
           scrubbed.append("\n");
         } else if (line.startsWith("contact ")) {
-          original.append(line + "\n");
           scrubbed.append("contact somebody at example dot " + country
               + "\n");
           contactWritten = true;
         } else if (line.startsWith("router-signature")) {
-          String originalDesc = original.toString() + line + "\n";
-          String originalHash = DigestUtils.shaHex(originalDesc);
+          endDescriptorIndex = asciiString.indexOf(line,
+              endDescriptorIndex + 1) + line.length() + 1;
+          byte[] forDigest = new byte[endDescriptorIndex -
+              startDescriptorIndex];
+          System.arraycopy(allData, startDescriptorIndex, forDigest, 0,
+              endDescriptorIndex - startDescriptorIndex);
+          String originalHash = DigestUtils.shaHex(forDigest);
           String scrubbedDesc = scrubbed.toString();
           String scrubbedHash = DigestUtils.shaHex(scrubbedDesc);
           if (descriptorMapping.containsKey(originalHash) &&
@@ -294,7 +329,6 @@
             haveExtraInfo = extrainfoMapping.get(originalExtraInfo).
                 toUpperCase();
           }
-          original.append(line + "\n");
           scrubbed.append("opt extra-info-digest " + haveExtraInfo
               + "\n");
         } else if (line.startsWith("reject ")
@@ -304,7 +338,6 @@
                 + "\n");
             contactWritten = true;
           }
-          original.append(line + "\n");
           scrubbed.append(line + "\n");
         } else if (line.startsWith("platform ")
             || line.startsWith("opt protocols ")
@@ -315,7 +348,6 @@
             || line.equals("opt hidden-service-dir")
             || line.equals("opt caches-extra-info")
             || line.equals("opt allow-single-hop-exits")) {
-          original.append(line + "\n");
           scrubbed.append(line + "\n");
         } else if (line.startsWith("family ")) {
           StringBuilder familyLine = new StringBuilder("family");
@@ -327,17 +359,14 @@
               familyLine.append(" Unnamed");
             }
           }
-          original.append(line + "\n");
           scrubbed.append(familyLine.toString() + "\n");
         } else if (line.startsWith("@purpose ")) {
           continue;
         } else if (line.startsWith("-----BEGIN ")
             || line.equals("onion-key") || line.equals("signing-key")) {
           skipCrypto = true;
-          original.append(line + "\n");
         } else if (line.startsWith("-----END ")) {
           skipCrypto = false;
-          original.append(line + "\n");
         } else {
           System.out.println("Unrecognized line '" + line + "'. Exiting");
           System.exit(1);
@@ -369,8 +398,6 @@
         if (line.startsWith("r ")) {
           String[] parts = line.split(" ");
           String bridgeIdentity = parts[2] + "==";
-          String hexBridgeIdentity = Hex.encodeHexString(
-              Base64.decodeBase64(bridgeIdentity));
           String hashedBridgeIdentity = Base64.encodeBase64String(
               DigestUtils.sha(Base64.decodeBase64(bridgeIdentity))).
               substring(0, 27);