chore: hide autotls under compile flag (#1533)

This commit is contained in:
richΛrd
2025-07-14 13:52:33 -04:00
committed by GitHub
parent e83bd2d582
commit eee8341ad2
9 changed files with 645 additions and 612 deletions

View File

@@ -119,6 +119,11 @@ Enable quic transport support
nim c -d:libp2p_quic_support some_file.nim
```
Enable autotls support
```bash
nim c -d:libp2p_autotls_support some_file.nim
```
Enable expensive metrics (ie, metrics with per-peer cardinality):
```bash
nim c -d:libp2p_expensive_metrics some_file.nim

View File

@@ -30,7 +30,7 @@ proc runTest(filename: string, moreoptions: string = "") =
excstr.add(" " & moreoptions & " ")
if getEnv("CICOV").len > 0:
excstr &= " --nimcache:nimcache/" & filename & "-" & $excstr.hash
exec excstr & " -r -d:libp2p_quic_support tests/" & filename
exec excstr & " -r -d:libp2p_quic_support -d:libp2p_autotls_support tests/" & filename
rmFile "tests/" & filename.toExe
proc buildSample(filename: string, run = false, extraFlags = "") =

View File

@@ -1,6 +1,6 @@
import options, sequtils, strutils, json, uri
import json, uri
from times import DateTime, parse
import chronos/apps/http/httpclient, jwt, results, bearssl/pem, chronicles
import chronos/apps/http/httpclient, results, chronicles
import ./utils
import ../../crypto/crypto
@@ -158,7 +158,10 @@ type ACMECertificateResponse* = object
rawCertificate*: string
certificateExpiry*: DateTime
template handleError*(msg: string, body: untyped): untyped =
when defined(libp2p_autotls_support):
import options, sequtils, strutils, jwt, bearssl/pem
template handleError*(msg: string, body: untyped): untyped =
try:
body
except ACMEError as exc:
@@ -174,30 +177,30 @@ template handleError*(msg: string, body: untyped): untyped =
except CatchableError as exc:
raise newException(ACMEError, msg & ": Unexpected error", exc)
method post*(
method post*(
self: ACMEApi, uri: Uri, payload: string
): Future[HTTPResponse] {.
): Future[HTTPResponse] {.
async: (raises: [ACMEError, HttpError, CancelledError]), base
.}
.}
method get*(
method get*(
self: ACMEApi, uri: Uri
): Future[HTTPResponse] {.
): Future[HTTPResponse] {.
async: (raises: [ACMEError, HttpError, CancelledError]), base
.}
.}
proc new*(
proc new*(
T: typedesc[ACMEApi], acmeServerURL: Uri = parseUri(LetsEncryptURL)
): ACMEApi =
): ACMEApi =
let session = HttpSessionRef.new()
ACMEApi(
session: session, directory: Opt.none(ACMEDirectory), acmeServerURL: acmeServerURL
)
proc getDirectory(
proc getDirectory(
self: ACMEApi
): Future[ACMEDirectory] {.async: (raises: [ACMEError, CancelledError]).} =
): Future[ACMEDirectory] {.async: (raises: [ACMEError, CancelledError]).} =
handleError("getDirectory"):
self.directory.valueOr:
let acmeResponse = await self.get(self.acmeServerURL / "directory")
@@ -205,17 +208,17 @@ proc getDirectory(
self.directory = Opt.some(directory)
directory
method requestNonce*(
method requestNonce*(
self: ACMEApi
): Future[Nonce] {.async: (raises: [ACMEError, CancelledError]), base.} =
): Future[Nonce] {.async: (raises: [ACMEError, CancelledError]), base.} =
handleError("requestNonce"):
let acmeResponse = await self.get(parseUri((await self.getDirectory()).newNonce))
Nonce(acmeResponse.headers.keyOrError("Replay-Nonce"))
# TODO: save n and e in account so we don't have to recalculate every time
proc acmeHeader(
# TODO: save n and e in account so we don't have to recalculate every time
proc acmeHeader(
self: ACMEApi, uri: Uri, key: KeyPair, needsJwk: bool, kid: Opt[Kid]
): Future[ACMERequestHeader] {.async: (raises: [ACMEError, CancelledError]).} =
): Future[ACMERequestHeader] {.async: (raises: [ACMEError, CancelledError]).} =
if not needsJwk and kid.isNone():
raise newException(ACMEError, "kid not set")
@@ -245,11 +248,11 @@ proc acmeHeader(
kid: kid.get(),
)
method post*(
method post*(
self: ACMEApi, uri: Uri, payload: string
): Future[HTTPResponse] {.
): Future[HTTPResponse] {.
async: (raises: [ACMEError, HttpError, CancelledError]), base
.} =
.} =
let rawResponse = await HttpClientRequestRef
.post(self.session, $uri, body = payload, headers = ACMEHttpHeaders)
.get()
@@ -257,23 +260,23 @@ method post*(
let body = await rawResponse.getResponseBody()
HTTPResponse(body: body, headers: rawResponse.headers)
method get*(
method get*(
self: ACMEApi, uri: Uri
): Future[HTTPResponse] {.
): Future[HTTPResponse] {.
async: (raises: [ACMEError, HttpError, CancelledError]), base
.} =
.} =
let rawResponse = await HttpClientRequestRef.get(self.session, $uri).get().send()
let body = await rawResponse.getResponseBody()
HTTPResponse(body: body, headers: rawResponse.headers)
proc createSignedAcmeRequest(
proc createSignedAcmeRequest(
self: ACMEApi,
uri: Uri,
payload: auto,
key: KeyPair,
needsJwk: bool = false,
kid: Opt[Kid] = Opt.none(Kid),
): Future[string] {.async: (raises: [ACMEError, CancelledError]).} =
): Future[string] {.async: (raises: [ACMEError, CancelledError]).} =
if key.pubkey.scheme != PKScheme.RSA or key.seckey.scheme != PKScheme.RSA:
raise newException(ACMEError, "Unsupported signing key type")
@@ -285,9 +288,9 @@ proc createSignedAcmeRequest(
token.sign(pemPrivKey)
$token.toFlattenedJson()
proc requestRegister*(
proc requestRegister*(
self: ACMEApi, key: KeyPair
): Future[ACMERegisterResponse] {.async: (raises: [ACMEError, CancelledError]).} =
): Future[ACMERegisterResponse] {.async: (raises: [ACMEError, CancelledError]).} =
let registerRequest = ACMERegisterRequest(termsOfServiceAgreed: true)
handleError("acmeRegister"):
let payload = await self.createSignedAcmeRequest(
@@ -301,12 +304,13 @@ proc requestRegister*(
let acmeResponseBody = acmeResponse.body.to(ACMERegisterResponseBody)
ACMERegisterResponse(
status: acmeResponseBody.status, kid: acmeResponse.headers.keyOrError("location")
status: acmeResponseBody.status,
kid: acmeResponse.headers.keyOrError("location"),
)
proc requestNewOrder*(
proc requestNewOrder*(
self: ACMEApi, domains: seq[Domain], key: KeyPair, kid: Kid
): Future[ACMEChallengeResponse] {.async: (raises: [ACMEError, CancelledError]).} =
): Future[ACMEChallengeResponse] {.async: (raises: [ACMEError, CancelledError]).} =
# request challenge from ACME server
let orderRequest = ACMEChallengeRequest(
identifiers: domains.mapIt(ACMEChallengeIdentifier(`type`: "dns", value: it))
@@ -330,22 +334,25 @@ proc requestNewOrder*(
order: acmeResponse.headers.keyOrError("location"),
)
proc requestAuthorizations*(
proc requestAuthorizations*(
self: ACMEApi, authorizations: seq[Authorization], key: KeyPair, kid: Kid
): Future[ACMEAuthorizationsResponse] {.async: (raises: [ACMEError, CancelledError]).} =
): Future[ACMEAuthorizationsResponse] {.async: (raises: [ACMEError, CancelledError]).} =
handleError("requestAuthorizations"):
doAssert authorizations.len > 0
let acmeResponse = await self.get(parseUri(authorizations[0]))
acmeResponse.body.to(ACMEAuthorizationsResponse)
proc requestChallenge*(
proc requestChallenge*(
self: ACMEApi, domains: seq[Domain], key: KeyPair, kid: Kid
): Future[ACMEChallengeResponseWrapper] {.async: (raises: [ACMEError, CancelledError]).} =
): Future[ACMEChallengeResponseWrapper] {.
async: (raises: [ACMEError, CancelledError])
.} =
let orderResponse = await self.requestNewOrder(domains, key, kid)
if orderResponse.status != ACMEOrderStatus.PENDING and
orderResponse.status != ACMEOrderStatus.READY:
# ready is a valid status when renewing certs before expiry
raise newException(ACMEError, "Invalid new order status: " & $orderResponse.status)
raise
newException(ACMEError, "Invalid new order status: " & $orderResponse.status)
let authorizationsResponse =
await self.requestAuthorizations(orderResponse.authorizations, key, kid)
@@ -361,9 +368,9 @@ proc requestChallenge*(
# getting the first element is safe since we checked that authorizationsResponse.challenges.len != 0
)
proc requestCheck*(
proc requestCheck*(
self: ACMEApi, checkURL: Uri, checkKind: ACMECheckKind, key: KeyPair, kid: Kid
): Future[ACMECheckResponse] {.async: (raises: [ACMEError, CancelledError]).} =
): Future[ACMECheckResponse] {.async: (raises: [ACMEError, CancelledError]).} =
handleError("requestCheck"):
let acmeResponse = await self.get(checkURL)
let retryAfter =
@@ -388,7 +395,8 @@ proc requestCheck*(
try:
ACMECheckResponse(
kind: checkKind,
chalStatus: parseEnum[ACMEChallengeStatus](acmeResponse.body["status"].getStr),
chalStatus:
parseEnum[ACMEChallengeStatus](acmeResponse.body["status"].getStr),
retryAfter: retryAfter,
)
except ValueError:
@@ -396,24 +404,25 @@ proc requestCheck*(
ACMEError, "Invalid order status: " & acmeResponse.body["status"].getStr
)
proc sendChallengeCompleted*(
proc sendChallengeCompleted*(
self: ACMEApi, chalURL: Uri, key: KeyPair, kid: Kid
): Future[ACMECompletedResponse] {.async: (raises: [ACMEError, CancelledError]).} =
): Future[ACMECompletedResponse] {.async: (raises: [ACMEError, CancelledError]).} =
handleError("sendChallengeCompleted"):
let payload =
await self.createSignedAcmeRequest(chalURL, %*{}, key, kid = Opt.some(kid))
let acmeResponse = await self.post(chalURL, payload)
acmeResponse.body.to(ACMECompletedResponse)
proc checkChallengeCompleted*(
proc checkChallengeCompleted*(
self: ACMEApi,
checkURL: Uri,
key: KeyPair,
kid: Kid,
retries: int = DefaultChalCompletedRetries,
): Future[bool] {.async: (raises: [ACMEError, CancelledError]).} =
): Future[bool] {.async: (raises: [ACMEError, CancelledError]).} =
for i in 0 .. retries:
let checkResponse = await self.requestCheck(checkURL, ACMEChallengeCheck, key, kid)
let checkResponse =
await self.requestCheck(checkURL, ACMEChallengeCheck, key, kid)
case checkResponse.chalStatus
of ACMEChallengeStatus.PENDING:
await sleepAsync(checkResponse.retryAfter) # try again after some delay
@@ -427,20 +436,20 @@ proc checkChallengeCompleted*(
)
return false
proc completeChallenge*(
proc completeChallenge*(
self: ACMEApi,
chalURL: Uri,
key: KeyPair,
kid: Kid,
retries: int = DefaultChalCompletedRetries,
): Future[bool] {.async: (raises: [ACMEError, CancelledError]).} =
): Future[bool] {.async: (raises: [ACMEError, CancelledError]).} =
let completedResponse = await self.sendChallengeCompleted(chalURL, key, kid)
# check until acme server is done (poll validation)
return await self.checkChallengeCompleted(chalURL, key, kid, retries = retries)
proc requestFinalize*(
proc requestFinalize*(
self: ACMEApi, domain: Domain, finalize: Uri, key: KeyPair, kid: Kid
): Future[ACMEFinalizeResponse] {.async: (raises: [ACMEError, CancelledError]).} =
): Future[ACMEFinalizeResponse] {.async: (raises: [ACMEError, CancelledError]).} =
handleError("requestFinalize"):
let payload = await self.createSignedAcmeRequest(
finalize, %*{"csr": createCSR(domain)}, key, kid = Opt.some(kid)
@@ -449,13 +458,13 @@ proc requestFinalize*(
# server responds with updated order response
acmeResponse.body.to(ACMEFinalizeResponse)
proc checkCertFinalized*(
proc checkCertFinalized*(
self: ACMEApi,
order: Uri,
key: KeyPair,
kid: Kid,
retries: int = DefaultChalCompletedRetries,
): Future[bool] {.async: (raises: [ACMEError, CancelledError]).} =
): Future[bool] {.async: (raises: [ACMEError, CancelledError]).} =
for i in 0 .. retries:
let checkResponse = await self.requestCheck(order, ACMEOrderCheck, key, kid)
case checkResponse.orderStatus
@@ -470,7 +479,7 @@ proc checkCertFinalized*(
return false
proc certificateFinalized*(
proc certificateFinalized*(
self: ACMEApi,
domain: Domain,
finalize: Uri,
@@ -478,21 +487,21 @@ proc certificateFinalized*(
key: KeyPair,
kid: Kid,
retries: int = DefaultFinalizeRetries,
): Future[bool] {.async: (raises: [ACMEError, CancelledError]).} =
): Future[bool] {.async: (raises: [ACMEError, CancelledError]).} =
let finalizeResponse = await self.requestFinalize(domain, finalize, key, kid)
# keep checking order until cert is valid (done)
return await self.checkCertFinalized(order, key, kid, retries = retries)
proc requestGetOrder*(
proc requestGetOrder*(
self: ACMEApi, order: Uri
): Future[ACMEOrderResponse] {.async: (raises: [ACMEError, CancelledError]).} =
): Future[ACMEOrderResponse] {.async: (raises: [ACMEError, CancelledError]).} =
handleError("requestGetOrder"):
let acmeResponse = await self.get(order)
acmeResponse.body.to(ACMEOrderResponse)
proc downloadCertificate*(
proc downloadCertificate*(
self: ACMEApi, order: Uri
): Future[ACMECertificateResponse] {.async: (raises: [ACMEError, CancelledError]).} =
): Future[ACMECertificateResponse] {.async: (raises: [ACMEError, CancelledError]).} =
let orderResponse = await self.requestGetOrder(order)
handleError("downloadCertificate"):
@@ -505,5 +514,8 @@ proc downloadCertificate*(
certificateExpiry: parse(orderResponse.expires, "yyyy-MM-dd'T'HH:mm:ss'Z'"),
)
proc close*(self: ACMEApi) {.async: (raises: [CancelledError]).} =
proc close*(self: ACMEApi) {.async: (raises: [CancelledError]).} =
await self.session.closeWait()
else:
{.hint: "autotls disabled. Use -d:libp2p_autotls_support".}

View File

@@ -28,59 +28,66 @@ type ACMEClient* = ref object
logScope:
topics = "libp2p acme client"
proc new*(
when defined(libp2p_autotls_support):
proc new*(
T: typedesc[ACMEClient],
rng: ref HmacDrbgContext = newRng(),
api: ACMEApi = ACMEApi.new(acmeServerURL = parseUri(LetsEncryptURL)),
key: Opt[KeyPair] = Opt.none(KeyPair),
kid: Kid = Kid(""),
): T {.raises: [].} =
): T {.raises: [].} =
let key = key.valueOr:
KeyPair.random(PKScheme.RSA, rng[]).get()
T(api: api, key: key, kid: kid)
proc getOrInitKid*(
proc getOrInitKid*(
self: ACMEClient
): Future[Kid] {.async: (raises: [ACMEError, CancelledError]).} =
): Future[Kid] {.async: (raises: [ACMEError, CancelledError]).} =
if self.kid.len == 0:
let registerResponse = await self.api.requestRegister(self.key)
self.kid = registerResponse.kid
return self.kid
proc genKeyAuthorization*(self: ACMEClient, token: string): KeyAuthorization =
proc genKeyAuthorization*(self: ACMEClient, token: string): KeyAuthorization =
base64UrlEncode(@(sha256.digest((token & "." & thumbprint(self.key)).toBytes).data))
proc getChallenge*(
proc getChallenge*(
self: ACMEClient, domains: seq[api.Domain]
): Future[ACMEChallengeResponseWrapper] {.async: (raises: [ACMEError, CancelledError]).} =
): Future[ACMEChallengeResponseWrapper] {.
async: (raises: [ACMEError, CancelledError])
.} =
await self.api.requestChallenge(domains, self.key, await self.getOrInitKid())
proc getCertificate*(
proc getCertificate*(
self: ACMEClient, domain: api.Domain, challenge: ACMEChallengeResponseWrapper
): Future[ACMECertificateResponse] {.async: (raises: [ACMEError, CancelledError]).} =
): Future[ACMECertificateResponse] {.async: (raises: [ACMEError, CancelledError]).} =
let chalURL = parseUri(challenge.dns01.url)
let orderURL = parseUri(challenge.order)
let finalizeURL = parseUri(challenge.finalize)
trace "sending challenge completed notification"
discard
await self.api.sendChallengeCompleted(chalURL, self.key, await self.getOrInitKid())
discard await self.api.sendChallengeCompleted(
chalURL, self.key, await self.getOrInitKid()
)
trace "checking for completed challenge"
let completed =
await self.api.checkChallengeCompleted(chalURL, self.key, await self.getOrInitKid())
let completed = await self.api.checkChallengeCompleted(
chalURL, self.key, await self.getOrInitKid()
)
if not completed:
raise
newException(ACMEError, "Failed to signal ACME server about challenge completion")
raise newException(
ACMEError, "Failed to signal ACME server about challenge completion"
)
trace "waiting for certificate to be finalized"
let finalized = await self.api.certificateFinalized(
domain, finalizeURL, orderURL, self.key, await self.getOrInitKid()
)
if not finalized:
raise newException(ACMEError, "Failed to finalize certificate for domain " & domain)
raise
newException(ACMEError, "Failed to finalize certificate for domain " & domain)
trace "downloading certificate"
await self.api.downloadCertificate(orderURL)
proc close*(self: ACMEClient) {.async: (raises: [CancelledError]).} =
proc close*(self: ACMEClient) {.async: (raises: [CancelledError]).} =
await self.api.close()

View File

@@ -73,23 +73,24 @@ type AutotlsService* = ref object of Service
peerInfo: PeerInfo
rng: ref HmacDrbgContext
proc new*(T: typedesc[AutotlsCert], cert: TLSCertificate, expiry: Moment): T =
when defined(libp2p_autotls_support):
proc new*(T: typedesc[AutotlsCert], cert: TLSCertificate, expiry: Moment): T =
T(cert: cert, expiry: expiry)
proc getCertWhenReady*(
proc getCertWhenReady*(
self: AutotlsService
): Future[TLSCertificate] {.async: (raises: [AutoTLSError, CancelledError]).} =
): Future[TLSCertificate] {.async: (raises: [AutoTLSError, CancelledError]).} =
await self.certReady.wait()
return self.cert.get.cert
proc new*(
proc new*(
T: typedesc[AutotlsConfig],
ipAddress: Opt[IpAddress] = NoneIp,
nameServers: seq[TransportAddress] = DefaultDnsServers,
acmeServerURL: Uri = parseUri(LetsEncryptURL),
renewCheckTime: Duration = DefaultRenewCheckTime,
renewBufferTime: Duration = DefaultRenewBufferTime,
): T =
): T =
T(
dnsResolver: DnsResolver.new(nameServers),
acmeServerURL: acmeServerURL,
@@ -98,13 +99,14 @@ proc new*(
renewBufferTime: renewBufferTime,
)
proc new*(
proc new*(
T: typedesc[AutotlsService],
rng: ref HmacDrbgContext = newRng(),
config: AutotlsConfig = AutotlsConfig.new(),
): T =
): T =
T(
acmeClient: ACMEClient.new(api = ACMEApi.new(acmeServerURL = config.acmeServerURL)),
acmeClient:
ACMEClient.new(api = ACMEApi.new(acmeServerURL = config.acmeServerURL)),
brokerClient: PeerIDAuthClient.new(),
bearer: Opt.none(BearerToken),
cert: Opt.none(AutotlsCert),
@@ -115,9 +117,9 @@ proc new*(
rng: rng,
)
method setup*(
method setup*(
self: AutotlsService, switch: Switch
): Future[bool] {.async: (raises: [CancelledError]).} =
): Future[bool] {.async: (raises: [CancelledError]).} =
trace "Setting up AutotlsService"
let hasBeenSetup = await procCall Service(self).setup(switch)
if hasBeenSetup:
@@ -131,9 +133,11 @@ method setup*(
self.managerFut = self.run(switch)
return hasBeenSetup
method issueCertificate(
method issueCertificate(
self: AutotlsService
) {.base, async: (raises: [AutoTLSError, ACMEError, PeerIDAuthError, CancelledError]).} =
) {.
base, async: (raises: [AutoTLSError, ACMEError, PeerIDAuthError, CancelledError])
.} =
trace "Issuing certificate"
assert not self.peerInfo.isNil(), "Cannot issue new certificate: peerInfo not set"
@@ -186,9 +190,9 @@ method issueCertificate(
self.certReady.fire()
debug "Certificate installed"
method run*(
method run*(
self: AutotlsService, switch: Switch
) {.async: (raises: [CancelledError]).} =
) {.async: (raises: [CancelledError]).} =
heartbeat "Certificate Management", self.config.renewCheckTime:
if self.cert.isNone():
try:
@@ -211,9 +215,9 @@ method run*(
error "Failed to renew certificate", err = exc.msg
break
method stop*(
method stop*(
self: AutotlsService, switch: Switch
): Future[bool] {.async: (raises: [CancelledError]).} =
): Future[bool] {.async: (raises: [CancelledError]).} =
let hasBeenStopped = await procCall Service(self).stop(switch)
if hasBeenStopped:
if not self.acmeClient.isNil():

View File

@@ -6,23 +6,11 @@
# at your option.
# This file may not be copied, modified, or distributed except according to
# those terms.
{.push raises: [].}
{.push public.}
import net, strutils
from times import DateTime, toTime, toUnix
import chronos, stew/base36, chronicles
import
./acme/client,
../errors,
../peerid,
../multihash,
../cid,
../multicodec,
../nameresolving/dnsresolver
import chronos
import ../errors
const
DefaultDnsRetries = 10
@@ -30,7 +18,19 @@ const
type AutoTLSError* = object of LPError
proc checkedGetPrimaryIPAddr*(): IpAddress {.raises: [AutoTLSError].} =
when defined(libp2p_autotls_support):
import net, strutils
from times import DateTime, toTime, toUnix
import stew/base36, chronicles
import
../peerid,
../multihash,
../cid,
../multicodec,
../nameresolving/dnsresolver,
./acme/client
proc checkedGetPrimaryIPAddr*(): IpAddress {.raises: [AutoTLSError].} =
# This is so that we don't need to catch Exceptions directly
# since we support 1.6.16 and getPrimaryIPAddr before nim 2 didn't have explicit .raises. pragmas
try:
@@ -38,10 +38,10 @@ proc checkedGetPrimaryIPAddr*(): IpAddress {.raises: [AutoTLSError].} =
except Exception as exc:
raise newException(AutoTLSError, "Error while getting primary IP address", exc)
proc isIPv4*(ip: IpAddress): bool =
proc isIPv4*(ip: IpAddress): bool =
ip.family == IpAddressFamily.IPv4
proc isPublic*(ip: IpAddress): bool {.raises: [AutoTLSError].} =
proc isPublic*(ip: IpAddress): bool {.raises: [AutoTLSError].} =
let ip = $ip
try:
not (
@@ -52,7 +52,7 @@ proc isPublic*(ip: IpAddress): bool {.raises: [AutoTLSError].} =
except ValueError as exc:
raise newException(AutoTLSError, "Failed to parse IP address", exc)
proc getPublicIPAddress*(): IpAddress {.raises: [AutoTLSError].} =
proc getPublicIPAddress*(): IpAddress {.raises: [AutoTLSError].} =
let ip = checkedGetPrimaryIPAddr()
if not ip.isIPv4():
raise newException(AutoTLSError, "Host does not have an IPv4 address")
@@ -60,11 +60,11 @@ proc getPublicIPAddress*(): IpAddress {.raises: [AutoTLSError].} =
raise newException(AutoTLSError, "Host does not have a public IPv4 address")
return ip
proc asMoment*(dt: DateTime): Moment =
proc asMoment*(dt: DateTime): Moment =
let unixTime: int64 = dt.toTime.toUnix
return Moment.init(unixTime, Second)
proc encodePeerId*(peerId: PeerId): string {.raises: [AutoTLSError].} =
proc encodePeerId*(peerId: PeerId): string {.raises: [AutoTLSError].} =
var mh: MultiHash
let decodeResult = MultiHash.decode(peerId.data, mh)
if decodeResult.isErr() or decodeResult.get() == -1:
@@ -77,13 +77,13 @@ proc encodePeerId*(peerId: PeerId): string {.raises: [AutoTLSError].} =
return Base36.encode(cidResult.get().data.buffer)
proc checkDNSRecords*(
proc checkDNSRecords*(
dnsResolver: DnsResolver,
ipAddress: IpAddress,
baseDomain: api.Domain,
keyAuth: KeyAuthorization,
retries: int = DefaultDnsRetries,
): Future[bool] {.async: (raises: [AutoTLSError, CancelledError]).} =
): Future[bool] {.async: (raises: [AutoTLSError, CancelledError]).} =
# if my ip address is 100.10.10.3 then the ip4Domain will be:
# 100-10-10-3.{peerIdBase36}.libp2p.direct
# and acme challenge TXT domain will be:

View File

@@ -257,9 +257,10 @@ proc withAutonat*(b: SwitchBuilder): SwitchBuilder =
b.autonat = true
b
proc withAutotls*(
when defined(libp2p_autotls_support):
proc withAutotls*(
b: SwitchBuilder, config: AutotlsConfig = AutotlsConfig.new()
): SwitchBuilder {.public.} =
): SwitchBuilder {.public.} =
b.autotls = AutotlsService.new(config = config)
b

View File

@@ -10,4 +10,5 @@ when defined(linux) and defined(amd64):
# This file may not be copied, modified, or distributed except according to
# those terms.
import testpeeridauth_integration, testautotls_integration
when defined(libp2p_autotls_support):
import testpeeridauth_integration, testautotls_integration

View File

@@ -28,10 +28,13 @@ import
transports/tls/testcertificate
import
testautotls, testnameresolve, testmultistream, testbufferstream, testidentify,
testnameresolve, testmultistream, testbufferstream, testidentify,
testobservedaddrmanager, testconnmngr, testswitch, testnoise, testpeerinfo,
testpeerstore, testping, testmplex, testrelayv1, testrelayv2, testrendezvous,
testdiscovery, testyamux, testautonat, testautonatservice, testautorelay, testdcutr,
testhpservice, testutility, testhelpers, testwildcardresolverservice, testperf
import kademlia/[testencoding, testroutingtable]
when defined(libp2p_autotls_support):
import testautotls