Skip to content

Instantly share code, notes, and snippets.

@schwabe
Last active April 3, 2020 09:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save schwabe/c95d7fdd4926eb287a533177c6375d5e to your computer and use it in GitHub Desktop.
Save schwabe/c95d7fdd4926eb287a533177c6375d5e to your computer and use it in GitHub Desktop.
def generate_pem(data:bytes, pemtype:bytes):
s = b"-----BEGIN %s-----\n" % pemtype
s += base64.encodebytes(data)
s += b"-----END %s-----" % pemtype
return s
def generate_tls_crypt2_wrapped_client_key_(clientkeys, serverkey, metadata: bytes):
TLS_CRYPT_V2_TAG_SIZE = int(256/8)
# The real max length is more but we restrict us here to a bit shorter string
if len(metadata) > 512:
raise ValueError("Metadata length too long")
# user metadata (0x0,
metadata = b"\x00" + metadata
serverkey = C.read_pem_key(serverkey.encode(), b"OpenVPN tls-crypt-v2 server key")
h = hmac.HMAC(serverkey[64:96], hashes.SHA256(), backend=default_backend())
wlen = len(clientkeys) + len(metadata) + TLS_CRYPT_V2_TAG_SIZE + 2
net_len = struct.pack("!h", wlen)
h.update(net_len)
h.update(clientkeys)
h.update(metadata)
tag = h.finalize()
ciph = Cipher(algorithms.AES(serverkey[0:32]), modes.CTR(tag[0:16]), backend=default_backend())
enc = ciph.encryptor()
encdata = enc.update(clientkeys)
encdata += enc.update(metadata)
encdata += enc.finalize()
wkc = tag + encdata + net_len
return generate_pem(clientkeys + wkc, b"OpenVPN tls-crypt-v2 client key")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment