fold autocrypt header lines differently

This commit is contained in:
Vincent Breitmoser 2017-09-01 19:03:32 +02:00
parent 79352d8358
commit d705f2c278
2 changed files with 65 additions and 25 deletions

View file

@ -41,29 +41,52 @@ class AutocryptHeader {
}
String toRawHeaderString() {
// TODO we don't properly fold lines here. if we want to support parameters, we need to do that somehow
if (!parameters.isEmpty()) {
throw new UnsupportedOperationException("arbitrary parameters not supported");
}
String autocryptHeaderString = AutocryptHeader.AUTOCRYPT_HEADER + ": ";
autocryptHeaderString += AutocryptHeader.AUTOCRYPT_PARAM_ADDR + "=" + addr + ";";
StringBuilder builder = new StringBuilder();
builder.append(AutocryptHeader.AUTOCRYPT_HEADER).append(": ");
builder.append(AutocryptHeader.AUTOCRYPT_PARAM_ADDR).append('=').append(addr).append("; ");
if (isPreferEncryptMutual) {
autocryptHeaderString += AutocryptHeader.AUTOCRYPT_PARAM_PREFER_ENCRYPT + "=" +
AutocryptHeader.AUTOCRYPT_PREFER_ENCRYPT_MUTUAL + ";";
builder.append(AutocryptHeader.AUTOCRYPT_PARAM_PREFER_ENCRYPT)
.append('=').append(AutocryptHeader.AUTOCRYPT_PREFER_ENCRYPT_MUTUAL).append("; ");
}
autocryptHeaderString += AutocryptHeader.AUTOCRYPT_PARAM_KEY_DATA + "=" + ByteString.of(keyData).base64();
builder.append(AutocryptHeader.AUTOCRYPT_PARAM_KEY_DATA).append("=");
StringBuilder headerLines = new StringBuilder();
int autocryptHeaderLength = autocryptHeaderString.length();
for (int i = 0; i < autocryptHeaderLength; i += HEADER_LINE_LENGTH) {
if (i + HEADER_LINE_LENGTH <= autocryptHeaderLength) {
headerLines.append(autocryptHeaderString, i, i + HEADER_LINE_LENGTH).append("\r\n ");
appendBase64KeyData(builder);
return builder.toString();
}
private void appendBase64KeyData(StringBuilder builder) {
String base64KeyData = ByteString.of(keyData).base64();
int base64Length = base64KeyData.length();
int lineLengthBeforeKeyData = builder.length();
int dataLengthInFirstLine = HEADER_LINE_LENGTH -lineLengthBeforeKeyData;
boolean keyDataFitsInFirstLine = dataLengthInFirstLine > 0 && base64Length < dataLengthInFirstLine;
if (keyDataFitsInFirstLine) {
builder.append(base64KeyData, 0, base64Length);
return;
}
if (dataLengthInFirstLine > 0) {
builder.append(base64KeyData, 0, dataLengthInFirstLine).append("\r\n ");
} else {
builder.append("\r\n ");
dataLengthInFirstLine = 0;
}
for (int i = dataLengthInFirstLine; i < base64Length; i += HEADER_LINE_LENGTH) {
if (i + HEADER_LINE_LENGTH <= base64Length) {
builder.append(base64KeyData, i, i + HEADER_LINE_LENGTH).append("\r\n ");
} else {
headerLines.append(autocryptHeaderString, i, autocryptHeaderLength);
builder.append(base64KeyData, i, base64Length);
}
}
return headerLines.toString();
}
@Override

View file

@ -13,27 +13,44 @@ import static org.junit.Assert.*;
public class AutocryptHeaderTest {
static final HashMap<String, String> PARAMETERS = new HashMap<>();
static final String ADDR = "addr";
static final String ADDR_LONG = "veryveryverylongaddressthatspansmorethanalinelengthintheheader";
static final byte[] KEY_DATA = ("theseare120charactersxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx").getBytes();
static final byte[] KEY_DATA_SHORT = ("theseare15chars").getBytes();
static final boolean IS_PREFER_ENCRYPT_MUTUAL = true;
private AutocryptHeader autocryptHeader;
@Before
public void setUp() throws Exception {
autocryptHeader = new AutocryptHeader(PARAMETERS, ADDR, KEY_DATA, IS_PREFER_ENCRYPT_MUTUAL);
}
@Test
public void toRawHeaderString_returnsExpected() throws Exception {
AutocryptHeader autocryptHeader = new AutocryptHeader(PARAMETERS, ADDR, KEY_DATA, IS_PREFER_ENCRYPT_MUTUAL);
String autocryptHeaderString = autocryptHeader.toRawHeaderString();
String expected = "Autocrypt: addr=addr;prefer-encrypt=mutual;keydata=dGhlc2VhcmUxMjBjaGFyYWN0Z\r\n" +
" XJzeHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4e\r\n" +
" Hh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4";
String expected = "Autocrypt: addr=addr; prefer-encrypt=mutual; keydata=dGhlc2VhcmUxMjBjaGFyYWN\r\n" +
" 0ZXJzeHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh\r\n" +
" 4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4";
assertEquals(expected, autocryptHeaderString);
}
@Test
public void toRawHeaderString_withLongAddress_returnsExpected() throws Exception {
AutocryptHeader autocryptHeader = new AutocryptHeader(PARAMETERS,
ADDR_LONG, KEY_DATA, IS_PREFER_ENCRYPT_MUTUAL);
String autocryptHeaderString = autocryptHeader.toRawHeaderString();
String expected = "Autocrypt: addr=veryveryverylongaddressthatspansmorethanalinelengthintheheader; prefer-encrypt=mutual; keydata=\r\n" +
" dGhlc2VhcmUxMjBjaGFyYWN0ZXJzeHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4\r\n" +
" eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4\r\n" +
" eHh4eHh4";
assertEquals(expected, autocryptHeaderString);
}
@Test
public void toRawHeaderString_withShortData_returnsExpected() throws Exception {
AutocryptHeader autocryptHeader = new AutocryptHeader(PARAMETERS,
ADDR, KEY_DATA_SHORT, IS_PREFER_ENCRYPT_MUTUAL);
String autocryptHeaderString = autocryptHeader.toRawHeaderString();
String expected = "Autocrypt: addr=addr; prefer-encrypt=mutual; keydata=dGhlc2VhcmUxNWNoYXJz";
assertEquals(expected, autocryptHeaderString);
}
}