Skip to content

Commit

Permalink
Merge d17b31f into 0b4fad8
Browse files Browse the repository at this point in the history
  • Loading branch information
serega6531 committed May 10, 2020
2 parents 0b4fad8 + d17b31f commit b5983c8
Show file tree
Hide file tree
Showing 41 changed files with 3,151 additions and 0 deletions.
8 changes: 8 additions & 0 deletions pcap4j-core/src/main/java/module-info.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
module org.pcap4j.core {
exports org.pcap4j.core;
exports org.pcap4j.packet;

exports org.pcap4j.packet.tls.records;
exports org.pcap4j.packet.tls.records.handshakes;
exports org.pcap4j.packet.tls.extensions;
exports org.pcap4j.packet.tls.extensions.keyshare;
exports org.pcap4j.packet.tls.keys.enums;
exports org.pcap4j.packet.namednumber.tls;

exports org.pcap4j.packet.factory;
exports org.pcap4j.packet.namednumber;
exports org.pcap4j.packet.constant;
Expand Down
205 changes: 205 additions & 0 deletions pcap4j-core/src/main/java/org/pcap4j/packet/TlsPacket.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
package org.pcap4j.packet;

import org.pcap4j.packet.namednumber.tls.ContentType;
import org.pcap4j.packet.namednumber.tls.TlsVersion;
import org.pcap4j.packet.tls.records.*;
import org.pcap4j.util.ByteArrays;

import java.util.ArrayList;
import java.util.List;

import static org.pcap4j.util.ByteArrays.BYTE_SIZE_IN_BYTES;
import static org.pcap4j.util.ByteArrays.SHORT_SIZE_IN_BYTES;

public class TlsPacket extends AbstractPacket {

private final TlsPacket.TlsHeader header;
private final Packet payload;

public static TlsPacket newPacket(byte[] rawData, int offset, int length) throws IllegalRawDataException {
ByteArrays.validateBounds(rawData, offset, length);
return new TlsPacket(rawData, offset, length);
}

private TlsPacket(byte[] rawData, int offset, int length) throws IllegalRawDataException {
this.header = new TlsPacket.TlsHeader(rawData, offset, length);

int payloadLength = length - header.length();
if (payloadLength > 0) {
this.payload = TlsPacket.newPacket(rawData, offset + header.length(), payloadLength);
} else {
this.payload = null;
}
}

private TlsPacket(TlsPacket.Builder builder) {
if (builder == null) {
throw new NullPointerException("builder: null");
}

this.payload = builder.payloadBuilder != null ? builder.payloadBuilder.build() : null;
this.header = new TlsPacket.TlsHeader(builder);
}

@Override
public TlsHeader getHeader() {
return header;
}

@Override
public Packet getPayload() {
return payload;
}

@Override
public Builder getBuilder() {
return new Builder(this);
}

@Override
protected String buildString() {
StringBuilder sb = new StringBuilder(getHeader().toString());

TlsPacket p = (TlsPacket) getPayload();

if (p != null) {
sb.append('\n');
sb.append(p.toString());
}

return sb.toString();
}

public static final class TlsHeader extends AbstractHeader {

/*
0x0 - Content Type
0x1 - Version
0x3 - Length
0x5 - Record content
*/

private static final int CONTENT_TYPE_OFFSET = 0;
private static final int VERSION_OFFSET = CONTENT_TYPE_OFFSET + BYTE_SIZE_IN_BYTES;
private static final int LENGTH_OFFSET = VERSION_OFFSET + SHORT_SIZE_IN_BYTES;
private static final int RECORD_OFFSET = LENGTH_OFFSET + SHORT_SIZE_IN_BYTES;

private final ContentType contentType;
private final TlsVersion version;
private final short recordLength;
private final TlsRecord record;

private TlsHeader(Builder builder) {
this.contentType = builder.contentType;
this.version = builder.version;
this.recordLength = builder.recordLength;
this.record = builder.record;
}

private TlsHeader(byte[] rawData, int offset, int length) {
ByteArrays.validateBounds(rawData, offset, RECORD_OFFSET);
this.contentType = ContentType.getInstance(ByteArrays.getByte(rawData, CONTENT_TYPE_OFFSET + offset));
this.version = TlsVersion.getInstance(ByteArrays.getShort(rawData, VERSION_OFFSET + offset));
this.recordLength = ByteArrays.getShort(rawData, LENGTH_OFFSET + offset);

if (contentType == ContentType.HANDSHAKE) {
this.record = HandshakeRecord.newInstance(rawData, offset + RECORD_OFFSET, recordLength);
} else if (contentType == ContentType.CHANGE_CIPHER_SPEC) {
this.record = ChangeCipherSpecRecord.newInstance(rawData, offset + RECORD_OFFSET, recordLength);
} else if (contentType == ContentType.APPLICATION_DATA) {
this.record = ApplicationDataRecord.newInstance(rawData, offset + RECORD_OFFSET, recordLength);
} else if (contentType == ContentType.ALERT) {
this.record = AlertRecord.newInstance(rawData, offset + RECORD_OFFSET, recordLength);
} else if (contentType == ContentType.HEARTBEAT) {
this.record = HeartbeatRecord.newInstance(rawData, offset + RECORD_OFFSET, recordLength);
} else {
throw new IllegalArgumentException("Unknown content type: " + contentType);
}
}

public ContentType getContentType() {
return contentType;
}

public TlsVersion getVersion() {
return version;
}

public short getRecordLength() {
return recordLength;
}

public TlsRecord getRecord() {
return record;
}

@Override
protected List<byte[]> getRawFields() {
List<byte[]> rawFields = new ArrayList<byte[]>();
rawFields.add(new byte[]{contentType.value()});
rawFields.add(ByteArrays.toByteArray(version.value()));
rawFields.add(ByteArrays.toByteArray(recordLength));
rawFields.add(record.toByteArray());
return rawFields;
}

@Override
protected int calcLength() {
return RECORD_OFFSET + recordLength;
}

@Override
protected String buildString() {
return "[TLS Header (" + length() + " bytes)]\n" +
" Version: " + version + "\n" +
" Type: " + contentType + "\n" +
record.toString();
}
}

public static final class Builder extends AbstractBuilder {

private ContentType contentType;
private TlsVersion version;
private short recordLength;
private TlsRecord record;

private Packet.Builder payloadBuilder;

public Builder() {
}

public Builder(TlsPacket packet) {
this.payloadBuilder = packet.payload != null ? packet.payload.getBuilder() : null;
this.contentType = packet.header.contentType;
this.version = packet.header.version;
this.recordLength = packet.header.recordLength;
this.record = packet.header.record;
}

public Builder contentType(ContentType contentType) {
this.contentType = contentType;
return this;
}

public Builder version(TlsVersion version) {
this.version = version;
return this;
}

public Builder recordLength(short recordLength) {
this.recordLength = recordLength;
return this;
}

public Builder record(TlsRecord record) {
this.record = record;
return this;
}

@Override
public TlsPacket build() {
return new TlsPacket(this);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package org.pcap4j.packet.namednumber.tls;

import org.pcap4j.packet.namednumber.NamedNumber;

import java.util.HashMap;
import java.util.Map;

public class AlertDescription extends NamedNumber<Byte, AlertDescription> {

private static final Map<Byte, AlertDescription> registry = new HashMap<Byte, AlertDescription>();

// https://techcommunity.microsoft.com/t5/iis-support-blog/ssl-tls-alert-protocol-and-the-alert-codes/ba-p/377132

public static AlertDescription close_notify = new AlertDescription((byte) 0, "close_notify");
public static AlertDescription unexpected_message = new AlertDescription((byte) 10, "unexpected_message");
public static AlertDescription bad_record_mac = new AlertDescription((byte) 20, "bad_record_mac");
public static AlertDescription decryption_failed_RESERVED = new AlertDescription((byte) 21, "decryption_failed_RESERVED");
public static AlertDescription record_overflow = new AlertDescription((byte) 22, "record_overflow");
public static AlertDescription decompression_failure_RESERVED = new AlertDescription((byte) 30, "decompression_failure_RESERVED");
public static AlertDescription handshake_failure = new AlertDescription((byte) 40, "handshake_failure");
public static AlertDescription no_certificate_RESERVED = new AlertDescription((byte) 41, "no_certificate_RESERVED");
public static AlertDescription bad_certificate = new AlertDescription((byte) 42, "bad_certificate");
public static AlertDescription unsupported_certificate = new AlertDescription((byte) 43, "unsupported_certificate");
public static AlertDescription certificate_revoked = new AlertDescription((byte) 44, "certificate_revoked");
public static AlertDescription certificate_expired = new AlertDescription((byte) 45, "certificate_expired");
public static AlertDescription certificate_unknown = new AlertDescription((byte) 46, "certificate_unknown");
public static AlertDescription illegal_parameter = new AlertDescription((byte) 47, "illegal_parameter");
public static AlertDescription unknown_ca = new AlertDescription((byte) 48, "unknown_ca");
public static AlertDescription access_denied = new AlertDescription((byte) 49, "access_denied");
public static AlertDescription decode_error = new AlertDescription((byte) 50, "decode_error");
public static AlertDescription decrypt_error = new AlertDescription((byte) 51, "decrypt_error");
public static AlertDescription export_restriction_RESERVED = new AlertDescription((byte) 60, "export_restriction_RESERVED");
public static AlertDescription protocol_version = new AlertDescription((byte) 70, "protocol_version");
public static AlertDescription insufficient_security = new AlertDescription((byte) 71, "insufficient_security");
public static AlertDescription internal_error = new AlertDescription((byte) 80, "internal_error");
public static AlertDescription inappropriate_fallback = new AlertDescription((byte) 86, "inappropriate_fallback");
public static AlertDescription user_canceled = new AlertDescription((byte) 90, "user_canceled");
public static AlertDescription no_renegotiation_RESERVED = new AlertDescription((byte) 100, "no_renegotiation_RESERVED");
public static AlertDescription missing_extension = new AlertDescription((byte) 109, "missing_extension");
public static AlertDescription unsupported_extension = new AlertDescription((byte) 110, "unsupported_extension");
public static AlertDescription certificate_unobtainable_RESERVED = new AlertDescription((byte) 111, "certificate_unobtainable_RESERVED");
public static AlertDescription unrecognized_name = new AlertDescription((byte) 112, "unrecognized_name");
public static AlertDescription bad_certificate_status_response = new AlertDescription((byte) 113, "bad_certificate_status_response");
public static AlertDescription bad_certificate_hash_value_RESERVED = new AlertDescription((byte) 114, "bad_certificate_hash_value_RESERVED");
public static AlertDescription unknown_psk_identity = new AlertDescription((byte) 115, "unknown_psk_identity");
public static AlertDescription certificate_required = new AlertDescription((byte) 116, "certificate_required");
public static AlertDescription no_application_protocol = new AlertDescription((byte) 120, "no_application_protocol");

public AlertDescription(Byte value, String name) {
super(value, name);
registry.put(value, this);
}

public static AlertDescription getInstance(Byte value) {
if (registry.containsKey(value)) {
return registry.get(value);
} else {
throw new IllegalArgumentException("Unknown alert description: " + value);
}
}

@Override
public int compareTo(AlertDescription o) {
return value().compareTo(o.value());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.pcap4j.packet.namednumber.tls;

import org.pcap4j.packet.namednumber.NamedNumber;

import java.util.HashMap;
import java.util.Map;

@SuppressWarnings("unused")
public class AlertLevel extends NamedNumber<Byte, AlertLevel> {

private static final Map<Byte, AlertLevel> registry = new HashMap<Byte, AlertLevel>();

public static final AlertLevel WARNING = new AlertLevel((byte) 1, "warning");
public static final AlertLevel FATAL = new AlertLevel((byte) 2, "fatal");

public static final AlertLevel ENCRYPTED_ALERT = new AlertLevel((byte) 0, "encrypted alert");

public AlertLevel(Byte value, String name) {
super(value, name);
registry.put(value, this);
}

public static AlertLevel getInstance(Byte value) {
if (registry.containsKey(value)) {
return registry.get(value);
} else {
return ENCRYPTED_ALERT;
}
}

@Override
public int compareTo(AlertLevel o) {
return value().compareTo(o.value());
}

}

0 comments on commit b5983c8

Please sign in to comment.