Code change:
[Edit: deleted "Fixes" line for ]
From , we also talked about IP addresses and such. Do we still want to do that? Whether the client validation is SHOULD or MUST (TBH I kinda prefer MUST, given the implications on private services... if it's a SHOULD, we should talk about why so implementations can make an informed decision), we do also need to say what values are valid for the server.
OK, switched to a MUST. Added IP addresses as well. I'm calling out to for IPv4/IPv6 parsing. I'd like to avoid any ambiguities that might creep in if I were allowed to define the grammar, like allowing octal numbers in an IPv4 address, e.g. != . For hostname parsing, I'm borrowing from so we can parse IDNs.
I think that is a mistake.
Why is that?
I think IP addresses are a mistake because they can introduce parsing ambiguities (as pointed out above), and sometimes those cause problems (URL). Also, SNI is really limited to hostname (as NAME has pointed out before, referencing AGL's post), and having the two mismatch in their capabilities bothers me.
Agreed that the capability mismatch between SNI and ECHConfig.publicname is odd. However, there is already a capability mismatch between ECHConfig.publicname and names allowable on server certificates. At least in theory, the server's certificate might not have a hostname. That being said, I don't have a strong opinion either way. If we do decide to disallow IP addresses, I think we'd still want the client to look for them so it can reject those ECHConfigs that use IP addresses. This is about stopping wacky values from bubbling up to the application.
The client sending the ECH or the server receiving it? Current TLS stacks don't seem to check, on either side. (At least OpenSSL and its major forks)
I was referring to the client, but yeah, scratch that idea. If public_name can only be a hostname, the client should only validate that it looks like a hostname.
I don't think the capability mismatch between SNI and ECHConfig.publicname is a fatal. We can move ECHConfig.publicname up an abstraction level. I think we should do this whether we allow IPs or not. The public name isn't "put this in ClientHelloOuter.servername" but "the name you are trying to connect to in the outer handshake". In particular, this encompasses both ClientHelloOuter.servername and certificate verification. To fill in ClientHelloOuter.servername, you use the rules in RFC6066: servername is the name you are trying to connect to, provided it's a DNS name. Under this model, it is perfectly coherent for "the name you are trying to connect to" to be an IP address, if we want to do that. If we wish to do that then, yeah, we'll need to spell out the syntax here. That syntax clearly does already exist (URLs, etc.), but not in TLS. I don't particular care whether we do it, though. How about this: Right now, IP addresses are implicitly not okay by way of CHOuter.servername = ECHConfig.publicname. So let's not introduce them in this PR and merely iron out the DNS name validation. This PR adds to, but does not We then rework the text to redefine public_name as above. This is a prerequisite to allowing IPs, but I think it's worth doing either way. We decide the IP question (interim?) and with the result. (Sorry, I think some of this confusion is my fault. I filed two related, but separate, discussion points in , which was confusing. My comment in URL was most in reaction to "; that we shouldn't close it out without resolving both points.)
I think I'd mostly be against supporting IP addresses in ECHConfig.publicname. I suspect including an IP address in URL would break some things. The comment below is from OpenSSL's ssl/statem/extensionssrvr.c: / Although the intent was for servername to be extensible, RFC 4366 was not clear about it; and so OpenSSL among other implementations, always and only allows a 'hostname' name types. RFC 6066 corrected the mistake but adding new name types is nevertheless no longer feasible, so act as if no other SNI types can exist, to simplify parsing. Also note that the RFC permits only one SNI value per type, i.e., we can only have a single hostname. / Separately, we could land ourselves with yet more confusion related to the address to which one ought send a ClientHello, (the address in the ECHConfig or in the URL or the A/AAAA of one of the names involved, and which to prefer if some things have DNSSEC etc etc.). Cheers, S.
NAME Right, I think it's unambiguous, whatever we do with IP addresses, they won't go in ClientHelloOuter.servername. Any use of this, if we want it, would be for public name verification, not the servername value. See my comment above with how to think about public_name.
SGTM, folks. Just dropped the parts about IP addresses.
Looks like I was a little overzealous removing the IP address text. We still need to check that publicname is not an IPv4 address because dotted-decimal IPv4 addresses would slip through the cracks of hostname validation. This is bad because a malicious/misconfigured DNS would cause the ECH client to break 's rule on the contents of "servername": (Re-added this IPv4 check in the last commit.)
I would rather make "validate the host name" be a SHOULD and remove all these requirements.
ECH implementations not validating that string risks surprising behavior for a lot of applications, and potentially more attack surface to private services than before. Have you looked at the discussion in issue , in particular: Sadly, the thing that makes that work (logic earlier in the application) doesn't apply here. See URL
Can you explain your concerns in more detail? I think the application should be responsible for validation.
The application should never see the value of ECHConfig.public_name, right?
See , specifically URL and URL Well, there are several things going on here: First, different systems may differently divide the "TLS" part and the "application" part. The spec mostly captures behavior of the overall client system, because that's all we can usefully talk about. (For example, ECH specifies a retry flow that involves making a new connection. At the level of many TLS libraries, including OpenSSL + derivatives, the caller makes connections. So instead the TLS library can expose APIs and document the caller's responsibilities as part of enabling ECH. Other interfaces may be create their own connections and handle this internally.) So whether it's the application or TLS, at the implementation level, isn't a hard deciding factor. Second, with that said, yes, I expect that the majority of TLS application interfaces will treat the ECHConfigList as an opaque blob. That is a good division of responsibilities because the TLS half already needs to process individual ECHConfigs in the ECHConfigList and select one based on its internal capabilities. Having to thread through application-specific DNS validation seems like it'd be complex. (But this is just my view as an implementor. The spec merely describes the overall behavior of the client system. How you choose to layer it is an implementation decision.) Finally, there's the question of whether TLS as a spec should have opinions here or if it should punt to some upper layer spec profile, as we did with 0-RTT. I don't think that's warranted here. RFC6066 already decided what can go in server_name, so TLS already is plenty opinionated on the shape of strings meant to be DNS names. Thus, IMO, the simplest and most practical story is to have TLS handle this, rather than thread it up through all the layers.
I am willing to accept that I am in the rough here.
As noted in URL, I don't think we should be putting IP addresses in .
In the interest of dealing with one problem at a time, this PR no longer attempts to spell out how to recognize IP addresses. Roughly: The client MUST validate as a LDH hostname. The client SHOULD exclude IP address literals, which may come in many strange forms, or else it may send a non-compliant "servername" extension. If we care to make excluding IP addresses a MUST, let's work out the details in another PR. Same goes for if we want to explicitly support IP address literals — we still need to validate them to protect server applications from receiving IP addresses in non-standard notations, e.g. octal.
I think there are a couple things going on here: ECHConfig.publicname, as currently written, is described as what goes in CHOuter.servername. That wasn't right and we should have made it outer reference identity. I believe NAME is going to do a separate PR after this goes through. SNI or reference identity, we need to define what the type of the thing that goes in ECHConfig.publicname and what validation the client does. In particular, without validation, it gives the network more control over what goes into CHOuter.servername than would otherwise be the case. Normally, in a typical HTTPS client, TLS can just assume the hostname has passed whatever checks earlier in the stack (URL parsing, DNS lookup, etc.) and so checks in TLS are not load-bearing. The public name breaks this because the TLS layer is fabricating a hostname on its own. So we should have TLS validate it before running too far with it. This PR addresses (2).
Following up on NAME comment, I was indeed planning on clarifying that ECHConfig.publicname is a reference identity, and planned on renaming this to something other than to match. Basically: may be either a name or IP address, validated according to the rules in this PR, and clients will use that identity when constructing the ClientHello per the normal rules. (If it's a name, put it in "servername," else don't put it in that name.) I think we can probably land this PR as-is. Is everyone else OK with this plan?
It's a nit, but I don't think I've ever seen a use of the term "identity" that didn't eventually cause confusion. I think public_name was better TBH. Sorry if I missed the discussion but: Are one or more IPv4/IPv6 addresses allowed and if so with what syntax? If only 1 is allowed, why? (Syntax still needs a reference.) I don't know how an IP address here ought be handled if it differs from those in the SVCB address hints fields. (Not to mention the origin's A/AAAA records.) Lastly, I forget why we even want an IP address there at all. Thanks, S.
I assumed there's at most one identity in this field, be it a name or address, but NAME can clarify. Also, I think the identity here only pertains to how the client-facing server is authenticated. If a server uses an IP-address certificate for the rejection path then it might specify the single IP address of that certificate. (Clients don't use SVCB hints for this, so they're orthogonal.)
There can be many SANs even if those are IP addresses. So I think you mean that you want exactly one IP address here and if one is here that MUST match one SAN iPaddress from the cert? Personally I don't think that's useful enough to support but maybe I missed why it was really good. TBH, I doubt implementers will notice that orthogonality. And those deploying even less would be my guess. If one is allowed put a single IP address in an ECHConfig and others in SVCB hints then someone needs to say what to do when those aren't the same. S.
True, but I'm just commenting on parity with what's there right now. (ECHConfig.public_name is just one name.) We may change that later if people want it? I don't see a reason to, though. Yeah, that's what I'm thinking. Hmm, yeah, we may be able to clarify this, but given that we don't discuss anything about the SVCB record (beyond the config) currently, it may not be needed.
Currently, this PR explicitly states that the client SHOULD ignore the ECHConfig if its contains an IP address. Unfortunately, what constitutes a textual representation of an IPv4 address is pretty underspecified, so I didn't manage to come up with a foolproof validation algorithm, otherwise I would make it a MUST. If we want to allow IP addresses, let's figure it out in another PR.
So I don't think that we need to worry about IPv6 here. That will never match LDH. The IPv4 thing is unfortunate. I think that the risk is that the public name is passed to a certificate validation library that subsequently treats the name as an IP address (matching against an ipAddress SAN rather than dNSName SAN) when doing fallback process. If there is any potential for confusion about this string (or look-alikes if we consider the octal mess) then it might happen that there is variation in what certificates are considered OK. That leads to a reliance on the certification authorities being careful about issuance for names that look like IP addresses. We don't want that. Either way, I don't like "SHOULD" here. It retains the potential confusion. If one client component is sloppy and doesn't bother other components are then forced to contend with that choice. I think that I've come around to NAME viewpoint on this. It's reasonable to require a domain name for fallback in all cases, even where a server is identified by IP address alone. I think that means prohibiting IPv4 addresses, just to avoid the potential confusion. That is, if the name contains exactly 4 labels that are only digits, then the record is invalid. IPv6 addresses will look after themselves as they aren't valid LDH A-labels. Note: I don't know if there are rules that might allow 172.0.2.2045 to be registered, which is clearly not an IP address. I believe that the main protection we have against valid DNS names appearing to be IPv4 addresses is the gTLD registration rules (from URL Section 2.2.1.3.1 clause 1.2.1 this is currently assured as only a-z is permitted from the ASCII range).
NAME can you drill into this? I must be misunderstanding you (and maybe the problem), but are you suggesting that strings which look like IP addresses might be parsed incorrectly by the thing validating certificates against such look-alike addresses? They also have to be careful about names that aren't actually domain names ("DROP TABLES" or whatever). How is this a substantially new requirement? Prohibiting IP addresses here seems overly restrictive. Given that it doesn't seem challenging to support, and does not, to my knowledge, introduce any new requirements for CAs or certificate validation APIs, I'd like to hear more reasons why we ought to definitely rule them out. And as NAME says, we should hash this out in a separate issue and PR. In the interest of making forward progress, I'm going to merge this PR as-is, and we can discuss more in .
In most cases, I don't anticipate problems: there will be one certificate validator used during fallback and that will make a single determination. IP address lookalikes in that case probably won't be a problem. However, in cases where there are multiple components involved, there might be IP address lookalikes that pass one validator but not another. That might be used to attack clients.
Given how IPv4 literals can get in some applications, I suspect the TLS library classifying and rejecting IPv4 literals in a way that ensures the calling application always interprets it as a DNS name is hopeless. I'm now inclined to say we should: Do and say publicname is exclusively DNS. If anyone adds IP in the future, the expectation will be a separate extension and thus not require any parsing to pick semantics. The exclusively-DNS publicname field is validated according to DNS rules and leave it at that. That at least avoids completely unbounded DNS control on the ClientHello. Concede that we can't reliably exclude IPv4 literals at this layer. Call this out and say that clients MUST NOT validate the string as IP addresses. If your verifier has separate APIs for configuring DNS vs IP names for subjectAltName, feel free to pass the string as a DNS input and move on. If your verifier's API takes a more URL-like hostname, you should use whatever logic you used to distinguish DNS vs. IP and fail the verification if you think the string is an IP. (Effectively that verifier believes "DNS:1.2.3.4" is never valid because it has no way to spell it.) This does mean the DNS can cause ClientHelloOuter to violate the RFC6066 prohibition on IPv4 literals, but since RFC6066 failed to specify what syntax it was prohibiting, the meaning of that rule is somewhat unclear.
In , there's been a lot of discussion around how and whether or not IP addresses should be allowed as a reference identity of the client-facing server. This issue tracks sorting this particular question out. NAME suggested in the case the reference identity is an IP address. (Whether or not this address is in the ECHConfig is separate.) NAME suggested . (Whether or not this allows the outer SNI to be empty is separate.) So there seems to be two questions we need to sort out, in relation to : Should the ECHConfig be allowed to supply IP addresses? And if so, how do client stacks validate them? Should clients be allowed to validate servers using IP addresses as a reference identity? (If yes, then the ClientHelloOuter.SNI must be allowed to be empty/omitted.) I think (2) should be 'yes', given that's currently possible today introduces no new complexity. I think it should be feasible to spell out the requirements to make (1) feasible, so I also think that should be 'yes'. What do others think?
Yes and yes. RFC 8738 using reverse-IP notation, which seems like a halfway-reasonable option. An "empty" public name seems a little more flexible (doesn't require servers to carry certificates for each other's IP addresses), and ought to be easy enough to support on clients.
NAME to clarify this: You're suggesting that if ECHConfig is empty then the client should use the IP address of the client-facing server as the reference identity, right? That seems like a reasonable way around the language we might need to specify what is a valid address in ECHConfig. (If the reference identity is not empty, then it MUST be a name, otherwise it's the IP address, and clients should connect and validate based on that identity accordingly.)
NAME Correct. NAME previously raised a concern that this could complicate client implementations: the TLS stack can no longer make use of a connected socket given solely on the ECHConfig and inner reference identity; it also needs the remote IP in some cases. This is true, but I think the remote IP is essentially always "at hand" so perhaps it can be passed in unconditionally without too much difficulty.
I don't think that's true when the client is using a proxy, depending on how much of DNS is done on the client and how much is done on the proxy. If the client does the SVCB lookup itself but asks the proxy to look up TargetName, as the SVCB draft , the client won't have the remote IP of the client-facing server available. (Are there weird networks that rewrite addresses at the DNS level? That would also break with this idea.)
To try and sharpen NAME point: will the client always have access to the client-facing server IP? I don't see how this won't always be true, since the client connects to something, but maybe I'm misunderstanding the proxy scenario.
NAME is correct about the behavior when using a SOCKS5 or HTTP CONNECT proxy in domain-oriented mode. The proxy performs A/AAAA resolution and TCP connection establishment, and does not provide this information back to the client, so the client doesn't know which server IP it is using. That does suggest that "empty" won't work.
Oh! I see. The proxy is the one establishing the transport connection.
There's probably at least three modes here, if not more: Proxy gets the origin DNS name and takes over the whole DNS lookup. Client doesn't do SVCB at all. The only way to salvage SVCB-based features is to invent a header for the proxy to tell the client what SVCB path it followed in the CONNECT response. Client does SVCB lookup and gives TargetName to the proxy. Client does the whole lookup and gives the IP address to the proxy. The one that breaks empty names is (2). Though, given that proxies today are often used to access internal services (i.e. without the proxy, you may not even be able to resolve the name), I expect (1) to be the default for existing schemes. Whereas (3) might make sense for other kinds of proxy use cases. (I'm actually not entirely sure when you'd want (2) despite the spec recommendation... maybe if you're relying on the proxy to rewrite IPs, but the proxy needs to a DNS name to do so?)
This is presumably not the right forum for this topic, but mode (2) is the one that gives you correct Happy Eyeballs, geo-DNS, etc.
I seem to recall some DNS IPv6 transition thing that maybe has that property. S.
Yes, there are transition technologies that rewrite addresses. Clients get a v6 address because they only have v6, but the server address is v4. As for the general proxy problem, there is no value in any design that does not involve the client having the ECHConfig. It can't use the public IP (because it doesn't know it always), but it can still populate servername according to the value of publicname. I might have missed something there though. From David's , option 1 is a bit silly (it adds unnecessary latency), but it also gives you the best locality if your goal is to use the proxy egress as the client network location (option 2 as Ben only works if you care about the network location of the client, at which point you might as well not use a proxy). The only difference between 2 and 3 there is whether the proxy needs to perform its own name resolution, which might differ from the client (and cause problems as a result; but that's mostly just a case of insisting that clients don't choose option 2). I don't understand why it's so hard to require the use of a domain name. It shouldn't be "". Adding other forms of reference identity adds complexity to what is already a morass of horrifying complexity, so we should insist on justification for every addition. And I'm not seeing any concrete arguments in favour of the complex option. So my answer is No to both questions.
I don't agree with Martin's characterization of the proxy behaviors, but I don't think this is the place to discuss that topic anyway. To me, the main advantage of supporting IP reference identities is for origins that are not using a large-scale hosting provider, and thus cannot rely on a widely shared . Domain names are typically more closely linked to an organization than IP addresses (especially with VM hosting), and more expensive to change. An IP address ensures that the client does not populate the outer SNI, and supports a configuration where the default certificate only contains an IP address SAN. This minimizes the information visible to an adversary unless they can also identify the service that runs on this IP address (e.g. by scanning the whole DNS). An alternative to IP address in would be a flag in the ECHConfig indicating that the specified reference identity is in the default certificate (which is implicitly true for IP reference identities). This would allow clients to omit the SNI, improving small services' privacy against a passive adversary, but active adversaries could fetch the default certificate to learn the .
For everyone's consideration, we now have as an alternate solution to this problem (thanks to NAME which does two things: (1) avoids overloading a single field for two types of values (names and addresses), and (2) punts IP address validation to a future change. While I sympathize with Martin's view, it seems overly restrictive to just prohibit IP addresses outright. This change allows us to sort that out in a future change, and should make everyone happy. Thoughts?
Re , the idea is largely me going "oops, I'm sorry for the mess". :-) When I filed , I was mostly interested in the client validation. But most places with DNS strings have a semi-overlap with IP literal syntax, and RFC6066 already prohibits of IP literals. (Without declaring an actual syntax being prohibited!) So it seemed hard to resolve those questions without going one way or another on IPs. So I brought up that question too as a seemingly minor (hah) side question on the main issue. That side question has turned out to be way more messy than I anticipated. Since there isn't a strong need for IPs as public identities, but also unease to completely close that door, I propose we tweak the encoding so it's easy enough to add later (reuse the extension mechanism we're already putting in), but not actually bother in this draft.
Isn't it the case that the extension scheme would allow us to add IP addresses later, even without ?
There's lots of different ways we can accomplish this, and it'll come down to personal taste. For example: Make publicname optional in the main ECHConfig (and waste the two byte length field), and allow an extension to specify the IP address. Move publicname to a mandatory extension (as 426 does), and allow future extensions to specify addresses override the name. etc. Given the bikeshed that's happening here, it seems prudent to at least separate these things (names and addresses). If we can agree on that, then we just need to decide where we put those bits. does the job one way. If someone wants to propose an alternative PR to put the bits somewhere else, please do so!
If we're really talking about a bikeshed, then the "no change" option works for me. It's fewer bits on the wire (by 4), it is less complicated to enforce it being mandatory, and we already have it implemented. I do think that public_name being optional has some impact here. It means that you don't have a reference identity for fallback handling. I think that's probably legitimate. There might be cases where fallback is not needed.
Hmm... how do you see this working if a future extension wants to specify IP addresses as a fallback but the publicname is not allowed to be optional? I agree that there will be cases where fallback is not needed. DNS-SD is one of them. And in that case, removing the publicname field (or allowing it to be empty, or whatever) will be needed. I think addresses that pretty nicely.
Ahh, I misunderstood. It's not that the extension is mandatory to use, but it is mandatory to understand when present. Let's be really crisp about the words we use. Of course, an empty value is an equally good way to indicate that the value isn't operative. It's one byte in the less-common case to save 4 bytes in the common case. The question occurs to me: is there any possibility that you could have both a publicname extension and this hypothetical ipreference_identity extension? What would that mean? I want to be really open about my priors here: I think that extensibility along this axis is an anti-feature for ECH. The mandatory-to-understand extensions are part of what really confirmed that for me. I think that the current format would be improved by removing the extensions block.
Unclear -- I think it'd be up to the hypothetical extension to define how those things interact. I hear you. If we didn't care about IP addresses for the fallback certificate, much of this would be simplified. (And admittedly the desire to remove the extensions block would increase for me, too.) I'm going to take this to the list, since we don't seem to be getting anywhere without consensus on that point.
The draft already defines a notion of "mandatory". Although does both (let's call the other one "required"?), which I think is the minimal encoding change because... I don't think we should open that can of worms. Even though not having a fallback flow is really the server's decision, I think the client has a stake in this too. It's useful to nudge the ecosystem towards things that work well. If a server deploys without fallback, underestimating the predictability of DNS caching, it will break rarely in some clients. That sort of thing is bad UX and increases the pressure for clients to adopt insecure fallbacks. Unless there is a clear need, I don't think we should allow that. (Otherwise not setting it up is deceptively attractive for a naive server since they make fewer decision.) The extensibility story for ECH is a little funny. You send an ECHConfigList and the client ignores any ECHConfigs it can't understand. So if we say today's ECH clients require a publicname extension, future ECH clients can still support a publicip extension that relaxes the publicname requirement. Today's ECH clients will just ignore the publicip-using configs, which is the desired behavior. But I should say I have no stake in this IP mess and do not care whether we allow those. Just pick something that everyone's happy with, please. was an attempt to punt this out of the draft while keeping all the existing semantics unchanged (hence required extension; the correct reading is that it is purely an encoding change).
That point about making it hard NOT to provide a fallback makes me more inclined to reject . If the effect is just a change in encoding, it's a less efficient encoding and one that is harder to validate properly. If the effect is to make it optional under certain conditions, you have just argued effectively for why that has negative consequences.
It's really a different point and maybe deserves it's own issue but since I'm not logged into github and email works... The "critical" bit in x.509 extensions IMO didn't work. IIRC we really designed it for the basicConstraints extension, as that had to be understood by relying parties, but the result was that we more or less only had one shot at introducing any critical extensions - unless I'm forgetting stuff (which is entirely possible:-) pretty much all later attempts to add new critical extensions failed as they'd break deployed clients. We'd have been better off adding the is-a-ca flag and anything else we knew to be critical the TBSCertificate. (Again IIRC, we put both critical and non-critical stuff into extensions because the UniqueID fields in TBSCertificate that were added in x.509v2 hadn't been useful so there was a reluctance to put new fields in there at that point.) I don't see why criticality is different for ECH extensions. My bet is that any new critical extension will need a new TLS extension code point once the first ECH RFC is issued. So I'd remove the extensions fields we've defined and if not then at least get rid of the idea of criticality. Cheers, S.
NAME I filed to discuss ECHConfig.extensions -- let's try and keep this issue focused on the IP address question(s).
Addressed in , closing.
Some edge cases around the publicname: What if the public name is some random string which is not a valid DNS name? (What's the right terminology here? Same from RFC6066?) Does the client reject the ECHConfig? My feeling is yes. Imagine you have some random service accessible on a private address. Today, it can assume it'll never see in the servername field. Even if an attacker pointed at that private address, the attacker is constrained by valid DNS strings. But the public name is never directly queried in DNS. Is a server deployment allowed to use an IP certificate for the ECH rejection identity? (That was actually the original idea for the fallback flow.) If so, how do they specify it? Do they use the ASCII serialization of the IPv4 or IPv6 address? Note that IP addresses do not go in server name, so the client would need to recognize this and leave server_name empty. NAME
I imagined the outer name would be set from the config similar to how an application sets the inner name. That is, one provides a string to and, internally, the library determines whether or not that string is a valid domain name (and thus goes in the server name) or is an IP address (and thus is used to verify the IP-based cert that might come back from the server). ASCII serialization of addresses seems fine here, if one just takes that string and passes it to the function (or equivalent).
Well, OpenSSL and derivatives have a lower-level API and just take the server name as an opaque string. :-) But yeah, that seems a reasonable model. Whatever we pick, we should write it down. What do you think should happen if the public name is neither a valid DNS name, nor a valid IP address? Like . ECHConfig parse error would be my inclination.
Yeah, that seems like a configuration error on behalf of the server.
That seems like it's already an unsafe assumption, right? Malicious clients could send SQL-injection strings to vulnerable servers without ECH. I suppose ECH introduces some asymmetry; one malicious DNS server could cause N clients to send the malicious payload.
Backing up a step, if we care to protect applications from malicious/malformed DNS hostnames, it seems prudent to validate all incoming server_name values on the server, whether they came from ClientHelloInner/ClientHelloOuter or even a non-ECH ClientHello. (Assuming we're using the RFC6066 HostName definition.)
NAME yeah, that's basically what I was thinking the function would do. Would you have cycles to prep a PR to resolve this issue?
It depends. Services listening on private addresses often make a lot of assumptions. These assumptions are pretty questionable, but we put in effort to anyway because that is reality. Yes, any server listening on a network should tolerate arbitrary input and behave well. Nonetheless, the reality is private services are often buggy. Where we break soft assumptions that might have previously (mostly) worked, we should at least think about it. Here, it seems there's no point in breaking the assumption.
Ah, servers at private addresses was not even on my radar. I support client validation of ECHConfig.publicname at parse time AND server validation of all ClientHello* servername extensions. NAME Happy to do a PR.
(I don't think the ECH spec should say anything about server validation here. The server looks at whichever ClientHello it selects and does whatever it would normally do with the server name in the selected one.)
There doesn't seem to be a standard that reflects actual current practice. Chrome and Firefox accept SNIs with underscores, which are not allowed in valid DNS names (URL).
Yep, thanks for raising that, Carrick. Perhaps we should make hostname validation a SHOULD rather than MUST?
The issue doesn't sound like a MUST vs. a SHOULD but rather what they SHOULD or MUST do. I guess we could say "do whatever you usually do with the SNI."
Oh and yeah, SHOULD seems like a better idea than MUST since there are conflicting opinions about the right way to go about it.
It's a little tricky due to what layers we're talking about. Chrome doesn't particularly validate the SNI at the TLS level. Rather, we leave that to URL parsing and DNS logic earlier in the pipeline. If we've gotten far enough to make a TLS connection, we assume we're happy with the string we're passing to SNI and certificate validation. I imagine this is reasonably common: OpenSSL likewise treats the setservername API as an opaque byte string. ECH breaks this assumption by bypassing all the earlier layers. Suddenly a TLS-level construct (ECHConfig) is fabricating a DNS name on its own, and now TLS needs to pick up all the validation.
Technically couldn't DNS logic validate the DNS name in the ECHConfig?
Hi folks, PR is a little more complete now, if you get a chance :)
To close the loop on this: it could, but we're treating the ECH parts of SVCB as opaque to DNS. [edit: I miswrote "opaque to TLS" at first] I think that's desirable because TLS may introduce new ECH extensions or ECH versions that the DNS stack may not be aware of. Also, any validation on the URL parsing / DNS query path happens in the process of making a request to the DNS server at all, whereas any validation here would be a check afterwards on the result. Whatever we do, it'll end up looking like someone, DNS or TLS, implementing a check we need to write down.
To come back to this: because SNI does not support IP addresses, IP certs must be the server's default-cert, i.e. they must be served to requests that omit the SNI. Thus, we merely need a way to tell clients to omit . My suggestion is to allow to be empty, meaning "omit outer SNI".
Keeping in mind that the client uses to authenticate the server's , the client now needs to be aware of which IP address it's connecting to. I suppose this isn't a protocol concern, but it's more ergonomic when the ECHConfig contains all the information TLS needs to do ECH.
OK. As I mentioned yesterday, I think should probably be an X.509 .
I do not think GeneralName will work. There's somewhat a mismatch between what the application thinks of as identities and how those identities are encoded into X.509. GeneralName is part of the latter. What does a browser certificate verifier, which only believes in things that fit in a URL, do if it's told the identity is now an EDIPartyName? What SNI, etc., does that translate into, given that our identity-to-TLS-config algorithm takes an HTTPS origin, not an X.509 name? (Note that the type field in SNI is fiction. There is and will be .) More importantly, this glomming too many things into an already overloaded issue. If you want to pursue this, can you please fork GeneralName into a separate topic? The status quo in the existing text is that the public name is clearly only good for DNS or DNS+IP, depending on how much you believe in URL syntax. We already have a need to better specify that case, including client validation. Let's fix that, and then we can separate tackle more complex cases.
Strongly disagree. GeneralName was a reasonable guess at a thing to do 20 years ago but is no longer a structure that ought be leveraged - we have no need for EDI nor X.400 names for ECH and even tempting someone to write code for ORAddress handling is risky - there's >1 can of worms there all of which are best avoided. S.
Agree with Stephen. Using GeneralName is like hunting butterflies with an elephant gun. :)
Addressed in , closing.
This seems like it would prohibit URL NAME NAME would this be a problem for the DNS-SD case?High-level, I think that we need to agree on what this value is for first. Editorially, I think that this text needs more space to move. Trying to cram all this stuff into a single paragraph isn't doing us any favours. Make a new section for this. It's certainly important enough to do properly. My sense is that the right answer to the underlying issues is that this is a reference identity rather than something we put in servername in ClientHelloOuter. In that case, the fallback is achieved by establishing a connection and validating that the entity providing the updated configuration is able to answer for this reference identity. You then construct ClientHelloOuter in such a way as to ensure that you are able to successfully connect to that reference identity if ClientHelloInner cannot be accepted. If this is just a name, then this is over-specified. If the goal is to describe what goes in ClientHelloOuter server_name, none of the validation is necessary. If the server wants you to put junk in the field, then I don't see how that junk would be any more identifying than an identifying DNS name. You really only need special IP address rules if you intend for this to be a reference identity. The Server Name Indication (SNI) extension in TLS has a provision to provide names other than host names[1]. None have even been defined to my knowledge, but it's there. OpenSSL (and possibly others) have had a long-standing bug[2] (fixed in master) that means that different types of names will cause an error. To be clear: I live in a glass house and am not throwing stones; these things happen. However, it means that a huge fraction of the TLS deployment will not be able to accept a different name type should one ever be defined. (This issue might have been caused by the fact that the original[3] spec didn't define the extension in such a way that unknown name types could be skipped over.) Therefore we (i.e. BoringSSL, and thus Google) are proposing to give up on this and implement our parser such that the SNI extension is only allowed to contain a single host name value. (This is compatible with all known clients.) We're assuming that since this is already the de-facto reality that there will be little objection. I'm sending this mostly to record the fact so that, if someone tries to define a new name type in the future, they won't waste their time. If the community wishes to indicate a different type of name in the future, a new extension can be defined. This is already effectively the case because we wouldn't fight this level of incompatibility when there's any other option. (I think the lesson here is that protocols should have a single joint, and that it should be kept well oiled. For TLS, that means that extensions should have minimal extensionality in themselves and that we should generally rely on the main extensions mechanism for these sorts of things.) [1] URL [2] URL – note that the data pointer is not updated. [3] URL Cheers AGL Adam Langley EMAIL URL

Related discussion:
text: The non-empty name of the client-facing server, i.e., the entity trusted to update the ECH configuration.  This is used to correct misconfigured clients, as described in handle-server-response. <ins> This value MUST NOT begin or end with an ASCII dot and MUST be parsable as a dot-separated sequence of LDH labels, as defined in RFC5890, Section 2.3.1.  Clients MUST ignore any "ECHConfig" structure whose "public_name" does not meet these criteria.  Note that these criteria are incomplete; they incidentally rule out textual representations of IPv6 addresses (see RFC3986, Section 3.2.2), but do not exclude IPv4 addresses in standard dotted-decimal or other non-standard notations such as octal and hexadecimal (see RFC3986, Section 7.4).  If "public_name" contains a literal IPv4 or IPv6 address, the client SHOULD ignore the "ECHConfig" to avoid sending a non-compliant "server_name" extension on the ClientHelloOuter (see RFC6066, Section 3). </ins> A list of extensions that the client must take into consideration when generating a ClientHello message.  These are described below