X.509 Are all parts of a DN optional? - security

Are all the parts of the DN in a X.509 optional?
From RFC3280:
Implementations of this specification MUST be prepared to receive
the following standard attribute types in issuer and subject
(section 4.1.2.6) names:
* country,
* organization,
* organizational-unit,
* distinguished name qualifier,
* state or province name,
* common name (e.g., "Susan Housley"), and
* serial number.
I could not find if any of these is mandatory.
I am asking because I am seeing a certificate that is signed by a trusted CA but in the issuer's field the CN is missing (and the C but I don't think that's important).
I was expecting that CN is mandatory. Is it?
Is there any security implications of the omission of theCN from the issuer's field?

As #Bruno says, there is no requirement in RFC3280 for an Issuer DN to have a CN.
RFC3280 states:
The issuer field MUST contain a non-empty distinguished name (DN).
However, RFC3280 does not make any requirement on which RDN(s) should be present. Most CAs do include a CN in the Issuer DN, but some don't, such as this Equifax CA.
OU = Equifax Secure Certificate Authority,O = Equifax,C = US
Or this Verisign CA.
OU = VeriSign Trust Network,OU = "(c) 1998 VeriSign, Inc. - For
authorized use only",OU = Class 3 Public Primary Certification
Authority - G2,O = "VeriSign, Inc.",C = US
Path building and validation using RFC3280 does not require a CN in the Issuer DN.

The RFC says that the name of the subject may be present in Subject Alternative Name extension. Section 4.2.1.7 says the following (which must be your case):
Further, if the only subject identity included in the certificate is
an alternative name form (e.g., an electronic mail address), then the
subject distinguished name MUST be empty (an empty sequence), and the
subjectAltName extension MUST be present. If the subject field
contains an empty sequence, the subjectAltName extension MUST be
marked critical.

X509 certificates should compare the whole dn. That is
Dn1 == Dn2
Two distinguished names DN1 and DN2 match if they
have the same number of RDNs, for each RDN in DN1 there is a matching
RDN in DN2, and the matching RDNs appear in the same order in both
DNs.
Each component is optional, they may be repeated. However a match requires all the fields match.
From ietf rfc5280

Related

SAML Authentication with login.microsoft.com from Progress Openedge

Hi Does anyone have any experience of getting Progress Openedge to authenticate with login.microsoft.com.
Specifically with the certificates required to get it to work.
I have installed the Baltimore Root cert and the VeriSignClass3PublicPrimaryCertificationAuthority-G5
and the Symantec SymantecClass3EVSSLCA-G3 certificates in the Progress\Openedge\certs folder.
The error i'm getting is
Secure Socket Layer (SSL) failure. error code -55: CONNECT HostName: (login.microsoftonline.com) does not match
Certificate: (graph.windows.net) (9318)
Nowhere in my code am i referencing graph.windows.net and i believe this is an issue with the certificate setup but i'm at a loss as to what it is.
BLOCK-LEVEL ON ERROR UNDO, THROW.
USING OpenEdge.Core.String.
USING OpenEdge.Net.HTTP.ClientBuilder.
USING OpenEdge.Net.HTTP.IHttpRequest.
USING OpenEdge.Net.HTTP.IHttpResponse.
USING OpenEdge.Net.HTTP.RequestBuilder.
DEFINE VARIABLE httpUrl AS CHARACTER NO-UNDO.
DEFINE VARIABLE oRequest AS IHttpRequest NO-UNDO.
DEFINE VARIABLE oResponse AS IHttpResponse NO-UNDO.
DEFINE VARIABLE oRequestBody AS String NO-UNDO.
DEFINE VARIABLE JsonString AS LONGCHAR NO-UNDO.
SESSION:DEBUG-ALERT = TRUE.
httpUrl = "https://login.microsoftonline.com/extSTS.srf".
oRequestBody = new String('samlenvelope').
oRequest = RequestBuilder:Post(httpUrl, oRequestBody)
:ContentType('application/soap+xml; charset=utf-8')
:AcceptJson()
:Request.
oResponse = ClientBuilder:Build():Client:Execute(oRequest).
MESSAGE
oResponse:StatusCode SKIP
oResponse:StatusReason SKIP
VIEW-AS ALERT-BOX.
OpenEdge < 11.7 is still common, so the answer below is still valid. However, Microsoft changed the certificates and aliases, and this addressed in my specific answer.
The error message of SSL failure, is telling us that the HTTPS certificate was issued to a different entity than expected. This is what older OpenEdge see, because it does not see a property called SAN, which contain all valid name for the site.
In practice, all you need to do is following these 3 steps:
Step 1: Do you trust the certificate?
Validate that you trust "stamp2.login.microsoftonline.com" (at the time of the question was "login.microsoftonline.com").
Step 2: Optional Mapping
It is possible that "stamp2.login.microsoftonline.com" is not reachable. In this case you'd need to edit the "hosts" file of the OE server, so "stamp2.login.microsoftonline.com" would resolve to the IP of "login.microsoftonline.com" (how to edit the "hosts" file: https://www.siteground.com/kb/how_to_use_the_hosts_file/)
Step 3: Replace the URL in your code
Replace
httpUrl = "https://login.microsoftonline.com/extSTS.srf".
with
httpUrl = "https://stamp2.login.microsoftonline.com/extSTS.srf".

openssl custom attribute during creation

during the execution of :
openssl req -new
it asked for some attributes:
-----
Country Name (2 letter code) [XX]:IT
State or Province Name (full name) []:Rome
Locality Name (eg, city) [Default City]:Rome
Organization Name (eg, company) [Default Company Ltd]:PP
Organizational Unit Name (eg, section) []:Information Technology
Common Name (eg, your name or your server's hostname) []:test
Email Address []:test at test dot it
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:claudio
An optional company name []:cc
is it possible to add an additional custom attribute during the creation?
Thank you in advance
Claudio
1) login as root
2) open file openssl.cnf
3) add your custom attribute in "[new oids]" section
4) add description in "req_distinguished_name" section
5) save & close
6) create your new certificate
[ new oids]
newCustom=1.2.3.4.5.6
[req_distinguished_name]
newCustom = new custom attibute
openssl req -new -key server.key -out server.csr
nter pass phrase for server.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
new custom attribute []:
..
..
..
I hope this could help!
Regards
Claudio

Verify SHA1withECDSA signature on javacard

i have self-signed certificate signed by SHA1withECDSA algorithm using BouncyCastle.
Under BC i can verify it easily, but when i`m doing it on JavaCard it send me false everytime(Curve secp192r1 from NIST). Certificate hold sign in plain (non X9.62 mean just r+s without any TAGs).
There is my code to verify it (with values putted as constant - for tests of course).
byte[] certdata = {...}
Signature signature = Signature.getInstance(Signature.ALG_ECDSA_SHA, false);
ECPublicKey ecpk = (ECPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PUBLIC, KeyBuilder.LENGTH_EC_FP_192, true);
ecpk.setA(new byte[]{...}, (short)0, (short)0x0018);
ecpk.setB(new byte[]{...}, (short)0, (short)0x0018);
ecpk.setG(new byte[]{...}, (short)0, (short)0x0031);
//Point format: uncompressed tag(0x04), x, y
ecpk.setK((short)0x0001);
ecpk.setR(new byte[]{}, (short)0, (short)0x0018);
ecpk.setW(new byte[]{}, (short)0, (short)0x31);
ecpk.setFieldFP(new byte[]{}, (short)0, (short)0x0018);
signature.init(ecpk, Signature.MODE_VERIFY);
boolean result = signature.verify(certdata, (short)0, (short)certdata.length, signtab, (short)0, (short)signtab.length);
if(result) ISOException.throwIt((short)0x0001);
else ISOException.throwIt((short)0x0002);
}
'...' instead of bytes for clear view (192bits curve can do big mess).
Certificate with TAGS explanation on pastebin:
http://pastebin.com/gvqYzm2g
Thanks for any help
sevar
edit:
New tests:
All tests re on same data (PublicKey, PrivateKey, Message to be signed)
sign is randomized so i ll use 2 sign (signT - sign generated by Terminal (BC), signC - sign generated by Chip)
signT cant be verified on CHIP but can be verified on Terminal.
signC is verified on CHIP & Terminal
so I checked cross between API
Cross Relation directed to BC works well
Cross Relation directed to CHIP isn't work
pair of key generated well because when i put PrivateKey and PublicKey generated by BC to CHIP, then signature generated on the CHIP can be verified by CHIP.
KeyPair generated well
I have no idea what i should check now. Problem probably can be with filling array in ECDSA step e = SHA1(Message). Whats happen with array after hash(hash is shorter than curve and card needs to declare size of array before copy)
Signing and verification of ECDSAwithSHA-1 with Prime192v1 from Bouncy Castle to JavaCard works fine for me.
Your problem is probably format of the signature itself.
Signature is a DER encoded structure, it is a sequence (tag 0x30) of two integers (tag 0x02). In JavaCard, 56 bytes are always expected: two coordinates of length 25 plus 6 bytes of DER headers. JavaCard always expects leading zeros in each coordinate. However, BC often produces signatures without leading zeros in coordinates, so the signature can be shorter than 56 bytes and that is why JavaCard is confused.
The opposite direction is always OK, because BC can handle leading zeros, although it does not add them when creating signature.
What you should do: wrap the BC signing mechanism with your own code and ALWAYS add leading zeros to coordinates in your BC signature. If you do so, you will be able to verify the signature both in BC and JavaCard.
I would like to post my code, but unfortunately it is a part of a commercial security project...
I had a problem with verifinge a ECDSA singature (generated on JavaCard 192r1) using BouncyCastle and i found a solution. I hope that it will be useful
Verify javacard signature ALG_ECDSA_SHA on bouncy castle

From CRMF request into CertificateRequest (PKCS#10) Signature

I did a example code to understand how to get a CRMF (mozilla certificate request) to convert it into a CSR more similar to PKCS#10
I got the Base 64 CRMFRequest as a ASN1InputStream type.
I convert it into a CertReqMsg type (Bouncycastle)
when I debug, I realize the CertReqMsg have the public key, another data like Subject (CN, O, OU, etc)and other, but more important, it has a signature and an AlgoritmIdentifier.
but the object doesn't have getters
How I extract the signature as a DERBitString...? I need it to use as parameter to the CertificationRequest object (which returns the CSR as I want it)
by the way, the CertificationRequest need a CertificationRequestInfo object as parameter. and inside it (CertificationRequestInfo ), it receives Attributes as parameter . I supose to this attributes are of the kind of:
distributionPoint, unotice, policyOID, subjectAlternativeNameDN
I know that it start with a
ASN1Set attributes = null;
attributes = new DERSet();
But I don't know how to fill this paramethers to
CertificationRequestInfo info = new CertificationRequestInfo(subject, infoPublicKey, attributes);
Sorry if some question seems obvious... but I can't find the solve..
Thanks in advance
You won't be able to convert the CRMF format into a PKCS#10 CSR.
The CSR is structured like this and signed by the subject's private key:
CertificationRequest ::= SEQUENCE {
certificationRequestInfo CertificationRequestInfo,
signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }},
signature BIT STRING
}
(Essentially, it's very similar to a self-signed X.509 certificate, without issuer and validity dates.)
Since when you get the CRMF request, you won't have the subject's private key, you won't be able to make this signature.
If you're writing some sort of CA software, you don't really need this. Processing a CRMF request and a CSR request is more or less equivalent. A CA shouldn't really do what the CSR wants blindly anyway, so it would have to vet the attributes it associates with the public key and identity some other way anyway.

Key Management: Public/Subordinate key

I was looking at GnuPG manual (Manual) and came across below section at page 18:
chloe% gpg -edit-key chloe#cyb.org
Secret key is available.
pub 1024D/26B6AAE1 created: 1999-06-15 expires: never trust: -/u
sub 2048g/0CF8CB7A created: 1999-06-15 expires: never
sub 1792G/08224617 created: 1999-06-15 expires: 2002-06-14
sub 960D/B1F423E7 created: 1999-06-15 expires: 2002-06-14
(1) Chloe (Jester) <chloe#cyb.org>
(2) Chloe (Plebian) <chloe#tel.net>
It says: The keyword pub identifies the public master signing key, and the keyword sub identifies a public subordinate
key.
I am not understanding, what is subordinate key for? Any help?
Short version: keys are tagged and used for different types of functions. For example, the primary key must be a signing key. Subordinate keys allow for additional functions (ie encryption).
Long Version: From the GNUPG site:In a public-key system, each user has a pair of keys consisting of a private key and a public key.... GnuPG uses a somewhat more sophisticated scheme in which a user has a primary keypair and then zero or more additional subordinate keypairs. The primary and subordinate keypairs are bundled to facilitate key management and the bundle can often be considered simply as one keypair.
...
GnuPG is able to create several different types of keypairs, but a primary key must be capable of making signatures. There are therefore only three options. Option 1 actually creates two keypairs. A DSA keypair is the primary keypair usable only for making signatures. An ElGamal subordinate keypair is also created for encryption
...
it is possible to later add additional subkeys for encryption and signing.

Resources