SolarManager unter Versionsverwaltung
Erster Stand der Hintergrundprozesse, die auf der Synology unter /volume1/homes/wagner/SolarManager laufen: der Manager selbst, die Sammler je Geraet, die MQTT-Bruecke, der Wecker und - neu hinzugezogen - der AutoAction-Runner, der als Hintergrundprozess hierher gehoert und nicht ins Web-Verzeichnis. Zugangsdaten stehen nicht mehr im Quelltext, sondern in config.ini, die nicht mit eingecheckt wird. Vorlage ist config.ini.example, gelesen wird sie von konfig.py. Betroffen waren solarManager.py (Datenbank und Wattpilot), zeit.py, gatherWaterData.py, wecker.py und skoda_testdaten.py, das sich das Passwort bisher aus dem Quelltext eines anderen Moduls herausgesucht hat. Die Kia-Anbindung ist mit dem Fahrzeug entfallen: kiaTest.py, gatherCarData.py und hyundai_kia_connect_api sind nicht mehr dabei, ebenso gatherInverterData.py, auf das nur noch eine auskommentierte Zeile zeigte. Die mitgelieferten Bibliotheken bleiben im Repository - die NAS hat kein pip, sie muessen neben den Skripten liegen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
import pathlib
|
||||
|
||||
tests_path = pathlib.Path(__file__).parent
|
||||
lib_path = tests_path.parent
|
||||
ssl_path = tests_path / "ssl"
|
||||
@@ -0,0 +1,223 @@
|
||||
import binascii
|
||||
import struct
|
||||
from typing import Tuple
|
||||
|
||||
|
||||
def dump_packet(prefix: str, data: bytes) -> None:
|
||||
try:
|
||||
data = to_string(data)
|
||||
print(prefix, ": ", data, sep="")
|
||||
except struct.error:
|
||||
data = binascii.b2a_hex(data).decode('utf8')
|
||||
print(prefix, " (not decoded): 0x", data, sep="")
|
||||
|
||||
|
||||
def remaining_length(packet: bytes) -> Tuple[bytes, int]:
|
||||
l = min(5, len(packet)) # noqa: E741
|
||||
all_bytes = struct.unpack("!" + "B" * l, packet[:l])
|
||||
mult = 1
|
||||
rl = 0
|
||||
for i in range(1, l - 1):
|
||||
byte = all_bytes[i]
|
||||
|
||||
rl += (byte & 127) * mult
|
||||
mult *= 128
|
||||
if byte & 128 == 0:
|
||||
packet = packet[i + 1:]
|
||||
break
|
||||
|
||||
return (packet, rl)
|
||||
|
||||
|
||||
def to_hex_string(packet: bytes) -> str:
|
||||
if not packet:
|
||||
return ""
|
||||
|
||||
s = ""
|
||||
while len(packet) > 0:
|
||||
packet0 = struct.unpack("!B", packet[0])
|
||||
s = s+hex(packet0[0]) + " "
|
||||
packet = packet[1:]
|
||||
|
||||
return s
|
||||
|
||||
|
||||
def to_string(packet: bytes) -> str:
|
||||
if not packet:
|
||||
return ""
|
||||
|
||||
packet0 = struct.unpack("!B%ds" % (len(packet)-1), bytes(packet))
|
||||
packet0 = packet0[0]
|
||||
cmd = packet0 & 0xF0
|
||||
if cmd == 0x00:
|
||||
# Reserved
|
||||
return "0x00"
|
||||
elif cmd == 0x10:
|
||||
# CONNECT
|
||||
(packet, rl) = remaining_length(packet)
|
||||
pack_format = "!H" + str(len(packet) - 2) + 's'
|
||||
(slen, packet) = struct.unpack(pack_format, packet)
|
||||
pack_format = "!" + str(slen) + 'sBBH' + str(len(packet) - slen - 4) + 's'
|
||||
(protocol, proto_ver, flags, keepalive, packet) = struct.unpack(pack_format, packet)
|
||||
kind = ("clean-session" if flags & 2 else "durable")
|
||||
s = f"CONNECT, proto={protocol}{proto_ver}, keepalive={keepalive}, {kind}"
|
||||
|
||||
pack_format = "!H" + str(len(packet) - 2) + 's'
|
||||
(slen, packet) = struct.unpack(pack_format, packet)
|
||||
pack_format = "!" + str(slen) + 's' + str(len(packet) - slen) + 's'
|
||||
(client_id, packet) = struct.unpack(pack_format, packet)
|
||||
s = s + ", id=" + str(client_id)
|
||||
|
||||
if flags & 4:
|
||||
pack_format = "!H" + str(len(packet) - 2) + 's'
|
||||
(slen, packet) = struct.unpack(pack_format, packet)
|
||||
pack_format = "!" + str(slen) + 's' + str(len(packet) - slen) + 's'
|
||||
(will_topic, packet) = struct.unpack(pack_format, packet)
|
||||
s = s + ", will-topic=" + str(will_topic)
|
||||
|
||||
pack_format = "!H" + str(len(packet) - 2) + 's'
|
||||
(slen, packet) = struct.unpack(pack_format, packet)
|
||||
pack_format = "!" + str(slen) + 's' + str(len(packet) - slen) + 's'
|
||||
(will_message, packet) = struct.unpack(pack_format, packet)
|
||||
s = s + ", will-message=" + will_message
|
||||
|
||||
s = s + ", will-qos=" + str((flags & 24) >> 3)
|
||||
s = s + ", will-retain=" + str((flags & 32) >> 5)
|
||||
|
||||
if flags & 128:
|
||||
pack_format = "!H" + str(len(packet) - 2) + 's'
|
||||
(slen, packet) = struct.unpack(pack_format, packet)
|
||||
pack_format = "!" + str(slen) + 's' + str(len(packet) - slen) + 's'
|
||||
(username, packet) = struct.unpack(pack_format, packet)
|
||||
s = s + ", username=" + str(username)
|
||||
|
||||
if flags & 64:
|
||||
pack_format = "!H" + str(len(packet) - 2) + 's'
|
||||
(slen, packet) = struct.unpack(pack_format, packet)
|
||||
pack_format = "!" + str(slen) + 's' + str(len(packet) - slen) + 's'
|
||||
(password, packet) = struct.unpack(pack_format, packet)
|
||||
s = s + ", password=" + str(password)
|
||||
|
||||
if flags & 1:
|
||||
s = s + ", reserved=1"
|
||||
|
||||
return s
|
||||
elif cmd == 0x20:
|
||||
# CONNACK
|
||||
if len(packet) == 4:
|
||||
(cmd, rl, resv, rc) = struct.unpack('!BBBB', packet)
|
||||
return "CONNACK, rl="+str(rl)+", res="+str(resv)+", rc="+str(rc)
|
||||
elif len(packet) == 5:
|
||||
(cmd, rl, flags, reason_code, proplen) = struct.unpack('!BBBBB', packet)
|
||||
return "CONNACK, rl="+str(rl)+", flags="+str(flags)+", rc="+str(reason_code)+", proplen="+str(proplen)
|
||||
else:
|
||||
return "CONNACK, (not decoded)"
|
||||
|
||||
elif cmd == 0x30:
|
||||
# PUBLISH
|
||||
dup = (packet0 & 0x08) >> 3
|
||||
qos = (packet0 & 0x06) >> 1
|
||||
retain = (packet0 & 0x01)
|
||||
(packet, rl) = remaining_length(packet)
|
||||
pack_format = "!H" + str(len(packet) - 2) + 's'
|
||||
(tlen, packet) = struct.unpack(pack_format, packet)
|
||||
pack_format = "!" + str(tlen) + 's' + str(len(packet) - tlen) + 's'
|
||||
(topic, packet) = struct.unpack(pack_format, packet)
|
||||
s = "PUBLISH, rl=" + str(rl) + ", topic=" + str(topic) + ", qos=" + str(qos) + ", retain=" + str(retain) + ", dup=" + str(dup)
|
||||
if qos > 0:
|
||||
pack_format = "!H" + str(len(packet) - 2) + 's'
|
||||
(mid, packet) = struct.unpack(pack_format, packet)
|
||||
s = s + ", mid=" + str(mid)
|
||||
|
||||
s = s + ", payload=" + str(packet)
|
||||
return s
|
||||
elif cmd == 0x40:
|
||||
# PUBACK
|
||||
if len(packet) == 5:
|
||||
(cmd, rl, mid, reason_code) = struct.unpack('!BBHB', packet)
|
||||
return "PUBACK, rl="+str(rl)+", mid="+str(mid)+", reason_code="+str(reason_code)
|
||||
else:
|
||||
(cmd, rl, mid) = struct.unpack('!BBH', packet)
|
||||
return "PUBACK, rl="+str(rl)+", mid="+str(mid)
|
||||
elif cmd == 0x50:
|
||||
# PUBREC
|
||||
if len(packet) == 5:
|
||||
(cmd, rl, mid, reason_code) = struct.unpack('!BBHB', packet)
|
||||
return "PUBREC, rl="+str(rl)+", mid="+str(mid)+", reason_code="+str(reason_code)
|
||||
else:
|
||||
(cmd, rl, mid) = struct.unpack('!BBH', packet)
|
||||
return "PUBREC, rl="+str(rl)+", mid="+str(mid)
|
||||
elif cmd == 0x60:
|
||||
# PUBREL
|
||||
dup = (packet0 & 0x08) >> 3
|
||||
(cmd, rl, mid) = struct.unpack('!BBH', packet)
|
||||
return "PUBREL, rl=" + str(rl) + ", mid=" + str(mid) + ", dup=" + str(dup)
|
||||
elif cmd == 0x70:
|
||||
# PUBCOMP
|
||||
(cmd, rl, mid) = struct.unpack('!BBH', packet)
|
||||
return "PUBCOMP, rl=" + str(rl) + ", mid=" + str(mid)
|
||||
elif cmd == 0x80:
|
||||
# SUBSCRIBE
|
||||
(packet, rl) = remaining_length(packet)
|
||||
pack_format = "!H" + str(len(packet) - 2) + 's'
|
||||
(mid, packet) = struct.unpack(pack_format, packet)
|
||||
s = "SUBSCRIBE, rl=" + str(rl) + ", mid=" + str(mid)
|
||||
topic_index = 0
|
||||
while len(packet) > 0:
|
||||
pack_format = "!H" + str(len(packet) - 2) + 's'
|
||||
(tlen, packet) = struct.unpack(pack_format, packet)
|
||||
pack_format = "!" + str(tlen) + 'sB' + str(len(packet) - tlen - 1) + 's'
|
||||
(topic, qos, packet) = struct.unpack(pack_format, packet)
|
||||
s = s + ", topic" + str(topic_index) + "=" + str(topic) + "," + str(qos)
|
||||
return s
|
||||
elif cmd == 0x90:
|
||||
# SUBACK
|
||||
(packet, rl) = remaining_length(packet)
|
||||
pack_format = "!H" + str(len(packet) - 2) + 's'
|
||||
(mid, packet) = struct.unpack(pack_format, packet)
|
||||
pack_format = "!" + "B" * len(packet)
|
||||
granted_qos = struct.unpack(pack_format, packet)
|
||||
|
||||
s = "SUBACK, rl=" + str(rl) + ", mid=" + str(mid) + ", granted_qos=" + str(granted_qos[0])
|
||||
for i in range(1, len(granted_qos) - 1):
|
||||
s = s + ", " + str(granted_qos[i])
|
||||
return s
|
||||
elif cmd == 0xA0:
|
||||
# UNSUBSCRIBE
|
||||
(packet, rl) = remaining_length(packet)
|
||||
pack_format = "!H" + str(len(packet) - 2) + 's'
|
||||
(mid, packet) = struct.unpack(pack_format, packet)
|
||||
s = "UNSUBSCRIBE, rl=" + str(rl) + ", mid=" + str(mid)
|
||||
topic_index = 0
|
||||
while len(packet) > 0:
|
||||
pack_format = "!H" + str(len(packet) - 2) + 's'
|
||||
(tlen, packet) = struct.unpack(pack_format, packet)
|
||||
pack_format = "!" + str(tlen) + 's' + str(len(packet) - tlen) + 's'
|
||||
(topic, packet) = struct.unpack(pack_format, packet)
|
||||
s = s + ", topic" + str(topic_index) + "=" + str(topic)
|
||||
return s
|
||||
elif cmd == 0xB0:
|
||||
# UNSUBACK
|
||||
(cmd, rl, mid) = struct.unpack('!BBH', packet)
|
||||
return "UNSUBACK, rl=" + str(rl) + ", mid=" + str(mid)
|
||||
elif cmd == 0xC0:
|
||||
# PINGREQ
|
||||
(cmd, rl) = struct.unpack('!BB', packet)
|
||||
return "PINGREQ, rl=" + str(rl)
|
||||
elif cmd == 0xD0:
|
||||
# PINGRESP
|
||||
(cmd, rl) = struct.unpack('!BB', packet)
|
||||
return "PINGRESP, rl=" + str(rl)
|
||||
elif cmd == 0xE0:
|
||||
# DISCONNECT
|
||||
if len(packet) == 3:
|
||||
(cmd, rl, reason_code) = struct.unpack('!BBB', packet)
|
||||
return "DISCONNECT, rl="+str(rl)+", reason_code="+str(reason_code)
|
||||
else:
|
||||
(cmd, rl) = struct.unpack('!BB', packet)
|
||||
return "DISCONNECT, rl="+str(rl)
|
||||
elif cmd == 0xF0:
|
||||
# AUTH
|
||||
(cmd, rl) = struct.unpack('!BB', packet)
|
||||
return "AUTH, rl="+str(rl)
|
||||
raise ValueError(f"Unknown packet type {cmd}")
|
||||
@@ -0,0 +1,89 @@
|
||||
import asyncio
|
||||
import socket
|
||||
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port
|
||||
|
||||
client_id = 'asyncio-test'
|
||||
|
||||
|
||||
class AsyncioHelper:
|
||||
def __init__(self, loop, client):
|
||||
self.loop = loop
|
||||
self.client = client
|
||||
self.client.on_socket_open = self.on_socket_open
|
||||
self.client.on_socket_close = self.on_socket_close
|
||||
self.client.on_socket_register_write = self.on_socket_register_write
|
||||
self.client.on_socket_unregister_write = self.on_socket_unregister_write
|
||||
|
||||
def on_socket_open(self, client, userdata, sock):
|
||||
def cb():
|
||||
client.loop_read()
|
||||
|
||||
self.loop.add_reader(sock, cb)
|
||||
self.misc = self.loop.create_task(self.misc_loop())
|
||||
|
||||
def on_socket_close(self, client, userdata, sock):
|
||||
self.loop.remove_reader(sock)
|
||||
self.misc.cancel()
|
||||
|
||||
def on_socket_register_write(self, client, userdata, sock):
|
||||
def cb():
|
||||
client.loop_write()
|
||||
|
||||
self.loop.add_writer(sock, cb)
|
||||
|
||||
def on_socket_unregister_write(self, client, userdata, sock):
|
||||
self.loop.remove_writer(sock)
|
||||
|
||||
async def misc_loop(self):
|
||||
while self.client.loop_misc() == mqtt.MQTT_ERR_SUCCESS:
|
||||
try:
|
||||
await asyncio.sleep(1)
|
||||
except asyncio.CancelledError:
|
||||
break
|
||||
|
||||
|
||||
async def main():
|
||||
loop = asyncio.get_event_loop()
|
||||
payload = ""
|
||||
|
||||
def on_connect(client, obj, flags, rc):
|
||||
client.subscribe("sub-test", 1)
|
||||
|
||||
def on_subscribe(client, obj, mid, granted_qos):
|
||||
client.unsubscribe("unsub-test")
|
||||
|
||||
def on_unsubscribe(client, obj, mid):
|
||||
nonlocal payload
|
||||
payload = "message"
|
||||
|
||||
def on_message(client, obj, msg):
|
||||
client.publish("asyncio", qos=1, payload=payload)
|
||||
|
||||
def on_publish(client, obj, mid):
|
||||
client.disconnect()
|
||||
|
||||
def on_disconnect(client, userdata, rc):
|
||||
disconnected.set_result(rc)
|
||||
|
||||
disconnected = loop.create_future()
|
||||
|
||||
client = mqtt.Client(callback_api_version=mqtt.CallbackAPIVersion.VERSION1, client_id=client_id)
|
||||
client.on_connect = on_connect
|
||||
client.on_message = on_message
|
||||
client.on_publish = on_publish
|
||||
client.on_subscribe = on_subscribe
|
||||
client.on_unsubscribe = on_unsubscribe
|
||||
client.on_disconnect = on_disconnect
|
||||
|
||||
_aioh = AsyncioHelper(loop, client)
|
||||
|
||||
client.connect('localhost', get_test_server_port(), 60)
|
||||
client.socket().setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2048)
|
||||
|
||||
await disconnected
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,42 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "decorators-test", clean_session=True)
|
||||
payload = b""
|
||||
|
||||
|
||||
@mqttc.connect_callback()
|
||||
def on_connect(mqttc, obj, flags, rc):
|
||||
mqttc.subscribe("sub-test", 1)
|
||||
|
||||
|
||||
@mqttc.subscribe_callback()
|
||||
def on_subscribe(mqttc, obj, mid, granted_qos):
|
||||
mqttc.unsubscribe("unsub-test")
|
||||
|
||||
|
||||
@mqttc.unsubscribe_callback()
|
||||
def on_unsubscribe(mqttc, obj, mid):
|
||||
global payload
|
||||
payload = "message"
|
||||
|
||||
|
||||
@mqttc.message_callback()
|
||||
def on_message(mqttc, obj, msg):
|
||||
global payload
|
||||
mqttc.publish("decorators", qos=1, payload=payload)
|
||||
|
||||
|
||||
@mqttc.publish_callback()
|
||||
def on_publish(mqttc, obj, mid):
|
||||
mqttc.disconnect()
|
||||
|
||||
|
||||
@mqttc.disconnect_callback()
|
||||
def on_disconnect(mqttc, obj, rc):
|
||||
pass # TODO: should probably test that this gets called
|
||||
|
||||
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,14 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
|
||||
def on_connect(mqttc, obj, flags, rc):
|
||||
assert rc == 0, f"Connect failed ({rc})"
|
||||
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "01-keepalive-pingreq")
|
||||
mqttc.on_connect = on_connect
|
||||
|
||||
mqttc.connect("localhost", get_test_server_port(), keepalive=4)
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,8 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "01-no-clean-session", clean_session=False)
|
||||
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,16 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, wait_for_keyboard_interrupt
|
||||
|
||||
|
||||
def on_connect(mqttc, obj, flags, rc):
|
||||
mqttc.publish("reconnect/test", "message")
|
||||
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "01-reconnect-on-failure", reconnect_on_failure=False)
|
||||
mqttc.on_connect = on_connect
|
||||
|
||||
with wait_for_keyboard_interrupt():
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
mqttc.loop_forever()
|
||||
exit(42) # this is expected by the test case
|
||||
@@ -0,0 +1,9 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "01-unpwd-set")
|
||||
|
||||
mqttc.username_pw_set("uname", "")
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,9 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "01-unpwd-set")
|
||||
|
||||
mqttc.username_pw_set("", "")
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,9 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "01-unpwd-set")
|
||||
|
||||
mqttc.username_pw_set("uname", ";'[08gn=#")
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "01-unpwd-unicode-set")
|
||||
|
||||
username = "\u00fas\u00e9rn\u00e1m\u00e9-h\u00e9ll\u00f3"
|
||||
password = "h\u00e9ll\u00f3"
|
||||
mqttc.username_pw_set(username, password)
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,9 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "01-will-set")
|
||||
|
||||
mqttc.will_set("topic/on/unexpected/disconnect", "will message", 1, True)
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,10 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "01-will-unpwd-set")
|
||||
|
||||
mqttc.username_pw_set("oibvvwqw", "#'^2hg9a&nm38*us")
|
||||
mqttc.will_set("will-topic", "will message", 2, False)
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,20 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
|
||||
def on_connect(mqttc, obj, flags, rc):
|
||||
assert rc == 0, f"Connect failed ({rc})"
|
||||
mqttc.disconnect()
|
||||
|
||||
|
||||
def on_disconnect(mqttc, obj, rc):
|
||||
mqttc.loop()
|
||||
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "", clean_session=True, protocol=mqtt.MQTTv311)
|
||||
mqttc.on_connect = on_connect
|
||||
mqttc.on_disconnect = on_disconnect
|
||||
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,20 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
|
||||
def on_connect(mqttc, obj, flags, rc):
|
||||
assert rc == 0, f"Connect failed ({rc})"
|
||||
mqttc.subscribe("qos0/test", 0)
|
||||
|
||||
|
||||
def on_subscribe(mqttc, obj, mid, granted_qos):
|
||||
mqttc.disconnect()
|
||||
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "subscribe-qos0-test", clean_session=True)
|
||||
mqttc.on_connect = on_connect
|
||||
mqttc.on_subscribe = on_subscribe
|
||||
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,20 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
|
||||
def on_connect(mqttc, obj, flags, rc):
|
||||
assert rc == 0, f"Connect failed ({rc})"
|
||||
mqttc.subscribe("qos1/test", 1)
|
||||
|
||||
|
||||
def on_subscribe(mqttc, obj, mid, granted_qos):
|
||||
mqttc.disconnect()
|
||||
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "subscribe-qos1-test", clean_session=True)
|
||||
mqttc.on_connect = on_connect
|
||||
mqttc.on_subscribe = on_subscribe
|
||||
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,20 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
|
||||
def on_connect(mqttc, obj, flags, rc):
|
||||
assert rc == 0, f"Connect failed ({rc})"
|
||||
mqttc.subscribe("qos2/test", 2)
|
||||
|
||||
|
||||
def on_subscribe(mqttc, obj, mid, granted_qos):
|
||||
mqttc.disconnect()
|
||||
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "subscribe-qos2-test", clean_session=True)
|
||||
mqttc.on_connect = on_connect
|
||||
mqttc.on_subscribe = on_subscribe
|
||||
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,20 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
|
||||
def on_connect(mqttc, obj, flags, rc):
|
||||
assert rc == 0, f"Connect failed ({rc})"
|
||||
mqttc.unsubscribe("unsubscribe/test")
|
||||
|
||||
|
||||
def on_unsubscribe(mqttc, obj, mid):
|
||||
mqttc.disconnect()
|
||||
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "unsubscribe-test", clean_session=True)
|
||||
mqttc.on_connect = on_connect
|
||||
mqttc.on_unsubscribe = on_unsubscribe
|
||||
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,25 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
expected_payload = b"message"
|
||||
|
||||
|
||||
def on_message(mqttc, obj, msg):
|
||||
assert msg.mid == 123, f"Invalid mid: ({msg.mid})"
|
||||
assert msg.topic == "pub/qos1/receive", f"Invalid topic: ({msg.topic})"
|
||||
assert msg.payload == expected_payload, f"Invalid payload: ({msg.payload})"
|
||||
assert msg.qos == 1, f"Invalid qos: ({msg.qos})"
|
||||
assert not msg.retain, f"Invalid retain: ({msg.retain})"
|
||||
|
||||
|
||||
def on_connect(mqttc, obj, flags, rc):
|
||||
assert rc == 0, f"Connect failed ({rc})"
|
||||
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "publish-qos1-test")
|
||||
mqttc.on_connect = on_connect
|
||||
mqttc.on_message = on_message
|
||||
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,28 @@
|
||||
import logging
|
||||
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
expected_payload = b"message"
|
||||
|
||||
|
||||
def on_message(mqttc, obj, msg):
|
||||
assert msg.mid == 13423, f"Invalid mid: ({msg.mid})"
|
||||
assert msg.topic == "pub/qos2/receive", f"Invalid topic: ({msg.topic})"
|
||||
assert msg.payload == expected_payload, f"Invalid payload: ({msg.payload})"
|
||||
assert msg.qos == 2, f"Invalid qos: ({msg.qos})"
|
||||
assert not msg.retain, f"Invalid retain: ({msg.retain})"
|
||||
|
||||
|
||||
def on_connect(mqttc, obj, flags, rc):
|
||||
assert rc == 0, f"Connect failed ({rc})"
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "publish-qos2-test", clean_session=True)
|
||||
mqttc.enable_logger()
|
||||
mqttc.on_connect = on_connect
|
||||
mqttc.on_message = on_message
|
||||
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,33 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
sent_mid = -1
|
||||
|
||||
|
||||
def on_connect(mqttc, obj, flags, rc):
|
||||
global sent_mid
|
||||
assert rc == 0, f"Connect failed ({rc})"
|
||||
if sent_mid == -1:
|
||||
res = mqttc.publish("pub/qos1/test", "message", 1)
|
||||
sent_mid = res[1]
|
||||
|
||||
|
||||
def on_disconnect(mqttc, obj, rc):
|
||||
if rc != mqtt.MQTT_ERR_SUCCESS:
|
||||
mqttc.reconnect()
|
||||
|
||||
|
||||
def on_publish(mqttc, obj, mid):
|
||||
global sent_mid
|
||||
assert mid == sent_mid, f"Invalid mid: ({mid})"
|
||||
mqttc.disconnect()
|
||||
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "publish-qos1-test", clean_session=False)
|
||||
mqttc.on_connect = on_connect
|
||||
mqttc.on_disconnect = on_disconnect
|
||||
mqttc.on_publish = on_publish
|
||||
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,31 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
first_connection = 1
|
||||
|
||||
|
||||
def on_connect(mqttc, obj, flags, rc):
|
||||
global first_connection
|
||||
assert rc == 0, f"Connect failed ({rc})"
|
||||
if first_connection == 1:
|
||||
mqttc.publish("pub/qos2/test", "message", 2)
|
||||
first_connection = 0
|
||||
|
||||
|
||||
def on_disconnect(mqttc, obj, rc):
|
||||
if rc != 0:
|
||||
mqttc.reconnect()
|
||||
|
||||
|
||||
def on_publish(mqttc, obj, mid):
|
||||
mqttc.disconnect()
|
||||
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "publish-qos2-test", clean_session=False)
|
||||
mqttc.on_connect = on_connect
|
||||
mqttc.on_disconnect = on_disconnect
|
||||
mqttc.on_publish = on_publish
|
||||
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,39 @@
|
||||
import logging
|
||||
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
|
||||
def expected_payload(i: int) -> bytes:
|
||||
return f"message{i}".encode()
|
||||
|
||||
|
||||
def on_message(mqttc, obj, msg):
|
||||
assert msg.mid == 123, f"Invalid mid: ({msg.mid})"
|
||||
assert msg.topic == "pub/qos1/receive", f"Invalid topic: ({msg.topic})"
|
||||
assert msg.payload == expected_payload, f"Invalid payload: ({msg.payload})"
|
||||
assert msg.qos == 1, f"Invalid qos: ({msg.qos})"
|
||||
assert msg.retain is not False, f"Invalid retain: ({msg.retain})"
|
||||
|
||||
|
||||
def on_connect(mqttc, obj, flags, rc):
|
||||
assert rc == 0, f"Connect failed ({rc})"
|
||||
for i in range(12):
|
||||
mqttc.publish("topic", expected_payload(i), qos=1)
|
||||
|
||||
def on_disconnect(mqttc, rc, properties):
|
||||
logging.info("disconnected")
|
||||
mqttc.reconnect()
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
logging.info(str(mqtt))
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "publish-qos1-test")
|
||||
mqttc.max_inflight_messages_set(10)
|
||||
mqttc.on_connect = on_connect
|
||||
mqttc.on_disconnect = on_disconnect
|
||||
mqttc.on_message = on_message
|
||||
mqttc.enable_logger()
|
||||
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,15 @@
|
||||
import paho.mqtt.client
|
||||
import paho.mqtt.publish
|
||||
|
||||
from tests.paho_test import get_test_server_port, wait_for_keyboard_interrupt
|
||||
|
||||
with wait_for_keyboard_interrupt():
|
||||
paho.mqtt.publish.single(
|
||||
"pub/qos0/test",
|
||||
"message",
|
||||
qos=0,
|
||||
hostname="localhost",
|
||||
port=get_test_server_port(),
|
||||
client_id="publish-helper-qos0-test",
|
||||
protocol=paho.mqtt.client.MQTTv5,
|
||||
)
|
||||
@@ -0,0 +1,13 @@
|
||||
import paho.mqtt.publish
|
||||
|
||||
from tests.paho_test import get_test_server_port, wait_for_keyboard_interrupt
|
||||
|
||||
with wait_for_keyboard_interrupt():
|
||||
paho.mqtt.publish.single(
|
||||
"pub/qos0/test",
|
||||
"message",
|
||||
qos=0,
|
||||
hostname="localhost",
|
||||
port=get_test_server_port(),
|
||||
client_id="publish-helper-qos0-test",
|
||||
)
|
||||
@@ -0,0 +1,13 @@
|
||||
import paho.mqtt.publish
|
||||
|
||||
from tests.paho_test import get_test_server_port, wait_for_keyboard_interrupt
|
||||
|
||||
with wait_for_keyboard_interrupt():
|
||||
paho.mqtt.publish.single(
|
||||
"pub/qos1/test",
|
||||
"message",
|
||||
qos=1,
|
||||
hostname="localhost",
|
||||
port=get_test_server_port(),
|
||||
client_id="publish-helper-qos1-disconnect-test",
|
||||
)
|
||||
@@ -0,0 +1,24 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
sent_mid = -1
|
||||
|
||||
|
||||
def on_connect(mqttc, obj, flags, rc):
|
||||
global sent_mid
|
||||
assert rc == 0, f"Connect failed ({rc})"
|
||||
(res, sent_mid) = mqttc.publish("pub/qos0/no-payload/test")
|
||||
|
||||
|
||||
def on_publish(mqttc, obj, mid):
|
||||
if sent_mid == mid:
|
||||
mqttc.disconnect()
|
||||
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "publish-qos0-test-np", clean_session=True)
|
||||
mqttc.on_connect = on_connect
|
||||
mqttc.on_publish = on_publish
|
||||
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,26 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
sent_mid = -1
|
||||
|
||||
|
||||
def on_connect(mqttc, obj, flags, rc):
|
||||
global sent_mid
|
||||
assert rc == 0, f"Connect failed ({rc})"
|
||||
res = mqttc.publish("pub/qos0/test", "message")
|
||||
sent_mid = res[1]
|
||||
|
||||
|
||||
def on_publish(mqttc, obj, mid):
|
||||
global sent_mid, run
|
||||
if sent_mid == mid:
|
||||
mqttc.disconnect()
|
||||
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "publish-qos0-test", clean_session=True)
|
||||
mqttc.on_connect = on_connect
|
||||
mqttc.on_publish = on_publish
|
||||
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,15 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
|
||||
def on_connect(mqttc, obj, flags, rc):
|
||||
assert rc == 0, f"Connect failed ({rc})"
|
||||
mqttc.publish("retain/qos0/test", "retained message", 0, True)
|
||||
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "retain-qos0-test", clean_session=True)
|
||||
mqttc.on_connect = on_connect
|
||||
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,23 @@
|
||||
import os
|
||||
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
|
||||
def on_connect(mqttc, obj, flags, rc):
|
||||
assert rc == 0, f"Connect failed ({rc})"
|
||||
mqttc.disconnect()
|
||||
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "08-ssl-connect-alpn", clean_session=True)
|
||||
mqttc.tls_set(
|
||||
os.path.join(os.environ["PAHO_SSL_PATH"], "all-ca.crt"),
|
||||
os.path.join(os.environ["PAHO_SSL_PATH"], "client.crt"),
|
||||
os.path.join(os.environ["PAHO_SSL_PATH"], "client.key"),
|
||||
alpn_protocols=["paho-test-protocol"],
|
||||
)
|
||||
mqttc.on_connect = on_connect
|
||||
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,23 @@
|
||||
import os
|
||||
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
|
||||
def on_connect(mqttc, obj, flags, rc):
|
||||
assert rc == 0, f"Connect failed ({rc})"
|
||||
mqttc.disconnect()
|
||||
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "08-ssl-connect-crt-auth-pw")
|
||||
mqttc.tls_set(
|
||||
os.path.join(os.environ["PAHO_SSL_PATH"], "all-ca.crt"),
|
||||
os.path.join(os.environ["PAHO_SSL_PATH"], "client-pw.crt"),
|
||||
os.path.join(os.environ["PAHO_SSL_PATH"], "client-pw.key"),
|
||||
keyfile_password="password",
|
||||
)
|
||||
mqttc.on_connect = on_connect
|
||||
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,22 @@
|
||||
import os
|
||||
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
|
||||
def on_connect(mqttc, obj, flags, rc):
|
||||
assert rc == 0, f"Connect failed ({rc})"
|
||||
mqttc.disconnect()
|
||||
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "08-ssl-connect-crt-auth")
|
||||
mqttc.tls_set(
|
||||
os.path.join(os.environ["PAHO_SSL_PATH"], "all-ca.crt"),
|
||||
os.path.join(os.environ["PAHO_SSL_PATH"], "client.crt"),
|
||||
os.path.join(os.environ["PAHO_SSL_PATH"], "client.key"),
|
||||
)
|
||||
mqttc.on_connect = on_connect
|
||||
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,18 @@
|
||||
import os
|
||||
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, loop_until_keyboard_interrupt
|
||||
|
||||
|
||||
def on_connect(mqttc, obj, flags, rc):
|
||||
assert rc == 0, f"Connect failed ({rc})"
|
||||
mqttc.disconnect()
|
||||
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "08-ssl-connect-no-auth")
|
||||
mqttc.tls_set(os.path.join(os.environ["PAHO_SSL_PATH"], "all-ca.crt"))
|
||||
mqttc.on_connect = on_connect
|
||||
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
loop_until_keyboard_interrupt(mqttc)
|
||||
@@ -0,0 +1,27 @@
|
||||
import os
|
||||
import ssl
|
||||
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tests.paho_test import get_test_server_port, wait_for_keyboard_interrupt
|
||||
|
||||
|
||||
def on_connect(mqttc, obj, flags, rc):
|
||||
raise RuntimeError("Connection should have failed!")
|
||||
|
||||
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "08-ssl-fake-cacert")
|
||||
mqttc.tls_set(
|
||||
os.path.join(os.environ["PAHO_SSL_PATH"], "test-fake-root-ca.crt"),
|
||||
os.path.join(os.environ["PAHO_SSL_PATH"], "client.crt"),
|
||||
os.path.join(os.environ["PAHO_SSL_PATH"], "client.key"),
|
||||
)
|
||||
mqttc.on_connect = on_connect
|
||||
|
||||
with wait_for_keyboard_interrupt():
|
||||
try:
|
||||
mqttc.connect("localhost", get_test_server_port())
|
||||
except ssl.SSLError as msg:
|
||||
assert msg.errno == 1 and "certificate verify failed" in msg.strerror
|
||||
else:
|
||||
raise Exception("Expected SSLError")
|
||||
@@ -0,0 +1,80 @@
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
from tests.consts import ssl_path, tests_path
|
||||
from tests.paho_test import create_server_socket, create_server_socket_ssl, ssl
|
||||
|
||||
clients_path = tests_path / "lib" / "clients"
|
||||
|
||||
|
||||
def _yield_server(monkeypatch, sockport):
|
||||
sock, port = sockport
|
||||
monkeypatch.setenv("PAHO_SERVER_PORT", str(port))
|
||||
try:
|
||||
yield sock
|
||||
finally:
|
||||
sock.close()
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def server_socket(monkeypatch):
|
||||
yield from _yield_server(monkeypatch, create_server_socket())
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def ssl_server_socket(monkeypatch):
|
||||
if ssl is None:
|
||||
pytest.skip("no ssl module")
|
||||
yield from _yield_server(monkeypatch, create_server_socket_ssl())
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def alpn_ssl_server_socket(monkeypatch):
|
||||
if ssl is None:
|
||||
pytest.skip("no ssl module")
|
||||
if not getattr(ssl, "HAS_ALPN", False):
|
||||
pytest.skip("ALPN not supported in this version of Python")
|
||||
yield from _yield_server(monkeypatch, create_server_socket_ssl(alpn_protocols=["paho-test-protocol"]))
|
||||
|
||||
|
||||
def stop_process(proc: subprocess.Popen) -> None:
|
||||
if sys.platform == "win32":
|
||||
proc.send_signal(signal.CTRL_C_EVENT)
|
||||
else:
|
||||
proc.send_signal(signal.SIGINT)
|
||||
try:
|
||||
proc.wait(5)
|
||||
except subprocess.TimeoutExpired:
|
||||
proc.terminate()
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def start_client(request: pytest.FixtureRequest):
|
||||
def starter(name: str, expected_returncode: int = 0) -> None:
|
||||
client_path = clients_path / name
|
||||
if not client_path.exists():
|
||||
raise FileNotFoundError(client_path)
|
||||
env = dict(
|
||||
os.environ,
|
||||
PAHO_SSL_PATH=str(ssl_path),
|
||||
PYTHONPATH=f"{tests_path}{os.pathsep}{os.environ.get('PYTHONPATH', '')}",
|
||||
)
|
||||
assert 'PAHO_SERVER_PORT' in env, "PAHO_SERVER_PORT must be set in the environment when starting a client"
|
||||
proc = subprocess.Popen([ # noqa: S603
|
||||
sys.executable,
|
||||
str(client_path),
|
||||
], env=env)
|
||||
|
||||
def fin():
|
||||
stop_process(proc)
|
||||
if proc.returncode != expected_returncode:
|
||||
raise RuntimeError(f"Client {name} exited with code {proc.returncode}, expected {expected_returncode}")
|
||||
|
||||
request.addfinalizer(fin)
|
||||
return proc
|
||||
|
||||
return starter
|
||||
@@ -0,0 +1,45 @@
|
||||
# Test whether asyncio works
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect("asyncio-test", keepalive=60)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
|
||||
subscribe_packet = paho_test.gen_subscribe(mid=1, topic="sub-test", qos=1)
|
||||
suback_packet = paho_test.gen_suback(mid=1, qos=1)
|
||||
|
||||
unsubscribe_packet = paho_test.gen_unsubscribe(mid=2, topic="unsub-test")
|
||||
unsuback_packet = paho_test.gen_unsuback(mid=2)
|
||||
|
||||
publish_packet = paho_test.gen_publish("b2c", qos=0, payload="msg")
|
||||
|
||||
publish_packet_in = paho_test.gen_publish("asyncio", qos=1, mid=3, payload="message")
|
||||
puback_packet_in = paho_test.gen_puback(mid=3)
|
||||
|
||||
disconnect_packet = paho_test.gen_disconnect()
|
||||
|
||||
|
||||
def test_01_asyncio(server_socket, start_client):
|
||||
proc = start_client("01-asyncio.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "subscribe", subscribe_packet)
|
||||
conn.send(suback_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "unsubscribe", unsubscribe_packet)
|
||||
conn.send(unsuback_packet)
|
||||
conn.send(publish_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "publish", publish_packet_in)
|
||||
conn.send(puback_packet_in)
|
||||
|
||||
paho_test.expect_packet(conn, "disconnect", disconnect_packet)
|
||||
|
||||
conn.close()
|
||||
assert proc.wait() == 0
|
||||
@@ -0,0 +1,44 @@
|
||||
# Test whether callback decorators work
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect("decorators-test", keepalive=60)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
|
||||
subscribe_packet = paho_test.gen_subscribe(mid=1, topic="sub-test", qos=1)
|
||||
suback_packet = paho_test.gen_suback(mid=1, qos=1)
|
||||
|
||||
unsubscribe_packet = paho_test.gen_unsubscribe(mid=2, topic="unsub-test")
|
||||
unsuback_packet = paho_test.gen_unsuback(mid=2)
|
||||
|
||||
publish_packet = paho_test.gen_publish("b2c", qos=0, payload="msg")
|
||||
|
||||
publish_packet_in = paho_test.gen_publish("decorators", qos=1, mid=3, payload="message")
|
||||
puback_packet_in = paho_test.gen_puback(mid=3)
|
||||
|
||||
disconnect_packet = paho_test.gen_disconnect()
|
||||
|
||||
|
||||
def test_01_decorators(server_socket, start_client):
|
||||
start_client("01-decorators.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "subscribe", subscribe_packet)
|
||||
conn.send(suback_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "unsubscribe", unsubscribe_packet)
|
||||
conn.send(unsuback_packet)
|
||||
conn.send(publish_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "publish", publish_packet_in)
|
||||
conn.send(puback_packet_in)
|
||||
|
||||
paho_test.expect_packet(conn, "disconnect", disconnect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,32 @@
|
||||
# Test whether a client sends a pingreq after the keepalive time
|
||||
|
||||
# The client should connect with keepalive=4, clean session set,
|
||||
# and client id 01-keepalive-pingreq
|
||||
# The client should send a PINGREQ message after the appropriate amount of time
|
||||
# (4 seconds after no traffic).
|
||||
|
||||
import time
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect("01-keepalive-pingreq", keepalive=4)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
|
||||
pingreq_packet = paho_test.gen_pingreq()
|
||||
pingresp_packet = paho_test.gen_pingresp()
|
||||
|
||||
|
||||
def test_01_keepalive_pingreq(server_socket, start_client):
|
||||
start_client("01-keepalive-pingreq.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "pingreq", pingreq_packet)
|
||||
time.sleep(1.0)
|
||||
conn.send(pingresp_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "pingreq", pingreq_packet)
|
||||
@@ -0,0 +1,20 @@
|
||||
# Test whether a client produces a correct connect with clean session not set.
|
||||
|
||||
# The client should connect with keepalive=60, clean session not
|
||||
# set, and client id 01-no-clean-session.
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect("01-no-clean-session", clean_session=False, keepalive=60)
|
||||
|
||||
|
||||
def test_01_no_clean_session(server_socket, start_client):
|
||||
start_client("01-no-clean-session.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,31 @@
|
||||
# Test the reconnect_on_failure = False mode
|
||||
import pytest
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect("01-reconnect-on-failure", keepalive=60)
|
||||
connack_packet_ok = paho_test.gen_connack(rc=0)
|
||||
connack_packet_failure = paho_test.gen_connack(rc=1) # CONNACK_REFUSED_PROTOCOL_VERSION
|
||||
|
||||
publish_packet = paho_test.gen_publish(
|
||||
"reconnect/test", qos=0, payload="message")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("ok_code", [False, True])
|
||||
def test_01_reconnect_on_failure(server_socket, start_client, ok_code):
|
||||
client = start_client("01-reconnect-on-failure.py", expected_returncode=42)
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
if ok_code:
|
||||
conn.send(connack_packet_ok)
|
||||
# Connection is a success, so we expect a publish
|
||||
paho_test.expect_packet(conn, "publish", publish_packet)
|
||||
else:
|
||||
conn.send(connack_packet_failure)
|
||||
conn.close()
|
||||
# Expect the client to quit here due to socket being closed
|
||||
client.wait(1)
|
||||
assert client.returncode == 42
|
||||
@@ -0,0 +1,21 @@
|
||||
# Test whether a client produces a correct connect with a username and password.
|
||||
|
||||
# The client should connect with keepalive=60, clean session set,
|
||||
# client id 01-unpwd-set, username set to uname and password set to empty string
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect(
|
||||
"01-unpwd-set", keepalive=60, username="uname", password="")
|
||||
|
||||
|
||||
def test_01_unpwd_empty_password_set(server_socket, start_client):
|
||||
start_client("01-unpwd-empty-password-set.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,21 @@
|
||||
# Test whether a client produces a correct connect with a username and password.
|
||||
|
||||
# The client should connect with keepalive=60, clean session set,
|
||||
# client id 01-unpwd-set, username and password set to empty string.
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect(
|
||||
"01-unpwd-set", keepalive=60, username="", password='')
|
||||
|
||||
|
||||
def test_01_unpwd_empty_set(server_socket, start_client):
|
||||
start_client("01-unpwd-empty-set.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,21 @@
|
||||
# Test whether a client produces a correct connect with a username and password.
|
||||
|
||||
# The client should connect with keepalive=60, clean session set,
|
||||
# client id 01-unpwd-set, username set to uname and password set to ;'[08gn=#
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect(
|
||||
"01-unpwd-set", keepalive=60, username="uname", password=";'[08gn=#")
|
||||
|
||||
|
||||
def test_01_unpwd_set(server_socket, start_client):
|
||||
start_client("01-unpwd-set.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,25 @@
|
||||
# Test whether a client produces a correct connect with a unicode username and password.
|
||||
|
||||
# The client should connect with keepalive=60, clean session set,
|
||||
# client id 01-unpwd-unicode-set, username and password from corresponding variables
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect(
|
||||
"01-unpwd-unicode-set",
|
||||
keepalive=60,
|
||||
username="\u00fas\u00e9rn\u00e1m\u00e9-h\u00e9ll\u00f3",
|
||||
password="h\u00e9ll\u00f3",
|
||||
)
|
||||
|
||||
|
||||
def test_01_unpwd_unicode_set(server_socket, start_client):
|
||||
start_client("01-unpwd-unicode-set.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,21 @@
|
||||
# Test whether a client produces a correct connect with a will.
|
||||
# Will QoS=1, will retain=1.
|
||||
|
||||
# The client should connect with keepalive=60, clean session set,
|
||||
# client id 01-will-set will topic set to topic/on/unexpected/disconnect , will
|
||||
# payload set to "will message", will qos set to 1 and will retain set.
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect(
|
||||
"01-will-set", keepalive=60, will_topic="topic/on/unexpected/disconnect",
|
||||
will_qos=1, will_retain=True, will_payload="will message")
|
||||
|
||||
|
||||
def test_01_will_set(server_socket, start_client):
|
||||
start_client("01-will-set.py")
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.close()
|
||||
@@ -0,0 +1,26 @@
|
||||
# Test whether a client produces a correct connect with a will, username and password.
|
||||
|
||||
# The client should connect with keepalive=60, clean session set,
|
||||
# client id 01-will-unpwd-set , will topic set to "will-topic", will payload
|
||||
# set to "will message", will qos=2, will retain not set, username set to
|
||||
# "oibvvwqw" and password set to "#'^2hg9a&nm38*us".
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect(
|
||||
"01-will-unpwd-set",
|
||||
keepalive=60, username="oibvvwqw", password="#'^2hg9a&nm38*us",
|
||||
will_topic="will-topic", will_qos=2, will_payload="will message",
|
||||
)
|
||||
|
||||
|
||||
def test_01_will_unpwd_set(server_socket, start_client):
|
||||
start_client("01-will-unpwd-set.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,23 @@
|
||||
# Test whether a client connects correctly with a zero length clientid.
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect("", keepalive=60, proto_ver=4)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
|
||||
disconnect_packet = paho_test.gen_disconnect()
|
||||
|
||||
|
||||
def test_01_zero_length_clientid(server_socket, start_client):
|
||||
start_client("01-zero-length-clientid.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "disconnect", disconnect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,40 @@
|
||||
# Test whether a client sends a correct SUBSCRIBE to a topic with QoS 0.
|
||||
|
||||
# The client should connect with keepalive=60, clean session set,
|
||||
# and client id subscribe-qos0-test
|
||||
# The test will send a CONNACK message to the client with rc=0. Upon receiving
|
||||
# the CONNACK and verifying that rc=0, the client should send a SUBSCRIBE
|
||||
# message to subscribe to topic "qos0/test" with QoS=0. If rc!=0, the client
|
||||
# should exit with an error.
|
||||
# Upon receiving the correct SUBSCRIBE message, the test will reply with a
|
||||
# SUBACK message with the accepted QoS set to 0. On receiving the SUBACK
|
||||
# message, the client should send a DISCONNECT message.
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect("subscribe-qos0-test", keepalive=60)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
|
||||
disconnect_packet = paho_test.gen_disconnect()
|
||||
|
||||
mid = 1
|
||||
subscribe_packet = paho_test.gen_subscribe(mid, "qos0/test", 0)
|
||||
suback_packet = paho_test.gen_suback(mid, 0)
|
||||
|
||||
|
||||
def test_02_subscribe_qos0(server_socket, start_client):
|
||||
start_client("02-subscribe-qos0.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "subscribe", subscribe_packet)
|
||||
conn.send(suback_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "disconnect", disconnect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,40 @@
|
||||
# Test whether a client sends a correct SUBSCRIBE to a topic with QoS 1.
|
||||
|
||||
# The client should connect with keepalive=60, clean session set,
|
||||
# and client id subscribe-qos1-test
|
||||
# The test will send a CONNACK message to the client with rc=0. Upon receiving
|
||||
# the CONNACK and verifying that rc=0, the client should send a SUBSCRIBE
|
||||
# message to subscribe to topic "qos1/test" with QoS=1. If rc!=0, the client
|
||||
# should exit with an error.
|
||||
# Upon receiving the correct SUBSCRIBE message, the test will reply with a
|
||||
# SUBACK message with the accepted QoS set to 1. On receiving the SUBACK
|
||||
# message, the client should send a DISCONNECT message.
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect("subscribe-qos1-test", keepalive=60)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
|
||||
disconnect_packet = paho_test.gen_disconnect()
|
||||
|
||||
mid = 1
|
||||
subscribe_packet = paho_test.gen_subscribe(mid, "qos1/test", 1)
|
||||
suback_packet = paho_test.gen_suback(mid, 1)
|
||||
|
||||
|
||||
def test_02_subscribe_qos1(server_socket, start_client):
|
||||
start_client("02-subscribe-qos1.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "subscribe", subscribe_packet)
|
||||
conn.send(suback_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "disconnect", disconnect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,40 @@
|
||||
# Test whether a client sends a correct SUBSCRIBE to a topic with QoS 2.
|
||||
|
||||
# The client should connect with keepalive=60, clean session set,
|
||||
# and client id subscribe-qos2-test
|
||||
# The test will send a CONNACK message to the client with rc=0. Upon receiving
|
||||
# the CONNACK and verifying that rc=0, the client should send a SUBSCRIBE
|
||||
# message to subscribe to topic "qos2/test" with QoS=2. If rc!=0, the client
|
||||
# should exit with an error.
|
||||
# Upon receiving the correct SUBSCRIBE message, the test will reply with a
|
||||
# SUBACK message with the accepted QoS set to 2. On receiving the SUBACK
|
||||
# message, the client should send a DISCONNECT message.
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect("subscribe-qos2-test", keepalive=60)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
|
||||
disconnect_packet = paho_test.gen_disconnect()
|
||||
|
||||
mid = 1
|
||||
subscribe_packet = paho_test.gen_subscribe(mid, "qos2/test", 2)
|
||||
suback_packet = paho_test.gen_suback(mid, 2)
|
||||
|
||||
|
||||
def test_02_subscribe_qos2(server_socket, start_client):
|
||||
start_client("02-subscribe-qos2.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "subscribe", subscribe_packet)
|
||||
conn.send(suback_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "disconnect", disconnect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,30 @@
|
||||
# Test whether a client sends a correct UNSUBSCRIBE packet.
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect("unsubscribe-test", keepalive=60)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
|
||||
disconnect_packet = paho_test.gen_disconnect()
|
||||
|
||||
mid = 1
|
||||
unsubscribe_packet = paho_test.gen_unsubscribe(mid, "unsubscribe/test")
|
||||
unsuback_packet = paho_test.gen_unsuback(mid)
|
||||
|
||||
|
||||
def test_02_unsubscribe(server_socket, start_client):
|
||||
start_client("02-unsubscribe.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "unsubscribe", unsubscribe_packet)
|
||||
conn.send(unsuback_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "disconnect", disconnect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,36 @@
|
||||
# Test whether a client responds correctly to a PUBLISH with QoS 1.
|
||||
|
||||
# The client should connect with keepalive=60, clean session set,
|
||||
# and client id publish-qos1-test
|
||||
# The test will send a CONNACK message to the client with rc=0. Upon receiving
|
||||
# the CONNACK the client should verify that rc==0.
|
||||
# The test will send the client a PUBLISH message with topic
|
||||
# "pub/qos1/receive", payload of "message", QoS=1 and mid=123. The client
|
||||
# should handle this as per the spec by sending a PUBACK message.
|
||||
# The client should then exit with return code==0.
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect("publish-qos1-test", keepalive=60)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
|
||||
disconnect_packet = paho_test.gen_disconnect()
|
||||
|
||||
mid = 123
|
||||
publish_packet = paho_test.gen_publish(
|
||||
"pub/qos1/receive", qos=1, mid=mid, payload="message")
|
||||
puback_packet = paho_test.gen_puback(mid)
|
||||
|
||||
|
||||
def test_03_publish_b2c_qos1(server_socket, start_client):
|
||||
start_client("03-publish-b2c-qos1.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
conn.send(publish_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "puback", puback_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,41 @@
|
||||
# Test whether a client responds correctly to a PUBLISH with QoS 1.
|
||||
|
||||
# The client should connect with keepalive=60, clean session set,
|
||||
# and client id publish-qos1-test
|
||||
# The test will send a CONNACK message to the client with rc=0. Upon receiving
|
||||
# the CONNACK the client should verify that rc==0.
|
||||
# The test will send the client a PUBLISH message with topic
|
||||
# "pub/qos1/receive", payload of "message", QoS=1 and mid=123. The client
|
||||
# should handle this as per the spec by sending a PUBACK message.
|
||||
# The client should then exit with return code==0.
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect("publish-qos2-test", keepalive=60)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
|
||||
disconnect_packet = paho_test.gen_disconnect()
|
||||
|
||||
mid = 13423
|
||||
publish_packet = paho_test.gen_publish(
|
||||
"pub/qos2/receive", qos=2, mid=mid, payload="message")
|
||||
pubrec_packet = paho_test.gen_pubrec(mid=mid)
|
||||
pubrel_packet = paho_test.gen_pubrel(mid=mid)
|
||||
pubcomp_packet = paho_test.gen_pubcomp(mid)
|
||||
|
||||
|
||||
def test_03_publish_b2c_qos2(server_socket, start_client):
|
||||
start_client("03-publish-b2c-qos2.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
conn.send(publish_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "pubrec", pubrec_packet)
|
||||
conn.send(pubrel_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "pubcomp", pubcomp_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,45 @@
|
||||
# Test whether a client sends a correct PUBLISH to a topic with QoS 1, then responds correctly to a disconnect.
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect(
|
||||
"publish-qos1-test", keepalive=60, clean_session=False,
|
||||
)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
|
||||
disconnect_packet = paho_test.gen_disconnect()
|
||||
|
||||
mid = 1
|
||||
publish_packet = paho_test.gen_publish(
|
||||
"pub/qos1/test", qos=1, mid=mid, payload="message")
|
||||
publish_packet_dup = paho_test.gen_publish(
|
||||
"pub/qos1/test", qos=1, mid=mid, payload="message", dup=True)
|
||||
puback_packet = paho_test.gen_puback(mid)
|
||||
|
||||
|
||||
def test_03_publish_c2b_qos1_disconnect(server_socket, start_client):
|
||||
start_client("03-publish-c2b-qos1-disconnect.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(15)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "publish", publish_packet)
|
||||
# Disconnect client. It should reconnect.
|
||||
conn.close()
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(15)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "retried publish", publish_packet_dup)
|
||||
conn.send(puback_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "disconnect", disconnect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,61 @@
|
||||
# Test whether a client sends a correct PUBLISH to a topic with QoS 2 and responds to a disconnect.
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect(
|
||||
"publish-qos2-test", keepalive=60, clean_session=False,
|
||||
)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
|
||||
disconnect_packet = paho_test.gen_disconnect()
|
||||
|
||||
mid = 1
|
||||
publish_packet = paho_test.gen_publish(
|
||||
"pub/qos2/test", qos=2, mid=mid, payload="message")
|
||||
publish_dup_packet = paho_test.gen_publish(
|
||||
"pub/qos2/test", qos=2, mid=mid, payload="message", dup=True)
|
||||
pubrec_packet = paho_test.gen_pubrec(mid)
|
||||
pubrel_packet = paho_test.gen_pubrel(mid)
|
||||
pubcomp_packet = paho_test.gen_pubcomp(mid)
|
||||
|
||||
|
||||
def test_03_publish_c2b_qos2_disconnect(server_socket, start_client):
|
||||
start_client("03-publish-c2b-qos2-disconnect.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(5)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "publish", publish_packet)
|
||||
# Disconnect client. It should reconnect.
|
||||
conn.close()
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(15)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "retried publish", publish_dup_packet)
|
||||
conn.send(pubrec_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "pubrel", pubrel_packet)
|
||||
# Disconnect client. It should reconnect.
|
||||
conn.close()
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(15)
|
||||
|
||||
# Complete connection and message flow.
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "retried pubrel", pubrel_packet)
|
||||
conn.send(pubcomp_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "disconnect", disconnect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,90 @@
|
||||
# Test whether a client responds to max-inflight and reconnect when max-inflight is reached
|
||||
|
||||
# The client should connect with keepalive=60, clean session set,
|
||||
# and client id publish-fill-inflight
|
||||
# The test will send a CONNACK message to the client with rc=0. Upon receiving
|
||||
# the CONNACK the client should verify that rc==0.
|
||||
# Then client should send 10 PUBLISH with QoS == 1. On client side 12 message will be
|
||||
# submitted, so 2 will be queued.
|
||||
# The test will wait 0.5 seconds after received the 10 PUBLISH. After this wait, it will
|
||||
# disconnect the client.
|
||||
# The client should re-connect and re-sent the first 10 messages.
|
||||
# The test will PUBACK one message, it should receive another PUBLISH.
|
||||
# The test will wait 0.5 seconds and expect no PUBLISH.
|
||||
# The test will then PUBACK all message.
|
||||
# The client should disconnect once everything is acked.
|
||||
|
||||
import pytest
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
|
||||
def expected_payload(i: int) -> bytes:
|
||||
return f"message{i}"
|
||||
|
||||
connect_packet = paho_test.gen_connect("publish-qos1-test", keepalive=60)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
|
||||
disconnect_packet = paho_test.gen_disconnect()
|
||||
|
||||
first_connection_publishs = [
|
||||
paho_test.gen_publish(
|
||||
"topic", qos=1, mid=i+1, payload=expected_payload(i),
|
||||
)
|
||||
for i in range(10)
|
||||
]
|
||||
second_connection_publishs = [
|
||||
paho_test.gen_publish(
|
||||
# I'm not sure we should have the mid+13.
|
||||
# Currently on reconnection client will do two wrong thing:
|
||||
# * it sent more than max_inflight packet
|
||||
# * it re-send message both with mid = old_mid + 12 AND with mid = old_mid & dup=1
|
||||
"topic", qos=1, mid=i+13, payload=expected_payload(i),
|
||||
)
|
||||
for i in range(12)
|
||||
]
|
||||
second_connection_pubacks = [
|
||||
paho_test.gen_puback(i+13)
|
||||
for i in range(12)
|
||||
]
|
||||
|
||||
@pytest.mark.xfail
|
||||
def test_03_publish_fill_inflight(server_socket, start_client):
|
||||
start_client("03-publish-fill-inflight.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
for packet in first_connection_publishs:
|
||||
paho_test.expect_packet(conn, "publish", packet)
|
||||
|
||||
paho_test.expect_no_packet(conn, 0.5)
|
||||
|
||||
conn.close()
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
for packet in second_connection_publishs[:10]:
|
||||
paho_test.expect_packet(conn, "publish", packet)
|
||||
|
||||
paho_test.expect_no_packet(conn, 0.2)
|
||||
|
||||
conn.send(second_connection_pubacks[0])
|
||||
paho_test.expect_packet(conn, "publish", second_connection_publishs[10])
|
||||
|
||||
paho_test.expect_no_packet(conn, 0.5)
|
||||
|
||||
for packet in second_connection_pubacks[1:11]:
|
||||
conn.send(packet)
|
||||
|
||||
paho_test.expect_packet(conn, "publish", second_connection_publishs[11])
|
||||
|
||||
paho_test.expect_no_packet(conn, 0.5)
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# Test whether a client sends a correct PUBLISH to a topic with QoS 0.
|
||||
# Use paho.mqtt.publish helper for that.
|
||||
|
||||
# The client should connect with keepalive=60, clean session set,
|
||||
# and client id publish-helper-qos0-test
|
||||
# The test will send a CONNACK message to the client with rc=0. Upon receiving
|
||||
# the CONNACK and verifying that rc=0, the client should send a PUBLISH message
|
||||
# to topic "pub/qos0/test" with payload "message" and QoS=0. If rc!=0, the
|
||||
# client should exit with an error.
|
||||
# After sending the PUBLISH message, the client should send a
|
||||
# DISCONNECT message.
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect(
|
||||
"publish-helper-qos0-test", keepalive=60,
|
||||
)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
|
||||
publish_packet = paho_test.gen_publish(
|
||||
"pub/qos0/test", qos=0, payload="message"
|
||||
)
|
||||
|
||||
disconnect_packet = paho_test.gen_disconnect()
|
||||
|
||||
|
||||
def test_03_publish_helper_qos0(server_socket, start_client):
|
||||
start_client("03-publish-helper-qos0.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "publish", publish_packet)
|
||||
paho_test.expect_packet(conn, "disconnect", disconnect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,40 @@
|
||||
# Test whether a client sends a correct PUBLISH to a topic with QoS 0.
|
||||
# Use paho.mqtt.publish helper for that.
|
||||
|
||||
# The client should connect with keepalive=60, clean session set,
|
||||
# and client id publish-helper-qos0-test
|
||||
# The test will send a CONNACK message to the client with rc=0. Upon receiving
|
||||
# the CONNACK and verifying that rc=0, the client should send a PUBLISH message
|
||||
# to topic "pub/qos0/test" with payload "message" and QoS=0. If rc!=0, the
|
||||
# client should exit with an error.
|
||||
# After sending the PUBLISH message, the client should send a
|
||||
# DISCONNECT message.
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect(
|
||||
"publish-helper-qos0-test", keepalive=60, proto_ver=5, properties=None
|
||||
)
|
||||
connack_packet = paho_test.gen_connack(rc=0, proto_ver=5)
|
||||
|
||||
publish_packet = paho_test.gen_publish(
|
||||
"pub/qos0/test", qos=0, payload="message", proto_ver=5
|
||||
)
|
||||
|
||||
disconnect_packet = paho_test.gen_disconnect()
|
||||
|
||||
|
||||
def test_03_publish_helper_qos0_v5(server_socket, start_client):
|
||||
start_client("03-publish-helper-qos0-v5.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "publish", publish_packet)
|
||||
paho_test.expect_packet(conn, "disconnect", disconnect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,50 @@
|
||||
# Test whether a client sends a correct PUBLISH to a topic with QoS 1,
|
||||
# then responds correctly to a disconnect.
|
||||
# Use paho.mqtt.publish helper for that.
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect(
|
||||
"publish-helper-qos1-disconnect-test", keepalive=60,
|
||||
)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
|
||||
mid = 1
|
||||
publish_packet = paho_test.gen_publish(
|
||||
"pub/qos1/test", qos=1, mid=mid, payload="message"
|
||||
)
|
||||
publish_packet_dup = paho_test.gen_publish(
|
||||
"pub/qos1/test", qos=1, mid=mid, payload="message",
|
||||
dup=True,
|
||||
)
|
||||
puback_packet = paho_test.gen_puback(mid)
|
||||
|
||||
disconnect_packet = paho_test.gen_disconnect()
|
||||
|
||||
|
||||
def test_03_publish_helper_qos1_disconnect(server_socket, start_client):
|
||||
start_client("03-publish-helper-qos1-disconnect.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "publish", publish_packet)
|
||||
# Disconnect client. It should reconnect.
|
||||
conn.close()
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(15)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "retried publish", publish_packet_dup)
|
||||
conn.send(puback_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "disconnect", disconnect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,33 @@
|
||||
# Test whether a client sends a correct PUBLISH to a topic with QoS 0.
|
||||
|
||||
# The client should connect with keepalive=60, clean session set,
|
||||
# and client id publish-qos0-test
|
||||
# The test will send a CONNACK message to the client with rc=0. Upon receiving
|
||||
# the CONNACK and verifying that rc=0, the client should send a PUBLISH message
|
||||
# to topic "pub/qos0/test" with payload "message" and QoS=0. If rc!=0, the
|
||||
# client should exit with an error.
|
||||
# After sending the PUBLISH message, the client should send a DISCONNECT message.
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect("publish-qos0-test", keepalive=60)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
|
||||
publish_packet = paho_test.gen_publish("pub/qos0/test", qos=0, payload="message")
|
||||
|
||||
disconnect_packet = paho_test.gen_disconnect()
|
||||
|
||||
|
||||
def test_03_publish_qos0(server_socket, start_client):
|
||||
start_client("03-publish-qos0.py")
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "publish", publish_packet)
|
||||
paho_test.expect_packet(conn, "disconnect", disconnect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,34 @@
|
||||
# Test whether a client sends a correct PUBLISH to a topic with QoS 0 and no payload.
|
||||
|
||||
# The client should connect with keepalive=60, clean session set,
|
||||
# and client id publish-qos0-test-np
|
||||
# The test will send a CONNACK message to the client with rc=0. Upon receiving
|
||||
# the CONNACK and verifying that rc=0, the client should send a PUBLISH message
|
||||
# to topic "pub/qos0/no-payload/test" with zero length payload and QoS=0. If
|
||||
# rc!=0, the client should exit with an error.
|
||||
# After sending the PUBLISH message, the client should send a DISCONNECT message.
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect("publish-qos0-test-np", keepalive=60)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
|
||||
publish_packet = paho_test.gen_publish("pub/qos0/no-payload/test", qos=0)
|
||||
|
||||
disconnect_packet = paho_test.gen_disconnect()
|
||||
|
||||
|
||||
def test_03_publish_qos0_no_payload(server_socket, start_client):
|
||||
start_client("03-publish-qos0-no-payload.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "publish", publish_packet)
|
||||
paho_test.expect_packet(conn, "disconnect", disconnect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,25 @@
|
||||
# Test whether a client sends a correct retained PUBLISH to a topic with QoS 0.
|
||||
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
mid = 16
|
||||
connect_packet = paho_test.gen_connect("retain-qos0-test", keepalive=60)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
|
||||
publish_packet = paho_test.gen_publish(
|
||||
"retain/qos0/test", qos=0, payload="retained message", retain=True)
|
||||
|
||||
|
||||
def test_04_retain_qos0(server_socket, start_client):
|
||||
start_client("04-retain-qos0.py")
|
||||
|
||||
(conn, address) = server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "publish", publish_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,8 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
import pytest
|
||||
|
||||
|
||||
def test_08_ssl_bad_cacert():
|
||||
with pytest.raises(IOError):
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, "08-ssl-bad-cacert")
|
||||
mqttc.tls_set("this/file/doesnt/exist")
|
||||
@@ -0,0 +1,38 @@
|
||||
# Test whether a client produces a correct connect and subsequent disconnect when using SSL.
|
||||
# Client must provide a certificate.
|
||||
#
|
||||
# The client should connect with keepalive=60, clean session set,
|
||||
# and client id 08-ssl-connect-alpn
|
||||
# It should use the CA certificate ssl/all-ca.crt for verifying the server.
|
||||
# The test will send a CONNACK message to the client with rc=0. Upon receiving
|
||||
# the CONNACK and verifying that rc=0, the client should send a DISCONNECT
|
||||
# message. If rc!=0, the client should exit with an error.
|
||||
#
|
||||
# Additionally, the secure socket must have been negotiated with the "paho-test-protocol"
|
||||
|
||||
|
||||
from tests import paho_test
|
||||
from tests.paho_test import ssl
|
||||
|
||||
|
||||
def test_08_ssl_connect_alpn(alpn_ssl_server_socket, start_client):
|
||||
connect_packet = paho_test.gen_connect("08-ssl-connect-alpn", keepalive=60)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
disconnect_packet = paho_test.gen_disconnect()
|
||||
|
||||
start_client("08-ssl-connect-alpn.py")
|
||||
|
||||
(conn, address) = alpn_ssl_server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "disconnect", disconnect_packet)
|
||||
|
||||
if ssl.HAS_ALPN:
|
||||
negotiated_protocol = conn.selected_alpn_protocol()
|
||||
if negotiated_protocol != "paho-test-protocol":
|
||||
raise Exception(f"Unexpected protocol '{negotiated_protocol}'")
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,29 @@
|
||||
# Test whether a client produces a correct connect and subsequent disconnect when using SSL.
|
||||
# Client must provide a certificate.
|
||||
#
|
||||
# The client should connect with keepalive=60, clean session set,
|
||||
# and client id 08-ssl-connect-crt-auth
|
||||
# It should use the CA certificate ssl/all-ca.crt for verifying the server.
|
||||
# The test will send a CONNACK message to the client with rc=0. Upon receiving
|
||||
# the CONNACK and verifying that rc=0, the client should send a DISCONNECT
|
||||
# message. If rc!=0, the client should exit with an error.
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect("08-ssl-connect-crt-auth", keepalive=60)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
disconnect_packet = paho_test.gen_disconnect()
|
||||
|
||||
|
||||
def test_08_ssl_connect_crt_auth(ssl_server_socket, start_client):
|
||||
start_client("08-ssl-connect-cert-auth.py")
|
||||
|
||||
(conn, address) = ssl_server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "disconnect", disconnect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,29 @@
|
||||
# Test whether a client produces a correct connect and subsequent disconnect when using SSL.
|
||||
# Client must provide a certificate - the private key is encrypted with a password.
|
||||
#
|
||||
# The client should connect with keepalive=60, clean session set,
|
||||
# and client id 08-ssl-connect-crt-auth
|
||||
# It should use the CA certificate ssl/all-ca.crt for verifying the server.
|
||||
# The test will send a CONNACK message to the client with rc=0. Upon receiving
|
||||
# the CONNACK and verifying that rc=0, the client should send a DISCONNECT
|
||||
# message. If rc!=0, the client should exit with an error.
|
||||
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect("08-ssl-connect-crt-auth-pw", keepalive=60)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
disconnect_packet = paho_test.gen_disconnect()
|
||||
|
||||
|
||||
def test_08_ssl_connect_crt_auth_pw(ssl_server_socket, start_client):
|
||||
start_client("08-ssl-connect-cert-auth-pw.py")
|
||||
|
||||
(conn, address) = ssl_server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "disconnect", disconnect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,26 @@
|
||||
# Test whether a client produces a correct connect and subsequent disconnect when using SSL.
|
||||
#
|
||||
# The client should connect with keepalive=60, clean session set,# and client id 08-ssl-connect-no-auth
|
||||
# It should use the CA certificate ssl/all-ca.crt for verifying the server.
|
||||
# The test will send a CONNACK message to the client with rc=0. Upon receiving
|
||||
# the CONNACK and verifying that rc=0, the client should send a DISCONNECT
|
||||
# message. If rc!=0, the client should exit with an error.
|
||||
import tests.paho_test as paho_test
|
||||
|
||||
connect_packet = paho_test.gen_connect("08-ssl-connect-no-auth", keepalive=60)
|
||||
connack_packet = paho_test.gen_connack(rc=0)
|
||||
disconnect_packet = paho_test.gen_disconnect()
|
||||
|
||||
|
||||
def test_08_ssl_connect_no_auth(ssl_server_socket, start_client):
|
||||
start_client("08-ssl-connect-no-auth.py")
|
||||
|
||||
(conn, address) = ssl_server_socket.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
paho_test.expect_packet(conn, "connect", connect_packet)
|
||||
conn.send(connack_packet)
|
||||
|
||||
paho_test.expect_packet(conn, "disconnect", disconnect_packet)
|
||||
|
||||
conn.close()
|
||||
@@ -0,0 +1,10 @@
|
||||
import pytest
|
||||
|
||||
from tests.paho_test import ssl
|
||||
|
||||
|
||||
def test_08_ssl_fake_cacert(ssl_server_socket, start_client):
|
||||
start_client("08-ssl-fake-cacert.py")
|
||||
with pytest.raises(ssl.SSLError):
|
||||
(conn, address) = ssl_server_socket.accept()
|
||||
conn.close()
|
||||
@@ -0,0 +1,76 @@
|
||||
import struct
|
||||
|
||||
PROP_PAYLOAD_FORMAT_INDICATOR = 1
|
||||
PROP_MESSAGE_EXPIRY_INTERVAL = 2
|
||||
PROP_CONTENT_TYPE = 3
|
||||
PROP_RESPONSE_TOPIC = 8
|
||||
PROP_CORRELATION_DATA = 9
|
||||
PROP_SUBSCRIPTION_IDENTIFIER = 11
|
||||
PROP_SESSION_EXPIRY_INTERVAL = 17
|
||||
PROP_ASSIGNED_CLIENT_IDENTIFIER = 18
|
||||
PROP_SERVER_KEEP_ALIVE = 19
|
||||
PROP_AUTHENTICATION_METHOD = 21
|
||||
PROP_AUTHENTICATION_DATA = 22
|
||||
PROP_REQUEST_PROBLEM_INFO = 23
|
||||
PROP_WILL_DELAY_INTERVAL = 24
|
||||
PROP_REQUEST_RESPONSE_INFO = 25
|
||||
PROP_RESPONSE_INFO = 26
|
||||
PROP_SERVER_REFERENCE = 28
|
||||
PROP_REASON_STRING = 31
|
||||
PROP_RECEIVE_MAXIMUM = 33
|
||||
PROP_TOPIC_ALIAS_MAXIMUM = 34
|
||||
PROP_TOPIC_ALIAS = 35
|
||||
PROP_MAXIMUM_QOS = 36
|
||||
PROP_RETAIN_AVAILABLE = 37
|
||||
PROP_USER_PROPERTY = 38
|
||||
PROP_MAXIMUM_PACKET_SIZE = 39
|
||||
PROP_WILDCARD_SUB_AVAILABLE = 40
|
||||
PROP_SUBSCRIPTION_ID_AVAILABLE = 41
|
||||
PROP_SHARED_SUB_AVAILABLE = 42
|
||||
|
||||
def gen_byte_prop(identifier, byte):
|
||||
prop = struct.pack('BB', identifier, byte)
|
||||
return prop
|
||||
|
||||
def gen_uint16_prop(identifier, word):
|
||||
prop = struct.pack('!BH', identifier, word)
|
||||
return prop
|
||||
|
||||
def gen_uint32_prop(identifier, word):
|
||||
prop = struct.pack('!BI', identifier, word)
|
||||
return prop
|
||||
|
||||
def gen_string_prop(identifier, s):
|
||||
s = s.encode("utf-8")
|
||||
prop = struct.pack(f'!BH{len(s)}s', identifier, len(s), s)
|
||||
return prop
|
||||
|
||||
def gen_string_pair_prop(identifier, s1, s2):
|
||||
s1 = s1.encode("utf-8")
|
||||
s2 = s2.encode("utf-8")
|
||||
prop = struct.pack(f'!BH{len(s1)}sH{len(s2)}s', identifier, len(s1), s1, len(s2), s2)
|
||||
return prop
|
||||
|
||||
def gen_varint_prop(identifier, val):
|
||||
v = pack_varint(val)
|
||||
return struct.pack(f"!B{len(v)}s", identifier, v)
|
||||
|
||||
def pack_varint(varint):
|
||||
s = b""
|
||||
while True:
|
||||
byte = varint % 128
|
||||
varint = varint // 128
|
||||
# If there are more digits to encode, set the top bit of this digit
|
||||
if varint > 0:
|
||||
byte = byte | 0x80
|
||||
|
||||
s = s + struct.pack("!B", byte)
|
||||
if varint == 0:
|
||||
return s
|
||||
|
||||
def prop_finalise(props):
|
||||
if props is None:
|
||||
return pack_varint(0)
|
||||
else:
|
||||
return pack_varint(len(props)) + props
|
||||
|
||||
@@ -0,0 +1,444 @@
|
||||
import contextlib
|
||||
import os
|
||||
import socket
|
||||
import struct
|
||||
import time
|
||||
|
||||
from tests.consts import ssl_path
|
||||
from tests.debug_helpers import dump_packet
|
||||
|
||||
try:
|
||||
import ssl
|
||||
except ImportError:
|
||||
ssl = None
|
||||
|
||||
from tests import mqtt5_props
|
||||
|
||||
|
||||
def bind_to_any_free_port(sock) -> int:
|
||||
"""
|
||||
Bind a socket to an available port on localhost,
|
||||
and return the port number.
|
||||
"""
|
||||
sock.bind(('localhost', 0))
|
||||
return sock.getsockname()[1]
|
||||
|
||||
|
||||
def create_server_socket():
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.settimeout(10)
|
||||
port = bind_to_any_free_port(sock)
|
||||
sock.listen(5)
|
||||
return (sock, port)
|
||||
|
||||
|
||||
def create_server_socket_ssl(*, verify_mode=None, alpn_protocols=None):
|
||||
assert ssl, "SSL not available"
|
||||
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
|
||||
context.load_verify_locations(str(ssl_path / "all-ca.crt"))
|
||||
context.load_cert_chain(
|
||||
str(ssl_path / "server.crt"),
|
||||
str(ssl_path / "server.key"),
|
||||
)
|
||||
if verify_mode:
|
||||
context.verify_mode = verify_mode
|
||||
|
||||
if alpn_protocols is not None:
|
||||
context.set_alpn_protocols(alpn_protocols)
|
||||
|
||||
ssock = context.wrap_socket(sock, server_side=True)
|
||||
ssock.settimeout(10)
|
||||
port = bind_to_any_free_port(ssock)
|
||||
ssock.listen(5)
|
||||
return (ssock, port)
|
||||
|
||||
|
||||
def expect_packet(sock, name, expected):
|
||||
rlen = len(expected) if len(expected) > 0 else 1
|
||||
|
||||
packet_recvd = b""
|
||||
try:
|
||||
while len(packet_recvd) < rlen:
|
||||
data = sock.recv(rlen-len(packet_recvd))
|
||||
if len(data) == 0:
|
||||
break
|
||||
packet_recvd += data
|
||||
except socket.timeout: # pragma: no cover
|
||||
pass
|
||||
|
||||
assert packet_matches(name, packet_recvd, expected)
|
||||
return True
|
||||
|
||||
|
||||
def expect_no_packet(sock, delay=1):
|
||||
""" expect that nothing is received within given delay
|
||||
"""
|
||||
try:
|
||||
previous_timeout = sock.gettimeout()
|
||||
sock.settimeout(delay)
|
||||
data = sock.recv(1024)
|
||||
except socket.timeout:
|
||||
data = None
|
||||
finally:
|
||||
sock.settimeout(previous_timeout)
|
||||
|
||||
if data is not None:
|
||||
dump_packet("Received unexpected", data)
|
||||
|
||||
assert data is None, "shouldn't receive any data"
|
||||
|
||||
|
||||
def packet_matches(name, recvd, expected):
|
||||
if recvd != expected: # pragma: no cover
|
||||
print(f"FAIL: Received incorrect {name}.")
|
||||
dump_packet("Received", recvd)
|
||||
dump_packet("Expected", expected)
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def gen_connect(
|
||||
client_id,
|
||||
clean_session=True,
|
||||
keepalive=60,
|
||||
username=None,
|
||||
password=None,
|
||||
will_topic=None,
|
||||
will_qos=0,
|
||||
will_retain=False,
|
||||
will_payload=b"",
|
||||
proto_ver=4,
|
||||
connect_reserved=False,
|
||||
properties=b"",
|
||||
will_properties=b"",
|
||||
session_expiry=-1,
|
||||
):
|
||||
if (proto_ver&0x7F) == 3 or proto_ver == 0:
|
||||
remaining_length = 12
|
||||
elif (proto_ver&0x7F) == 4 or proto_ver == 5:
|
||||
remaining_length = 10
|
||||
else:
|
||||
raise ValueError
|
||||
|
||||
if client_id is not None:
|
||||
client_id = client_id.encode("utf-8")
|
||||
remaining_length = remaining_length + 2+len(client_id)
|
||||
else:
|
||||
remaining_length = remaining_length + 2
|
||||
|
||||
connect_flags = 0
|
||||
|
||||
if connect_reserved:
|
||||
connect_flags = connect_flags | 0x01
|
||||
|
||||
if clean_session:
|
||||
connect_flags = connect_flags | 0x02
|
||||
|
||||
if proto_ver == 5:
|
||||
if properties == b"":
|
||||
properties += mqtt5_props.gen_uint16_prop(mqtt5_props.PROP_RECEIVE_MAXIMUM, 20)
|
||||
|
||||
if session_expiry != -1:
|
||||
properties += mqtt5_props.gen_uint32_prop(mqtt5_props.PROP_SESSION_EXPIRY_INTERVAL, session_expiry)
|
||||
|
||||
properties = mqtt5_props.prop_finalise(properties)
|
||||
remaining_length += len(properties)
|
||||
|
||||
if will_topic is not None:
|
||||
will_topic = will_topic.encode('utf-8')
|
||||
remaining_length = remaining_length + 2 + len(will_topic) + 2 + len(will_payload)
|
||||
connect_flags = connect_flags | 0x04 | ((will_qos & 0x03) << 3)
|
||||
if will_retain:
|
||||
connect_flags = connect_flags | 32
|
||||
if proto_ver == 5:
|
||||
will_properties = mqtt5_props.prop_finalise(will_properties)
|
||||
remaining_length += len(will_properties)
|
||||
|
||||
if username is not None:
|
||||
username = username.encode('utf-8')
|
||||
remaining_length = remaining_length + 2 + len(username)
|
||||
connect_flags = connect_flags | 0x80
|
||||
if password is not None:
|
||||
password = password.encode('utf-8')
|
||||
connect_flags = connect_flags | 0x40
|
||||
remaining_length = remaining_length + 2 + len(password)
|
||||
|
||||
rl = pack_remaining_length(remaining_length)
|
||||
packet = struct.pack("!B" + str(len(rl)) + "s", 0x10, rl)
|
||||
if (proto_ver&0x7F) == 3 or proto_ver == 0:
|
||||
packet = packet + struct.pack("!H6sBBH", len(b"MQIsdp"), b"MQIsdp", proto_ver, connect_flags, keepalive)
|
||||
elif (proto_ver&0x7F) == 4 or proto_ver == 5:
|
||||
packet = packet + struct.pack("!H4sBBH", len(b"MQTT"), b"MQTT", proto_ver, connect_flags, keepalive)
|
||||
|
||||
if proto_ver == 5:
|
||||
packet += properties
|
||||
|
||||
if client_id is not None:
|
||||
packet = packet + struct.pack("!H" + str(len(client_id)) + "s", len(client_id), bytes(client_id))
|
||||
else:
|
||||
packet = packet + struct.pack("!H", 0)
|
||||
|
||||
if will_topic is not None:
|
||||
packet += will_properties
|
||||
packet = packet + struct.pack("!H" + str(len(will_topic)) + "s", len(will_topic), will_topic)
|
||||
if len(will_payload) > 0:
|
||||
packet = packet + struct.pack("!H" + str(len(will_payload)) + "s", len(will_payload), will_payload.encode('utf8'))
|
||||
else:
|
||||
packet = packet + struct.pack("!H", 0)
|
||||
|
||||
if username is not None:
|
||||
packet = packet + struct.pack("!H" + str(len(username)) + "s", len(username), username)
|
||||
if password is not None:
|
||||
packet = packet + struct.pack("!H" + str(len(password)) + "s", len(password), password)
|
||||
return packet
|
||||
|
||||
def gen_connack(flags=0, rc=0, proto_ver=4, properties=b"", property_helper=True):
|
||||
if proto_ver == 5:
|
||||
if property_helper:
|
||||
if properties is not None:
|
||||
properties = mqtt5_props.gen_uint16_prop(mqtt5_props.PROP_TOPIC_ALIAS_MAXIMUM, 10) \
|
||||
+ properties + mqtt5_props.gen_uint16_prop(mqtt5_props.PROP_RECEIVE_MAXIMUM, 20)
|
||||
else:
|
||||
properties = b""
|
||||
properties = mqtt5_props.prop_finalise(properties)
|
||||
|
||||
packet = struct.pack('!BBBB', 32, 2+len(properties), flags, rc) + properties
|
||||
else:
|
||||
packet = struct.pack('!BBBB', 32, 2, flags, rc)
|
||||
|
||||
return packet
|
||||
|
||||
def gen_publish(topic, qos, payload=None, retain=False, dup=False, mid=0, proto_ver=4, properties=b""):
|
||||
if isinstance(topic, str):
|
||||
topic = topic.encode("utf-8")
|
||||
rl = 2+len(topic)
|
||||
pack_format = "H"+str(len(topic))+"s"
|
||||
if qos > 0:
|
||||
rl = rl + 2
|
||||
pack_format = pack_format + "H"
|
||||
|
||||
if proto_ver == 5:
|
||||
properties = mqtt5_props.prop_finalise(properties)
|
||||
rl += len(properties)
|
||||
# This will break if len(properties) > 127
|
||||
pack_format = pack_format + "%ds"%(len(properties))
|
||||
|
||||
if payload is not None:
|
||||
if isinstance(payload, str):
|
||||
payload = payload.encode("utf-8")
|
||||
rl = rl + len(payload)
|
||||
pack_format = pack_format + str(len(payload)) + "s"
|
||||
else:
|
||||
payload = b""
|
||||
pack_format = pack_format + "0s"
|
||||
|
||||
rlpacked = pack_remaining_length(rl)
|
||||
cmd = 48 | (qos << 1)
|
||||
if retain:
|
||||
cmd = cmd + 1
|
||||
if dup:
|
||||
cmd = cmd + 8
|
||||
|
||||
if proto_ver == 5:
|
||||
if qos > 0:
|
||||
return struct.pack("!B" + str(len(rlpacked))+"s" + pack_format, cmd, rlpacked, len(topic), topic, mid, properties, payload)
|
||||
else:
|
||||
return struct.pack("!B" + str(len(rlpacked))+"s" + pack_format, cmd, rlpacked, len(topic), topic, properties, payload)
|
||||
else:
|
||||
if qos > 0:
|
||||
return struct.pack("!B" + str(len(rlpacked))+"s" + pack_format, cmd, rlpacked, len(topic), topic, mid, payload)
|
||||
else:
|
||||
return struct.pack("!B" + str(len(rlpacked))+"s" + pack_format, cmd, rlpacked, len(topic), topic, payload)
|
||||
|
||||
def _gen_command_with_mid(cmd, mid, proto_ver=4, reason_code=-1, properties=None):
|
||||
if proto_ver == 5 and (reason_code != -1 or properties is not None):
|
||||
if reason_code == -1:
|
||||
reason_code = 0
|
||||
|
||||
if properties is None:
|
||||
return struct.pack('!BBHB', cmd, 3, mid, reason_code)
|
||||
elif properties == "":
|
||||
return struct.pack('!BBHBB', cmd, 4, mid, reason_code, 0)
|
||||
else:
|
||||
properties = mqtt5_props.prop_finalise(properties)
|
||||
pack_format = "!BBHB"+str(len(properties))+"s"
|
||||
return struct.pack(pack_format, cmd, 2+1+len(properties), mid, reason_code, properties)
|
||||
else:
|
||||
return struct.pack('!BBH', cmd, 2, mid)
|
||||
|
||||
def gen_puback(mid, proto_ver=4, reason_code=-1, properties=None):
|
||||
return _gen_command_with_mid(64, mid, proto_ver, reason_code, properties)
|
||||
|
||||
def gen_pubrec(mid, proto_ver=4, reason_code=-1, properties=None):
|
||||
return _gen_command_with_mid(80, mid, proto_ver, reason_code, properties)
|
||||
|
||||
def gen_pubrel(mid, dup=False, proto_ver=4, reason_code=-1, properties=None):
|
||||
if dup:
|
||||
cmd = 96+8+2
|
||||
else:
|
||||
cmd = 96+2
|
||||
return _gen_command_with_mid(cmd, mid, proto_ver, reason_code, properties)
|
||||
|
||||
def gen_pubcomp(mid, proto_ver=4, reason_code=-1, properties=None):
|
||||
return _gen_command_with_mid(112, mid, proto_ver, reason_code, properties)
|
||||
|
||||
|
||||
def gen_subscribe(mid, topic, qos, cmd=130, proto_ver=4, properties=b""):
|
||||
topic = topic.encode("utf-8")
|
||||
packet = struct.pack("!B", cmd)
|
||||
if proto_ver == 5:
|
||||
if properties == b"":
|
||||
packet += pack_remaining_length(2+1+2+len(topic)+1)
|
||||
pack_format = "!HBH"+str(len(topic))+"sB"
|
||||
return packet + struct.pack(pack_format, mid, 0, len(topic), topic, qos)
|
||||
else:
|
||||
properties = mqtt5_props.prop_finalise(properties)
|
||||
packet += pack_remaining_length(2+1+2+len(topic)+len(properties))
|
||||
pack_format = "!H"+str(len(properties))+"s"+"H"+str(len(topic))+"sB"
|
||||
return packet + struct.pack(pack_format, mid, properties, len(topic), topic, qos)
|
||||
else:
|
||||
packet += pack_remaining_length(2+2+len(topic)+1)
|
||||
pack_format = "!HH"+str(len(topic))+"sB"
|
||||
return packet + struct.pack(pack_format, mid, len(topic), topic, qos)
|
||||
|
||||
|
||||
def gen_suback(mid, qos, proto_ver=4):
|
||||
if proto_ver == 5:
|
||||
return struct.pack('!BBHBB', 144, 2+1+1, mid, 0, qos)
|
||||
else:
|
||||
return struct.pack('!BBHB', 144, 2+1, mid, qos)
|
||||
|
||||
def gen_unsubscribe(mid, topic, cmd=162, proto_ver=4, properties=b""):
|
||||
topic = topic.encode("utf-8")
|
||||
if proto_ver == 5:
|
||||
if properties == b"":
|
||||
pack_format = "!BBHBH"+str(len(topic))+"s"
|
||||
return struct.pack(pack_format, cmd, 2+2+len(topic)+1, mid, 0, len(topic), topic)
|
||||
else:
|
||||
properties = mqtt5_props.prop_finalise(properties)
|
||||
packet = struct.pack("!B", cmd)
|
||||
l = 2+2+len(topic)+1+len(properties) # noqa: E741
|
||||
packet += pack_remaining_length(l)
|
||||
pack_format = "!HB"+str(len(properties))+"sH"+str(len(topic))+"s"
|
||||
packet += struct.pack(pack_format, mid, len(properties), properties, len(topic), topic)
|
||||
return packet
|
||||
else:
|
||||
pack_format = "!BBHH"+str(len(topic))+"s"
|
||||
return struct.pack(pack_format, cmd, 2+2+len(topic), mid, len(topic), topic)
|
||||
|
||||
def gen_unsubscribe_multiple(mid, topics, proto_ver=4):
|
||||
packet = b""
|
||||
remaining_length = 0
|
||||
for t in topics:
|
||||
t = t.encode("utf-8")
|
||||
remaining_length += 2+len(t)
|
||||
packet += struct.pack("!H"+str(len(t))+"s", len(t), t)
|
||||
|
||||
if proto_ver == 5:
|
||||
remaining_length += 2+1
|
||||
|
||||
return struct.pack("!BBHB", 162, remaining_length, mid, 0) + packet
|
||||
else:
|
||||
remaining_length += 2
|
||||
|
||||
return struct.pack("!BBH", 162, remaining_length, mid) + packet
|
||||
|
||||
def gen_unsuback(mid, reason_code=0, proto_ver=4):
|
||||
if proto_ver == 5:
|
||||
if isinstance(reason_code, list):
|
||||
reason_code_count = len(reason_code)
|
||||
p = struct.pack('!BBHB', 176, 3+reason_code_count, mid, 0)
|
||||
for r in reason_code:
|
||||
p += struct.pack('B', r)
|
||||
return p
|
||||
else:
|
||||
return struct.pack('!BBHBB', 176, 4, mid, 0, reason_code)
|
||||
else:
|
||||
return struct.pack('!BBH', 176, 2, mid)
|
||||
|
||||
def gen_pingreq():
|
||||
return struct.pack('!BB', 192, 0)
|
||||
|
||||
def gen_pingresp():
|
||||
return struct.pack('!BB', 208, 0)
|
||||
|
||||
|
||||
def _gen_short(cmd, reason_code=-1, proto_ver=5, properties=None):
|
||||
if proto_ver == 5 and (reason_code != -1 or properties is not None):
|
||||
if reason_code == -1:
|
||||
reason_code = 0
|
||||
|
||||
if properties is None:
|
||||
return struct.pack('!BBB', cmd, 1, reason_code)
|
||||
elif properties == "":
|
||||
return struct.pack('!BBBB', cmd, 2, reason_code, 0)
|
||||
else:
|
||||
properties = mqtt5_props.prop_finalise(properties)
|
||||
return struct.pack("!BBB", cmd, 1+len(properties), reason_code) + properties
|
||||
else:
|
||||
return struct.pack('!BB', cmd, 0)
|
||||
|
||||
def gen_disconnect(reason_code=-1, proto_ver=4, properties=None):
|
||||
return _gen_short(0xE0, reason_code, proto_ver, properties)
|
||||
|
||||
def gen_auth(reason_code=-1, properties=None):
|
||||
return _gen_short(0xF0, reason_code, 5, properties)
|
||||
|
||||
|
||||
def pack_remaining_length(remaining_length):
|
||||
s = b""
|
||||
while True:
|
||||
byte = remaining_length % 128
|
||||
remaining_length = remaining_length // 128
|
||||
# If there are more digits to encode, set the top bit of this digit
|
||||
if remaining_length > 0:
|
||||
byte = byte | 0x80
|
||||
|
||||
s = s + struct.pack("!B", byte)
|
||||
if remaining_length == 0:
|
||||
return s
|
||||
|
||||
|
||||
def loop_until_keyboard_interrupt(mqttc):
|
||||
"""
|
||||
Call loop() in a loop until KeyboardInterrupt is received.
|
||||
|
||||
This is used by the test clients in `lib/clients`;
|
||||
the client spawner will send a SIGINT to the client process
|
||||
when it wants the client to stop, so we should catch that
|
||||
and stop the client gracefully.
|
||||
"""
|
||||
try:
|
||||
while True:
|
||||
mqttc.loop()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def wait_for_keyboard_interrupt():
|
||||
"""
|
||||
Run the code in the context manager, then wait for a KeyboardInterrupt.
|
||||
|
||||
This is used by the test clients in `lib/clients`;
|
||||
the client spawner will send a SIGINT to the client process
|
||||
when it wants the client to stop, so we should catch that
|
||||
and stop the client gracefully.
|
||||
"""
|
||||
yield # If we get a KeyboardInterrupt during the block, it's too soon!
|
||||
try:
|
||||
while True:
|
||||
time.sleep(0.1)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
|
||||
def get_test_server_port() -> int:
|
||||
"""
|
||||
Get the port number for the test server.
|
||||
"""
|
||||
return int(os.environ['PAHO_SERVER_PORT'])
|
||||
@@ -0,0 +1,101 @@
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 1 (0x1)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: C=GB, ST=Derbyshire, L=Derby, O=Paho Project, OU=Testing, CN=Root CA
|
||||
Validity
|
||||
Not Before: Jul 7 11:14:42 2021 GMT
|
||||
Not After : Jul 6 11:14:42 2026 GMT
|
||||
Subject: C=GB, ST=Derbyshire, O=Paho Project, OU=Testing, CN=Signing CA
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
RSA Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:cb:32:6c:8c:48:e8:44:58:36:18:70:36:42:3d:
|
||||
2d:29:47:3c:69:12:9e:7b:f7:45:62:ef:91:44:46:
|
||||
97:a0:ea:5f:da:fd:9f:98:d4:bf:43:02:e3:39:90:
|
||||
33:7b:13:13:d5:31:30:9c:07:fc:ca:1b:a9:e4:89:
|
||||
42:e5:d0:6e:f4:a2:e0:23:ee:9d:9a:cc:80:3b:78:
|
||||
bf:7e:27:a8:46:1b:28:9f:4a:64:53:7a:89:3e:ab:
|
||||
65:6f:af:0b:29:fa:4d:4f:04:f1:1e:10:2c:bf:2b:
|
||||
ea:fc:c5:fa:77:c9:1a:7a:78:29:f5:a2:cb:25:7c:
|
||||
02:bb:91:8d:76:4d:23:bc:9c:19:da:be:c5:20:04:
|
||||
ad:fe:bd:b9:d4:bb:29:2a:c3:e4:fc:4c:84:db:a3:
|
||||
55:9f:f0:70:7f:40:38:b5:c3:78:a5:db:06:36:b7:
|
||||
10:8e:ca:6c:1a:92:66:be:0e:1a:97:59:6b:18:f4:
|
||||
c2:b8:c9:31:7b:d1:b1:a1:00:78:7f:c0:09:f6:ef:
|
||||
b2:8f:94:87:5d:b1:a2:23:93:4d:ec:fa:95:09:a9:
|
||||
90:c4:02:f0:1e:d9:ab:a2:8b:7f:7f:54:95:e7:da:
|
||||
c3:c9:7d:a7:d7:04:89:59:db:88:9d:57:16:5d:b9:
|
||||
66:b0:d6:88:bb:e0:ee:43:e9:ab:02:78:fc:bd:e8:
|
||||
98:d9
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Subject Key Identifier:
|
||||
C2:8F:09:9B:D5:F1:BA:C4:74:5E:97:50:BB:86:9D:A1:F1:FA:C4:36
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:13:A0:B6:1F:F5:C7:64:C2:F9:FD:2E:08:F2:19:01:77:54:19:73:7F
|
||||
|
||||
X509v3 Basic Constraints:
|
||||
CA:TRUE
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
3e:70:76:69:37:e4:6e:e0:08:c6:8e:5b:2e:aa:26:fe:e9:ed:
|
||||
ac:02:ce:2c:37:08:6a:8a:c3:0d:c0:ef:43:51:01:2e:e0:96:
|
||||
76:23:1b:1f:75:98:df:7c:d1:b7:c1:67:aa:62:c1:bd:ef:84:
|
||||
eb:d9:28:47:50:f2:1b:54:7f:ed:cb:52:f7:fc:c3:f8:62:22:
|
||||
0c:b3:95:ed:bb:3f:74:91:bc:d2:eb:c0:81:7d:74:12:85:61:
|
||||
a3:7e:fb:22:4a:25:99:0b:5d:ef:69:f2:5a:e6:d5:12:a3:95:
|
||||
38:30:0c:c7:d9:da:28:30:10:b4:3d:3e:ad:20:85:31:e0:bf:
|
||||
30:33:2e:0b:e3:07:3d:ed:22:dc:67:f8:93:64:89:ed:e7:08:
|
||||
74:b5:0a:7a:01:3d:f9:44:62:71:cf:60:12:92:c3:95:9a:e5:
|
||||
a5:f2:24:6a:22:64:d5:76:22:c9:03:1c:c5:d1:a5:85:4d:55:
|
||||
f9:80:47:ca:12:20:df:05:fb:82:12:45:6f:e8:c0:20:a8:ae:
|
||||
f7:17:c5:c3:b6:9c:51:bd:d8:84:e4:db:c7:03:44:d2:cb:75:
|
||||
51:79:3f:86:33:3c:e4:34:1d:77:b2:60:24:5c:21:c5:c3:53:
|
||||
36:08:2f:a7:14:0b:68:78:67:95:90:b9:06:0e:85:04:65:57:
|
||||
b4:34:31:cf
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDmDCCAoCgAwIBAgIBATANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQGEwJHQjET
|
||||
MBEGA1UECAwKRGVyYnlzaGlyZTEOMAwGA1UEBwwFRGVyYnkxFTATBgNVBAoMDFBh
|
||||
aG8gUHJvamVjdDEQMA4GA1UECwwHVGVzdGluZzEQMA4GA1UEAwwHUm9vdCBDQTAe
|
||||
Fw0yMTA3MDcxMTE0NDJaFw0yNjA3MDYxMTE0NDJaMGAxCzAJBgNVBAYTAkdCMRMw
|
||||
EQYDVQQIDApEZXJieXNoaXJlMRUwEwYDVQQKDAxQYWhvIFByb2plY3QxEDAOBgNV
|
||||
BAsMB1Rlc3RpbmcxEzARBgNVBAMMClNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEB
|
||||
AQUAA4IBDwAwggEKAoIBAQDLMmyMSOhEWDYYcDZCPS0pRzxpEp5790Vi75FERpeg
|
||||
6l/a/Z+Y1L9DAuM5kDN7ExPVMTCcB/zKG6nkiULl0G70ouAj7p2azIA7eL9+J6hG
|
||||
GyifSmRTeok+q2Vvrwsp+k1PBPEeECy/K+r8xfp3yRp6eCn1osslfAK7kY12TSO8
|
||||
nBnavsUgBK3+vbnUuykqw+T8TITbo1Wf8HB/QDi1w3il2wY2txCOymwakma+DhqX
|
||||
WWsY9MK4yTF70bGhAHh/wAn277KPlIddsaIjk03s+pUJqZDEAvAe2auii39/VJXn
|
||||
2sPJfafXBIlZ24idVxZduWaw1oi74O5D6asCePy96JjZAgMBAAGjUDBOMB0GA1Ud
|
||||
DgQWBBTCjwmb1fG6xHRel1C7hp2h8frENjAfBgNVHSMEGDAWgBQToLYf9cdkwvn9
|
||||
LgjyGQF3VBlzfzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA+cHZp
|
||||
N+Ru4AjGjlsuqib+6e2sAs4sNwhqisMNwO9DUQEu4JZ2IxsfdZjffNG3wWeqYsG9
|
||||
74Tr2ShHUPIbVH/ty1L3/MP4YiIMs5Xtuz90kbzS68CBfXQShWGjfvsiSiWZC13v
|
||||
afJa5tUSo5U4MAzH2dooMBC0PT6tIIUx4L8wMy4L4wc97SLcZ/iTZInt5wh0tQp6
|
||||
AT35RGJxz2ASksOVmuWl8iRqImTVdiLJAxzF0aWFTVX5gEfKEiDfBfuCEkVv6MAg
|
||||
qK73F8XDtpxRvdiE5NvHA0TSy3VReT+GMzzkNB13smAkXCHFw1M2CC+nFAtoeGeV
|
||||
kLkGDoUEZVe0NDHP
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDuDCCAqCgAwIBAgIUS1Q+E18/+trcKfhT+xz8ghGukmYwDQYJKoZIhvcNAQEL
|
||||
BQAwbTELMAkGA1UEBhMCR0IxEzARBgNVBAgMCkRlcmJ5c2hpcmUxDjAMBgNVBAcM
|
||||
BURlcmJ5MRUwEwYDVQQKDAxQYWhvIFByb2plY3QxEDAOBgNVBAsMB1Rlc3Rpbmcx
|
||||
EDAOBgNVBAMMB1Jvb3QgQ0EwHhcNMjEwNzA3MTExNDQyWhcNMzEwNzA1MTExNDQy
|
||||
WjBtMQswCQYDVQQGEwJHQjETMBEGA1UECAwKRGVyYnlzaGlyZTEOMAwGA1UEBwwF
|
||||
RGVyYnkxFTATBgNVBAoMDFBhaG8gUHJvamVjdDEQMA4GA1UECwwHVGVzdGluZzEQ
|
||||
MA4GA1UEAwwHUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
||||
AKpCq45dCrroNa+y3zgdBglQOtw4og3MD/3Rn6ZftyL0dv1rSMkCFU8lCtZ4bIpz
|
||||
iNSJKau79owCudX3qQTPfiX2pmR5uuYjvMzRiZohZtz5uqXByy/CMS8dPRI3po6i
|
||||
kfNx9n7EQqOlxdwkY1kae2j5ybkAld2MNci93BH4P8qqaQckVRKpv6cKq33KsXK7
|
||||
jHgjAYMGrihTAwxgP1JX9NS8yxxjMUYvFqeEOLARoeWc6Nl7oDbGLs2fr0j2Yssm
|
||||
cz0AMu7LWcbhnfs2S8Troksztnq38yHu+YTs6hX4NhANBgon5CAdyzmmE/b2OwOX
|
||||
p8rQepUfG7wO5QaS0OrAEXsCAwEAAaNQME4wHQYDVR0OBBYEFBOgth/1x2TC+f0u
|
||||
CPIZAXdUGXN/MB8GA1UdIwQYMBaAFBOgth/1x2TC+f0uCPIZAXdUGXN/MAwGA1Ud
|
||||
EwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAHgE1oMwIcilQFN4xPYCf8jbsa5o
|
||||
zA5ljTbxv7fU3Zd+7KdlDFYroGjgHb7o3r0//b8+ZarxBqn1274u4KPs39Ow7h6m
|
||||
YJo7IM2Z2fC6IWZroqeidfFx5SwejAP1j7coYLblTIbNF+P08sJG5nSQ+Yx0gams
|
||||
6C1x0mETaaglDwllU1KXHTm8fUpEwpISc/VfKABYgScODMpdsDghyHANvnFjmvp4
|
||||
ktABnasliZYTmdl0t3szNm7zIk+bntiK4KunFea8GqgslWqGPwtNxxJFHzPjMCxK
|
||||
EHgubLgp1lNZzH13XSO6ZpiNRDJ6IVed3Zq+yn+24uKH+1Hqp6Bt20ZFB4E=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,82 @@
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 3 (0x3)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: C=GB, ST=Derbyshire, O=Paho Project, OU=Testing, CN=Signing CA
|
||||
Validity
|
||||
Not Before: Aug 20 00:00:00 2012 GMT
|
||||
Not After : Aug 21 00:00:00 2012 GMT
|
||||
Subject: C=GB, ST=Nottinghamshire, L=Nottingham, O=Server, OU=Production, CN=test client expired
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
RSA Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:d0:58:ed:ad:44:b4:f8:30:16:27:d9:b4:2c:b4:
|
||||
24:67:9a:19:fe:32:04:0d:9a:7e:75:97:12:d6:2c:
|
||||
d4:97:33:fb:30:8c:ef:a2:b1:ef:e5:92:d6:56:05:
|
||||
75:c8:19:82:92:4e:4b:13:8e:25:90:b9:21:72:f4:
|
||||
a4:bf:7a:e2:0f:75:52:08:04:4c:e8:6a:35:7e:7d:
|
||||
78:d9:b8:f7:2b:3d:8e:4e:b5:f3:7a:9a:06:10:50:
|
||||
ca:95:63:2c:bd:3a:89:d0:8a:84:12:32:9b:00:a7:
|
||||
25:33:70:d2:18:0a:43:94:12:62:e7:77:db:b8:0f:
|
||||
dc:23:48:95:5c:77:c6:11:4f:0f:d6:6e:73:59:7c:
|
||||
ed:6a:fd:ba:24:f0:b2:59:c3:a2:16:65:ad:19:7f:
|
||||
92:87:8c:ea:b5:e5:0f:26:f8:b1:74:98:c3:fd:ed:
|
||||
4d:74:d0:58:ce:d9:9c:24:34:9b:75:79:25:d0:aa:
|
||||
6c:03:03:0c:3a:4a:4c:9a:36:50:ab:55:74:1e:8b:
|
||||
de:41:a7:14:b9:57:ee:8b:31:90:5c:00:af:31:9d:
|
||||
e0:55:07:8d:05:ed:c9:5f:e1:79:b7:96:be:d9:5b:
|
||||
cf:a7:5c:cd:48:fc:bd:a4:34:bf:e0:49:d5:25:60:
|
||||
7a:4c:32:37:97:e4:f8:64:24:a6:79:c1:62:8d:93:
|
||||
52:53
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Basic Constraints:
|
||||
CA:FALSE
|
||||
Netscape Comment:
|
||||
OpenSSL Generated Certificate
|
||||
X509v3 Subject Key Identifier:
|
||||
61:62:90:E6:BB:8A:BB:06:6C:8A:66:9F:A5:C7:85:12:43:5C:94:6F
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:C2:8F:09:9B:D5:F1:BA:C4:74:5E:97:50:BB:86:9D:A1:F1:FA:C4:36
|
||||
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
8d:7b:2a:16:2a:2e:50:db:5d:6e:20:ec:4e:5f:2e:d0:f4:9a:
|
||||
a9:c8:b3:f0:73:02:9f:2f:32:a2:2a:a5:a7:83:1e:e3:36:6b:
|
||||
99:d2:4c:6a:ea:09:0b:73:5e:7f:69:da:50:69:5b:dc:0f:4d:
|
||||
59:ec:d2:c7:ca:0e:a8:55:c0:5a:f6:67:e8:a0:0b:4b:0a:9a:
|
||||
a8:1f:b3:f0:e7:e6:10:4b:db:1b:5a:18:7a:ee:52:16:93:2e:
|
||||
70:1c:4f:7d:c6:eb:4a:11:35:92:db:8c:f0:86:1b:f7:64:4f:
|
||||
f5:1b:31:d6:da:89:97:c6:46:4b:c9:df:7f:80:c4:77:5e:c6:
|
||||
a8:b7:47:12:48:b5:2b:f2:73:80:e4:dd:5b:cf:a1:20:3c:3b:
|
||||
b3:37:34:d1:72:37:e1:a6:06:d4:22:cc:65:d3:af:0f:aa:ea:
|
||||
ad:dd:e9:21:c5:1e:86:81:94:33:6c:ca:68:c2:48:ed:ea:0e:
|
||||
c4:be:38:a5:4f:bb:0b:2b:7f:e7:63:e1:9f:e1:c8:6a:c4:4c:
|
||||
7b:43:a2:56:c9:ff:56:88:2e:e3:4f:d6:d0:69:59:96:6e:26:
|
||||
d9:3d:f3:62:4e:c3:a3:79:8f:f9:e4:82:11:52:f0:a2:c7:79:
|
||||
b6:54:50:21:31:e6:4a:8c:2c:df:23:e9:2e:50:6e:9d:a8:61:
|
||||
5b:e1:cb:51
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID1zCCAr+gAwIBAgIBAzANBgkqhkiG9w0BAQsFADBgMQswCQYDVQQGEwJHQjET
|
||||
MBEGA1UECAwKRGVyYnlzaGlyZTEVMBMGA1UECgwMUGFobyBQcm9qZWN0MRAwDgYD
|
||||
VQQLDAdUZXN0aW5nMRMwEQYDVQQDDApTaWduaW5nIENBMB4XDTEyMDgyMDAwMDAw
|
||||
MFoXDTEyMDgyMTAwMDAwMFowgYAxCzAJBgNVBAYTAkdCMRgwFgYDVQQIDA9Ob3R0
|
||||
aW5naGFtc2hpcmUxEzARBgNVBAcMCk5vdHRpbmdoYW0xDzANBgNVBAoMBlNlcnZl
|
||||
cjETMBEGA1UECwwKUHJvZHVjdGlvbjEcMBoGA1UEAwwTdGVzdCBjbGllbnQgZXhw
|
||||
aXJlZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANBY7a1EtPgwFifZ
|
||||
tCy0JGeaGf4yBA2afnWXEtYs1Jcz+zCM76Kx7+WS1lYFdcgZgpJOSxOOJZC5IXL0
|
||||
pL964g91UggETOhqNX59eNm49ys9jk6183qaBhBQypVjLL06idCKhBIymwCnJTNw
|
||||
0hgKQ5QSYud327gP3CNIlVx3xhFPD9Zuc1l87Wr9uiTwslnDohZlrRl/koeM6rXl
|
||||
Dyb4sXSYw/3tTXTQWM7ZnCQ0m3V5JdCqbAMDDDpKTJo2UKtVdB6L3kGnFLlX7osx
|
||||
kFwArzGd4FUHjQXtyV/hebeWvtlbz6dczUj8vaQ0v+BJ1SVgekwyN5fk+GQkpnnB
|
||||
Yo2TUlMCAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNT
|
||||
TCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFGFikOa7irsGbIpmn6XH
|
||||
hRJDXJRvMB8GA1UdIwQYMBaAFMKPCZvV8brEdF6XULuGnaHx+sQ2MA0GCSqGSIb3
|
||||
DQEBCwUAA4IBAQCNeyoWKi5Q211uIOxOXy7Q9JqpyLPwcwKfLzKiKqWngx7jNmuZ
|
||||
0kxq6gkLc15/adpQaVvcD01Z7NLHyg6oVcBa9mfooAtLCpqoH7Pw5+YQS9sbWhh6
|
||||
7lIWky5wHE99xutKETWS24zwhhv3ZE/1GzHW2omXxkZLyd9/gMR3Xsaot0cSSLUr
|
||||
8nOA5N1bz6EgPDuzNzTRcjfhpgbUIsxl068Pquqt3ekhxR6GgZQzbMpowkjt6g7E
|
||||
vjilT7sLK3/nY+Gf4chqxEx7Q6JWyf9WiC7jT9bQaVmWbibZPfNiTsOjeY/55IIR
|
||||
UvCix3m2VFAhMeZKjCzfI+kuUG6dqGFb4ctR
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,82 @@
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 4 (0x4)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: C=GB, ST=Derbyshire, O=Paho Project, OU=Testing, CN=Signing CA
|
||||
Validity
|
||||
Not Before: Jul 7 11:14:42 2021 GMT
|
||||
Not After : Jul 6 11:14:42 2026 GMT
|
||||
Subject: C=GB, ST=Nottinghamshire, L=Nottingham, O=Server, OU=Production, CN=test client with password
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
RSA Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:ca:cb:93:49:45:28:95:5b:c4:51:b4:2b:d0:e7:
|
||||
e4:b7:3b:37:34:f6:5c:ec:f8:7d:3a:8b:b8:da:3c:
|
||||
94:38:85:5f:41:ea:2b:08:d7:3e:97:12:50:09:1f:
|
||||
37:4f:e4:25:a1:59:b6:98:63:22:8d:80:7e:b1:b4:
|
||||
24:03:2e:5e:5d:45:a4:4c:76:e8:ac:2c:5f:ca:9d:
|
||||
ed:6e:0a:7b:6f:2b:34:d1:4e:6a:e1:b6:72:66:42:
|
||||
ec:fd:b8:97:bf:40:4b:24:9c:47:6c:8c:4a:73:aa:
|
||||
e0:3a:db:ac:45:65:23:df:8f:4a:30:ed:d6:ad:5c:
|
||||
eb:a9:e9:83:da:39:d1:eb:98:31:74:98:bd:99:6b:
|
||||
85:0e:1d:f8:93:cf:e2:bd:59:77:fe:b2:a0:c4:e5:
|
||||
63:ae:92:10:13:47:14:55:22:a0:30:b6:f0:cb:17:
|
||||
b6:2d:f9:7d:f9:82:50:b2:64:88:dd:5a:3b:b6:81:
|
||||
67:8c:e3:de:89:76:63:82:af:b7:ba:83:5c:3b:bc:
|
||||
cf:1f:8e:fe:25:04:6f:f2:70:bf:2f:b0:6b:4f:77:
|
||||
d2:2d:e4:37:20:84:f3:94:c3:12:80:ae:bc:c3:2b:
|
||||
93:d2:fa:92:a3:1a:33:8d:d7:4a:eb:23:04:c0:38:
|
||||
51:73:fb:7a:9f:f5:3a:ca:7e:2e:c7:b6:22:3e:68:
|
||||
69:0f
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Basic Constraints:
|
||||
CA:FALSE
|
||||
Netscape Comment:
|
||||
OpenSSL Generated Certificate
|
||||
X509v3 Subject Key Identifier:
|
||||
8E:E7:D7:66:D5:0C:10:B5:7A:4F:7F:83:C3:43:94:E9:BC:E2:88:D0
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:C2:8F:09:9B:D5:F1:BA:C4:74:5E:97:50:BB:86:9D:A1:F1:FA:C4:36
|
||||
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
17:54:5a:5e:9e:7d:fe:3f:6d:82:c5:e8:42:6b:61:91:13:5f:
|
||||
07:d5:25:4b:3c:05:e6:4c:99:a5:ff:20:ff:d3:e8:a4:25:08:
|
||||
8c:82:1b:2f:25:73:79:97:12:5e:e9:30:a1:b2:16:36:51:e2:
|
||||
a5:41:bf:1c:c1:db:d2:9a:36:67:75:da:e7:36:9a:b4:65:17:
|
||||
74:af:73:02:b0:09:b3:ac:29:e7:ca:cd:01:12:7f:ba:39:29:
|
||||
90:d4:7c:3f:99:89:66:e7:eb:79:80:77:91:e4:3d:7e:87:69:
|
||||
7b:da:b5:68:07:26:ab:30:20:49:2b:46:33:3f:f7:4b:4e:e7:
|
||||
a0:13:19:53:7d:73:ff:4a:95:86:35:d2:cd:ff:3c:b1:14:b4:
|
||||
d8:d4:ca:de:b7:8d:2e:e3:47:f8:5d:2e:e7:b1:5b:b9:23:d3:
|
||||
54:11:89:8e:98:12:a8:10:2a:da:bb:d0:0c:07:c7:d7:21:7e:
|
||||
f0:88:91:31:07:2a:a6:42:84:4a:61:9e:68:72:d4:7c:3f:59:
|
||||
b2:02:e1:a6:11:9b:d2:90:73:39:13:07:e1:6b:57:2a:78:b4:
|
||||
b4:f0:75:7c:6d:48:9d:33:cd:3f:d0:ff:43:a4:7e:3a:8d:fe:
|
||||
98:10:df:ab:ee:c0:58:82:cb:23:7a:b7:f5:5c:29:29:af:d0:
|
||||
40:fc:42:a3
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID3TCCAsWgAwIBAgIBBDANBgkqhkiG9w0BAQsFADBgMQswCQYDVQQGEwJHQjET
|
||||
MBEGA1UECAwKRGVyYnlzaGlyZTEVMBMGA1UECgwMUGFobyBQcm9qZWN0MRAwDgYD
|
||||
VQQLDAdUZXN0aW5nMRMwEQYDVQQDDApTaWduaW5nIENBMB4XDTIxMDcwNzExMTQ0
|
||||
MloXDTI2MDcwNjExMTQ0MlowgYYxCzAJBgNVBAYTAkdCMRgwFgYDVQQIDA9Ob3R0
|
||||
aW5naGFtc2hpcmUxEzARBgNVBAcMCk5vdHRpbmdoYW0xDzANBgNVBAoMBlNlcnZl
|
||||
cjETMBEGA1UECwwKUHJvZHVjdGlvbjEiMCAGA1UEAwwZdGVzdCBjbGllbnQgd2l0
|
||||
aCBwYXNzd29yZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMrLk0lF
|
||||
KJVbxFG0K9Dn5Lc7NzT2XOz4fTqLuNo8lDiFX0HqKwjXPpcSUAkfN0/kJaFZtphj
|
||||
Io2AfrG0JAMuXl1FpEx26KwsX8qd7W4Ke28rNNFOauG2cmZC7P24l79ASyScR2yM
|
||||
SnOq4DrbrEVlI9+PSjDt1q1c66npg9o50euYMXSYvZlrhQ4d+JPP4r1Zd/6yoMTl
|
||||
Y66SEBNHFFUioDC28MsXti35ffmCULJkiN1aO7aBZ4zj3ol2Y4Kvt7qDXDu8zx+O
|
||||
/iUEb/Jwvy+wa0930i3kNyCE85TDEoCuvMMrk9L6kqMaM43XSusjBMA4UXP7ep/1
|
||||
Osp+Lse2Ij5oaQ8CAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYd
|
||||
T3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFI7n12bVDBC1
|
||||
ek9/g8NDlOm84ojQMB8GA1UdIwQYMBaAFMKPCZvV8brEdF6XULuGnaHx+sQ2MA0G
|
||||
CSqGSIb3DQEBCwUAA4IBAQAXVFpenn3+P22CxehCa2GRE18H1SVLPAXmTJml/yD/
|
||||
0+ikJQiMghsvJXN5lxJe6TChshY2UeKlQb8cwdvSmjZnddrnNpq0ZRd0r3MCsAmz
|
||||
rCnnys0BEn+6OSmQ1Hw/mYlm5+t5gHeR5D1+h2l72rVoByarMCBJK0YzP/dLTueg
|
||||
ExlTfXP/SpWGNdLN/zyxFLTY1Mret40u40f4XS7nsVu5I9NUEYmOmBKoECrau9AM
|
||||
B8fXIX7wiJExByqmQoRKYZ5octR8P1myAuGmEZvSkHM5Ewfha1cqeLS08HV8bUid
|
||||
M80/0P9DpH46jf6YEN+r7sBYgssjerf1XCkpr9BA/EKj
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,30 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-128-CBC,84549D95979482A29416CC3DBA507BC0
|
||||
|
||||
tAbMy3JP4/R53W9E8sB+fFFvGQOb+QKSW0vtjb8Z3GlIW+9wdGJ89GhXcspP7+HN
|
||||
eQZy6trDmPHJ++m4sVEwBGjngLdDaajRvQVlqCIXgLvjCwIIaE2gHo3yF37umunR
|
||||
0dg4NVjfEgNS3luPu7DzCv9pwIQl2YOsoPK7TuHOTGVGHCovHAr/IJ7fdaT5N9G8
|
||||
ypC7rHZhneLUs02J/L0FZUPlztOXRuiqnJisZr0pPs6ZoVEoNvR4D3VgU0nOFMcF
|
||||
UmcWA+vJsXaPzmC0HDErYqfr0Mwc/7mZURCGm/+A6Q79PAAAR7pPoMczaRHP4szS
|
||||
BxegO6XyKYs8a52q/XojKTcb0FESNjX0syW3+OjZusCYpuBmK4MofSdDmXVNxBLD
|
||||
iBqUDLGSfU2W5H/UkHWh7O0VW1DT0RvqqFV1p1WI0dvixM80wx12rPiJ79RYLG8D
|
||||
HMD7lR2iODDibCXePMg0XeCz+zf8OSfqzw6YeAMxmapZWBd8cJJ4eaUq6ziZO0hE
|
||||
kvj6tUZk7d/nTSissQR2Tx6xlSm0AuHWdKx1s5gKnVg6xLKNKIVyeHnXdXkgCwSq
|
||||
dICwmtP/1iYrslWCrhnB4MLA6R2vgpglwBfh7h7rW59K2untdIzr/td+h/xkynHQ
|
||||
wMKJ5xZ2oRQc9oZrV0PXHQKdukniLr3owBPiu+i+QbqpzGtvhyt1wUs+NjDROrim
|
||||
kritxoz6SXSIH6Wv9ae1crdhK1YTaMt1YOJT4tPjTdZyhMXqYszAH25L3ar2HaEv
|
||||
Cv2YU9VqPno45/ZSVSA8xZ+E74AoZsgDMOWKFJimJv+P9CGNbm8d9SGlHDAsyj0U
|
||||
+cTeyH6AWWHuAdEtVNA36qDdWOJOwhH2vT2iLuqdDySX5EJRszoxFo2RdGF3lRuQ
|
||||
lVFo1v41tnvB89i9g8ZVqqkfs1IjybU2Aq+hpnqRVThRrbN75o2s2BC0K2sUvgu5
|
||||
gKUzXBl2B5CX6kWrUZ9llTSi2nH6zFAMtKvvuRQx+r+qrjJbxiPkRm9HFXlRRKYG
|
||||
NZbYyrB0ovuNgL5mwraNBL8Ytzx/nGvnaJsxWqhNiDENEziGcjTiA0/gh/mtru7K
|
||||
xTAQt7vVgrsynAK7c5Yhu3BBJspjgq2S9mKNpgXadcYcKQRcJnsYR9VCNWy4f7dD
|
||||
sTDy9NPttZM24ayC8OjUtyusk/DxXubuqRf4mF7jKsmoTqZR/yW5/NGPOpYRs0If
|
||||
9ysiBP8ctyti+snS8jSzb7PVCBJzKgEDthjLvXmV2AIeuiXTFvqTmKOlTYT8mkev
|
||||
ZaXl4tS+3GGJgrSmPweAJsGFo58oQA8skExrXBW0w2rRSQDqzEo/GAbmd65IDGXh
|
||||
YMOwsdvjiu9Ug4E7icxB2w5bKmhEsIh/Vj3Np/h5xcJ9W9O8zq0oYhjle3GLDGro
|
||||
yPA1g0wWLeuxwPhPk7cNHFdF2Yr2CXFVug3Q9WkGTABKbZd2zV/7kk6YMRFmieV0
|
||||
h4nQBSFqR6qkF9CiUFkKS2dod0zKLPJiBRqgiopEur5QdHg1PpdEQAj6fLQo0Zfw
|
||||
LoQyVi3ta9IMO1wZU8fy9w+bXoo8c76VD5jzfXw1ig0bK3iu1ozZc2UjnNlBmpYp
|
||||
-----END RSA PRIVATE KEY-----
|
||||
@@ -0,0 +1,82 @@
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 5 (0x5)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: C=GB, ST=Derbyshire, O=Paho Project, OU=Testing, CN=Signing CA
|
||||
Validity
|
||||
Not Before: Jul 7 11:14:43 2021 GMT
|
||||
Not After : Jul 6 11:14:43 2026 GMT
|
||||
Subject: C=GB, ST=Nottinghamshire, L=Nottingham, O=Server, OU=Production, CN=test client revoked
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
RSA Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:a5:7a:5f:a2:55:1f:50:22:cd:92:0d:9a:69:fa:
|
||||
47:d4:d1:2f:6f:e5:3e:22:06:2f:f4:ed:a8:85:9b:
|
||||
2a:0d:e7:e2:81:f4:23:08:68:e2:75:5b:ba:58:f5:
|
||||
57:61:5a:5c:c4:e5:27:5e:9c:8e:82:77:72:25:c2:
|
||||
2e:1d:e0:61:dc:32:f0:3b:be:7d:26:e3:a0:bb:5d:
|
||||
75:7f:87:d8:a1:26:2f:7f:01:7b:1e:2f:25:cb:bd:
|
||||
15:6c:43:12:6a:a6:02:1d:fd:7b:34:e2:1e:6c:06:
|
||||
13:de:39:e8:ee:ae:ed:cd:cc:bd:1e:48:d5:e6:11:
|
||||
95:12:08:61:88:13:d6:88:40:cc:9d:18:1c:c6:30:
|
||||
5e:8f:e8:a4:2a:c8:62:78:19:f6:95:6a:f0:ce:27:
|
||||
e3:af:aa:fd:46:41:9d:83:32:f6:8e:a4:1f:32:00:
|
||||
c3:ca:5f:a5:3e:bc:74:6e:96:3e:50:cd:12:ca:81:
|
||||
5a:ab:cf:a1:f8:3a:2f:fe:91:73:79:14:b3:fb:e6:
|
||||
6b:c3:57:a9:8c:2d:f6:6c:53:4f:2e:e9:4c:25:67:
|
||||
88:ac:ce:bc:84:ac:b8:d8:f5:6a:a4:ae:24:10:ea:
|
||||
4e:2c:ef:90:f5:a6:68:c3:5c:a7:e0:40:99:06:6a:
|
||||
ec:b1:63:f5:7a:0b:a9:f1:81:26:95:12:9c:02:20:
|
||||
77:df
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Basic Constraints:
|
||||
CA:FALSE
|
||||
Netscape Comment:
|
||||
OpenSSL Generated Certificate
|
||||
X509v3 Subject Key Identifier:
|
||||
C7:6A:63:58:7D:DB:19:38:77:1F:41:E8:67:38:78:9D:0B:BE:51:92
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:C2:8F:09:9B:D5:F1:BA:C4:74:5E:97:50:BB:86:9D:A1:F1:FA:C4:36
|
||||
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
5c:b9:89:ad:18:b6:0b:93:f1:b0:0a:3e:aa:f3:d0:ad:d1:6f:
|
||||
04:31:29:5a:b8:74:81:3c:4b:bb:98:8a:ca:c8:95:fa:8f:3e:
|
||||
89:ba:f2:c3:83:a2:18:1c:7c:c6:56:4b:52:83:ef:fe:87:23:
|
||||
7f:2d:6f:a2:36:22:46:04:ed:bf:ad:34:e6:9d:87:7e:92:72:
|
||||
80:b2:5d:b1:b3:23:f6:f2:bd:74:c5:34:ef:8f:50:89:8b:64:
|
||||
77:95:9d:ec:72:09:a6:c4:74:da:1d:2a:57:60:38:8f:6c:22:
|
||||
ff:9e:40:73:98:ac:1f:bc:b6:e4:1b:1d:2d:73:a2:9a:ad:53:
|
||||
95:d2:17:b3:c5:8a:6c:5a:5a:be:e2:80:e4:f5:d6:99:06:61:
|
||||
ec:66:44:1a:ec:ac:86:36:ef:84:4b:c5:b3:a0:c5:d7:0d:be:
|
||||
51:8c:95:46:03:e4:74:61:bf:7c:10:68:91:12:46:b8:38:94:
|
||||
9f:a2:68:77:4d:92:57:43:ff:a1:c2:67:43:33:01:1d:fd:29:
|
||||
13:8d:04:ed:7e:2d:4c:ed:8c:2f:f6:6f:44:33:3c:71:4d:f6:
|
||||
51:04:c5:c0:cb:2c:ea:95:6e:22:32:03:37:0b:32:87:89:c0:
|
||||
e5:bc:72:d2:8f:73:db:40:a9:4d:f2:15:bd:c4:0d:aa:ea:2e:
|
||||
0c:ce:77:9d
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID1zCCAr+gAwIBAgIBBTANBgkqhkiG9w0BAQsFADBgMQswCQYDVQQGEwJHQjET
|
||||
MBEGA1UECAwKRGVyYnlzaGlyZTEVMBMGA1UECgwMUGFobyBQcm9qZWN0MRAwDgYD
|
||||
VQQLDAdUZXN0aW5nMRMwEQYDVQQDDApTaWduaW5nIENBMB4XDTIxMDcwNzExMTQ0
|
||||
M1oXDTI2MDcwNjExMTQ0M1owgYAxCzAJBgNVBAYTAkdCMRgwFgYDVQQIDA9Ob3R0
|
||||
aW5naGFtc2hpcmUxEzARBgNVBAcMCk5vdHRpbmdoYW0xDzANBgNVBAoMBlNlcnZl
|
||||
cjETMBEGA1UECwwKUHJvZHVjdGlvbjEcMBoGA1UEAwwTdGVzdCBjbGllbnQgcmV2
|
||||
b2tlZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKV6X6JVH1AizZIN
|
||||
mmn6R9TRL2/lPiIGL/TtqIWbKg3n4oH0Iwho4nVbulj1V2FaXMTlJ16cjoJ3ciXC
|
||||
Lh3gYdwy8Du+fSbjoLtddX+H2KEmL38Bex4vJcu9FWxDEmqmAh39ezTiHmwGE945
|
||||
6O6u7c3MvR5I1eYRlRIIYYgT1ohAzJ0YHMYwXo/opCrIYngZ9pVq8M4n46+q/UZB
|
||||
nYMy9o6kHzIAw8pfpT68dG6WPlDNEsqBWqvPofg6L/6Rc3kUs/vma8NXqYwt9mxT
|
||||
Ty7pTCVniKzOvISsuNj1aqSuJBDqTizvkPWmaMNcp+BAmQZq7LFj9XoLqfGBJpUS
|
||||
nAIgd98CAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNT
|
||||
TCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFMdqY1h92xk4dx9B6Gc4
|
||||
eJ0LvlGSMB8GA1UdIwQYMBaAFMKPCZvV8brEdF6XULuGnaHx+sQ2MA0GCSqGSIb3
|
||||
DQEBCwUAA4IBAQBcuYmtGLYLk/GwCj6q89Ct0W8EMSlauHSBPEu7mIrKyJX6jz6J
|
||||
uvLDg6IYHHzGVktSg+/+hyN/LW+iNiJGBO2/rTTmnYd+knKAsl2xsyP28r10xTTv
|
||||
j1CJi2R3lZ3scgmmxHTaHSpXYDiPbCL/nkBzmKwfvLbkGx0tc6KarVOV0hezxYps
|
||||
Wlq+4oDk9daZBmHsZkQa7KyGNu+ES8WzoMXXDb5RjJVGA+R0Yb98EGiREka4OJSf
|
||||
omh3TZJXQ/+hwmdDMwEd/SkTjQTtfi1M7Ywv9m9EMzxxTfZRBMXAyyzqlW4iMgM3
|
||||
CzKHicDlvHLSj3PbQKlN8hW9xA2q6i4Mzned
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEApXpfolUfUCLNkg2aafpH1NEvb+U+IgYv9O2ohZsqDefigfQj
|
||||
CGjidVu6WPVXYVpcxOUnXpyOgndyJcIuHeBh3DLwO759JuOgu111f4fYoSYvfwF7
|
||||
Hi8ly70VbEMSaqYCHf17NOIebAYT3jno7q7tzcy9HkjV5hGVEghhiBPWiEDMnRgc
|
||||
xjBej+ikKshieBn2lWrwzifjr6r9RkGdgzL2jqQfMgDDyl+lPrx0bpY+UM0SyoFa
|
||||
q8+h+Dov/pFzeRSz++Zrw1epjC32bFNPLulMJWeIrM68hKy42PVqpK4kEOpOLO+Q
|
||||
9aZow1yn4ECZBmrssWP1egup8YEmlRKcAiB33wIDAQABAoIBACVlqZVLPX9jzieS
|
||||
0XHf8TnkaJ8WJNuVoGLvDuXa8j8gR61s2jn9UiiJqWyPTccfn9WToDkekopjqjVk
|
||||
U/3Ghvc3v9kQrMIMMXgGoBZJQijxM0y1rfhdWWJZAi1sXw4hJFtYvO5vp8Zr/TN8
|
||||
zOqcN/wJqDfe6BBNqu3fXQNe0F4MQeiLVYi7c1Q0ZupiALZDFPJ1u03xFiIzlMrN
|
||||
QLghfUoq4pFgqC08wR31XncvcWQ/iOggznxjy16Ezx1ubqGf7cMWZmXEWtdD0fsP
|
||||
8P3x/VS+MBzVtX9hhTaS3pVUAZKriCLF8kQiCUgtzlbUvKNrRb6gLan+OcD+J2sE
|
||||
0wopLZkCgYEA0BsLbbf0pc+PT+oCFUUueyADSl3SuH8j1YCpSU0nl0h6lE90cOen
|
||||
HSPRa4WHhhQm9lgCtTLXlHxJsZym0Lau7Nd90MIrjuvgRv0uOk07tRyThoGGuSCL
|
||||
2fBnD+a8NGjh+s/KTxmBDdWPkRpaZ5MVl8ZSGSM5zUZzplwPLx/J+wUCgYEAy4/W
|
||||
nd+rU4oh3Hm6cVp4YaktZ9cU/YB0yDd/sIm7bJ+kDyz0LSw7l/FSxMzQ+Dqybqht
|
||||
We+jn07BOh89r70vbcxx+4kMtHbg5Ii1u/R74AgGK6JSiKKpybLi7LA+3vcW/Hg6
|
||||
lemxE1U/PmmdvvSjzN/EXpeABkSgbctkJeoYRJMCgYBKLvnZ+NNrMBxEPoTTlD/H
|
||||
gFfr8JonTps1hpHSIYDVeu7HY7N8c/eseZIzo/v1ncVt113Pvfn/Ynbaq58Dk7uz
|
||||
jfW5rx3b6tWeOK579gAsxa0JK68c2y8/V2VF09iPTjwQLnZN0CejCNgOv7guZ84w
|
||||
tm+Zqmb2eADN8s8u20QjCQKBgQCoUHXHskKqX6Ph9nD3+zNgpQ8bNldvyMBHMMSP
|
||||
B0OG7HUt6yC3HUTlPLAQc74yEe6p2vAYFjK3rdnNojlST16hLhPtRQPRUB5iOLvz
|
||||
/pJSyq+3co9F1SII2bYSuSQzHiHOfecLP+CfuLQDejbpxsSNyVRIVoKQLDxurGdR
|
||||
hj+sqwKBgQC+x2dapmrh7qcCbPxbheWH32ds9GgI1Nr8eW2Wm0wIguLA4TrBN0UH
|
||||
HQZSdOjQoD/gTtHu79xbD1LPJk4kDtkvdzAlvbEds+3ArlaibNPcDaatkFAJt+2e
|
||||
2t8UDdIKzxOaKEF8YfTaeCpyS7CZoVw3frA9nkK7h38PgFeB7Vx2Rw==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
@@ -0,0 +1,82 @@
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 2 (0x2)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: C=GB, ST=Derbyshire, O=Paho Project, OU=Testing, CN=Signing CA
|
||||
Validity
|
||||
Not Before: Jul 7 11:14:42 2021 GMT
|
||||
Not After : Jul 6 11:14:42 2026 GMT
|
||||
Subject: C=GB, ST=Nottinghamshire, L=Nottingham, O=Server, OU=Production, CN=test client
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
RSA Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:d0:58:ed:ad:44:b4:f8:30:16:27:d9:b4:2c:b4:
|
||||
24:67:9a:19:fe:32:04:0d:9a:7e:75:97:12:d6:2c:
|
||||
d4:97:33:fb:30:8c:ef:a2:b1:ef:e5:92:d6:56:05:
|
||||
75:c8:19:82:92:4e:4b:13:8e:25:90:b9:21:72:f4:
|
||||
a4:bf:7a:e2:0f:75:52:08:04:4c:e8:6a:35:7e:7d:
|
||||
78:d9:b8:f7:2b:3d:8e:4e:b5:f3:7a:9a:06:10:50:
|
||||
ca:95:63:2c:bd:3a:89:d0:8a:84:12:32:9b:00:a7:
|
||||
25:33:70:d2:18:0a:43:94:12:62:e7:77:db:b8:0f:
|
||||
dc:23:48:95:5c:77:c6:11:4f:0f:d6:6e:73:59:7c:
|
||||
ed:6a:fd:ba:24:f0:b2:59:c3:a2:16:65:ad:19:7f:
|
||||
92:87:8c:ea:b5:e5:0f:26:f8:b1:74:98:c3:fd:ed:
|
||||
4d:74:d0:58:ce:d9:9c:24:34:9b:75:79:25:d0:aa:
|
||||
6c:03:03:0c:3a:4a:4c:9a:36:50:ab:55:74:1e:8b:
|
||||
de:41:a7:14:b9:57:ee:8b:31:90:5c:00:af:31:9d:
|
||||
e0:55:07:8d:05:ed:c9:5f:e1:79:b7:96:be:d9:5b:
|
||||
cf:a7:5c:cd:48:fc:bd:a4:34:bf:e0:49:d5:25:60:
|
||||
7a:4c:32:37:97:e4:f8:64:24:a6:79:c1:62:8d:93:
|
||||
52:53
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Basic Constraints:
|
||||
CA:FALSE
|
||||
Netscape Comment:
|
||||
OpenSSL Generated Certificate
|
||||
X509v3 Subject Key Identifier:
|
||||
61:62:90:E6:BB:8A:BB:06:6C:8A:66:9F:A5:C7:85:12:43:5C:94:6F
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:C2:8F:09:9B:D5:F1:BA:C4:74:5E:97:50:BB:86:9D:A1:F1:FA:C4:36
|
||||
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
a4:ad:a8:cf:8b:f1:c0:e5:ed:e0:9f:eb:b8:46:17:fe:cf:49:
|
||||
ed:e2:94:3b:3c:ea:4d:8b:e5:e3:5b:5f:f0:51:f0:53:88:22:
|
||||
61:fc:f9:9d:c3:67:5f:9c:20:f3:2c:bb:65:c3:66:d9:15:b8:
|
||||
60:82:31:95:d4:96:43:11:c1:56:da:4b:ad:bc:3f:b2:5f:3d:
|
||||
40:8d:e4:22:26:9b:d5:5d:ff:02:55:c1:f9:ca:f3:67:46:be:
|
||||
7d:d0:8c:68:40:a6:64:01:f0:ce:8e:2c:c2:6c:16:96:23:64:
|
||||
e6:2f:95:b9:95:a2:85:8e:ec:61:56:6f:b9:3a:87:e9:cc:f1:
|
||||
94:ca:51:d4:ce:50:01:91:1a:8c:ff:f9:cf:30:d4:aa:53:44:
|
||||
67:44:84:4c:07:a7:ab:c3:34:3a:16:69:8c:37:7f:a0:fb:e1:
|
||||
fa:ec:e6:9d:3c:fd:13:a9:6f:b2:d8:dc:46:81:ae:a6:63:4f:
|
||||
80:47:a7:80:51:a7:d4:d6:c8:11:85:7d:5f:ab:ef:3a:93:62:
|
||||
d7:fb:c2:a9:e4:b9:40:7e:d1:59:d0:d4:ff:75:bf:70:72:a2:
|
||||
93:a3:47:41:d8:cf:d5:c6:8c:90:b8:d3:01:d8:53:a6:c1:3c:
|
||||
a9:d9:e4:ef:15:e9:47:9c:9d:eb:5a:bb:11:df:da:f1:81:5d:
|
||||
89:c9:4a:8f
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDzjCCAragAwIBAgIBAjANBgkqhkiG9w0BAQsFADBgMQswCQYDVQQGEwJHQjET
|
||||
MBEGA1UECAwKRGVyYnlzaGlyZTEVMBMGA1UECgwMUGFobyBQcm9qZWN0MRAwDgYD
|
||||
VQQLDAdUZXN0aW5nMRMwEQYDVQQDDApTaWduaW5nIENBMB4XDTIxMDcwNzExMTQ0
|
||||
MloXDTI2MDcwNjExMTQ0MloweDELMAkGA1UEBhMCR0IxGDAWBgNVBAgMD05vdHRp
|
||||
bmdoYW1zaGlyZTETMBEGA1UEBwwKTm90dGluZ2hhbTEPMA0GA1UECgwGU2VydmVy
|
||||
MRMwEQYDVQQLDApQcm9kdWN0aW9uMRQwEgYDVQQDDAt0ZXN0IGNsaWVudDCCASIw
|
||||
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANBY7a1EtPgwFifZtCy0JGeaGf4y
|
||||
BA2afnWXEtYs1Jcz+zCM76Kx7+WS1lYFdcgZgpJOSxOOJZC5IXL0pL964g91UggE
|
||||
TOhqNX59eNm49ys9jk6183qaBhBQypVjLL06idCKhBIymwCnJTNw0hgKQ5QSYud3
|
||||
27gP3CNIlVx3xhFPD9Zuc1l87Wr9uiTwslnDohZlrRl/koeM6rXlDyb4sXSYw/3t
|
||||
TXTQWM7ZnCQ0m3V5JdCqbAMDDDpKTJo2UKtVdB6L3kGnFLlX7osxkFwArzGd4FUH
|
||||
jQXtyV/hebeWvtlbz6dczUj8vaQ0v+BJ1SVgekwyN5fk+GQkpnnBYo2TUlMCAwEA
|
||||
AaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0
|
||||
ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFGFikOa7irsGbIpmn6XHhRJDXJRvMB8G
|
||||
A1UdIwQYMBaAFMKPCZvV8brEdF6XULuGnaHx+sQ2MA0GCSqGSIb3DQEBCwUAA4IB
|
||||
AQCkrajPi/HA5e3gn+u4Rhf+z0nt4pQ7POpNi+XjW1/wUfBTiCJh/Pmdw2dfnCDz
|
||||
LLtlw2bZFbhggjGV1JZDEcFW2kutvD+yXz1AjeQiJpvVXf8CVcH5yvNnRr590Ixo
|
||||
QKZkAfDOjizCbBaWI2TmL5W5laKFjuxhVm+5OofpzPGUylHUzlABkRqM//nPMNSq
|
||||
U0RnRIRMB6erwzQ6FmmMN3+g++H67OadPP0TqW+y2NxGga6mY0+AR6eAUafU1sgR
|
||||
hX1fq+86k2LX+8Kp5LlAftFZ0NT/db9wcqKTo0dB2M/VxoyQuNMB2FOmwTyp2eTv
|
||||
FelHnJ3rWrsR39rxgV2JyUqP
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEA0FjtrUS0+DAWJ9m0LLQkZ5oZ/jIEDZp+dZcS1izUlzP7MIzv
|
||||
orHv5ZLWVgV1yBmCkk5LE44lkLkhcvSkv3riD3VSCARM6Go1fn142bj3Kz2OTrXz
|
||||
epoGEFDKlWMsvTqJ0IqEEjKbAKclM3DSGApDlBJi53fbuA/cI0iVXHfGEU8P1m5z
|
||||
WXztav26JPCyWcOiFmWtGX+Sh4zqteUPJvixdJjD/e1NdNBYztmcJDSbdXkl0Kps
|
||||
AwMMOkpMmjZQq1V0HoveQacUuVfuizGQXACvMZ3gVQeNBe3JX+F5t5a+2VvPp1zN
|
||||
SPy9pDS/4EnVJWB6TDI3l+T4ZCSmecFijZNSUwIDAQABAoIBAQC60zN1jsm0T/Je
|
||||
E6Kz/2kxmYa7YQAvbpz9NtYGRbbwSwVwuMBdpK9Yrj4Sbtz57J4gMaKyy2E2EDxF
|
||||
R8i/hyJU+D/xvmF0e2CypzKKEYlaNd15CUFma90KHlg6cu74VBimbr8VTlmd0UPT
|
||||
h9RtCC8nBQG5S8ozl80vunNssl5iv2JeXvVOL2sRagCr787XeGur74jW2rsh65M/
|
||||
ba6X3iv143D/1KNGiPAoGpP6vxvnOvM2K9+oqDf5SifmXfgSPIEoBd315YeQdGez
|
||||
BnOJHb7k2vokb+PsiTwjMsIf0AUqwKZPok+sLfaACxs4b2IrmFIYhcAcfyKkPD8i
|
||||
A1DpsEUhAoGBAPfKBnFNiMKc+JFM9lc01nQcdIKgtSmIPNUB7jOeg62oI3VzNp11
|
||||
9iw2qCQGJZwc1U3QbmNTAap2MxDss98kP2UZcBNDC0pxo+6F7XxIANRURXrG4NRg
|
||||
iPDu1lzubrbzXoh8XMxjKYacPP/gW/2VnxwhOyeIAt3mAN/Bu57t+XRxAoGBANdA
|
||||
UmcYtbu1rW8tzSuXRVgFTDhK1bORao58qJBP95MpFh/nQPB2Q1nu+nReo3870xE2
|
||||
6/R0gBv8gvKdEMVvhoDRlEJNhelQSg+yVQsX25gQcsKmR6/0IH+S0CH0PibS7o3G
|
||||
sjR9g27MitpX9MzzMR5R5IQErrDw01eOecGzzMUDAoGAc9IJiuJL33ORuBD6QC7h
|
||||
Yqp+RySpKT2V+ZaKabRZJk2mLVrqF1Ww+F+f3h7Fa6AKj/Gx91kwOSZAnlOVi+Kc
|
||||
gzwNp+M5ntVZY79UDzh0ssqlI0tcgciRmdR5fDyyoW9GK5O9qIddPJ9A3/VV6kUK
|
||||
dxKNXN/1PxUoKW6brSDc7fECgYB2BcCo4rWSrLThxv0+L31IG++E1hOCl/MTGWrb
|
||||
Zd1bhSWqbIQA1Pds8knFULbY5pZ+U9zgdphfv/6UxGYTu2jGbSObjyIjoXBaVu+m
|
||||
W3h+UlZ6P+4CnhrLmFYip+cEJpfCiPXhLgjI0cI4og2J6rY9560ibebTAdj/oxFD
|
||||
kjBuvQKBgBaKdaszx7MOBEGmmcv7HQ/prgi1s3UZbG5Jl98XS2xMVJO9N7x7k0hC
|
||||
SEj6kwlOSkpoiDEHSJ2s0j58Mnp5YxwPi61w3ZCnYg/iLgFfnJ972nliBw3wB/iD
|
||||
ZdYerxKGa6Btdbwt14rzE5QfzL8TiFapmq7JnY/rgE11Tx5SR06H
|
||||
-----END RSA PRIVATE KEY-----
|
||||
@@ -0,0 +1,12 @@
|
||||
-----BEGIN X509 CRL-----
|
||||
MIIBzzCBuAIBATANBgkqhkiG9w0BAQsFADBgMQswCQYDVQQGEwJHQjETMBEGA1UE
|
||||
CAwKRGVyYnlzaGlyZTEVMBMGA1UECgwMUGFobyBQcm9qZWN0MRAwDgYDVQQLDAdU
|
||||
ZXN0aW5nMRMwEQYDVQQDDApTaWduaW5nIENBFw0yMTA3MDcxMTE0NDNaFw0yMTA4
|
||||
MDYxMTE0NDNaMBQwEgIBBRcNMjEwNzA3MTExNDQzWqAOMAwwCgYDVR0UBAMCAQEw
|
||||
DQYJKoZIhvcNAQELBQADggEBAL+k0y+sONbBjgtGs6WX3AuKPNv+uEVSAdRR1UMX
|
||||
3KwcwT9jy/5ypT7dv7UNz5V3IR8t41sCN6E3rVvOv+DFn6Br+eabg6GR/iZMhoUq
|
||||
hqknHZZTeMZ5VwzDIZvINHtRvli2bC5/sfU0S44d19lWW4rCVz78c1zf8MvsDc9U
|
||||
fwjtZofTZr/8p7t5KIdohYCwlHu+ANxi7qCJIuPJyZaPQ4wUSbRtu6idvkgYgmpC
|
||||
O74Fe+/eg6zQwd/B1MZEVdBx+66PAyELnyCW+R9PgILzET+YMDni/lT1AYwnCCJ2
|
||||
lgiTIQlmyT/xlFCfmmzbsCkTcrMPym4m3zTOzbaeiYUBAco=
|
||||
-----END X509 CRL-----
|
||||
@@ -0,0 +1,82 @@
|
||||
#!/bin/sh
|
||||
# This file generates the keys and certificates used for testing mosquitto.
|
||||
# None of the keys are encrypted, so do not just use this script to generate
|
||||
# files for your own use.
|
||||
|
||||
set -e
|
||||
|
||||
rm -f *.crt *.key *.csr
|
||||
for a in root signing; do
|
||||
rm -rf ${a}CA/
|
||||
mkdir -p ${a}CA/newcerts
|
||||
touch ${a}CA/index.txt
|
||||
echo 01 > ${a}CA/serial
|
||||
echo 01 > ${a}CA/crlnumber
|
||||
done
|
||||
rm -rf certs
|
||||
|
||||
BASESUBJ="/C=GB/ST=Derbyshire/L=Derby/O=Paho Project/OU=Testing"
|
||||
SBASESUBJ="/C=GB/ST=Nottinghamshire/L=Nottingham/O=Server/OU=Production"
|
||||
BBASESUBJ="/C=GB/ST=Nottinghamshire/L=Nottingham/O=Server/OU=Bridge"
|
||||
|
||||
# The root CA
|
||||
openssl genrsa -out test-root-ca.key 2048
|
||||
openssl req -new -x509 -days 3650 -key test-root-ca.key -out test-root-ca.crt -config openssl.cnf -subj "${BASESUBJ}/CN=Root CA/"
|
||||
|
||||
# Another root CA that doesn't sign anything
|
||||
openssl genrsa -out test-bad-root-ca.key 2048
|
||||
openssl req -new -x509 -days 3650 -key test-bad-root-ca.key -out test-bad-root-ca.crt -config openssl.cnf -subj "${BASESUBJ}/CN=Bad Root CA/"
|
||||
|
||||
# This is a root CA that has the exact same details as the real root CA, but is a different key and certificate. Effectively a "fake" CA.
|
||||
openssl genrsa -out test-fake-root-ca.key 2048
|
||||
openssl req -new -x509 -days 3650 -key test-fake-root-ca.key -out test-fake-root-ca.crt -config openssl.cnf -subj "${BASESUBJ}/CN=Root CA/"
|
||||
|
||||
# An intermediate CA, signed by the root CA, used to sign server/client csrs.
|
||||
openssl genrsa -out test-signing-ca.key 2048
|
||||
openssl req -out test-signing-ca.csr -key test-signing-ca.key -new -config openssl.cnf -subj "${BASESUBJ}/CN=Signing CA/"
|
||||
openssl ca -batch -config openssl.cnf -name CA_root -extensions v3_ca -out test-signing-ca.crt -infiles test-signing-ca.csr
|
||||
|
||||
# An alternative intermediate CA, signed by the root CA, not used to sign anything.
|
||||
openssl genrsa -out test-alt-ca.key 2048
|
||||
openssl req -out test-alt-ca.csr -key test-alt-ca.key -new -config openssl.cnf -subj "${BASESUBJ}/CN=Alternative Signing CA/"
|
||||
openssl ca -batch -config openssl.cnf -name CA_root -extensions v3_ca -out test-alt-ca.crt -infiles test-alt-ca.csr
|
||||
|
||||
# Valid server key and certificate.
|
||||
openssl genrsa -out server.key 2048
|
||||
openssl req -new -key server.key -out server.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=localhost/"
|
||||
openssl ca -batch -config openssl.cnf -name CA_signing -out server.crt -infiles server.csr
|
||||
|
||||
# Expired server certificate, based on the above server key.
|
||||
openssl req -new -days 1 -key server.key -out server-expired.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=localhost/"
|
||||
echo -n > signingCA/index.txt
|
||||
echo 01 > signingCA/serial
|
||||
openssl ca -batch -config openssl.cnf -name CA_signing -days 1 -startdate 120820000000Z -enddate 120821000000Z -out server-expired.crt -infiles server-expired.csr
|
||||
|
||||
# Valid client key and certificate.
|
||||
openssl genrsa -out client.key 2048
|
||||
openssl req -new -key client.key -out client.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=test client/"
|
||||
openssl ca -batch -config openssl.cnf -name CA_signing -out client.crt -infiles client.csr
|
||||
|
||||
# Expired client certificate, based on the above client key.
|
||||
openssl req -new -days 1 -key client.key -out client-expired.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=test client expired/"
|
||||
openssl ca -batch -config openssl.cnf -name CA_signing -days 1 -startdate 120820000000Z -enddate 120821000000Z -out client-expired.crt -infiles client-expired.csr
|
||||
|
||||
# Valid client key and certificate, key is encrypted with a password.
|
||||
openssl genrsa -aes128 -passout pass:password -out client-pw.key 2048
|
||||
openssl req -new -key client-pw.key -passin pass:password -out client-pw.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=test client with password/"
|
||||
openssl ca -batch -config openssl.cnf -name CA_signing -out client-pw.crt -infiles client-pw.csr
|
||||
|
||||
# Revoked client certificate, based on a new client key.
|
||||
openssl genrsa -out client-revoked.key 2048
|
||||
openssl req -new -days 1 -key client-revoked.key -out client-revoked.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=test client revoked/"
|
||||
openssl ca -batch -config openssl.cnf -name CA_signing -out client-revoked.crt -infiles client-revoked.csr
|
||||
openssl ca -batch -config openssl.cnf -name CA_signing -revoke client-revoked.crt
|
||||
openssl ca -batch -config openssl.cnf -name CA_signing -gencrl -out crl.pem
|
||||
|
||||
cat test-signing-ca.crt test-root-ca.crt > all-ca.crt
|
||||
#mkdir certs
|
||||
#cp test-signing-ca.crt certs/test-signing-ca.pem
|
||||
#cp test-root-ca.crt certs/test-root.ca.pem
|
||||
c_rehash certs
|
||||
|
||||
rm -f client-expired.csr client-revoked.csr server-expired.csr server.csr test-alt-ca.csr
|
||||
@@ -0,0 +1,406 @@
|
||||
#
|
||||
# OpenSSL example configuration file.
|
||||
# This is mostly being used for generation of certificate requests.
|
||||
#
|
||||
|
||||
# This definition stops the following lines choking if HOME isn't
|
||||
# defined.
|
||||
HOME = .
|
||||
RANDFILE = $ENV::HOME/.rnd
|
||||
|
||||
# Extra OBJECT IDENTIFIER info:
|
||||
#oid_file = $ENV::HOME/.oid
|
||||
oid_section = new_oids
|
||||
|
||||
# To use this configuration file with the "-extfile" option of the
|
||||
# "openssl x509" utility, name here the section containing the
|
||||
# X.509v3 extensions to use:
|
||||
# extensions =
|
||||
# (Alternatively, use a configuration file that has only
|
||||
# X.509v3 extensions in its main [= default] section.)
|
||||
|
||||
[ new_oids ]
|
||||
|
||||
# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
|
||||
# Add a simple OID like this:
|
||||
# testoid1=1.2.3.4
|
||||
# Or use config file substitution like this:
|
||||
# testoid2=${testoid1}.5.6
|
||||
|
||||
# Policies used by the TSA examples.
|
||||
tsa_policy1 = 1.2.3.4.1
|
||||
tsa_policy2 = 1.2.3.4.5.6
|
||||
tsa_policy3 = 1.2.3.4.5.7
|
||||
|
||||
####################################################################
|
||||
[ ca ]
|
||||
default_ca = CA_default # The default ca section
|
||||
|
||||
####################################################################
|
||||
[ CA_signing ]
|
||||
|
||||
dir = ./signingCA # Where everything is kept
|
||||
certs = $dir/certs # Where the issued certs are kept
|
||||
crl_dir = $dir/crl # Where the issued crl are kept
|
||||
database = $dir/index.txt # database index file.
|
||||
#unique_subject = no # Set to 'no' to allow creation of
|
||||
# several certificates with same subject.
|
||||
new_certs_dir = $dir/newcerts # default place for new certs.
|
||||
|
||||
certificate = test-signing-ca.crt # The CA certificate
|
||||
serial = $dir/serial # The current serial number
|
||||
crlnumber = $dir/crlnumber # the current crl number
|
||||
# must be commented out to leave a V1 CRL
|
||||
crl = $dir/crl.pem # The current CRL
|
||||
private_key = test-signing-ca.key # The private key
|
||||
RANDFILE = $dir/.rand # private random number file
|
||||
|
||||
x509_extensions = usr_cert # The extensions to add to the cert
|
||||
|
||||
# Comment out the following two lines for the "traditional"
|
||||
# (and highly broken) format.
|
||||
name_opt = ca_default # Subject Name options
|
||||
cert_opt = ca_default # Certificate field options
|
||||
|
||||
# Extension copying option: use with caution.
|
||||
# copy_extensions = copy
|
||||
|
||||
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
|
||||
# so this is commented out by default to leave a V1 CRL.
|
||||
# crlnumber must also be commented out to leave a V1 CRL.
|
||||
# crl_extensions = crl_ext
|
||||
|
||||
default_days = 1825 # how long to certify for
|
||||
default_crl_days= 30 # how long before next CRL
|
||||
default_md = default # use public key default MD
|
||||
preserve = no # keep passed DN ordering
|
||||
|
||||
# A few difference way of specifying how similar the request should look
|
||||
# For type CA, the listed attributes must be the same, and the optional
|
||||
# and supplied fields are just that :-)
|
||||
policy = policy_anything
|
||||
|
||||
[ CA_inter ]
|
||||
dir = ./interCA
|
||||
certs = $dir/certs
|
||||
crl_dir = $dir/crl
|
||||
database = $dir/index.txt
|
||||
new_certs_dir = $dir/newcerts
|
||||
|
||||
certificate = test-inter-ca.crt
|
||||
serial = $dir/serial
|
||||
crlnumber = $dir/crlnumber
|
||||
crl = $dir/crl.pem
|
||||
private_key = test-inter-ca.key
|
||||
RANDFILE = $dir/.rand
|
||||
|
||||
#x509_extensions = v3_ca
|
||||
x509_extensions = usr_cert
|
||||
|
||||
name_opt = ca_default
|
||||
cert_opt = ca_default
|
||||
|
||||
default_days = 1825
|
||||
default_crl_days = 30
|
||||
default_md = default
|
||||
preserve = no
|
||||
|
||||
policy = policy_match
|
||||
unique_subject = yes
|
||||
|
||||
[ CA_root ]
|
||||
dir = ./rootCA
|
||||
certs = $dir/certs
|
||||
crl_dir = $dir/crl
|
||||
database = $dir/index.txt
|
||||
new_certs_dir = $dir/newcerts
|
||||
|
||||
certificate = test-root-ca.crt
|
||||
serial = $dir/serial
|
||||
crlnumber = $dir/crlnumber
|
||||
crl = $dir/crl.pem
|
||||
private_key = test-root-ca.key
|
||||
RANDFILE = $dir/.rand
|
||||
|
||||
x509_extensions = v3_ca
|
||||
|
||||
name_opt = ca_default
|
||||
cert_opt = ca_default
|
||||
|
||||
default_days = 1825
|
||||
default_crl_days = 30
|
||||
default_md = default
|
||||
preserve = no
|
||||
|
||||
policy = policy_match
|
||||
unique_subject = yes
|
||||
|
||||
# For the CA policy
|
||||
[ policy_match ]
|
||||
countryName = match
|
||||
stateOrProvinceName = match
|
||||
organizationName = match
|
||||
organizationalUnitName = optional
|
||||
commonName = supplied
|
||||
emailAddress = optional
|
||||
|
||||
# For the 'anything' policy
|
||||
# At this point in time, you must list all acceptable 'object'
|
||||
# types.
|
||||
[ policy_anything ]
|
||||
countryName = optional
|
||||
stateOrProvinceName = optional
|
||||
localityName = optional
|
||||
organizationName = optional
|
||||
organizationalUnitName = optional
|
||||
commonName = supplied
|
||||
emailAddress = optional
|
||||
|
||||
####################################################################
|
||||
[ req ]
|
||||
default_bits = 2048
|
||||
default_keyfile = privkey.pem
|
||||
distinguished_name = req_distinguished_name
|
||||
attributes = req_attributes
|
||||
x509_extensions = v3_ca # The extensions to add to the self signed cert
|
||||
|
||||
# Passwords for private keys if not present they will be prompted for
|
||||
# input_password = secret
|
||||
# output_password = secret
|
||||
|
||||
# This sets a mask for permitted string types. There are several options.
|
||||
# default: PrintableString, T61String, BMPString.
|
||||
# pkix : PrintableString, BMPString (PKIX recommendation before 2004)
|
||||
# utf8only: only UTF8Strings (PKIX recommendation after 2004).
|
||||
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
|
||||
# MASK:XXXX a literal mask value.
|
||||
# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
|
||||
string_mask = utf8only
|
||||
|
||||
# req_extensions = v3_req # The extensions to add to a certificate request
|
||||
|
||||
[ req_distinguished_name ]
|
||||
countryName = Country Name (2 letter code)
|
||||
countryName_default = GB
|
||||
countryName_min = 2
|
||||
countryName_max = 2
|
||||
|
||||
stateOrProvinceName = State or Province Name (full name)
|
||||
stateOrProvinceName_default = Derbyshire
|
||||
|
||||
localityName = Locality Name (eg, city)
|
||||
localityName_default = Derby
|
||||
|
||||
0.organizationName = Organization Name (eg, company)
|
||||
0.organizationName_default = Paho Project
|
||||
|
||||
# we can do this but it is not needed normally :-)
|
||||
#1.organizationName = Second Organization Name (eg, company)
|
||||
#1.organizationName_default = World Wide Web Pty Ltd
|
||||
|
||||
organizationalUnitName = Organizational Unit Name (eg, section)
|
||||
organizationalUnitName_default = Testing
|
||||
|
||||
commonName = Common Name (e.g. server FQDN or YOUR name)
|
||||
commonName_max = 64
|
||||
|
||||
emailAddress = Email Address
|
||||
emailAddress_max = 64
|
||||
|
||||
# SET-ex3 = SET extension number 3
|
||||
|
||||
[ req_attributes ]
|
||||
challengePassword = A challenge password
|
||||
challengePassword_min = 4
|
||||
challengePassword_max = 20
|
||||
|
||||
unstructuredName = An optional company name
|
||||
|
||||
[ usr_cert ]
|
||||
|
||||
# These extensions are added when 'ca' signs a request.
|
||||
|
||||
# This goes against PKIX guidelines but some CAs do it and some software
|
||||
# requires this to avoid interpreting an end user certificate as a CA.
|
||||
|
||||
basicConstraints=CA:FALSE
|
||||
|
||||
# Here are some examples of the usage of nsCertType. If it is omitted
|
||||
# the certificate can be used for anything *except* object signing.
|
||||
|
||||
# This is OK for an SSL server.
|
||||
# nsCertType = server
|
||||
|
||||
# For an object signing certificate this would be used.
|
||||
# nsCertType = objsign
|
||||
|
||||
# For normal client use this is typical
|
||||
# nsCertType = client, email
|
||||
|
||||
# and for everything including object signing:
|
||||
# nsCertType = client, email, objsign
|
||||
|
||||
# This is typical in keyUsage for a client certificate.
|
||||
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
|
||||
# This will be displayed in Netscape's comment listbox.
|
||||
nsComment = "OpenSSL Generated Certificate"
|
||||
|
||||
# PKIX recommendations harmless if included in all certificates.
|
||||
subjectKeyIdentifier=hash
|
||||
authorityKeyIdentifier=keyid,issuer
|
||||
|
||||
# This stuff is for subjectAltName and issuerAltname.
|
||||
# Import the email address.
|
||||
# subjectAltName=email:copy
|
||||
# An alternative to produce certificates that aren't
|
||||
# deprecated according to PKIX.
|
||||
# subjectAltName=email:move
|
||||
|
||||
# Copy subject details
|
||||
# issuerAltName=issuer:copy
|
||||
|
||||
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
|
||||
#nsBaseUrl
|
||||
#nsRevocationUrl
|
||||
#nsRenewalUrl
|
||||
#nsCaPolicyUrl
|
||||
#nsSslServerName
|
||||
|
||||
# This is required for TSA certificates.
|
||||
# extendedKeyUsage = critical,timeStamping
|
||||
|
||||
[ v3_req ]
|
||||
|
||||
# Extensions to add to a certificate request
|
||||
|
||||
basicConstraints = CA:FALSE
|
||||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
|
||||
[ v3_ca ]
|
||||
|
||||
|
||||
# Extensions for a typical CA
|
||||
|
||||
|
||||
# PKIX recommendation.
|
||||
|
||||
subjectKeyIdentifier=hash
|
||||
|
||||
authorityKeyIdentifier=keyid:always,issuer
|
||||
|
||||
# This is what PKIX recommends but some broken software chokes on critical
|
||||
# extensions.
|
||||
#basicConstraints = critical,CA:true
|
||||
# So we do this instead.
|
||||
basicConstraints = CA:true
|
||||
|
||||
# Key usage: this is typical for a CA certificate. However since it will
|
||||
# prevent it being used as an test self-signed certificate it is best
|
||||
# left out by default.
|
||||
# keyUsage = cRLSign, keyCertSign
|
||||
|
||||
# Some might want this also
|
||||
# nsCertType = sslCA, emailCA
|
||||
|
||||
# Include email address in subject alt name: another PKIX recommendation
|
||||
# subjectAltName=email:copy
|
||||
# Copy issuer details
|
||||
# issuerAltName=issuer:copy
|
||||
|
||||
# DER hex encoding of an extension: beware experts only!
|
||||
# obj=DER:02:03
|
||||
# Where 'obj' is a standard or added object
|
||||
# You can even override a supported extension:
|
||||
# basicConstraints= critical, DER:30:03:01:01:FF
|
||||
|
||||
[ crl_ext ]
|
||||
|
||||
# CRL extensions.
|
||||
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
|
||||
|
||||
# issuerAltName=issuer:copy
|
||||
authorityKeyIdentifier=keyid:always
|
||||
|
||||
[ proxy_cert_ext ]
|
||||
# These extensions should be added when creating a proxy certificate
|
||||
|
||||
# This goes against PKIX guidelines but some CAs do it and some software
|
||||
# requires this to avoid interpreting an end user certificate as a CA.
|
||||
|
||||
basicConstraints=CA:FALSE
|
||||
|
||||
# Here are some examples of the usage of nsCertType. If it is omitted
|
||||
# the certificate can be used for anything *except* object signing.
|
||||
|
||||
# This is OK for an SSL server.
|
||||
# nsCertType = server
|
||||
|
||||
# For an object signing certificate this would be used.
|
||||
# nsCertType = objsign
|
||||
|
||||
# For normal client use this is typical
|
||||
# nsCertType = client, email
|
||||
|
||||
# and for everything including object signing:
|
||||
# nsCertType = client, email, objsign
|
||||
|
||||
# This is typical in keyUsage for a client certificate.
|
||||
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
|
||||
# This will be displayed in Netscape's comment listbox.
|
||||
nsComment = "OpenSSL Generated Certificate"
|
||||
|
||||
# PKIX recommendations harmless if included in all certificates.
|
||||
subjectKeyIdentifier=hash
|
||||
authorityKeyIdentifier=keyid,issuer
|
||||
|
||||
# This stuff is for subjectAltName and issuerAltname.
|
||||
# Import the email address.
|
||||
# subjectAltName=email:copy
|
||||
# An alternative to produce certificates that aren't
|
||||
# deprecated according to PKIX.
|
||||
# subjectAltName=email:move
|
||||
|
||||
# Copy subject details
|
||||
# issuerAltName=issuer:copy
|
||||
|
||||
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
|
||||
#nsBaseUrl
|
||||
#nsRevocationUrl
|
||||
#nsRenewalUrl
|
||||
#nsCaPolicyUrl
|
||||
#nsSslServerName
|
||||
|
||||
# This really needs to be in place for it to be a proxy certificate.
|
||||
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
|
||||
|
||||
####################################################################
|
||||
[ tsa ]
|
||||
|
||||
default_tsa = tsa_config1 # the default TSA section
|
||||
|
||||
[ tsa_config1 ]
|
||||
|
||||
# These are used by the TSA reply generation only.
|
||||
dir = ./demoCA # TSA root directory
|
||||
serial = $dir/tsaserial # The current serial number (mandatory)
|
||||
crypto_device = builtin # OpenSSL engine to use for signing
|
||||
signer_cert = $dir/tsacert.pem # The TSA signing certificate
|
||||
# (optional)
|
||||
certs = $dir/cacert.pem # Certificate chain to include in reply
|
||||
# (optional)
|
||||
signer_key = $dir/private/tsakey.pem # The TSA private key (optional)
|
||||
|
||||
default_policy = tsa_policy1 # Policy if request did not specify it
|
||||
# (optional)
|
||||
other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
|
||||
digests = md5, sha1 # Acceptable message digests (mandatory)
|
||||
accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
|
||||
clock_precision_digits = 0 # number of digits after dot. (optional)
|
||||
ordering = yes # Is ordering defined for timestamps?
|
||||
# (optional, default: no)
|
||||
tsa_name = yes # Must the TSA name be included in the reply?
|
||||
# (optional, default: no)
|
||||
ess_cert_id_chain = no # Must the ESS cert id chain be included?
|
||||
# (optional, default: no)
|
||||
@@ -0,0 +1,82 @@
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 1 (0x1)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: C=GB, ST=Derbyshire, O=Paho Project, OU=Testing, CN=Signing CA
|
||||
Validity
|
||||
Not Before: Aug 20 00:00:00 2012 GMT
|
||||
Not After : Aug 21 00:00:00 2012 GMT
|
||||
Subject: C=GB, ST=Nottinghamshire, L=Nottingham, O=Server, OU=Production, CN=localhost
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
RSA Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:a9:4c:88:db:56:36:f8:fc:e1:eb:6b:ad:9c:0f:
|
||||
78:3e:7d:d7:34:c6:83:94:6d:83:07:d5:3e:cb:fb:
|
||||
95:61:e5:73:78:43:db:51:d9:a0:4e:ec:8e:43:21:
|
||||
91:1f:56:95:08:47:7c:83:38:90:bb:53:91:ed:fd:
|
||||
b4:bd:08:27:dd:d6:d9:5b:fd:bb:84:1e:2e:62:d9:
|
||||
3c:1d:4d:c9:6b:17:45:d7:9e:b4:a5:9c:22:cd:14:
|
||||
41:32:c3:41:ad:8d:f5:2f:a3:d5:59:1f:a1:2b:67:
|
||||
d3:01:83:64:93:80:6b:bf:5a:b8:51:86:20:a0:e4:
|
||||
3f:18:0c:67:19:8d:e3:58:6d:85:83:8f:8b:37:b2:
|
||||
7d:21:3f:65:cf:19:53:2e:56:df:4d:89:50:7e:8c:
|
||||
6a:8e:dd:21:15:15:31:9b:c2:5c:98:68:1e:31:ff:
|
||||
c6:6c:1f:a8:42:b8:da:62:dc:ae:62:4c:40:f0:06:
|
||||
c6:e6:f4:a9:98:3d:ed:fb:c0:2a:63:da:60:69:83:
|
||||
11:0e:ce:ba:93:d7:4b:27:8f:86:91:ef:e4:65:5f:
|
||||
20:be:04:f2:4d:d6:d1:74:c5:ab:e9:18:df:16:f9:
|
||||
9a:8a:ff:2f:23:c5:46:3e:04:16:4e:fa:c1:0a:f4:
|
||||
dc:8e:1a:da:5f:a1:ad:50:7a:5d:60:00:3e:09:b8:
|
||||
8e:6d
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Basic Constraints:
|
||||
CA:FALSE
|
||||
Netscape Comment:
|
||||
OpenSSL Generated Certificate
|
||||
X509v3 Subject Key Identifier:
|
||||
C3:47:33:CF:07:18:14:7C:9A:E4:AB:11:62:89:88:54:3D:5D:7D:E8
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:C2:8F:09:9B:D5:F1:BA:C4:74:5E:97:50:BB:86:9D:A1:F1:FA:C4:36
|
||||
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
ca:b6:c4:8a:76:e2:14:01:2f:58:ea:5f:28:f3:1d:de:a5:73:
|
||||
17:13:d0:5a:2f:51:f8:a7:79:34:06:9d:73:8e:c9:bd:ba:e4:
|
||||
03:64:7b:fc:29:b1:f3:4a:22:a1:bd:31:7a:4e:03:0d:f0:0c:
|
||||
b0:d8:40:03:7a:b6:a5:2a:ff:78:0b:de:49:7b:ee:11:97:52:
|
||||
2a:df:68:53:d3:88:ac:bd:f2:04:25:68:04:12:8f:ea:26:05:
|
||||
0d:9b:71:76:a9:cd:ff:99:78:44:86:07:56:04:14:c6:d7:1d:
|
||||
63:6e:9f:07:76:95:0b:a0:2b:a2:0d:c4:79:ff:80:c2:80:cb:
|
||||
83:c3:ec:ae:46:62:bb:09:71:c9:65:00:b8:6a:13:a4:a7:31:
|
||||
ad:ff:81:97:1c:84:1e:16:d5:c2:69:83:88:63:2d:33:31:52:
|
||||
1b:fc:dc:c7:40:5c:c8:3e:0a:15:87:7f:82:47:8d:3e:f2:3e:
|
||||
43:34:c1:8f:9c:16:61:1e:17:3f:4b:37:e1:aa:80:ad:87:09:
|
||||
cb:5c:fe:5a:28:4d:85:ca:45:58:6f:a6:ab:e2:f7:7a:24:c9:
|
||||
34:2a:75:b9:29:b8:db:cf:0b:72:e3:89:06:d6:6c:a9:9f:82:
|
||||
e6:0f:90:b9:1a:4e:d1:f1:24:32:79:77:d3:cf:8f:27:64:f3:
|
||||
d6:3e:ff:45
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDzDCCArSgAwIBAgIBATANBgkqhkiG9w0BAQsFADBgMQswCQYDVQQGEwJHQjET
|
||||
MBEGA1UECAwKRGVyYnlzaGlyZTEVMBMGA1UECgwMUGFobyBQcm9qZWN0MRAwDgYD
|
||||
VQQLDAdUZXN0aW5nMRMwEQYDVQQDDApTaWduaW5nIENBMB4XDTEyMDgyMDAwMDAw
|
||||
MFoXDTEyMDgyMTAwMDAwMFowdjELMAkGA1UEBhMCR0IxGDAWBgNVBAgMD05vdHRp
|
||||
bmdoYW1zaGlyZTETMBEGA1UEBwwKTm90dGluZ2hhbTEPMA0GA1UECgwGU2VydmVy
|
||||
MRMwEQYDVQQLDApQcm9kdWN0aW9uMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0G
|
||||
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpTIjbVjb4/OHra62cD3g+fdc0xoOU
|
||||
bYMH1T7L+5Vh5XN4Q9tR2aBO7I5DIZEfVpUIR3yDOJC7U5Ht/bS9CCfd1tlb/buE
|
||||
Hi5i2TwdTclrF0XXnrSlnCLNFEEyw0GtjfUvo9VZH6ErZ9MBg2STgGu/WrhRhiCg
|
||||
5D8YDGcZjeNYbYWDj4s3sn0hP2XPGVMuVt9NiVB+jGqO3SEVFTGbwlyYaB4x/8Zs
|
||||
H6hCuNpi3K5iTEDwBsbm9KmYPe37wCpj2mBpgxEOzrqT10snj4aR7+RlXyC+BPJN
|
||||
1tF0xavpGN8W+ZqK/y8jxUY+BBZO+sEK9NyOGtpfoa1Qel1gAD4JuI5tAgMBAAGj
|
||||
ezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVk
|
||||
IENlcnRpZmljYXRlMB0GA1UdDgQWBBTDRzPPBxgUfJrkqxFiiYhUPV196DAfBgNV
|
||||
HSMEGDAWgBTCjwmb1fG6xHRel1C7hp2h8frENjANBgkqhkiG9w0BAQsFAAOCAQEA
|
||||
yrbEinbiFAEvWOpfKPMd3qVzFxPQWi9R+Kd5NAadc47JvbrkA2R7/Cmx80oiob0x
|
||||
ek4DDfAMsNhAA3q2pSr/eAveSXvuEZdSKt9oU9OIrL3yBCVoBBKP6iYFDZtxdqnN
|
||||
/5l4RIYHVgQUxtcdY26fB3aVC6Arog3Eef+AwoDLg8PsrkZiuwlxyWUAuGoTpKcx
|
||||
rf+BlxyEHhbVwmmDiGMtMzFSG/zcx0BcyD4KFYd/gkeNPvI+QzTBj5wWYR4XP0s3
|
||||
4aqArYcJy1z+WihNhcpFWG+mq+L3eiTJNCp1uSm4288LcuOJBtZsqZ+C5g+QuRpO
|
||||
0fEkMnl308+PJ2Tz1j7/RQ==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,82 @@
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 1 (0x1)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: C=GB, ST=Derbyshire, O=Paho Project, OU=Testing, CN=Signing CA
|
||||
Validity
|
||||
Not Before: Jul 7 11:14:42 2021 GMT
|
||||
Not After : Jul 6 11:14:42 2026 GMT
|
||||
Subject: C=GB, ST=Nottinghamshire, L=Nottingham, O=Server, OU=Production, CN=localhost
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
RSA Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:a9:4c:88:db:56:36:f8:fc:e1:eb:6b:ad:9c:0f:
|
||||
78:3e:7d:d7:34:c6:83:94:6d:83:07:d5:3e:cb:fb:
|
||||
95:61:e5:73:78:43:db:51:d9:a0:4e:ec:8e:43:21:
|
||||
91:1f:56:95:08:47:7c:83:38:90:bb:53:91:ed:fd:
|
||||
b4:bd:08:27:dd:d6:d9:5b:fd:bb:84:1e:2e:62:d9:
|
||||
3c:1d:4d:c9:6b:17:45:d7:9e:b4:a5:9c:22:cd:14:
|
||||
41:32:c3:41:ad:8d:f5:2f:a3:d5:59:1f:a1:2b:67:
|
||||
d3:01:83:64:93:80:6b:bf:5a:b8:51:86:20:a0:e4:
|
||||
3f:18:0c:67:19:8d:e3:58:6d:85:83:8f:8b:37:b2:
|
||||
7d:21:3f:65:cf:19:53:2e:56:df:4d:89:50:7e:8c:
|
||||
6a:8e:dd:21:15:15:31:9b:c2:5c:98:68:1e:31:ff:
|
||||
c6:6c:1f:a8:42:b8:da:62:dc:ae:62:4c:40:f0:06:
|
||||
c6:e6:f4:a9:98:3d:ed:fb:c0:2a:63:da:60:69:83:
|
||||
11:0e:ce:ba:93:d7:4b:27:8f:86:91:ef:e4:65:5f:
|
||||
20:be:04:f2:4d:d6:d1:74:c5:ab:e9:18:df:16:f9:
|
||||
9a:8a:ff:2f:23:c5:46:3e:04:16:4e:fa:c1:0a:f4:
|
||||
dc:8e:1a:da:5f:a1:ad:50:7a:5d:60:00:3e:09:b8:
|
||||
8e:6d
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Basic Constraints:
|
||||
CA:FALSE
|
||||
Netscape Comment:
|
||||
OpenSSL Generated Certificate
|
||||
X509v3 Subject Key Identifier:
|
||||
C3:47:33:CF:07:18:14:7C:9A:E4:AB:11:62:89:88:54:3D:5D:7D:E8
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:C2:8F:09:9B:D5:F1:BA:C4:74:5E:97:50:BB:86:9D:A1:F1:FA:C4:36
|
||||
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
a9:34:8d:b4:6c:99:14:e7:10:dc:36:7e:c2:24:7f:bf:9d:65:
|
||||
4c:2b:50:90:13:de:85:29:d7:b0:d5:c2:a0:d6:c2:42:40:9f:
|
||||
6a:b7:6a:05:cf:7e:57:ff:2c:3c:ba:0c:cf:e7:0a:92:89:6e:
|
||||
8b:bb:0c:b5:28:79:00:76:ed:12:cc:54:79:05:41:88:26:c9:
|
||||
e3:a8:6b:ba:1a:31:92:e6:40:2c:c6:a9:e8:4b:1b:4c:25:f1:
|
||||
7b:c5:19:0b:73:37:53:86:d5:8e:d1:1c:78:73:e4:a5:84:0f:
|
||||
49:5a:eb:80:15:09:c2:69:83:34:c0:da:db:9d:fa:eb:32:1f:
|
||||
e0:2e:99:f2:b0:76:91:8a:eb:34:b5:4d:c9:79:2a:f8:ef:f0:
|
||||
6d:55:a4:9d:f9:5f:61:d3:f8:ab:95:0a:12:12:64:33:c3:2f:
|
||||
6b:64:14:31:bf:42:c9:c8:9e:be:45:4f:02:c8:50:54:be:79:
|
||||
fe:e2:9a:fa:2d:b7:73:25:34:ea:53:dd:03:a4:f9:82:28:a7:
|
||||
95:37:f7:45:56:21:7a:e6:71:eb:95:34:99:15:1c:26:ac:00:
|
||||
bc:95:b0:91:d8:8a:d0:0d:98:8e:28:d7:76:14:b6:94:c9:ab:
|
||||
df:87:40:58:12:da:ee:65:d8:08:f2:05:f2:5e:3e:d2:8d:09:
|
||||
38:8f:b2:79
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDzDCCArSgAwIBAgIBATANBgkqhkiG9w0BAQsFADBgMQswCQYDVQQGEwJHQjET
|
||||
MBEGA1UECAwKRGVyYnlzaGlyZTEVMBMGA1UECgwMUGFobyBQcm9qZWN0MRAwDgYD
|
||||
VQQLDAdUZXN0aW5nMRMwEQYDVQQDDApTaWduaW5nIENBMB4XDTIxMDcwNzExMTQ0
|
||||
MloXDTI2MDcwNjExMTQ0MlowdjELMAkGA1UEBhMCR0IxGDAWBgNVBAgMD05vdHRp
|
||||
bmdoYW1zaGlyZTETMBEGA1UEBwwKTm90dGluZ2hhbTEPMA0GA1UECgwGU2VydmVy
|
||||
MRMwEQYDVQQLDApQcm9kdWN0aW9uMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0G
|
||||
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpTIjbVjb4/OHra62cD3g+fdc0xoOU
|
||||
bYMH1T7L+5Vh5XN4Q9tR2aBO7I5DIZEfVpUIR3yDOJC7U5Ht/bS9CCfd1tlb/buE
|
||||
Hi5i2TwdTclrF0XXnrSlnCLNFEEyw0GtjfUvo9VZH6ErZ9MBg2STgGu/WrhRhiCg
|
||||
5D8YDGcZjeNYbYWDj4s3sn0hP2XPGVMuVt9NiVB+jGqO3SEVFTGbwlyYaB4x/8Zs
|
||||
H6hCuNpi3K5iTEDwBsbm9KmYPe37wCpj2mBpgxEOzrqT10snj4aR7+RlXyC+BPJN
|
||||
1tF0xavpGN8W+ZqK/y8jxUY+BBZO+sEK9NyOGtpfoa1Qel1gAD4JuI5tAgMBAAGj
|
||||
ezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVk
|
||||
IENlcnRpZmljYXRlMB0GA1UdDgQWBBTDRzPPBxgUfJrkqxFiiYhUPV196DAfBgNV
|
||||
HSMEGDAWgBTCjwmb1fG6xHRel1C7hp2h8frENjANBgkqhkiG9w0BAQsFAAOCAQEA
|
||||
qTSNtGyZFOcQ3DZ+wiR/v51lTCtQkBPehSnXsNXCoNbCQkCfardqBc9+V/8sPLoM
|
||||
z+cKkolui7sMtSh5AHbtEsxUeQVBiCbJ46hruhoxkuZALMap6EsbTCXxe8UZC3M3
|
||||
U4bVjtEceHPkpYQPSVrrgBUJwmmDNMDa25366zIf4C6Z8rB2kYrrNLVNyXkq+O/w
|
||||
bVWknflfYdP4q5UKEhJkM8Mva2QUMb9CycievkVPAshQVL55/uKa+i23cyU06lPd
|
||||
A6T5giinlTf3RVYheuZx65U0mRUcJqwAvJWwkdiK0A2YjijXdhS2lMmr34dAWBLa
|
||||
7mXYCPIF8l4+0o0JOI+yeQ==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAqUyI21Y2+Pzh62utnA94Pn3XNMaDlG2DB9U+y/uVYeVzeEPb
|
||||
UdmgTuyOQyGRH1aVCEd8gziQu1OR7f20vQgn3dbZW/27hB4uYtk8HU3JaxdF1560
|
||||
pZwizRRBMsNBrY31L6PVWR+hK2fTAYNkk4Brv1q4UYYgoOQ/GAxnGY3jWG2Fg4+L
|
||||
N7J9IT9lzxlTLlbfTYlQfoxqjt0hFRUxm8JcmGgeMf/GbB+oQrjaYtyuYkxA8AbG
|
||||
5vSpmD3t+8AqY9pgaYMRDs66k9dLJ4+Gke/kZV8gvgTyTdbRdMWr6RjfFvmaiv8v
|
||||
I8VGPgQWTvrBCvTcjhraX6GtUHpdYAA+CbiObQIDAQABAoIBAFAbWL6AIu7ZqYSd
|
||||
pL4tS7Y2ETh1nhkDYHa6XkZiuqJh0atcYFBwazwtDnuRTHvJmicavD3S7BjXSDuW
|
||||
SokPbN25JYwzmSDAry4yoBE1l1LG5lNKUyvxnz3ukZMVdORMQXHTUcYkAzzomZ0j
|
||||
sNlicJlQsdpRXusCVSBp7fbXfnV+SCRA0JZrMkCmkkQASpzlfZaDYxT+QYzNZ7aS
|
||||
W4c+YwLEaSyVRPmWdelj17d1XP5RdnsL6Fhho6wNRoT18tgSvvl1cWv+/e+eMGFQ
|
||||
hxmTJmcBxTTxVDF1+bHIYNHkxHD4OEcrYIP99wwYg9zanO9edxD1OSY5a0xupNns
|
||||
E9r517kCgYEA0S76Kz0UOmuLnT7KUs6dq5fXq+LJU5Dp6cnMiEtz65VqgBUEwRGn
|
||||
WNPKDzMQ5SrfNCw6aEpRwPSJOPRoRbFvCZ1ZqHzunjOhssIjGiMMJq+WpckgoX8b
|
||||
kvzzCpf8DfEHep7PAu/ixKZs5Jm6wliF52dWt6rgYEPK33A4qa9R1aMCgYEAzzBm
|
||||
gqQ4DZy/ZkUp0GZ1gPJ+wpKJug96Bb7PMMnCtVtcfTtjyR1q7JWaZdli1vCKlMKW
|
||||
/sOmydD8uPkKhnxy6Ksz5u5/ZCBxkANGnEOc3ED3v7wXHCoiQwsl59lH0yoqx4ua
|
||||
Ur59L/ZVTMZAjtpci2NTTMN+mezR9LXvQb2qrK8CgYEAjVjs+mKfVIpvIKXZGPM8
|
||||
X0KPHTp1R95X8P3HEyHJBptEB6AsQjmnlsIlevfKps+9Wwe3v9jYPUX/o1ijTNSE
|
||||
bz6/4rXol0XUMXI1PegIwetMJGIvhnDZNQ1vPO1OCC2iHB1LTHTECpVaZ23pYIFo
|
||||
meCeHCV+0A1+/FRcNWyeI3kCgYBgFnhUOkjstzdk/MqJphr0tIHpRwCs06SpqXZ5
|
||||
j/jHFxnr0nFSwlvmYPN8LLdUK7Z5i01v1dkyW8P5HTaubGT2Vv/5J77Y9tr0CTDk
|
||||
I89Jrq+3skmdfETrhu4Leo9+9V1lse7eVQ3GAp5IvuEN32NwGZ52SWwbguNUdFQD
|
||||
zyyqbQKBgBj7ltu2L59S03I1rV1Wrm+BFYbsqTZrU2PaA0nz2/mZjzkp+BYqqeRA
|
||||
y/LBOHiaUxsPZqyR+neOSoDuQK2HWjut5B9JFy61m2pw2E2qwdkpOmceQYuLRRO7
|
||||
UAaHfCfkHE9R8k8FePBNB1HwWGGj02BpF5jP5Oph/JyuuQvPPH+M
|
||||
-----END RSA PRIVATE KEY-----
|
||||
@@ -0,0 +1,79 @@
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 2 (0x2)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: C=GB, ST=Derbyshire, L=Derby, O=Paho Project, OU=Testing, CN=Root CA
|
||||
Validity
|
||||
Not Before: Jul 7 11:14:42 2021 GMT
|
||||
Not After : Jul 6 11:14:42 2026 GMT
|
||||
Subject: C=GB, ST=Derbyshire, O=Paho Project, OU=Testing, CN=Alternative Signing CA
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
RSA Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:ca:f5:4f:c2:30:7d:fd:65:75:06:00:22:72:0a:
|
||||
d0:74:1e:00:03:aa:f3:64:1a:d4:d0:25:85:b9:2e:
|
||||
73:72:41:06:12:d9:52:1d:39:11:78:2d:c3:0d:d7:
|
||||
6f:06:05:68:3a:cc:ce:36:8d:a7:3a:a9:31:77:eb:
|
||||
e9:2d:87:00:7e:86:7a:bb:52:c2:02:d7:ef:07:4f:
|
||||
a9:88:91:d6:6e:dd:19:84:89:dc:72:bb:08:23:b4:
|
||||
be:1a:cf:af:b8:1a:af:62:21:d3:d4:a2:78:2f:b6:
|
||||
4a:44:6f:ab:7f:d7:27:21:79:40:2b:db:bf:90:bf:
|
||||
fb:cf:a4:fa:8b:25:f6:ad:f9:73:57:41:49:86:1d:
|
||||
ed:3c:c9:d5:43:e0:ac:8a:4a:88:51:ea:cf:95:f0:
|
||||
50:4b:ee:4c:fc:74:1d:92:00:5f:75:97:23:e4:b1:
|
||||
79:b1:b0:b8:e1:97:38:6c:78:b6:c1:a6:e7:2e:95:
|
||||
39:c8:ed:2a:65:65:b7:09:45:d4:f2:f1:4f:bf:97:
|
||||
9d:98:b7:26:0d:c1:cf:93:d1:55:9f:af:39:6f:71:
|
||||
29:a4:e9:74:48:2c:eb:8a:11:3d:3f:c4:3c:12:fe:
|
||||
0c:d9:c9:fc:2c:77:22:de:c8:bb:8e:05:55:0a:2b:
|
||||
18:38:0f:68:5d:2f:26:ea:cc:ec:04:df:fb:54:c4:
|
||||
83:3b
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Subject Key Identifier:
|
||||
9E:74:83:0D:43:6F:21:68:72:E1:A3:FC:E0:2D:C3:D0:47:55:0C:31
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:13:A0:B6:1F:F5:C7:64:C2:F9:FD:2E:08:F2:19:01:77:54:19:73:7F
|
||||
|
||||
X509v3 Basic Constraints:
|
||||
CA:TRUE
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
31:c8:c3:5c:31:7c:85:12:e0:01:9c:1a:eb:be:32:f0:19:cd:
|
||||
f3:55:e8:13:34:27:39:69:ca:88:1e:e9:44:47:9b:e1:bf:ff:
|
||||
3f:65:62:02:9f:ae:be:21:1d:03:83:02:3e:a8:f2:d4:fa:e8:
|
||||
14:50:e6:53:9e:e1:90:f9:96:5d:73:f3:da:8d:38:33:6d:5f:
|
||||
f9:ce:9b:60:d3:ae:86:18:7f:ef:4a:d1:69:4d:03:a7:e8:a5:
|
||||
c4:42:59:50:22:d1:25:bd:a4:22:d1:9c:f9:4c:72:ee:3d:e3:
|
||||
e1:c7:b0:c2:16:ba:46:4e:c9:29:91:e0:97:52:d8:3c:be:e2:
|
||||
ef:1c:aa:89:6d:ba:75:35:80:12:5d:5c:33:15:6c:fe:1b:1f:
|
||||
4a:b4:1a:12:47:d3:4b:cd:d2:96:61:88:69:ac:b4:3c:d5:be:
|
||||
52:7e:a0:99:5a:52:65:6a:86:ea:a7:a2:50:66:48:71:e3:82:
|
||||
9f:fc:ff:89:58:ef:04:fa:af:76:98:1b:40:d6:71:14:29:1e:
|
||||
db:b8:31:47:2b:4b:de:f3:e2:e5:d0:a0:75:1e:b6:d9:32:3f:
|
||||
8e:54:c3:92:e1:0f:74:85:0d:e9:27:5b:21:e8:f0:7b:10:3c:
|
||||
14:e4:9d:97:65:18:ef:57:ce:de:b9:f7:01:d0:b9:e4:81:7a:
|
||||
a3:d2:35:8c
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDpDCCAoygAwIBAgIBAjANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQGEwJHQjET
|
||||
MBEGA1UECAwKRGVyYnlzaGlyZTEOMAwGA1UEBwwFRGVyYnkxFTATBgNVBAoMDFBh
|
||||
aG8gUHJvamVjdDEQMA4GA1UECwwHVGVzdGluZzEQMA4GA1UEAwwHUm9vdCBDQTAe
|
||||
Fw0yMTA3MDcxMTE0NDJaFw0yNjA3MDYxMTE0NDJaMGwxCzAJBgNVBAYTAkdCMRMw
|
||||
EQYDVQQIDApEZXJieXNoaXJlMRUwEwYDVQQKDAxQYWhvIFByb2plY3QxEDAOBgNV
|
||||
BAsMB1Rlc3RpbmcxHzAdBgNVBAMMFkFsdGVybmF0aXZlIFNpZ25pbmcgQ0EwggEi
|
||||
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDK9U/CMH39ZXUGACJyCtB0HgAD
|
||||
qvNkGtTQJYW5LnNyQQYS2VIdORF4LcMN128GBWg6zM42jac6qTF36+kthwB+hnq7
|
||||
UsIC1+8HT6mIkdZu3RmEidxyuwgjtL4az6+4Gq9iIdPUongvtkpEb6t/1ycheUAr
|
||||
27+Qv/vPpPqLJfat+XNXQUmGHe08ydVD4KyKSohR6s+V8FBL7kz8dB2SAF91lyPk
|
||||
sXmxsLjhlzhseLbBpuculTnI7SplZbcJRdTy8U+/l52YtyYNwc+T0VWfrzlvcSmk
|
||||
6XRILOuKET0/xDwS/gzZyfwsdyLeyLuOBVUKKxg4D2hdLybqzOwE3/tUxIM7AgMB
|
||||
AAGjUDBOMB0GA1UdDgQWBBSedIMNQ28haHLho/zgLcPQR1UMMTAfBgNVHSMEGDAW
|
||||
gBQToLYf9cdkwvn9LgjyGQF3VBlzfzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEB
|
||||
CwUAA4IBAQAxyMNcMXyFEuABnBrrvjLwGc3zVegTNCc5acqIHulER5vhv/8/ZWIC
|
||||
n66+IR0DgwI+qPLU+ugUUOZTnuGQ+ZZdc/PajTgzbV/5zptg066GGH/vStFpTQOn
|
||||
6KXEQllQItElvaQi0Zz5THLuPePhx7DCFrpGTskpkeCXUtg8vuLvHKqJbbp1NYAS
|
||||
XVwzFWz+Gx9KtBoSR9NLzdKWYYhprLQ81b5SfqCZWlJlaobqp6JQZkhx44Kf/P+J
|
||||
WO8E+q92mBtA1nEUKR7buDFHK0ve8+Ll0KB1HrbZMj+OVMOS4Q90hQ3pJ1sh6PB7
|
||||
EDwU5J2XZRjvV87eufcB0LnkgXqj0jWM
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAyvVPwjB9/WV1BgAicgrQdB4AA6rzZBrU0CWFuS5zckEGEtlS
|
||||
HTkReC3DDddvBgVoOszONo2nOqkxd+vpLYcAfoZ6u1LCAtfvB0+piJHWbt0ZhInc
|
||||
crsII7S+Gs+vuBqvYiHT1KJ4L7ZKRG+rf9cnIXlAK9u/kL/7z6T6iyX2rflzV0FJ
|
||||
hh3tPMnVQ+CsikqIUerPlfBQS+5M/HQdkgBfdZcj5LF5sbC44Zc4bHi2wabnLpU5
|
||||
yO0qZWW3CUXU8vFPv5edmLcmDcHPk9FVn685b3EppOl0SCzrihE9P8Q8Ev4M2cn8
|
||||
LHci3si7jgVVCisYOA9oXS8m6szsBN/7VMSDOwIDAQABAoIBADVkjcP/b9Wu0Ddw
|
||||
557q22YA0m4klf061cugY2qRHsvq8UcaJvELJ15fY5YLm+iQmZgGcyWE5H6ZLitn
|
||||
Q6O3hVjD1hvbrLCE0BwzR91myGvH/MOSZQ1FyOFj1jNFeevMEWGWlpy01TtwEF+q
|
||||
pQpvtpqmxEwFdoMFDqDUvRjINvoTUn1zijLA/tujEwHDriSjQPNd8/RcxYONQaAu
|
||||
3SLInf7Gp3cJJ/EbE+MyK+/DpiG6kQ8Xkxdq928XtSpQAhxVjBzXaZR+hIXu+9jK
|
||||
884Avl/TqRwKoMpLQIUaSVz4F65Hprz1y+Jo28OZ5x+l1oicdnWPTbNtc2xqWcQ1
|
||||
3p0lO/ECgYEA96OAHgRwFwUwOmm9CDbAiYX4yssa7gmU1GVEJukqVwSb95M2Dff8
|
||||
SgkhBABIHcPsYdNAi0klvJv6VqxRHC0dvGi3y0MFG+VdihtpOEh7GrH1aNyUohS0
|
||||
Mx0p6fZjR2mLjCfdnTVD8mtGT97bTrkOP8jYe6r5ZpCE5V3fVHQif9MCgYEA0c+c
|
||||
DejT1uQMq3wQm5NwusRrMO6Eo/VOEJ22nkXNKC5kQEs8kXN8nkRdGCMznQY2Iurc
|
||||
MxhFPa1mBvYGVyefZFLjHJe1rWD0zujmjdjZ3cj9h0O5jf0vefQGuP5uteCtmUoj
|
||||
81eGXfRac/ntEdFQLNEv9PSvBRZpup7e/koStfkCgYEAyEYYtS4NoPB3QqaFVIFD
|
||||
UXVh8lA0ZVKmZOfJKFbmAR4fLSiHTODDzvR3GQ9JQ5lSMQNybbMoq9LRsQsHRexO
|
||||
4jMmgWKgXSEwdyMYA4bK2JoXyUirhDGOUtBBN5AmVnjLfPw4xI1xeDq90JaBcrdD
|
||||
CN7cBZgOv54dfIpgtaJ+zDUCgYEA0CzQSDTVzAgmUhgdWmAmoAm32asvzIbe2DnE
|
||||
MrJLZyzwp6J/DEqsQVTPkd2LnqfFG0wxBDl2qkXcT9fYXq2fxyk+0uXsi4UCIjKQ
|
||||
X/nj4d1FQOr/t1SZwMVRzkgVjTzKwqf/l7kmRx7miOBYSy+F/5HnpYMKDWA5s8Ni
|
||||
uqjAe/ECgYB/ew66RJjRiAxg5DnErIw6RX3lblHuK9tZ3uwyxVLev6wJnps1X4Ar
|
||||
m1WHFGgOGDDqOfC1n7JBp7qvWfLtr93aMlcSUPp34XItBr4LMgPAhk4irb079aoJ
|
||||
pCCx0JV+8ydFi4QaQcu4BRaed9T9PITf+qqTMtyXy4Q4QolV4rqiDw==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
@@ -0,0 +1,23 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDwDCCAqigAwIBAgIUZQzHgL/r7su5tQBXIZvwqj+HdqIwDQYJKoZIhvcNAQEL
|
||||
BQAwcTELMAkGA1UEBhMCR0IxEzARBgNVBAgMCkRlcmJ5c2hpcmUxDjAMBgNVBAcM
|
||||
BURlcmJ5MRUwEwYDVQQKDAxQYWhvIFByb2plY3QxEDAOBgNVBAsMB1Rlc3Rpbmcx
|
||||
FDASBgNVBAMMC0JhZCBSb290IENBMB4XDTIxMDcwNzExMTQ0MloXDTMxMDcwNTEx
|
||||
MTQ0MlowcTELMAkGA1UEBhMCR0IxEzARBgNVBAgMCkRlcmJ5c2hpcmUxDjAMBgNV
|
||||
BAcMBURlcmJ5MRUwEwYDVQQKDAxQYWhvIFByb2plY3QxEDAOBgNVBAsMB1Rlc3Rp
|
||||
bmcxFDASBgNVBAMMC0JhZCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
|
||||
MIIBCgKCAQEA3DRlR+CK8ZBUfaZB4RzWErQ+lewTPu+FaQuCSBvBMKgd+S0r/mZ0
|
||||
dQsA2/mWymggxb1wIZt/TY9sz2v1pYmg2Cw/dld9AQvJaqMXPdn3ZAmsihYd3is8
|
||||
M4c0FlFowHv0LyWUOlRJfUrAPc4aorRK4Dqssl+s8W/ikyiKsMKBk0Z1LQBxUzst
|
||||
AAQ3voBJW7SVsRzYgcbyITW2IXYBjsIJRWK68+TCNCqlmVKEKvg6DYFJ+1HLE/z6
|
||||
jFmzb10lXgg4FKKkUtWruawkErUbb8k1le+rnjZ0Wi9FhSWdM3HL1l6NX0IMWRmC
|
||||
Jm7WvXBHo9KCarcp+MWnKEjP4b/gR0bEvQIDAQABo1AwTjAdBgNVHQ4EFgQUc9Tb
|
||||
8nwTWl+HI3JbYIQAFL3eZYgwHwYDVR0jBBgwFoAUc9Tb8nwTWl+HI3JbYIQAFL3e
|
||||
ZYgwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAnhmnsmFDcZ7b0YEQ
|
||||
XlIj760EUHe/G1Rtur2fjjP59qz/8msP9QtVAy5O/a22aCBehhOzcK2e3NFIKlBs
|
||||
D5xb7UE8RV0i9btP57+ZF6kP89sMB/DBHI+TDD93cms5OvTDCteKO++CpwnkNmav
|
||||
xRnvQGAAOA+zxVsPlYL1Wy9Z75LQWdZKS68/JTd7b2LOQnYD2qp4omPYEYGAFtFz
|
||||
38EMgRS/QyQjjiHx6rz/wU5hmQCrNOUUCw+bHumZL3mxJ/aSBNrGVBLQ2Hnofhsw
|
||||
1Ik2EyzMh3+nlf2ImlSZKfjfg8PrfmgbvXvNc8AWRCad7xwt9ZPzaxj05vKupcwO
|
||||
2tIkOw==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpgIBAAKCAQEA3DRlR+CK8ZBUfaZB4RzWErQ+lewTPu+FaQuCSBvBMKgd+S0r
|
||||
/mZ0dQsA2/mWymggxb1wIZt/TY9sz2v1pYmg2Cw/dld9AQvJaqMXPdn3ZAmsihYd
|
||||
3is8M4c0FlFowHv0LyWUOlRJfUrAPc4aorRK4Dqssl+s8W/ikyiKsMKBk0Z1LQBx
|
||||
UzstAAQ3voBJW7SVsRzYgcbyITW2IXYBjsIJRWK68+TCNCqlmVKEKvg6DYFJ+1HL
|
||||
E/z6jFmzb10lXgg4FKKkUtWruawkErUbb8k1le+rnjZ0Wi9FhSWdM3HL1l6NX0IM
|
||||
WRmCJm7WvXBHo9KCarcp+MWnKEjP4b/gR0bEvQIDAQABAoIBAQDPcKSAo60Ah4Cw
|
||||
pXCmSm34TMgwn6Y5wZYiMO9YUp0Z4yXpWH57N7U5lVYH5AYDQzisTxtU7ZFtVVGh
|
||||
zQgqG47kVjqqlxxxYdMqm90HLVB6cwqRQuh8JKqfuBx/cc2Glr6fs30BvelFGKgl
|
||||
EQXShJmMxnltx+e5wjblfmm4vmMmgpf/I3ROVwaPCrB0Zu0zWBqNDk++te7jMqkG
|
||||
uoBQ9Zv/C93gejFUktzKEMkXUAVqKLlwXlKPc2ypzMW15Omu7YcAo+ZWZIDeQ3RU
|
||||
HzH2zJylVp5F/v9nQbHU5G+8RzIwiVewwEyU2z3wve7Z+9UBA2hf0M3q6NfgYDx0
|
||||
UDgaZzzZAoGBAO/vHy027FpULbfX93KZ9AMBjo2BrnDtOQCdL7qHkyov4Y1O4hH5
|
||||
aPBdeijZQhzJlyNF+0bB0Qht26YzQx+vfkDMIcolvLAbYLNivRNaxNElpE4eZweD
|
||||
T7qfhRahyrBPoKikzvIIQGScqYCmPar0fQ3CfIi0+a7GDlNQ30JsifHTAoGBAOrz
|
||||
FBBLzAlwS+YiKh/734xWM8l1L/4RVyT8pqW4lNCNP9di8oJj7EEVvXUV4VoA1uNS
|
||||
goyoED8OuKLhlGwE+RXq0hRGxyIJgbU08UwV6zEfAAYg+SiYI7t3oEp1IP9p7vZ9
|
||||
5LRfQyO1U6fxpub4l+tRdA1zGxVQNQJ7FJAcNMUvAoGBAJ8pDpNdxbe9833q45jA
|
||||
C6Aa3kd8aQ08L/36R3kDClqH3KVyWID34+be+3QxeqvCBmI9wAwV8eYXigdcJgDU
|
||||
13mAcEG6esqPvrwAmdBG/ByJTc8MV+gh8TepLg3vUZdXmwmEGktvsdeMHNzcajgH
|
||||
axU/mIDPHHoVo9cc5J0ZhwBFAoGBAKpiQ6+ZuEs0A+bN6eyt9S1Jql6zvG0s2By7
|
||||
mILf/BPOC3lAiYvjuQZuJKoPhxCFQVEzmfc1PirsmxuMKd24MYcidt07gtf9OvJV
|
||||
hZPe5WQHDjZjnS1CP8+I7lZw4NA5W5GoNL5Vw1PXAObvSVGBAHMn69iBHCf1taup
|
||||
5Hyp598DAoGBAOhN1mSzSeyddtJiidy2ByL5PL/6BygNxXI//vXRZHmBugLWLczI
|
||||
qtzyUBPMXl1AdxusDkRuQgIgmrums/szsVVgzjJcZzSlxoktbHs1JphxgTTTu7Mh
|
||||
Z1KIaFjXkGF+rRat8rkmy6BVi/PpoPHIWNvEdbR5JZ3jzpPfAqVkvrvO
|
||||
-----END RSA PRIVATE KEY-----
|
||||
@@ -0,0 +1 @@
|
||||
CDAE0E564A2891A9
|
||||
@@ -0,0 +1,22 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDuDCCAqCgAwIBAgIUcE+qUkqyZKFChp9j3+SuflCAAwgwDQYJKoZIhvcNAQEL
|
||||
BQAwbTELMAkGA1UEBhMCR0IxEzARBgNVBAgMCkRlcmJ5c2hpcmUxDjAMBgNVBAcM
|
||||
BURlcmJ5MRUwEwYDVQQKDAxQYWhvIFByb2plY3QxEDAOBgNVBAsMB1Rlc3Rpbmcx
|
||||
EDAOBgNVBAMMB1Jvb3QgQ0EwHhcNMjEwNzA3MTExNDQyWhcNMzEwNzA1MTExNDQy
|
||||
WjBtMQswCQYDVQQGEwJHQjETMBEGA1UECAwKRGVyYnlzaGlyZTEOMAwGA1UEBwwF
|
||||
RGVyYnkxFTATBgNVBAoMDFBhaG8gUHJvamVjdDEQMA4GA1UECwwHVGVzdGluZzEQ
|
||||
MA4GA1UEAwwHUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
||||
AJ9Oc5kDGXyzORIRKBNiQ0+p63LN4DUK8ux/PMD7SEuGKq+LIdieCjmExUq2nkIE
|
||||
052iYCM9aYJa8PuP+8UWl8UKE4/QWW6yWl28/O5n/Hwe28PfiiH1f5kxXt9khMjI
|
||||
oc3WCr8YkiDrrKiFyCGvF58b87woQFRMHHqus+o+Xd9YPKhsc/n/AhV4zl0S2wUC
|
||||
nnV+UF5c+/vlMh/SnD84yhMlySOC7fRNHziAJqqIpj44hQTdfjM6XDHOf3jSlHfv
|
||||
1JxKqyE8hAWxZVZhMBP1v14xQL5AbVhtSNZlIV/LzAGUbBztMKzPfE4GyQKIDCmi
|
||||
91A7nbXbkTBz/McL3kxmmAMCAwEAAaNQME4wHQYDVR0OBBYEFDZWdWv057drndtK
|
||||
9AYPQhTgHkUuMB8GA1UdIwQYMBaAFDZWdWv057drndtK9AYPQhTgHkUuMAwGA1Ud
|
||||
EwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAEuWZu5tSJyNZkzbFT0o/IP8zUgN
|
||||
lbfp9DxqqiOwUTx2ykOpMsXU94f+/HEACYQ773G/lXPDmMrz/j3mPYklhws07/SE
|
||||
q1jKM6ZXJh74nQekypvXtSY/Xd667JpRxU6GAedizi60owKPIUFpxkW70h4Of5j5
|
||||
Py7PGRGDZ7ItGtuk1fxcSCchfm0Q2bST8nOcD8D+MQcttNxGgelp2V6c0XckmijM
|
||||
oFUy/3Nm1B/qv4QWckmVX+gm+iBTBANItvcj+ie2c6diFwz7htDwOVm7/1Z/73wM
|
||||
YyM5Z27mVKR8FwK3jHHRQa5VWtTOdnqG3kHKmAKeOlXgO91wzCh8zq1Q76o=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAn05zmQMZfLM5EhEoE2JDT6nrcs3gNQry7H88wPtIS4Yqr4sh
|
||||
2J4KOYTFSraeQgTTnaJgIz1pglrw+4/7xRaXxQoTj9BZbrJaXbz87mf8fB7bw9+K
|
||||
IfV/mTFe32SEyMihzdYKvxiSIOusqIXIIa8XnxvzvChAVEwceq6z6j5d31g8qGxz
|
||||
+f8CFXjOXRLbBQKedX5QXlz7++UyH9KcPzjKEyXJI4Lt9E0fOIAmqoimPjiFBN1+
|
||||
MzpcMc5/eNKUd+/UnEqrITyEBbFlVmEwE/W/XjFAvkBtWG1I1mUhX8vMAZRsHO0w
|
||||
rM98TgbJAogMKaL3UDudtduRMHP8xwveTGaYAwIDAQABAoIBAG4D1KsHy/MlJjWG
|
||||
6aExTADY/MOkz8Bx1j9iw0cWgd++QP5H3FDnG3KLcWBeaz52bNnAyBmuEI44VZG0
|
||||
5o8+QgOOKOI5ZXmf6+4uVJIj9+aTvPsxBgjbrInT4YvutBChFbS7q2I7Crd3ah5b
|
||||
fVFdxLdZq2H2fi54/XXv7knHVjaldxf/mlq3XX1ndAvYXIY3L9PKjeeraEppRgce
|
||||
oZR6nnzliz7mBwIezaWV+DOCpotiJVYefeWsbN1QjKKzObnq1M5w4fv1R4jbT/zh
|
||||
RKIyxL3sa/8Beo3TSl4hFF9xNbQq957QdXKMqbdKdGWO0bQN4Mh4xqrEPo1ZK6qK
|
||||
RLyt5xECgYEAyvrgICVB4q7VFIqMzIznLnrBSg+HtpkLBIh2JjovWEQNh88Qul3t
|
||||
IH9VdOVT+SPeLCjED6vwQzU4bu4TJV2xwnv+Ujty4w8Aw4sSJlxSrMniKkdSxMus
|
||||
yhNgYg8E4WEDHxGtBNTyGc1lC2rvfDorvQAFajj5WJqGXLB9MumgP9sCgYEAyOso
|
||||
nZlfGKSWidUT+Mp0Jq9PG1kmAoBDEoMdCcpvp5p6ttUAb6sLVoY9Q+7U4VVVUIbH
|
||||
udYBvpDklgwJD2Erc6PK81g99bS/0fTuqCMlCGfDrqVTFxtWcYd9H2E3eJfo20YQ
|
||||
lUKgoOudXrlc7/a1TSK4Z0qGnWrygyhYypSwNPkCgYBKMv09IwF7sPd5g9BGcfeM
|
||||
eRkxTo4IxNdPN+cgwEJQXMgpbhsqVW16ZLHDgpV4zJDJybkqFWtF1i2j92mOTjrN
|
||||
4m+sdcjgkbpwwOTImxUpzr7bP6lVATNPx1eDYQQis0jl0ZtS2dkKb5fRXazf14/n
|
||||
jhtsohkcN5iIR4fs1ZRb4wKBgQCtu1HCfOVS7LbS9jGv1nf7H2na7wpD7V6R+le4
|
||||
qJhFp/lmcOZQqOlD5w3A2RqwwdXkrLa1RYz6mFVgPYX0C4TEGKScKPhipumbBhz7
|
||||
vHAARaFaOdCQUW48+vhBkxGhMFIEkSAzwIoeu723M7deM8jvqw8jGbkvE1Qh/1hP
|
||||
y6RWGQKBgQCNfn28PybCmShtMFXnmcbtYOfI9b7ycGqFiKcW3pT5Q/2C4ReAyEVH
|
||||
uZ7xXApAzESao5V1evp2jRYGQAhK00YX/F9CXn8C57K55B5EC5cNu7LVSA81GswF
|
||||
/9VRFpxIWzilLEUGmgA0rUfvgsUyx6ILREhD1Qw8ihWNKMO2gJxVog==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
@@ -0,0 +1,22 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDuDCCAqCgAwIBAgIUS1Q+E18/+trcKfhT+xz8ghGukmYwDQYJKoZIhvcNAQEL
|
||||
BQAwbTELMAkGA1UEBhMCR0IxEzARBgNVBAgMCkRlcmJ5c2hpcmUxDjAMBgNVBAcM
|
||||
BURlcmJ5MRUwEwYDVQQKDAxQYWhvIFByb2plY3QxEDAOBgNVBAsMB1Rlc3Rpbmcx
|
||||
EDAOBgNVBAMMB1Jvb3QgQ0EwHhcNMjEwNzA3MTExNDQyWhcNMzEwNzA1MTExNDQy
|
||||
WjBtMQswCQYDVQQGEwJHQjETMBEGA1UECAwKRGVyYnlzaGlyZTEOMAwGA1UEBwwF
|
||||
RGVyYnkxFTATBgNVBAoMDFBhaG8gUHJvamVjdDEQMA4GA1UECwwHVGVzdGluZzEQ
|
||||
MA4GA1UEAwwHUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
||||
AKpCq45dCrroNa+y3zgdBglQOtw4og3MD/3Rn6ZftyL0dv1rSMkCFU8lCtZ4bIpz
|
||||
iNSJKau79owCudX3qQTPfiX2pmR5uuYjvMzRiZohZtz5uqXByy/CMS8dPRI3po6i
|
||||
kfNx9n7EQqOlxdwkY1kae2j5ybkAld2MNci93BH4P8qqaQckVRKpv6cKq33KsXK7
|
||||
jHgjAYMGrihTAwxgP1JX9NS8yxxjMUYvFqeEOLARoeWc6Nl7oDbGLs2fr0j2Yssm
|
||||
cz0AMu7LWcbhnfs2S8Troksztnq38yHu+YTs6hX4NhANBgon5CAdyzmmE/b2OwOX
|
||||
p8rQepUfG7wO5QaS0OrAEXsCAwEAAaNQME4wHQYDVR0OBBYEFBOgth/1x2TC+f0u
|
||||
CPIZAXdUGXN/MB8GA1UdIwQYMBaAFBOgth/1x2TC+f0uCPIZAXdUGXN/MAwGA1Ud
|
||||
EwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAHgE1oMwIcilQFN4xPYCf8jbsa5o
|
||||
zA5ljTbxv7fU3Zd+7KdlDFYroGjgHb7o3r0//b8+ZarxBqn1274u4KPs39Ow7h6m
|
||||
YJo7IM2Z2fC6IWZroqeidfFx5SwejAP1j7coYLblTIbNF+P08sJG5nSQ+Yx0gams
|
||||
6C1x0mETaaglDwllU1KXHTm8fUpEwpISc/VfKABYgScODMpdsDghyHANvnFjmvp4
|
||||
ktABnasliZYTmdl0t3szNm7zIk+bntiK4KunFea8GqgslWqGPwtNxxJFHzPjMCxK
|
||||
EHgubLgp1lNZzH13XSO6ZpiNRDJ6IVed3Zq+yn+24uKH+1Hqp6Bt20ZFB4E=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAqkKrjl0Kuug1r7LfOB0GCVA63DiiDcwP/dGfpl+3IvR2/WtI
|
||||
yQIVTyUK1nhsinOI1Ikpq7v2jAK51fepBM9+JfamZHm65iO8zNGJmiFm3Pm6pcHL
|
||||
L8IxLx09EjemjqKR83H2fsRCo6XF3CRjWRp7aPnJuQCV3Yw1yL3cEfg/yqppByRV
|
||||
Eqm/pwqrfcqxcruMeCMBgwauKFMDDGA/Ulf01LzLHGMxRi8Wp4Q4sBGh5Zzo2Xug
|
||||
NsYuzZ+vSPZiyyZzPQAy7stZxuGd+zZLxOuiSzO2erfzIe75hOzqFfg2EA0GCifk
|
||||
IB3LOaYT9vY7A5enytB6lR8bvA7lBpLQ6sARewIDAQABAoIBACAK+BqM7C4M8b2l
|
||||
XllDLRWnocw8ZFNQaloMj41SSjcr5xD+le4ulDAW+pkuhM7xu3i0b8FAWMA06yCX
|
||||
wZmEK2udpecW+dPCOhAaB1mYm7FO1o/HjyPn2jXRvOKm0pPZiLpWYlutOBVwZ3Js
|
||||
7r2gPEWfbRWCRLIzZxPml3pSTD8p0IMGC4gO0jKHmGyLFQN0TOCdivVOzbQeDpUU
|
||||
lpj/v2wCfQQpfc/jP2bwTlGAZWVgmUtoj5XcWtRSLtwcWtK5KKgyQKlDdDL7d/Et
|
||||
J3x+QDLIwu9JNfaW8lcie16Y6qE4yOuBl95wfOpxN3wcmfxrKh7/rtN0Df1JNxvh
|
||||
4bkyrGECgYEA2Lc36y+S9fOEecTwQd+AozIrBVhfaDU3L/tuKqKRJAhjI37DHkZ3
|
||||
4tRYqd85bAcd+FED9cEK7Fqb51XovHTYQx0j3y++Iq6u+gzGWgSX2JGlprOkiNMk
|
||||
oXMX9P48KDBtCzD2aPxAslmrkhIPKEKmW+OTqpqHG6TsCshUoF1GQYMCgYEAyR+t
|
||||
A68mrnEcR3iapGhnnKqAEVx4zRdaXhBXFZvC0mF15xKtMTtjCEaT2X+iOiZE2fNn
|
||||
Si++pi/UGgLYChD7YsgWQlJUyrMVUHBYROfZ+sUIm9XvESVNQFLSSkr+vMH03hM3
|
||||
I7d4Z3pbMEwDzAnv37i1HZ91Tvm4nfIsePenRqkCgYAdWdMs+yiAPxb2FwIjKc4W
|
||||
TDkfZDSnvG1ZBkiJZbMamjgzGnv6obii8/d+KklwpBYfB3nt0tNT54Gt9yiqPXj8
|
||||
vfmZxLGPqPDx1MEYd/7IyhERXsst7MrNQvU/rR8gok5icaMt3Nw2S4a9Jcz/uucl
|
||||
EtFxDbS2vcNqQm+TuI5HWQKBgQC1xLj7IWsWMQfb2DX67Jjn0HhaOHa89KQpax8p
|
||||
WlKjDI4gPpLkccW5DwBEi8O0Ri3nxMHPHINzcrqAn51cy6hGyIrFed9EKsHSpxY/
|
||||
gENTDowPOzQLDOlafv+rQUgklC6YHkmxL/nTm5OafLjZyQlP6oFVum2s6KhfpyVm
|
||||
VnyJsQKBgBk2hykG1EZmkLDKbrCXU7ggTvA9/FhEAjOt5PtQBjdKWTInuoizWX3n
|
||||
/C8ZYig7pYNytsb2um4CrF1Divgqz2ZceTWxfEF5IKqjqfhwMkBZ/uGz27t/BFaF
|
||||
pE5RD8iBhG+1inxV2UVz0gzBCNGciDxKb+ZPW087yE6NphLRydHv
|
||||
-----END RSA PRIVATE KEY-----
|
||||
@@ -0,0 +1,79 @@
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 1 (0x1)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: C=GB, ST=Derbyshire, L=Derby, O=Paho Project, OU=Testing, CN=Root CA
|
||||
Validity
|
||||
Not Before: Jul 7 11:14:42 2021 GMT
|
||||
Not After : Jul 6 11:14:42 2026 GMT
|
||||
Subject: C=GB, ST=Derbyshire, O=Paho Project, OU=Testing, CN=Signing CA
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
RSA Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:cb:32:6c:8c:48:e8:44:58:36:18:70:36:42:3d:
|
||||
2d:29:47:3c:69:12:9e:7b:f7:45:62:ef:91:44:46:
|
||||
97:a0:ea:5f:da:fd:9f:98:d4:bf:43:02:e3:39:90:
|
||||
33:7b:13:13:d5:31:30:9c:07:fc:ca:1b:a9:e4:89:
|
||||
42:e5:d0:6e:f4:a2:e0:23:ee:9d:9a:cc:80:3b:78:
|
||||
bf:7e:27:a8:46:1b:28:9f:4a:64:53:7a:89:3e:ab:
|
||||
65:6f:af:0b:29:fa:4d:4f:04:f1:1e:10:2c:bf:2b:
|
||||
ea:fc:c5:fa:77:c9:1a:7a:78:29:f5:a2:cb:25:7c:
|
||||
02:bb:91:8d:76:4d:23:bc:9c:19:da:be:c5:20:04:
|
||||
ad:fe:bd:b9:d4:bb:29:2a:c3:e4:fc:4c:84:db:a3:
|
||||
55:9f:f0:70:7f:40:38:b5:c3:78:a5:db:06:36:b7:
|
||||
10:8e:ca:6c:1a:92:66:be:0e:1a:97:59:6b:18:f4:
|
||||
c2:b8:c9:31:7b:d1:b1:a1:00:78:7f:c0:09:f6:ef:
|
||||
b2:8f:94:87:5d:b1:a2:23:93:4d:ec:fa:95:09:a9:
|
||||
90:c4:02:f0:1e:d9:ab:a2:8b:7f:7f:54:95:e7:da:
|
||||
c3:c9:7d:a7:d7:04:89:59:db:88:9d:57:16:5d:b9:
|
||||
66:b0:d6:88:bb:e0:ee:43:e9:ab:02:78:fc:bd:e8:
|
||||
98:d9
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Subject Key Identifier:
|
||||
C2:8F:09:9B:D5:F1:BA:C4:74:5E:97:50:BB:86:9D:A1:F1:FA:C4:36
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:13:A0:B6:1F:F5:C7:64:C2:F9:FD:2E:08:F2:19:01:77:54:19:73:7F
|
||||
|
||||
X509v3 Basic Constraints:
|
||||
CA:TRUE
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
3e:70:76:69:37:e4:6e:e0:08:c6:8e:5b:2e:aa:26:fe:e9:ed:
|
||||
ac:02:ce:2c:37:08:6a:8a:c3:0d:c0:ef:43:51:01:2e:e0:96:
|
||||
76:23:1b:1f:75:98:df:7c:d1:b7:c1:67:aa:62:c1:bd:ef:84:
|
||||
eb:d9:28:47:50:f2:1b:54:7f:ed:cb:52:f7:fc:c3:f8:62:22:
|
||||
0c:b3:95:ed:bb:3f:74:91:bc:d2:eb:c0:81:7d:74:12:85:61:
|
||||
a3:7e:fb:22:4a:25:99:0b:5d:ef:69:f2:5a:e6:d5:12:a3:95:
|
||||
38:30:0c:c7:d9:da:28:30:10:b4:3d:3e:ad:20:85:31:e0:bf:
|
||||
30:33:2e:0b:e3:07:3d:ed:22:dc:67:f8:93:64:89:ed:e7:08:
|
||||
74:b5:0a:7a:01:3d:f9:44:62:71:cf:60:12:92:c3:95:9a:e5:
|
||||
a5:f2:24:6a:22:64:d5:76:22:c9:03:1c:c5:d1:a5:85:4d:55:
|
||||
f9:80:47:ca:12:20:df:05:fb:82:12:45:6f:e8:c0:20:a8:ae:
|
||||
f7:17:c5:c3:b6:9c:51:bd:d8:84:e4:db:c7:03:44:d2:cb:75:
|
||||
51:79:3f:86:33:3c:e4:34:1d:77:b2:60:24:5c:21:c5:c3:53:
|
||||
36:08:2f:a7:14:0b:68:78:67:95:90:b9:06:0e:85:04:65:57:
|
||||
b4:34:31:cf
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDmDCCAoCgAwIBAgIBATANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQGEwJHQjET
|
||||
MBEGA1UECAwKRGVyYnlzaGlyZTEOMAwGA1UEBwwFRGVyYnkxFTATBgNVBAoMDFBh
|
||||
aG8gUHJvamVjdDEQMA4GA1UECwwHVGVzdGluZzEQMA4GA1UEAwwHUm9vdCBDQTAe
|
||||
Fw0yMTA3MDcxMTE0NDJaFw0yNjA3MDYxMTE0NDJaMGAxCzAJBgNVBAYTAkdCMRMw
|
||||
EQYDVQQIDApEZXJieXNoaXJlMRUwEwYDVQQKDAxQYWhvIFByb2plY3QxEDAOBgNV
|
||||
BAsMB1Rlc3RpbmcxEzARBgNVBAMMClNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEB
|
||||
AQUAA4IBDwAwggEKAoIBAQDLMmyMSOhEWDYYcDZCPS0pRzxpEp5790Vi75FERpeg
|
||||
6l/a/Z+Y1L9DAuM5kDN7ExPVMTCcB/zKG6nkiULl0G70ouAj7p2azIA7eL9+J6hG
|
||||
GyifSmRTeok+q2Vvrwsp+k1PBPEeECy/K+r8xfp3yRp6eCn1osslfAK7kY12TSO8
|
||||
nBnavsUgBK3+vbnUuykqw+T8TITbo1Wf8HB/QDi1w3il2wY2txCOymwakma+DhqX
|
||||
WWsY9MK4yTF70bGhAHh/wAn277KPlIddsaIjk03s+pUJqZDEAvAe2auii39/VJXn
|
||||
2sPJfafXBIlZ24idVxZduWaw1oi74O5D6asCePy96JjZAgMBAAGjUDBOMB0GA1Ud
|
||||
DgQWBBTCjwmb1fG6xHRel1C7hp2h8frENjAfBgNVHSMEGDAWgBQToLYf9cdkwvn9
|
||||
LgjyGQF3VBlzfzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA+cHZp
|
||||
N+Ru4AjGjlsuqib+6e2sAs4sNwhqisMNwO9DUQEu4JZ2IxsfdZjffNG3wWeqYsG9
|
||||
74Tr2ShHUPIbVH/ty1L3/MP4YiIMs5Xtuz90kbzS68CBfXQShWGjfvsiSiWZC13v
|
||||
afJa5tUSo5U4MAzH2dooMBC0PT6tIIUx4L8wMy4L4wc97SLcZ/iTZInt5wh0tQp6
|
||||
AT35RGJxz2ASksOVmuWl8iRqImTVdiLJAxzF0aWFTVX5gEfKEiDfBfuCEkVv6MAg
|
||||
qK73F8XDtpxRvdiE5NvHA0TSy3VReT+GMzzkNB13smAkXCHFw1M2CC+nFAtoeGeV
|
||||
kLkGDoUEZVe0NDHP
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpgIBAAKCAQEAyzJsjEjoRFg2GHA2Qj0tKUc8aRKee/dFYu+RREaXoOpf2v2f
|
||||
mNS/QwLjOZAzexMT1TEwnAf8yhup5IlC5dBu9KLgI+6dmsyAO3i/fieoRhson0pk
|
||||
U3qJPqtlb68LKfpNTwTxHhAsvyvq/MX6d8kaengp9aLLJXwCu5GNdk0jvJwZ2r7F
|
||||
IASt/r251LspKsPk/EyE26NVn/Bwf0A4tcN4pdsGNrcQjspsGpJmvg4al1lrGPTC
|
||||
uMkxe9GxoQB4f8AJ9u+yj5SHXbGiI5NN7PqVCamQxALwHtmroot/f1SV59rDyX2n
|
||||
1wSJWduInVcWXblmsNaIu+DuQ+mrAnj8veiY2QIDAQABAoIBAQCh3tl6J9pgF6WA
|
||||
cmPHANUpPQZy7dIzDxjHZ/FhYpsIJa2W1tR8+34h8/rvsGBSezAhdb4zjmli2AbP
|
||||
eElCqni5icbk2QHUf3Tn65kg9pamwpvpyWmC1ureccus3NUX674KZPVv7ZK3+FSK
|
||||
aWzOX/Yn+fHzLGyIv/GtWpZG18zQQl0+i2sKqKYQu00qBBLp+t9GJYpqPx9qpumB
|
||||
JzWaVuMEwkTJ4J6j7d28V8r8fnrURIcb/3R6dZsB6QtjgnJNzJRwFpaDDKoH3ZNV
|
||||
IkMqRNGuzuuzhL5Rzd2nd8oRUvgUAl93ad/fxWfmVVSyVbh/LCkOBDwSC6Z2Ri4c
|
||||
BafNAoMBAoGBAP0E9y121/lMkiLh0KF3suwbSJ/Z/GFO9ZhP5wW2vibcrQppF6vz
|
||||
kdYyEmjyPH+3UoKZOYzAwkTDJFJaosaagmiPuIzsGeF20A7D7ZQ1Ru5ScxVo/XWK
|
||||
i2g4s4wqlEZ9vhlcg/QBOUfzi23lUyGAXuQlgORQtzbN/vzGSRkIivWNAoGBAM2X
|
||||
NU32Hw0RuOXtaw4aZyY4oFT2nyPP99fAzR+IGX7XMny5bt2kBnHExpC43VZevFHc
|
||||
qzQdot4DbOUi/kO+LOiUHcYIW2/nADJjsxnDlnxU+9L6cMv74rQgskjNgjS0l+bx
|
||||
/W6/QFoOOJeVDT1VXhQbjIL3PxffdKmEWPs7ZT99AoGBAKZ6SuymIorMv+alr/Fd
|
||||
4eMKPKm48x9Ppba29CnFSK4nSs/rwACKva0yuvxETlw2UdrOWJhtCCXYRCDPtAR7
|
||||
C00jK2nFu22nEFR2w+5dc7NBmqk+sG5TX1CO5kxWg8Mx3w+u2L+Gwpq9+0Kuvhjv
|
||||
7v+sUXdoSHSN67WD/fqzrULNAoGBAKv+Qvbc329Ek0Wv0K70wbSFDQTnaY1BT9us
|
||||
jS5C4ultSOx1CV3c+hM1htTOA0VdbfiiPowT+wv3G6O6GbM8pz9PonToyu4b99sv
|
||||
80arjPqo8h+3qqPMLwV4kQ489x/2sVngup9q2oA8g3W0mWXlRBZYUb3C8IKdS3EB
|
||||
qptLPlHVAoGBAMgetjin8PFljR6Wt/GF5Y84MtonxH0oyJ7F1nw4NfmxqZxPwSXG
|
||||
L1/Adc3qTyOTM+JhWL+mSqiF+go2RpEHB04kItFWgShGb6k84T7Hdq+Qrw6yZGR1
|
||||
wX7UpLwK2mrdIkzEVRMw2+7Uvi9nAn1rVxmlCFNamPxhC4ky0TBIboKl
|
||||
-----END RSA PRIVATE KEY-----
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,36 @@
|
||||
import paho.mqtt.client as client
|
||||
import pytest
|
||||
|
||||
|
||||
class Test_client_function:
|
||||
"""
|
||||
Tests on topic_matches_sub function in the client module
|
||||
"""
|
||||
|
||||
@pytest.mark.parametrize("sub,topic", [
|
||||
("foo/bar", "foo/bar"),
|
||||
("foo/+", "foo/bar"),
|
||||
("foo/+/baz", "foo/bar/baz"),
|
||||
("foo/+/#", "foo/bar/baz"),
|
||||
("A/B/+/#", "A/B/B/C"),
|
||||
("#", "foo/bar/baz"),
|
||||
("#", "/foo/bar"),
|
||||
("/#", "/foo/bar"),
|
||||
("$SYS/bar", "$SYS/bar"),
|
||||
])
|
||||
def test_matching(self, sub, topic):
|
||||
assert client.topic_matches_sub(sub, topic)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("sub,topic", [
|
||||
("test/6/#", "test/3"),
|
||||
("foo/bar", "foo"),
|
||||
("foo/+", "foo/bar/baz"),
|
||||
("foo/+/baz", "foo/bar/bar"),
|
||||
("foo/+/#", "fo2/bar/baz"),
|
||||
("/#", "foo/bar"),
|
||||
("#", "$SYS/bar"),
|
||||
("$BOB/bar", "$SYS/bar"),
|
||||
])
|
||||
def test_not_matching(self, sub, topic):
|
||||
assert not client.topic_matches_sub(sub, topic)
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user