Java tutorial
/* * ENTRADA, a big data platform for network data analytics * * Copyright (C) 2016 SIDN [https://www.sidn.nl] * * This file is part of ENTRADA. * * ENTRADA is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ENTRADA 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ENTRADA. If not, see [<http://www.gnu.org/licenses/]. * */ package nl.sidn.dnslib.message.records.dnssec; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; import javax.json.Json; import javax.json.JsonObject; import javax.json.JsonObjectBuilder; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Hex; import nl.sidn.dnslib.message.records.AbstractResourceRecord; import nl.sidn.dnslib.message.util.DNSStringUtil; import nl.sidn.dnslib.message.util.NetworkData; import nl.sidn.dnslib.types.AlgorithmType; import nl.sidn.dnslib.types.ResourceRecordType; import nl.sidn.dnslib.types.TypeMap; import nl.sidn.dnslib.util.LabelUtil; public class RRSIGResourceRecord extends AbstractResourceRecord { private static final long serialVersionUID = 1L; private static final SimpleDateFormat DATE_FMT = new SimpleDateFormat("YYYYMMddHHmmss"); /* The RDATA for an RRSIG RR consists of a 2 octet Type Covered field, a 1 octet Algorithm field, a 1 octet Labels field, a 4 octet Original TTL field, a 4 octet Signature Expiration field, a 4 octet Signature Inception field, a 2 octet Key tag, the Signer's Name field, and the Signature field. 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type Covered | Algorithm | Labels | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Original TTL | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Signature Expiration | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Signature Inception | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Key Tag | / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Signer's Name / / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / / Signature / / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ private TypeMap typeCovered; private AlgorithmType algorithm; private short labels; private long originalTtl; private long signatureExpiration; private long signatureInception; private char keytag; private String signerName; private byte[] signature; private boolean wildcard; @Override public void decode(NetworkData buffer) { super.decode(buffer); char type = buffer.readUnsignedChar(); ResourceRecordType rrType = ResourceRecordType.fromValue(type); if (rrType == null) { rrType = ResourceRecordType.RESERVED; } typeCovered = new TypeMap(rrType, type); short alg = buffer.readUnsignedByte(); algorithm = AlgorithmType.fromValue(alg); labels = buffer.readUnsignedByte(); //check if wildacrd was used wildcard = LabelUtil.count(getName()) > labels; originalTtl = buffer.readUnsignedInt(); signatureExpiration = buffer.readUnsignedInt(); signatureInception = buffer.readUnsignedInt(); keytag = buffer.readUnsignedChar(); signerName = DNSStringUtil.readName(buffer); int signatureLength = rdLength; if (signerName.length() == 1) { //root signatureLength = signatureLength - 1; } else { //non root signer signatureLength = signatureLength - (signerName.length() + 1); } signatureLength = signatureLength - 18; signature = new byte[signatureLength]; buffer.readBytes(signature); DATE_FMT.setTimeZone(TimeZone.getTimeZone("UTC")); } @Override public void encode(NetworkData buffer) { super.encode(buffer); buffer.writeChar(rdLength); buffer.writeChar(typeCovered.getValue()); buffer.writeByte(algorithm.getValue()); buffer.writeByte(labels); buffer.writeInt((int) originalTtl); buffer.writeInt((int) signatureExpiration); buffer.writeInt((int) signatureInception); buffer.writeChar(keytag); DNSStringUtil.writeName(signerName, buffer); buffer.writeBytes(signature); } public AlgorithmType getAlgorithm() { return algorithm; } public void setAlgorithm(AlgorithmType algorithm) { this.algorithm = algorithm; } public short getLabels() { return labels; } public void setLabels(short labels) { this.labels = labels; } public long getOriginalTtl() { return originalTtl; } public void setOriginalTtl(long originalTtl) { this.originalTtl = originalTtl; } public long getSignatureExpiration() { return signatureExpiration; } public void setSignatureExpiration(long signatureExpiration) { this.signatureExpiration = signatureExpiration; } public long getSignatureInception() { return signatureInception; } public void setSignatureInception(long signatureInception) { this.signatureInception = signatureInception; } public char getKeytag() { return keytag; } public void setKeytag(char keytag) { this.keytag = keytag; } public String getSignerName() { return signerName; } public void setSignerName(String signerName) { this.signerName = signerName; } public byte[] getSignature() { return signature; } public void setSignature(byte[] signature) { this.signature = signature; } public char getRdLength() { return rdLength; } public void setRdLength(char rdLength) { this.rdLength = rdLength; } @Override public String toString() { return "RRSIGResourceRecord [typeCovered=" + typeCovered + ", algorithm=" + algorithm + ", labels=" + labels + ", originalTtl=" + originalTtl + ", signatureExpiration=" + signatureExpiration + ", signatureInception=" + signatureInception + ", keytag=" + (int) keytag + ", signerName=" + signerName + ", signature=" + Hex.encodeHexString(signature) + ", rdLength=" + (int) rdLength + "]"; } @Override public String toZone(int maxLength) { Date exp = new Date(); exp.setTime((long) (signatureExpiration * 1000)); Date incep = new Date(); incep.setTime((long) (signatureInception * 1000)); SimpleDateFormat fmt = new SimpleDateFormat("YYYYMMddHHmmss"); fmt.setTimeZone(TimeZone.getTimeZone("UTC")); return super.toZone(maxLength) + "\t" + typeCovered.name() + " " + algorithm.getValue() + " " + labels + " " + originalTtl + " " + fmt.format(exp) + "(\n\t\t\t\t\t" + fmt.format(incep) + " " + (int) keytag + " " + signerName + "\n\t\t\t\t\t" + new Base64(36, "\n\t\t\t\t\t".getBytes()).encodeAsString(signature) + " )"; } @Override public JsonObject toJSon() { Date exp = new Date(); exp.setTime((long) (signatureExpiration * 1000)); Date incep = new Date(); incep.setTime((long) (signatureInception * 1000)); JsonObjectBuilder builder = super.createJsonBuilder(); return builder .add("rdata", Json.createObjectBuilder().add("type-covered", typeCovered.name()) .add("algorithm", algorithm.name()).add("labels", labels).add("original-ttl", originalTtl) .add("sig-exp", DATE_FMT.format(exp)).add("sig-inc", DATE_FMT.format(incep)) .add("keytag", (int) keytag).add("signer-name", signerName) .add("signature", new Base64(Integer.MAX_VALUE, "".getBytes()).encodeAsString(signature))) .build(); } public boolean getWildcard() { return wildcard; } }