Open ralfhauser opened 7 months ago
@ralfhauser Can you give sample code of what you're attempting to do?
It appears our code expects the identifier dnqualifier
rather than dnq
for this value, if you're using the RFC 4519 class rather than the BCStyle
class.
This matches OpenSSL's output for this certificate:
$ openssl x509 -in ~/Downloads/dnq.pem.txt -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4112325213882364794 (0x3911e9fe7657337a)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = IT, O = Namirial S.p.A./02046570426, OU = Certification Authority, CN = Namirial CA Firma Qualificata
Validity
Not Before: Dec 19 10:35:00 2022 GMT
Not After : Dec 17 23:00:00 2025 GMT
Subject: C = IT, SN = VINATTIERI, GN = GIACOMO, serialNumber = TINIT-VNTGCM75A21D612F, CN = VINATTIERI GIACOMO, dnQualifier = LOVG2022121631199701
... snip ...
However, it does appear to be missing from our BCStyle
class... so it could be that it might not work with BCStyle
and dnQualifier
either, in which case we can fix it. :-)
Are you aware of a reference calling this dnq
over dnqualifier
?
Hi Alexander, Thanks for the quick reply, I just do X500Principal java.security.cert.X509Certificate.getSubjectX500Principal() an then I get the IllegalArgumentException
@ralfhauser Interesting... What version of BC are you running?
I get the following:
but I will admit I'm on the as-of-yet unreleased BC 1.78. However, it doesn't look like this code has changed in a while. I went through PEMParser because I wanted to see what the internal X509CertificateHolder
would output, which seems OK, but then went back to DER for the CertificateFactory
parsing to get the java.security.cert.X509Certificate
from the BC provider.
bc*-jdk18on-171.jar
if you add one line to your code, it is reproducible
`... System.out.println("X500 Principal: " + xPrinc);
X500Name subDN = new X500Name(xPrinc.toString());`
@ralfhauser Have you seen the alternative X500Name
constructor?
public X500Name(X500NameStyle style, java.lang.String dirName)
This would let you parse DQNs directly in this format:
If you're willing to modify your application code, I think this will work the best, and follows what was originally intended (w.r.t. custom names for OIDs). Let me know what you think!
Why can't the simple constructor not handle this ? Or why is this DNQStyle only in the test class and not in X500Name.java as
private static X500NameStyle defaultStyle = DNQStyle.INSTANCE; //BCStyle.INSTANCE;
as it extends BCStyle , it seems to backward compatible (except for the IllegalArgumentException probably almost nobody is keen on seeing ?)
@ralfhauser Perhaps @dghgit can weigh in...
My understanding is a style class allows for overriding our understanding/parsing of string attributes into proper RDN sequences. You might prefer DNQ=
in the string form, others might prefer dnQualifier=
, which the default aligns with the RFC4519 style guide. Others still might want to parse completely custom OIDs (e.g., my favorite 1.2.3.4.5.6.7.8.9
should be parsed as favoriteSport=
!). With a broad enough set of OIDs, you're bound to get overlap names to multiple OIDs (see e.g., uid=
: is this a 2.5.4.45
or a 0.9.2342.19200300.100.1.1
? Probably depends on the context!).
A custom style parser gives you the flexibility to set the string form+identifiers of RDN attributes you want to see/understand/parse (and extending BCStyle
should hopefully give you), while letting others set the forms of attributes they want to see, without stepping on too many toes along the way. :-)
My 2c -- but this was likely written for exactly this type of extensibility.
Whether or not we want to add it to the default constructor (and if we'll add it as dnq
vs dnqualifier
) probably depends on popularity of this attribute. Given existing RFCs state it should be called dnQualifier
, I'm guessing its relatively unlikely we'll parse it as dnq
, and may be unlikely we'll add dnQualifier
either given it exists in the RFC4519Style
class... But I will defer to @dghgit here again.
Hi @ralfhauser, has been a while since this has come up.
So, the issue is it's not that anyone's right or wrong, and this isn't the first time we've found ourselves and Sun/Oracle using different symbols, IBM for example tend to treat this one as DNQUALIFIER, in our case it's always been "DN" (looking at RFC 4519 I have to admit IBM's probably the closest to correct, although we actually added the attribute before RFC 4519 came out, I'd guess based on either what OpenSSL was using at the time, or what Sun was using at the time, it was around 2005 though so while I was around, I'm afraid what and who in regards to this one are well lost in time).
What I've found in general is that avoiding converting directory names to strings until you actually have to hand one over to a human is the best idea, as the alternative is a path to madness.
The following will allow you to convert the directory name without issue:
X509Certificate cer = (X509Certificate)certFact.generateCertificate(new FileInputStream("dnq.pem"));
X500Name x500Name = X500Name.getInstance(cer.getSubjectX500Principal().getEncoded());
System.err.println(x500Name);
Now, it you'd like that to print just as the Oracle one does, there's a choice between using the X500NameStyle class as @cipherboy suggests (which can be useful if you like life with X500Name) or simply doing the reverse at output time, i.e:
System.err.println(new X500Principal(x500Name.getEncoded()));
It all depends how you want to play it. The one thing you can be confident of whatever decision you make you'll almost certainly run into someone that wants it to be done differently so I would recommend allowing for flexibility.
I just started running into the same issue. It seems it's Java (Amazon Corretto 17) that formats it as DNQ. We recently switched to getting the subject name from X509Certificate.getSubjectX500Principal().toString() and that produces the DNQ which then later fails as it is parse it with new X500Name(subject as string)
Fixed it by using X500Name.getInstance(cert.getSubjectX500Principal().getEncoded())
A qualified Italian QES cert seems to throw this error
dnq.pem.txt
Are they wrong ?
Edited for clarity by @cipherboy.