Skip to content

Commit

Permalink
Parse only from ByteBuffer, not from Readers
Browse files Browse the repository at this point in the history
  • Loading branch information
brl committed Sep 26, 2013
1 parent cfaf826 commit 240a81c
Show file tree
Hide file tree
Showing 13 changed files with 53 additions and 163 deletions.
10 changes: 5 additions & 5 deletions src/com/subgraph/orchid/circuits/hs/HSAuthentication.java
Expand Up @@ -18,7 +18,7 @@ public HSAuthentication(HSDescriptorCookie cookie) {
this.cookie = cookie;
}

public String decryptIntroductionPoints(byte[] content) throws HSAuthenticationException {
public byte[] decryptIntroductionPoints(byte[] content) throws HSAuthenticationException {
final ByteBuffer buffer = ByteBuffer.wrap(content);
final int firstByte = buffer.get() & 0xFF;
if(firstByte == 1) {
Expand Down Expand Up @@ -47,7 +47,7 @@ private BasicAuthEntry createEntry(ByteBuffer bb) {
return new BasicAuthEntry(id, skey);
}

private String decryptIntroductionPointsWithBasicAuth(ByteBuffer buffer) throws HSAuthenticationException {
private byte[] decryptIntroductionPointsWithBasicAuth(ByteBuffer buffer) throws HSAuthenticationException {
if(cookie == null || cookie.getType() != CookieType.COOKIE_BASIC) {
throw new TorParsingException("Introduction points encrypted with 'basic' authentication and no cookie available to decrypt");
}
Expand Down Expand Up @@ -102,15 +102,15 @@ private byte[] decryptAuthEntry(BasicAuthEntry entry) throws HSAuthenticationExc
return entry.skey;
}

private String decryptRemaining(ByteBuffer buffer, byte[] key, byte[] iv) {
private byte[] decryptRemaining(ByteBuffer buffer, byte[] key, byte[] iv) {
TorStreamCipher streamCipher = TorStreamCipher.createFromKeyBytesWithIV(key, iv);
final byte[] remaining = new byte[buffer.remaining()];
buffer.get(remaining);
streamCipher.encrypt(remaining);
return new String(remaining);
return remaining;
}

private String decryptIntroductionPointsWithStealthAuth(ByteBuffer buffer) {
private byte[] decryptIntroductionPointsWithStealthAuth(ByteBuffer buffer) {
if(cookie == null || cookie.getType() != CookieType.COOKIE_STEALTH) {
throw new TorParsingException("Introduction points encrypted with 'stealth' authentication and no cookie available to descrypt");
}
Expand Down
@@ -1,7 +1,7 @@
package com.subgraph.orchid.circuits.hs;

import java.io.IOException;
import java.io.Reader;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.concurrent.TimeoutException;
import java.util.logging.Logger;
Expand Down Expand Up @@ -54,7 +54,7 @@ private HSDescriptor downloadDescriptorFrom(HSDescriptorDirectory dd) {
http.sendGetRequest("/tor/rendezvous2/"+ dd.getDescriptorId().toBase32());
http.readResponse();
if(http.getStatusCode() == 200) {
return readDocument(dd, http.getBodyReader());
return readDocument(dd, http.getMessageBody());
} else {
logger.fine("HS descriptor download for "+ hiddenService.getOnionAddressForLogging() + " failed with status "+ http.getStatusCode());
}
Expand Down Expand Up @@ -98,8 +98,8 @@ private Stream openHSDirectoryStream(Router directory) throws TimeoutException,
}
}

private HSDescriptor readDocument(HSDescriptorDirectory dd, Reader reader) {
DocumentFieldParserImpl fieldParser = new DocumentFieldParserImpl(reader);
private HSDescriptor readDocument(HSDescriptorDirectory dd, ByteBuffer body) {
DocumentFieldParserImpl fieldParser = new DocumentFieldParserImpl(body);
HSDescriptorParser parser = new HSDescriptorParser(hiddenService, fieldParser, hiddenService.getAuthenticationCookie());
DescriptorParseResult result = new DescriptorParseResult(dd);
parser.parse(result);
Expand Down
16 changes: 7 additions & 9 deletions src/com/subgraph/orchid/circuits/hs/HSDescriptorParser.java
@@ -1,7 +1,6 @@
package com.subgraph.orchid.circuits.hs;

import java.io.Reader;
import java.io.StringReader;
import java.nio.ByteBuffer;
import java.util.logging.Logger;

import com.subgraph.orchid.TorParsingException;
Expand Down Expand Up @@ -115,8 +114,8 @@ private void processKeyword(HSDescriptorKeyword keyword) {

private void processIntroductionPoints() {
final DocumentObject ob = fieldParser.parseObject();
final Reader reader = createIntroductionPointReader(ob);
final IntroductionPointParser parser = new IntroductionPointParser(new DocumentFieldParserImpl(reader));
final ByteBuffer buffer = createIntroductionPointBuffer(ob);
final IntroductionPointParser parser = new IntroductionPointParser(new DocumentFieldParserImpl(buffer));
parser.parse(new DocumentParsingResultHandler<IntroductionPoint>() {

public void documentParsed(IntroductionPoint document) {
Expand All @@ -134,19 +133,18 @@ public void parsingError(String message) {
});
}

private Reader createIntroductionPointReader(DocumentObject ob) {
private ByteBuffer createIntroductionPointBuffer(DocumentObject ob) {
final byte[] content = Base64.decode(ob.getContent(false));
final String decoded;
if(content[0] == 'i') {
decoded = new String(content);
return ByteBuffer.wrap(content);
} else {
try {
decoded = authentication.decryptIntroductionPoints(content);
byte[] decrypted = authentication.decryptIntroductionPoints(content);
return ByteBuffer.wrap(decrypted);
} catch (HSAuthenticationException e) {
throw new TorParsingException("Failed to decrypt introduction points: "+ e.getMessage());
}
}
return new StringReader(decoded);
}

private void processSignature() {
Expand Down
52 changes: 6 additions & 46 deletions src/com/subgraph/orchid/directory/DocumentFieldParserImpl.java
@@ -1,10 +1,5 @@
package com.subgraph.orchid.directory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.text.ParseException;
Expand Down Expand Up @@ -36,7 +31,6 @@ public class DocumentFieldParserImpl implements DocumentFieldParser {
private final static String TAG_DELIMITER = "-----";
private final static String DEFAULT_DELIMITER = " ";
private final ByteBuffer inputBuffer;
private final BufferedReader reader;
private final SimpleDateFormat dateFormat;
private String delimiter = DEFAULT_DELIMITER;
private String currentKeyword;
Expand All @@ -53,33 +47,11 @@ public class DocumentFieldParserImpl implements DocumentFieldParser {
private DocumentParsingHandler callbackHandler;

public DocumentFieldParserImpl(ByteBuffer buffer) {
buffer.rewind();
this.inputBuffer = buffer;
this.reader = null;
rawDocumentBuffer = new StringBuilder();
dateFormat = createDateFormat();
}

public DocumentFieldParserImpl(InputStream input) {
try {
reader = new BufferedReader(new InputStreamReader(input, "ISO-8859-1"));
} catch (UnsupportedEncodingException e) {
throw new TorException(e);
}
rawDocumentBuffer = new StringBuilder();
dateFormat = createDateFormat();
inputBuffer = null;
}

public DocumentFieldParserImpl(Reader reader) {
if(reader instanceof BufferedReader) {
this.reader = (BufferedReader) reader;
} else {
this.reader = new BufferedReader(reader);
}
rawDocumentBuffer = new StringBuilder();
dateFormat = createDateFormat();
inputBuffer = null;
}

private static SimpleDateFormat createDateFormat() {
final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Expand Down Expand Up @@ -383,24 +355,12 @@ public boolean verifySignedEntity(TorPublicKey publicKey, TorSignature signature
}

private String readLine() {
try {
final String line = nextLine();
if(line != null) {
updateCurrentSignature(line);
updateRawDocument(line);
}
return line;
} catch (IOException e) {
throw new TorParsingException("I/O error parsing document: " + e.getMessage(), e);
}
}

private String nextLine() throws IOException {
if(inputBuffer != null) {
return nextLineFromInputBuffer();
} else {
return reader.readLine();
final String line = nextLineFromInputBuffer();
if(line != null) {
updateCurrentSignature(line);
updateRawDocument(line);
}
return line;
}

private String nextLineFromInputBuffer() {
Expand Down
43 changes: 0 additions & 43 deletions src/com/subgraph/orchid/directory/DocumentParserFactoryImpl.java
@@ -1,7 +1,5 @@
package com.subgraph.orchid.directory;

import java.io.InputStream;
import java.io.Reader;
import java.nio.ByteBuffer;

import com.subgraph.orchid.ConsensusDocument;
Expand All @@ -22,58 +20,17 @@ public DocumentParser<KeyCertificate> createKeyCertificateParser(ByteBuffer buff
return new KeyCertificateParser(new DocumentFieldParserImpl(buffer));
}

public DocumentParser<KeyCertificate> createKeyCertificateParser(InputStream input) {
return new KeyCertificateParser(createDocumentFieldParser(input));
}

public DocumentParser<KeyCertificate> createKeyCertificateParser(Reader reader) {
return new KeyCertificateParser(createDocumentFieldParser(reader));
}

public DocumentParser<RouterDescriptor> createRouterDescriptorParser(ByteBuffer buffer, boolean verifySignatures) {
return new RouterDescriptorParser(new DocumentFieldParserImpl(buffer), verifySignatures);
}

public DocumentParser<RouterDescriptor> createRouterDescriptorParser(InputStream input, boolean verifySignatures) {
return new RouterDescriptorParser(createDocumentFieldParser(input), verifySignatures);
}

public DocumentParser<RouterDescriptor> createRouterDescriptorParser(Reader reader, boolean verifySignatures) {
return new RouterDescriptorParser(createDocumentFieldParser(reader), verifySignatures);
}

public DocumentParser<RouterMicrodescriptor> createRouterMicrodescriptorParser(ByteBuffer buffer) {
buffer.rewind();
DocumentFieldParser dfp = new DocumentFieldParserImpl(buffer);
return new RouterMicrodescriptorParser(dfp);
}

public DocumentParser<RouterMicrodescriptor> createRouterMicrodescriptorParser(InputStream input) {
return new RouterMicrodescriptorParser(createDocumentFieldParser(input));
}

public DocumentParser<RouterMicrodescriptor> createRouterMicrodescriptorParser(Reader reader) {
return new RouterMicrodescriptorParser(createDocumentFieldParser(reader));
}

public DocumentParser<ConsensusDocument> createConsensusDocumentParser(ByteBuffer buffer) {
return new ConsensusDocumentParser(new DocumentFieldParserImpl(buffer));
}

public DocumentParser<ConsensusDocument> createConsensusDocumentParser(InputStream input) {
return new ConsensusDocumentParser(createDocumentFieldParser(input));
}

public DocumentParser<ConsensusDocument> createConsensusDocumentParser(Reader reader) {
return new ConsensusDocumentParser(createDocumentFieldParser(reader));
}

public DocumentFieldParser createDocumentFieldParser(InputStream input) {
return new DocumentFieldParserImpl(input);
}

public DocumentFieldParser createDocumentFieldParser(Reader reader) {
return new DocumentFieldParserImpl(reader);
}

}
7 changes: 4 additions & 3 deletions src/com/subgraph/orchid/directory/TrustedAuthorities.java
@@ -1,10 +1,11 @@
package com.subgraph.orchid.directory;

import java.io.StringReader;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

import com.subgraph.orchid.DirectoryServer;
import com.subgraph.orchid.Tor;
import com.subgraph.orchid.data.HexDigest;
import com.subgraph.orchid.data.IPv4Address;
import com.subgraph.orchid.directory.parsing.DocumentFieldParser;
Expand Down Expand Up @@ -59,8 +60,8 @@ void initialize() {
builder.append(entry);
builder.append('\n');
}
final StringReader reader = new StringReader(builder.toString());
final DocumentFieldParser parser = new DocumentFieldParserImpl(reader);
final ByteBuffer buffer = ByteBuffer.wrap(builder.toString().getBytes(Tor.getDefaultCharset()));
final DocumentFieldParser parser = new DocumentFieldParserImpl(buffer);

parser.setHandler(new DocumentParsingHandler() {
public void endOfDocument() {}
Expand Down
@@ -1,10 +1,9 @@
package com.subgraph.orchid.directory.downloader;

import java.io.IOException;
import java.io.Reader;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.concurrent.TimeoutException;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.subgraph.orchid.Directory;
Expand Down Expand Up @@ -59,41 +58,30 @@ public void run() {
private void makeRequest() throws InterruptedException, TimeoutException, OpenFailedException {
final HttpConnection http = openDirectoryConnection();
final String request = getRequestPath();
Reader response = null;
ByteBuffer response = null;
try {
logger.fine("request to "+ http.getHost() + " : "+ request);
response = requestDocument(http, request);
processResponse(response, http);
} catch(IOException e) {
logger.warning("IO error making request "+ request +" to host ["+ http.getHost() + "]: "+ e);
} finally {
closeReader(response);
http.close();
}
}

private void closeReader(Reader r) {
try {
if(r != null) {
r.close();
}
} catch (IOException e) {
logger.log(Level.WARNING, "Error closing directory reader "+ e.getMessage(), e);
}
}

abstract protected String getRequestPath();
abstract protected void processResponse(Reader response, HttpConnection http);
abstract protected void processResponse(ByteBuffer response, HttpConnection http);
abstract protected void finishRequest(DirectoryDownloader downloader);

protected Reader requestDocument(HttpConnection connection, String request) throws IOException {
protected ByteBuffer requestDocument(HttpConnection connection, String request) throws IOException {
if(USE_COMPRESSION) {
request += ".z";
}
connection.sendGetRequest(request);
connection.readResponse();
if(connection.getStatusCode() == 200) {
return connection.getBodyReader();
return connection.getMessageBody();
}
throw new TorException("Request "+ request +" to directory "+
connection.getHost() +" returned error code: "+
Expand Down
@@ -1,6 +1,6 @@
package com.subgraph.orchid.directory.downloader;

import java.io.Reader;
import java.nio.ByteBuffer;
import java.util.Set;

import com.subgraph.orchid.CircuitManager;
Expand Down Expand Up @@ -37,7 +37,7 @@ private String getRequiredCertificatesRequestString() {
}

@Override
protected void processResponse(Reader response, final HttpConnection http) {
protected void processResponse(ByteBuffer response, final HttpConnection http) {
final DocumentParser<KeyCertificate> parser = getParserFactory().createKeyCertificateParser(response);
final boolean success = parser.parse(new DocumentParsingResultHandler<KeyCertificate>() {

Expand Down
@@ -1,6 +1,6 @@
package com.subgraph.orchid.directory.downloader;

import java.io.Reader;
import java.nio.ByteBuffer;

import com.subgraph.orchid.CircuitManager;
import com.subgraph.orchid.ConsensusDocument;
Expand Down Expand Up @@ -28,7 +28,7 @@ protected String getRequestPath() {
}

@Override
protected void processResponse(Reader response, final HttpConnection http) {
protected void processResponse(ByteBuffer response, final HttpConnection http) {
final DocumentParser<ConsensusDocument> parser = getParserFactory().createConsensusDocumentParser(response);
final boolean success = parser.parse(new DocumentParsingResultHandler<ConsensusDocument>() {

Expand Down

0 comments on commit 240a81c

Please sign in to comment.