Open levicki opened 1 year ago
Seems ok to me.
@mattcaswell Thanks Matt. Can you please clarify if there are more places than obj_dat.h
and obj_mac.h
where this should be added?
Add new oids to crypto/objects/objects.txt. Then run "make update" which will automatically update other files as required.
Probably updates here will also be needed:
As well as updates to the X509_get_extended_key_usage()
documentation
Thanks for the quick response.
So basically, something like this?
I knew that coming up with names will be the worst part... sigh.
Yes, something like that, but you need better "short names". Just "ms" isn't sufficient.
I know, I put them there just as a placeholder for a screenshot.
Do you think using full name would be acceptable?
!Cname ms-windows-hardware-driver-verification
1 3 6 1 4 1 311 10 3 5 : msWindowsHardwareDriverVerification : Windows Hardware Driver Verification
!Cname ms-windows-hardware-driver-extended-verification
1 3 6 1 4 1 311 10 3 39 : msWindowsHardwareDriverExtendedVerification : Windows Hardware Driver Extended Verification
I am afraid with such naming we might hit some compiler limitation on macro length or something.
Perhaps this would be better?
!Cname ms-win-hw-drv-ver
1 3 6 1 4 1 311 10 3 5 : msWindowsHardwareDriverVerification : Windows Hardware Driver Verification
!Cname ms-win-hw-drv-ext-ver
1 3 6 1 4 1 311 10 3 39 : msWindowsHardwareDriverExtendedVerification : Windows Hardware Driver Extended Verification
Do you happen to know what is the length limit on Cname
?
The longest one we currently have is "pbe-WithSHA1And3_Key_TripleDES-CBC". Not sure what the limit is.
How about "win-hardware-driver-ext-verification"...only 2 characters longer than the max we already have?
I think that omitting ms-
prefix would be inconsistent considering the other Microsoft specific entries have it.
I'd rather shorten them like I posted above and maybe even shorten the verb form to:
!Cname ms-win-hw-drv-ver
1 3 6 1 4 1 311 10 3 5 : msWinHWDriverVerification : Windows Hardware Driver Verification
!Cname ms-win-hw-drv-ext-ver
1 3 6 1 4 1 311 10 3 39 : msWinHWDriverExtendedVerification : Windows Hardware Driver Extended Verification
Or maybe even:
!Cname ms-win-hw-drv-ver
1 3 6 1 4 1 311 10 3 5 : msWinHWDrvVerification : Windows Hardware Driver Verification
!Cname ms-win-hw-drv-ext-ver
1 3 6 1 4 1 311 10 3 39 : msWinHWDrvExtVerification : Windows Hardware Driver Extended Verification
I am setting up a Linux dev box to try to make a pull request for this, Windows build system doesn't have make update
.
@mattcaswell When you said changes to v3_purp.c
, did you mean something like this:
case NID_email_protect:
x->ex_xkusage |= XKU_SMIME;
break;
case NID_code_sign:
+ case NID_ms_win_hw_drv_ver:
+ case NID_ms_win_hw_drv_ext_ver:
x->ex_xkusage |= XKU_CODE_SIGN;
break;
case NID_ms_sgc:
case NID_ns_sgc:
x->ex_xkusage |= XKU_SGC;
break;
I am asking because I am not sure whether that would be correct or even necessary, because without codeSigning
EKU present either of those two on their own or even combined wouldn't be enough.
I am pretty sure you didn't mean adding new XKU_
flags.
I am pretty sure you didn't mean adding new XKU_ flags.
Well, I was actually thinking new XKU_ flags might be required. But I'm unsure about that. It seems that somehow, since we recognise these OIDs as XKU OIDs we should set an appropriate flag (it does not seem right to just ignore them as "unknown"). Whether that be an existing one, or a new one, I am less clear.
Well, I was actually thinking new XKU_ flags might be required. But I'm unsure about that. It seems that somehow, since we recognise these OIDs as XKU OIDs we should set an appropriate flag (it does not seem right to just ignore them as "unknown"). Whether that be an existing one, or a new one, I am less clear.
Well new flags might be a problem:
# define XKU_SSL_SERVER 0x1
# define XKU_SSL_CLIENT 0x2
# define XKU_SMIME 0x4
# define XKU_CODE_SIGN 0x8
# define XKU_SGC 0x10 /* Netscape or MS Server-Gated Crypto */
# define XKU_OCSP_SIGN 0x20
# define XKU_TIMESTAMP 0x40
# define XKU_DVCS 0x80
# define XKU_ANYEKU 0x100
With XKU_ANYEKU
being defined as a next bit in sequence instead of highest bit value of the containing type, adding new flags would really introduce a nasty code smell.
I do agree that adding two new flags makes the most sense, but only if we need to add the option to verify that a certificate is fit for that specific signing pupose. If we don't need or intend to support that sort of validation we might as well just ignore those OIDs because the user (supposedly) knows what they are doing with them.
Well, correct handling of the flags is required in order to make X509_get_extended_key_usage()
work. That seems like the minimum necessary to make this useful. At least with that an application can easily query to see what XKU a cert has and do whatever it wants with that information. The user hopefully "knows what they are doing with them" - but it seems we at least need to given them the opportunity to find out if they are present.
With XKU_ANYEKU being defined as a next bit in sequence instead of highest bit value of the containing type, adding new flags would really introduce a nasty code smell.
Right...ideally XKU_ANYEKU would have some large value and it would be easy to insert new XKU values before it. But we are restricted by backwards compatibility here, so we can't change its value. But, not adding new XKU values ever, just because of this seems like a bad outcome. I'm not overly concerned by this issue.
@mattcaswell The objects.txt change is passing the tests on my end and the newly built binary can produce the certificate with those OIDs now:
Relevant config part looks like this:
[ whql_req ]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
keyUsage = digitalSignature
extendedKeyUsage = codeSigning, msWinHWDrvVerification, msWinHWDrvExtVerification
[ whql_cert ]
basicConstraints = critical, CA:FALSE
keyUsage = critical, digitalSignature
extendedKeyUsage = codeSigning, msWinHWDrvVerification, msWinHWDrvExtVerification
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid, issuer
As for the flags, when I created this feature request I wasn't really thinking about programmatical usage, just about using openssl command to create a certificate without having to manually define an OID. I guess that's the reason I have no idea how to handle that part.
As far as I am aware, certificates with those OIDs are not issued to companies or individual users -- only Microsoft's own certificates used for driver (.SYS and .CAT files) cross-signing have those OIDs.
They are already performing purpose checks in their OS code so I am not sure how useful would this be for OpenSSL users. If you think it should be added as flags anyway then we should also add a couple more like for example:
HAL Extension (1.3.6.1.4.1.311.61.5.1)
Windows System Component Verification (1.3.6.1.4.1.311.10.3.6)
Again, not sure how useful that would be as flags. I think that for now we should just add the OIDs, and if someone wants to verify certicate purpose the code can certainly be added later.
@mattcaswell Coming back to this after writing my own CA store manager in C# and getting even more familiar with certificate encoding.
The way Windows native and .Net code handles EKU checking is by querying the OIDs directly. Here's an example using .Net 8.0:
public static bool SubjectIsServer(this X509Certificate2 Subject)
{
Oid ServerAuthentication = null;
X509EnhancedKeyUsageExtension EKU = (X509EnhancedKeyUsageExtension)Subject.Extensions["2.5.29.37"];
ServerAuthentication = EKU.EnhancedKeyUsages["1.3.6.1.5.5.7.3.1"];
return (ServerAuthentication != null);
}
Native Windows API is here.
Note that neither returns flags.
When you think about it, it doesn't really seem to be realistic to have such an API (outside of historical context) since people can define usages of their own which are encoded as OIDs and if you wanted to support all of them as flags you could easily exceed any number of bits in any available integer on any platform.
So what I propose is to define a single new flag:
# define XKU_OTHEREKU 0x8000 // or 0x80000000 whatever the type (short / int)
Then when the user calls X509_get_extended_key_usage()
if there's any other OID outside of historical ones which are already mapped to flags the user will get XKU_OTHEREKU
flag set which would instruct them to call a new API (let's say X509_get_extended_key_usage_ex()
which would return array of OIDs instead of flags so that user can check for those other EKUs.
There is already an EKU named
codeSigning
with the associated OID.For driver and catalog signing, Microsoft also adds the following OIDs to the certificate:
I am aware that self-issued certificates made by adding those EKUs to a signing certificate are unusable in production, but it would be really nice to have the ability to create them for testing environments.
I am also aware that I can add those manually in my config, but I would prefer if there was official support in OpenSSL.
Therefore I propose adding two new EKU verbs:
Those could probably be shortened somehow, although I have no idea what would be appropriate.
The proposed usage in the config file would then be:
Or whatever the names get decided upon.