Squashed History

This commit is contained in:
Moxie Marlinspike
2013-12-08 23:11:09 -08:00
commit 4ad0dad3d9
103 changed files with 9737 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,50 @@
/**
* Copyright (C) 2013 Open WhisperSystems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whispersystems.textsecuregcm.util;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
public class ByteArrayAdapter {
public static class Serializing extends JsonSerializer<byte[]> {
@Override
public void serialize(byte[] bytes, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
throws IOException, JsonProcessingException
{
jsonGenerator.writeString(Base64.encodeBytesWithoutPadding(bytes));
}
}
public static class Deserializing extends JsonDeserializer<byte[]> {
@Override
public byte[] deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
throws IOException, JsonProcessingException
{
return Base64.decodeWithoutPadding(jsonParser.getValueAsString());
}
}
}

View File

@@ -0,0 +1,180 @@
/**
* Copyright (C) 2013 Open WhisperSystems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whispersystems.textsecuregcm.util;
public class Conversions {
public static byte intsToByteHighAndLow(int highValue, int lowValue) {
return (byte)((highValue << 4 | lowValue) & 0xFF);
}
public static int highBitsToInt(byte value) {
return (value & 0xFF) >> 4;
}
public static int lowBitsToInt(byte value) {
return (value & 0xF);
}
public static int highBitsToMedium(int value) {
return (value >> 12);
}
public static int lowBitsToMedium(int value) {
return (value & 0xFFF);
}
public static byte[] shortToByteArray(int value) {
byte[] bytes = new byte[2];
shortToByteArray(bytes, 0, value);
return bytes;
}
public static int shortToByteArray(byte[] bytes, int offset, int value) {
bytes[offset+1] = (byte)value;
bytes[offset] = (byte)(value >> 8);
return 2;
}
public static int shortToLittleEndianByteArray(byte[] bytes, int offset, int value) {
bytes[offset] = (byte)value;
bytes[offset+1] = (byte)(value >> 8);
return 2;
}
public static byte[] mediumToByteArray(int value) {
byte[] bytes = new byte[3];
mediumToByteArray(bytes, 0, value);
return bytes;
}
public static int mediumToByteArray(byte[] bytes, int offset, int value) {
bytes[offset + 2] = (byte)value;
bytes[offset + 1] = (byte)(value >> 8);
bytes[offset] = (byte)(value >> 16);
return 3;
}
public static byte[] intToByteArray(int value) {
byte[] bytes = new byte[4];
intToByteArray(bytes, 0, value);
return bytes;
}
public static int intToByteArray(byte[] bytes, int offset, int value) {
bytes[offset + 3] = (byte)value;
bytes[offset + 2] = (byte)(value >> 8);
bytes[offset + 1] = (byte)(value >> 16);
bytes[offset] = (byte)(value >> 24);
return 4;
}
public static int intToLittleEndianByteArray(byte[] bytes, int offset, int value) {
bytes[offset] = (byte)value;
bytes[offset+1] = (byte)(value >> 8);
bytes[offset+2] = (byte)(value >> 16);
bytes[offset+3] = (byte)(value >> 24);
return 4;
}
public static byte[] longToByteArray(long l) {
byte[] bytes = new byte[8];
longToByteArray(bytes, 0, l);
return bytes;
}
public static int longToByteArray(byte[] bytes, int offset, long value) {
bytes[offset + 7] = (byte)value;
bytes[offset + 6] = (byte)(value >> 8);
bytes[offset + 5] = (byte)(value >> 16);
bytes[offset + 4] = (byte)(value >> 24);
bytes[offset + 3] = (byte)(value >> 32);
bytes[offset + 2] = (byte)(value >> 40);
bytes[offset + 1] = (byte)(value >> 48);
bytes[offset] = (byte)(value >> 56);
return 8;
}
public static int longTo4ByteArray(byte[] bytes, int offset, long value) {
bytes[offset + 3] = (byte)value;
bytes[offset + 2] = (byte)(value >> 8);
bytes[offset + 1] = (byte)(value >> 16);
bytes[offset + 0] = (byte)(value >> 24);
return 4;
}
public static int byteArrayToShort(byte[] bytes) {
return byteArrayToShort(bytes, 0);
}
public static int byteArrayToShort(byte[] bytes, int offset) {
return
(bytes[offset] & 0xff) << 8 | (bytes[offset + 1] & 0xff);
}
// The SSL patented 3-byte Value.
public static int byteArrayToMedium(byte[] bytes, int offset) {
return
(bytes[offset] & 0xff) << 16 |
(bytes[offset + 1] & 0xff) << 8 |
(bytes[offset + 2] & 0xff);
}
public static int byteArrayToInt(byte[] bytes) {
return byteArrayToInt(bytes, 0);
}
public static int byteArrayToInt(byte[] bytes, int offset) {
return
(bytes[offset] & 0xff) << 24 |
(bytes[offset + 1] & 0xff) << 16 |
(bytes[offset + 2] & 0xff) << 8 |
(bytes[offset + 3] & 0xff);
}
public static int byteArrayToIntLittleEndian(byte[] bytes, int offset) {
return
(bytes[offset + 3] & 0xff) << 24 |
(bytes[offset + 2] & 0xff) << 16 |
(bytes[offset + 1] & 0xff) << 8 |
(bytes[offset] & 0xff);
}
public static long byteArrayToLong(byte[] bytes) {
return byteArrayToLong(bytes, 0);
}
public static long byteArray4ToLong(byte[] bytes, int offset) {
return
((bytes[offset + 0] & 0xffL) << 24) |
((bytes[offset + 1] & 0xffL) << 16) |
((bytes[offset + 2] & 0xffL) << 8) |
((bytes[offset + 3] & 0xffL));
}
public static long byteArrayToLong(byte[] bytes, int offset) {
return
((bytes[offset] & 0xffL) << 56) |
((bytes[offset + 1] & 0xffL) << 48) |
((bytes[offset + 2] & 0xffL) << 40) |
((bytes[offset + 3] & 0xffL) << 32) |
((bytes[offset + 4] & 0xffL) << 24) |
((bytes[offset + 5] & 0xffL) << 16) |
((bytes[offset + 6] & 0xffL) << 8) |
((bytes[offset + 7] & 0xffL));
}
}

View File

@@ -0,0 +1,109 @@
/**
* Copyright (C) 2013 Open WhisperSystems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whispersystems.textsecuregcm.util;
/**
* Utility for generating hex dumps a la hexl-mode in emacs.
*/
public class Hex {
private final static int HEX_DIGITS_START = 10;
private final static int ASCII_TEXT_START = HEX_DIGITS_START + (16*2 + (16/2));
final static String EOL = System.getProperty("line.separator");
private final static char[] HEX_DIGITS = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
public static String toString(byte[] bytes) {
return toString(bytes, 0, bytes.length);
}
public static String toString(byte[] bytes, int offset, int length) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < length; i++) {
appendHexChar(buf, bytes[offset + i]);
buf.append(' ');
}
return buf.toString();
}
public static String dump(byte[] bytes) {
return dump(bytes, 0, bytes.length);
}
public static String dump(byte[] bytes, int offset, int length) {
StringBuffer buf = new StringBuffer();
int lines = ((length - 1) / 16) + 1;
int lineOffset;
int lineLength;
for (int i = 0; i < lines; i++) {
lineOffset = (i * 16) + offset;
lineLength = Math.min(16, (length - (i * 16)));
appendDumpLine(buf, i, bytes, lineOffset, lineLength);
buf.append(EOL);
}
return buf.toString();
}
private static void appendDumpLine(StringBuffer buf, int line,
byte[] bytes, int lineOffset,
int lineLength)
{
buf.append(HEX_DIGITS[(line >> 28) & 0xf]);
buf.append(HEX_DIGITS[(line >> 24) & 0xf]);
buf.append(HEX_DIGITS[(line >> 20) & 0xf]);
buf.append(HEX_DIGITS[(line >> 16) & 0xf]);
buf.append(HEX_DIGITS[(line >> 12) & 0xf]);
buf.append(HEX_DIGITS[(line >> 8) & 0xf]);
buf.append(HEX_DIGITS[(line >> 4) & 0xf]);
buf.append(HEX_DIGITS[(line ) & 0xf]);
buf.append(": ");
for (int i = 0; i < 16; i++) {
int idx = i + lineOffset;
if (i < lineLength) {
int b = bytes[idx];
appendHexChar(buf, b);
} else {
buf.append(" ");
}
if ((i % 2) == 1) {
buf.append(' ');
}
}
for (int i = 0; i < 16 && i < lineLength; i++) {
int idx = i + lineOffset;
int b = bytes[idx];
if (b >= 0x20 && b <= 0x7e) {
buf.append((char)b);
} else {
buf.append('.');
}
}
}
private static void appendHexChar(StringBuffer buf, int b) {
buf.append(HEX_DIGITS[(b >> 4) & 0xf]);
buf.append(HEX_DIGITS[b & 0xf]);
}
}

View File

@@ -0,0 +1,77 @@
/**
* Copyright (C) 2013 Open WhisperSystems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whispersystems.textsecuregcm.util;
import java.util.Iterator;
import java.util.List;
public class IterablePair <T1, T2> implements Iterable<IterablePair.Pair<T1,T2>> {
private final List<T1> first;
private final List<T2> second;
public IterablePair(List<T1> first, List<T2> second) {
this.first = first;
this.second = second;
}
@Override
public Iterator<Pair<T1, T2>> iterator(){
return new ParallelIterator<>( first.iterator(), second.iterator() );
}
public static class Pair<T1, T2> {
private final T1 v1;
private final T2 v2;
Pair(T1 v1, T2 v2) {
this.v1 = v1;
this.v2 = v2;
}
public T1 first(){
return v1;
}
public T2 second(){
return v2;
}
}
public static class ParallelIterator <T1, T2> implements Iterator<Pair<T1, T2>> {
private final Iterator<T1> it1;
private final Iterator<T2> it2;
public ParallelIterator(Iterator<T1> it1, Iterator<T2> it2) {
this.it1 = it1; this.it2 = it2;
}
@Override
public boolean hasNext() { return it1.hasNext() && it2.hasNext(); }
@Override
public Pair<T1, T2> next() {
return new Pair<>(it1.next(), it2.next());
}
@Override
public void remove(){
it1.remove();
it2.remove();
}
}
}

View File

@@ -0,0 +1,52 @@
/**
* Copyright (C) 2013 Open WhisperSystems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whispersystems.textsecuregcm.util;
import com.amazonaws.HttpMethod;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
import org.whispersystems.textsecuregcm.configuration.S3Configuration;
import java.net.URL;
import java.util.Date;
public class UrlSigner {
private static final long DURATION = 60 * 60 * 1000;
private final AWSCredentials credentials;
private final String bucket;
public UrlSigner(S3Configuration config) {
this.credentials = new BasicAWSCredentials(config.getAccessKey(), config.getAccessSecret());
this.bucket = config.getAttachmentsBucket();
}
public URL getPreSignedUrl(long attachmentId, HttpMethod method) {
AmazonS3 client = new AmazonS3Client(credentials);
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucket, String.valueOf(attachmentId), method);
request.setExpiration(new Date(System.currentTimeMillis() + DURATION));
request.setContentType("application/octet-stream");
return client.generatePresignedUrl(request);
}
}

View File

@@ -0,0 +1,86 @@
/**
* Copyright (C) 2013 Open WhisperSystems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whispersystems.textsecuregcm.util;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
public class Util {
public static byte[] getContactToken(String number) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA1");
byte[] result = digest.digest(number.getBytes());
byte[] truncated = Util.truncate(result, 10);
return truncated;
} catch (NoSuchAlgorithmException e) {
throw new AssertionError(e);
}
}
public static String getEncodedContactToken(String number) {
return Base64.encodeBytesWithoutPadding(getContactToken(number));
}
public static boolean isValidNumber(String number) {
return number.matches("^\\+[0-9]{10,}");
}
public static String encodeFormParams(Map<String, String> params) {
try {
StringBuffer buffer = new StringBuffer();
for (String key : params.keySet()) {
buffer.append(String.format("%s=%s",
URLEncoder.encode(key, "UTF-8"),
URLEncoder.encode(params.get(key), "UTF-8")));
buffer.append("&");
}
buffer.deleteCharAt(buffer.length()-1);
return buffer.toString();
} catch (UnsupportedEncodingException e) {
throw new AssertionError(e);
}
}
public static boolean isEmpty(String param) {
return param == null || param.length() == 0;
}
public static byte[] combine(byte[] one, byte[] two, byte[] three, byte[] four) {
byte[] combined = new byte[one.length + two.length + three.length + four.length];
System.arraycopy(one, 0, combined, 0, one.length);
System.arraycopy(two, 0, combined, one.length, two.length);
System.arraycopy(three, 0, combined, one.length + two.length, three.length);
System.arraycopy(four, 0, combined, one.length + two.length + three.length, four.length);
return combined;
}
public static byte[] truncate(byte[] element, int length) {
byte[] result = new byte[length];
System.arraycopy(element, 0, result, 0, result.length);
return result;
}
}

View File

@@ -0,0 +1,57 @@
/**
* Copyright (C) 2013 Open WhisperSystems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whispersystems.textsecuregcm.util;
public class VerificationCode {
private String verificationCode;
private String verificationCodeDisplay;
private String verificationCodeSpeech;
public VerificationCode(int verificationCode) {
this.verificationCode = verificationCode + "";
this.verificationCodeDisplay = this.verificationCode.substring(0, 3) + "-" +
this.verificationCode.substring(3, 6);
this.verificationCodeSpeech = delimit(verificationCode + "");
}
public String getVerificationCode() {
return verificationCode;
}
public String getVerificationCodeDisplay() {
return verificationCodeDisplay;
}
public String getVerificationCodeSpeech() {
return verificationCodeSpeech;
}
private String delimit(String code) {
String delimited = "";
for (int i=0;i<code.length();i++) {
delimited += code.charAt(i);
if (i != code.length() - 1)
delimited += ',';
}
return delimited;
}
}