> None of the above has anything to do with particular email message authenticity.
Only if you're on a shared email hoster. If you're the only one that has access to the mail server's signing keys, it's gonna be real hard to convince anyone that someone else signed that email.
> It is trivial for a prosecutor to prove the owner of the domain, or the owner of the host that used the DKIM key
The point of publishing the keys is that _anyone_ can then sign messages, making "ownership of the domain" a meaningless factor, no matter how much you can prove it.
The publication date of the DKIM record will be _after_ the email has been sent.
Obviously there is no real way to 'prove' the publication date of a DNS record, other than asking the DNS service provider for the logs maybe.
So IANAL, but I'd say the lack of provability of the publication date of the key makes it unsuitable for deniability. Just because the DKIM public key is currently public, does not prove in any way that it was already public when the email was sent.
Deniability means an adversary can't prove you did X, not that you can prove you didn't do X.
So to check if the property holds, the question is not: can you prove the key was public when the email was sent, it is a) can the adversary prove when the email was sent, and b) can the adversary prove that the key was not public at that timestamp?
On a), the adversary cannot just rely on Date: headers if those headers are signed by a public key, and the private key is now public - someone faking an email could just back-date the Date header to a date when the private key was not available, and hence an argument by the adversary that 'the Date header says it was sent at timestamp TS1, and at TS1, the key wasn't public, so therefore the email can't be repudiated' is not sound.
If the recipient of the email cooperates (or anyone who gets access to the email before the private key is published), they could, for example, hash all their emails, and then hash the list of hashes on a regular basis, and put that hash in a busy public blockchain. That would provide an upper bound on the email send timestamp, and, combined with a well-defined private key publication timeframe, provide non-repudiation.
> The publication date of the DKIM record will be _after_ the email has been sent.
Was that email even sent? Maybe it was forged after the key was leaked. This is what the author of the article is pointing out: The old private key being public, you can no longer rely on DKIM alone to prove anything about a document with a signature created with that key.
The point isn't establishing deniability, the point is undermining the authenticity argument (these are at least subtly different I think).
It isn't actually possible to prove that the key was secure at some point in time prior to publication, publication of the key moots that discussion, which is probably going to generally be socially favorable enough of the time to be the better thing to do.
> It doesn’t seem that terrible to prohibit this (Probably some very good reason to counter this though!)
The simple reason is that the whole point of editions is that you absolutely do not have to worry about which one you choose. They are entirely localized to your crate, and code written in any edition can interact with code written in any other edition. With your suggestion, updating the edition used by a library crate would suddenly make it unusable for all code using an older edition.
The point is that crates written against different editions are forwards and backwards compatible, but how the crate is written isn't.
So Rust can make a "breaking" change in a new edition. This isn't actually breaking because you need to "opt-in" by updating to the new edition. This allows many "breaking" changes without actually breaking the ecosystem. Each crate can upgrade whenever they feel like it (possibly never) and they can make this decision independently of any other crates.
You are right that the edition system does create limits for what can be changed. However this is because doing so would have downsides. Notably if older editions couldn't depend on newer editions I may need to migrate my crate to a new edition in order to update a dependency to get a security fix. Edition updates are typically quite easy but it was still a conscious decision that they aren't ever required, unless you want to take advantage of the new features added in that edition.
where do you think they learned it from? python 3 (like python's package management mess) is wonderful for PL because it was a very public materclass in decisions that seem reasonable, but work really badly in practice.
If the subdomains aren't supposed to be public, the public also doesn't need to trust the TLS certs. Sign them with your own CA and trust it on the devices that should be able to access the domains.
Where I work, having internal services be accessed by employees’ own, unmanaged devices would be a no-go anyway. It would be considered a huge security loophole.
You can scope CAs with name constraints. However, I believe many implementations ignore constraints on root CAs. Not sure if there is some practical way with cross-signing around that (giving users the choice between trusting your CA and creating their own and cross-signing your CA with that).
I looked before I started using Let’s Encrypt for some internal stuff and there really isn’t a way to use name constraints in a practical way with modern web browsers at this point. If you’re not using a browser, things get a lot easier, but for browsers you sort of got to suck up that you can’t really avoid the “big” internet.
There is a way, I've recently generated my own CA with domain name constraint, trusted it, and used it cross sign my company's self signed CA. It works like a charm.
As sibling poster already wrote, technically you can scope a CA to a set of subdomains only. Or try. The spec entry is "nameConstraints" but for a number of reasons it may not be well supported.
Some of those reasons are absolutely hilarious. I needed to set up an internal CA back in 2015, and wanted to limit the blast radius in case the private key was leaked. (Usually a "when", not "if" scenario.) I learned about the nameConstraints field and tried to use it. OpenSSL would ignore the key in a CSR input file. Okay, fine, the spec has an OID for the field so I reached for the nearest ASN.1 library to construct a modified CSR with the field in place.
OpenSSL broke trying to parse the file. Go's implementation blew up with a magnificent trace. I gave up and the internal CA was generated with a global validity scope.
I later learned that apparently Microsoft's PKI libraries had support for scope limits, but the feature was not used in real life. Likely because if such a thing came into contact with anything else in the wild, the underlying libraries would just implode.
If you had a self-signed client cert with a nameConstraints in the supplied CA chain, you could probably still crash a non-trivial fraction of web servers.
HSTS is about remembering to do an http:// -> https:// redirect. It's not about remembering a cert.
The downside of TOFU in browsers, is that it trains users to always click through cert warnings. Train them to do it once, and they'll click through it again when there's a real attack. The warning is the same on the first time visiting the site and on a later time visiting it if the cert has changed.
The TOFU UX in SSH is better, because it displays a different warning for when SSHing to a site for the first time vs SSHing to a site again and the cert has changed.
Many of our clients send automated updates for our systems for data managed in other services via SFTP. It surprises me that few seem to bother verifying the host fingerprints, just blindly accepting them on first connection, given how paranoid they are (quite rightly, the data contains staff and customer information) otherwise.
Every single company does it. The 3 of them: Asking employees to install a CA, using it for “.internal” resources, then ask employees to use a web proxy and MITM their connections. And optionally, leak the CA’s pk to get pawned. It’s the standard operating procedure of any well-run business.
Non-public usage doesn't necessarily mean that only devices under your direct control need access. Slack needs access to some of my organization's systems, for example, to support the way we collaborate on our projects -- but the general public doesn't and would likely just be confused if they stumbled into one of our infrastructure subdomains instead of visiting our public website.
Yeah. In that case, it's just easier to get a really cheap wild-card cert signed by a low-cost reseller for <50 bucks. They only reason to care about big-name certs is compatibility with all the devices out there, but if you don't need compatibility, then get the cheapest thing you can.
> and trust it on the devices that should be able to access the domains
Sometimes it's not an option. I spent too many hours trying to figure out why some Android apps didn't want to talk with a service I self-hosted. They just ignored my Root CA cert installed on the phone.
If you're interested in or already comfortable with Rust, Amos (fasterthanlime) has a nice long-form series that goes into this, basically building a custom ELF loader in the end. The writing style isn't everyone's cup of tea, but maybe you like it: https://fasterthanli.me/series/making-our-own-executable-pac...
The main goal of using async for me is to not have to handle all the IO wait state machines myself. It does a pretty good job of that, and as long as my program consists of a bunch of tasks concurrently waiting for IO to finish, a single thread is perfectly fine.
> Rust just took C++ std::unique and std::shared ptr and made those integrated directly in the language, and the only option for allocation
Not really. Both Box and Rc/Arc are first and foremost library features implemented using the equivalent of malloc() and free(). Box is a bit special due to its deref semantics, but other than that, there's nothing stopping you from implementing them or something else yourself.
There is no runtime (other than init/exit handling). The main thing that provides memory safety without a GC is the borrow checker, which is a language feature and independent of the smart pointer types in the standard library.
Only if you're on a shared email hoster. If you're the only one that has access to the mail server's signing keys, it's gonna be real hard to convince anyone that someone else signed that email.