mobile/android/tests/background/junit3/src/healthreport/TestEnvironmentV1HashAppender.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /* Any copyright is dedicated to the Public Domain.
     2    http://creativecommons.org/publicdomain/zero/1.0/ */
     4 package org.mozilla.gecko.background.healthreport;
     6 import java.io.UnsupportedEncodingException;
     7 import java.security.MessageDigest;
     8 import java.security.NoSuchAlgorithmException;
     9 import java.util.Arrays;
    10 import java.util.LinkedList;
    12 import org.mozilla.apache.commons.codec.binary.Base64;
    13 import org.mozilla.gecko.background.healthreport.EnvironmentV1.EnvironmentAppender;
    14 import org.mozilla.gecko.background.healthreport.EnvironmentV1.HashAppender;
    15 import org.mozilla.gecko.background.helpers.FakeProfileTestCase;
    16 import org.mozilla.gecko.sync.Utils;
    18 /**
    19  * Tests the HashAppender functionality. Note that these tests must be run on an Android
    20  * device because the SHA-1 native library needs to be loaded.
    21  */
    22 public class TestEnvironmentV1HashAppender extends FakeProfileTestCase {
    23   // input and expected values via: http://oauth.googlecode.com/svn/code/c/liboauth/src/sha1.c
    24   private final static String[] INPUTS = new String[] {
    25     "abc",
    26     "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
    27     "" // To be filled in below.
    28   };
    29   static {
    30     final String baseStr = "01234567";
    31     final int repetitions = 80;
    32     final StringBuilder builder = new StringBuilder(baseStr.length() * repetitions);
    33     for (int i = 0; i < 80; ++i) {
    34       builder.append(baseStr);
    35     }
    36     INPUTS[2] = builder.toString();
    37   }
    39   private final static String[] EXPECTEDS = new String[] {
    40     "a9993e364706816aba3e25717850c26c9cd0d89d",
    41     "84983e441c3bd26ebaae4aa1f95129e5e54670f1",
    42     "dea356a2cddd90c7a7ecedc5ebb563934f460452"
    43   };
    44   static {
    45     for (int i = 0; i < EXPECTEDS.length; ++i) {
    46       EXPECTEDS[i] = new Base64(-1, null, false).encodeAsString(Utils.hex2Byte(EXPECTEDS[i]));
    47     }
    48   }
    50   public void testSHA1Hashing() throws Exception {
    51     for (int i = 0; i < INPUTS.length; ++i) {
    52       final String input = INPUTS[i];
    53       final String expected = EXPECTEDS[i];
    55       final HashAppender appender = new HashAppender();
    56       addStringToAppenderInParts(appender, input);
    57       final String result = appender.toString();
    59       assertEquals(expected, result);
    60     }
    61   }
    63   /**
    64    * Tests to ensure output is the same as the former MessageDigest implementation (bug 959652).
    65    */
    66   public void testAgainstMessageDigestImpl() throws Exception {
    67     // List.add doesn't allow add(null) so we make a LinkedList here.
    68     final LinkedList<String> inputs = new LinkedList<String>(Arrays.asList(INPUTS));
    69     inputs.add(null);
    71     for (final String input : inputs) {
    72       final HashAppender hAppender = new HashAppender();
    73       final MessageDigestHashAppender mdAppender = new MessageDigestHashAppender();
    75       hAppender.append(input);
    76       mdAppender.append(input);
    78       final String hResult = hAppender.toString();
    79       final String mdResult = mdAppender.toString();
    80       assertEquals(mdResult, hResult);
    81     }
    82   }
    84   public void testIntegersAgainstMessageDigestImpl() throws Exception {
    85     final int[] INPUTS = {Integer.MIN_VALUE, -1337, -42, 0, 42, 1337, Integer.MAX_VALUE};
    86     for (final int input : INPUTS) {
    87       final HashAppender hAppender = new HashAppender();
    88       final MessageDigestHashAppender mdAppender = new MessageDigestHashAppender();
    90       hAppender.append(input);
    91       mdAppender.append(input);
    93       final String hResult = hAppender.toString();
    94       final String mdResult = mdAppender.toString();
    95       assertEquals(mdResult, hResult);
    96     }
    97   }
    99   private void addStringToAppenderInParts(final EnvironmentAppender appender, final String input) {
   100     int substrInd = 0;
   101     int substrLength = 1;
   102     while (substrInd < input.length()) {
   103       final int endInd = Math.min(substrInd + substrLength, input.length());
   105       appender.append(input.substring(substrInd, endInd));
   107       substrInd = endInd;
   108       ++substrLength;
   109     }
   110   }
   112   // --- COPY-PASTA'D CODE, FOR TESTING PURPOSES. ---
   113   public static class MessageDigestHashAppender extends EnvironmentAppender {
   114     final MessageDigest hasher;
   116     public MessageDigestHashAppender() throws NoSuchAlgorithmException {
   117       // Note to the security-minded reader: we deliberately use SHA-1 here, not
   118       // a stronger hash. These identifiers don't strictly need a cryptographic
   119       // hash function, because there is negligible value in attacking the hash.
   120       // We use SHA-1 because it's *shorter* -- the exact same reason that Git
   121       // chose SHA-1.
   122       hasher = MessageDigest.getInstance("SHA-1");
   123     }
   125     @Override
   126     public void append(String s) {
   127       try {
   128         hasher.update(((s == null) ? "null" : s).getBytes("UTF-8"));
   129       } catch (UnsupportedEncodingException e) {
   130         // This can never occur. Thanks, Java.
   131       }
   132     }
   134     @Override
   135     public void append(int profileCreation) {
   136       append(Integer.toString(profileCreation, 10));
   137     }
   139     @Override
   140     public String toString() {
   141       // We *could* use ASCII85… but the savings would be negated by the
   142       // inclusion of JSON-unsafe characters like double-quote.
   143       return new Base64(-1, null, false).encodeAsString(hasher.digest());
   144     }
   145   }
   146 }

mercurial