Doing some work with TLS 1.3 in both Go and Java, I recently found that Go ignores Key Usage status flags. On the other hand, Java's implementation checks key usage following the RFC. I'm thinking in particular about the digital signature bit:
the digitalSignature bit MUST be set if the Key Usage extension is present
Reading the comment in verify.go, I see that Go didn't implement this feature given its inconsistent usage in the world.
Is my understanding correct?
If you read articles on how to create X.509 certificate, certificate authorities, etc you will find they often leave out details such as keyUsage
and extendedKeyUsage
.
That means there are a lot of certificates created by users without the correct usage flags.
However, does it really matter? A private key is a private key no matter what flags you adorn the certificate bundle with. The flags are just lipstick. The keys work exactly the same with or without the usage flags.
Java libraries try to prevent incorrect usage for inexperienced cryptography developers. IMHO Golang targets a different audience.
For example, you can encrypt with the private key and the public key. The convention has you encrypt with the public key and decrypt with the private key. Java enforces that convention, but Golang does not. There are of course exceptions to my statement, but my point is the philosophy between the languages is different.
If the usage flags do not matter then what are they for? Businesses that sell certificates want you to buy certificates. They want to limit via usage flags what you can use the certificate for so that you either purchase more certificates or pay more for certain features.