package com.subgraph.orchid.directory.consensus;
import com.subgraph.orchid.crypto.TorMessageDigest;
import com.subgraph.orchid.crypto.TorSignature;
import com.subgraph.orchid.data.HexDigest;
import com.subgraph.orchid.directory.consensus.ConsensusDocumentParser.DocumentSection;
import com.subgraph.orchid.directory.parsing.DocumentFieldParser;
import com.subgraph.orchid.directory.parsing.NameIntegerParameter;
public class FooterSectionParser extends ConsensusDocumentSectionParser {
private boolean seenFirstSignature = false;
FooterSectionParser(DocumentFieldParser parser, ConsensusDocumentImpl document) {
super(parser, document);
}
@Override
String getNextStateKeyword() {
return null;
}
@Override
DocumentSection getSection() {
return DocumentSection.FOOTER;
}
DocumentSection nextSection() {
return DocumentSection.NO_SECTION;
}
@Override
void parseLine(DocumentKeyword keyword) {
switch(keyword) {
case BANDWIDTH_WEIGHTS:
processBandwidthWeights();
break;
case DIRECTORY_SIGNATURE:
processSignature();
break;
default:
break;
}
}
private void doFirstSignature() {
seenFirstSignature = true;
fieldParser.endSignedEntity();
final TorMessageDigest messageDigest = fieldParser.getSignatureMessageDigest();
messageDigest.update("directory-signature ");
document.setSigningHash(messageDigest.getHexDigest());
TorMessageDigest messageDigest256 = fieldParser.getSignatureMessageDigest256();
messageDigest256.update("directory-signature ");
document.setSigningHash256(messageDigest256.getHexDigest());
}
private void processSignature() {
if(!seenFirstSignature) {
doFirstSignature();
}
final String s = fieldParser.parseString();
final HexDigest identity;
boolean useSha256 = false;
if(s.length() < TorMessageDigest.TOR_DIGEST_SIZE) {
useSha256 = ("sha256".equals(s));
identity = fieldParser.parseHexDigest();
} else {
identity = HexDigest.createFromString(s);
}
HexDigest signingKey = fieldParser.parseHexDigest();
TorSignature signature = fieldParser.parseSignature();
document.addSignature(new DirectorySignature(identity, signingKey, signature, useSha256));
}
private void processBandwidthWeights() {
final int remaining = fieldParser.argumentsRemaining();
for(int i = 0; i < remaining; i++) {
NameIntegerParameter p = fieldParser.parseParameter();
document.addBandwidthWeight(p.getName(), p.getValue());
}
}
}