OpenSSL doesn't pass full cert chain

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

OpenSSL doesn't pass full cert chain

Fahim

Hello,

 

We are looking for a potential tweak or customization of openSSL for an existing project, and I was wondering if I could get your input.

 

Summary: we want to alter or configure openSSL so that it will pass the entire cert chain for authentication instead of just the first certificate. Passing just the first cert appears to be the default, which is not working for our application, but we cannot figure out how to change that particular setting so that the entire certificate chain is sent.

 

Background: We are trying to perform SMPP over SSL connectivity using kannel on the client side and done configuration changes at the kannel side to make it perform as client and created the single cert file with the whole certificate chain (Signed certificate of the server, intermediate certs and the root cert)  and the same currently deployed with kannel. But still clientside  authentication fails because openssl which handles the SSL at the server  passes the first certificate only (in our case it is signed certificate only) to the server side and does not process beyond that. In fact, openSSL must be configured to pass the entire chain (Intermediate certs and root cert), but it fails to do so. It turns out it is the by default behavior of the openSSL .We found at http://gagravarr.org/writing/openssl-certs/general.shtml that “In almost all cases, OpenSSL will assume that there's only one certificate in a given file. As such, it will generally only use the first certificate that it finds, and will ignore all others.” This is the behavior we are trying to figure out how to chain.

 

Does anyone have any suggestions here? I would appreciate your feedback.

 

Thanks in advance,

 

Best Regards,

 

Fahim

Reply | Threaded
Open this post in threaded view
|

RE: OpenSSL doesn't pass full cert chain

Dave Thompson-5

To be certain I’m clear, since your terminology is a bit unusual:

you have a server application using openssl library (libssl), which

has a cert that was issued by a CA using intermediate certs.

The prover (server in nearly all cases, client in rare cases)

per RFC MUST send the full chain except optionally the root

i.e. entity cert and any intermediate/chain cert(s) in order.

In some situations this isn’t actually needed, if the child

cert(s) specify where the parent(s) can be obtained using

AuthorityInfoAcccess extension and the relier implements AIA

(which libssl as relier does not), or if the relier has the lower cert(s)

in >its< truststore (which libssl and some other SSL implementations

can, but I know nothing about your client kannel).

 

Assuming you want to go with the standard approach, a libssl prover

(here your server) will send the full chain if you do either of two

(or maybe three) things:

- call SSL_CTX_use_certificate_chain_file INSTEAD OF use_certificate_file

and provide a file containing first the entity=server cert and then

the chain=intermediate cert(s), and optionally root, all in PEM

- provide a truststore which contains the chain certs, and optionally root,

unambiguosly (i.e. there are NOT two or more certs for the same CA name).

There are two variants of this:

- set up a private CA file and/or CA directory and call load_verify_locations

- put them in your system’s default store and call set_default_verify_paths

Both of these also mean that the provided certs are considered trusted

when verifying the peer, which for a server occurs only if client authentication

aka client cert is requested and is provided by the client. This should rarely

if ever be a problem because if you expect and assert the peer should

trust these CAs when verifying you, then you ought to trust them also.

 

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Fahim
Sent: Saturday, January 04, 2014 12:36
To: [hidden email]
Subject: OpenSSL doesn't pass full cert chain

 

Hello,

 

We are looking for a potential tweak or customization of openSSL for an existing project, and I was wondering if I could get your input.

 

Summary: we want to alter or configure openSSL so that it will pass the entire cert chain for authentication instead of just the first certificate. Passing just the first cert appears to be the default, which is not working for our application, but we cannot figure out how to change that particular setting so that the entire certificate chain is sent.

 

Background: We are trying to perform SMPP over SSL connectivity using kannel on the client side and done configuration changes at the kannel side to make it perform as client and created the single cert file with the whole certificate chain (Signed certificate of the server, intermediate certs and the root cert)  and the same currently deployed with kannel. But still clientside  authentication fails because openssl which handles the SSL at the server  passes the first certificate only (in our case it is signed certificate only) to the server side and does not process beyond that. In fact, openSSL must be configured to pass the entire chain (Intermediate certs and root cert), but it fails to do so. It turns out it is the by default behavior of the openSSL .We found at http://gagravarr.org/writing/openssl-certs/general.shtml that “In almost all cases, OpenSSL will assume that there's only one certificate in a given file. As such, it will generally only use the first certificate that it finds, and will ignore all others.” This is the behavior we are trying to figure out how to chain.

 

Does anyone have any suggestions here? I would appreciate your feedback.

 

Thanks in advance,

 

Best Regards,

 

Fahim

Reply | Threaded
Open this post in threaded view
|

RE: OpenSSL doesn't pass full cert chain

Fahim

Hello Dave,

 

I would like to simplify the issue as following.

 

1.       Both client and server performs SSL Handshake using cert chain.

2.       In our case server responds correctly with the entire chain of cert (Server is some proprietary system)

3.       Client also expected to send the entire cert chain, which is already available as a single file in .pem mode (Client is Kannel)

4.       What happens is, seems libssl pass only the first cert in the cert chain file and doesn’t pass the rest.

5.       Need a mechanism  to configure libssl to pass the entire chain, How to implement this?

 

Thanks in advance,

 

Fahim

From: [hidden email] [mailto:[hidden email]] On Behalf Of Dave Thompson
Sent: Tuesday, January 07, 2014 4:08 AM
To: [hidden email]
Subject: RE: OpenSSL doesn't pass full cert chain

 

To be certain I’m clear, since your terminology is a bit unusual:

you have a server application using openssl library (libssl), which

has a cert that was issued by a CA using intermediate certs.

The prover (server in nearly all cases, client in rare cases)

per RFC MUST send the full chain except optionally the root

i.e. entity cert and any intermediate/chain cert(s) in order.

In some situations this isn’t actually needed, if the child

cert(s) specify where the parent(s) can be obtained using

AuthorityInfoAcccess extension and the relier implements AIA

(which libssl as relier does not), or if the relier has the lower cert(s)

in >its< truststore (which libssl and some other SSL implementations

can, but I know nothing about your client kannel).

 

Assuming you want to go with the standard approach, a libssl prover

(here your server) will send the full chain if you do either of two

(or maybe three) things:

- call SSL_CTX_use_certificate_chain_file INSTEAD OF use_certificate_file

and provide a file containing first the entity=server cert and then

the chain=intermediate cert(s), and optionally root, all in PEM

- provide a truststore which contains the chain certs, and optionally root,

unambiguosly (i.e. there are NOT two or more certs for the same CA name).

There are two variants of this:

- set up a private CA file and/or CA directory and call load_verify_locations

- put them in your system’s default store and call set_default_verify_paths

Both of these also mean that the provided certs are considered trusted

when verifying the peer, which for a server occurs only if client authentication

aka client cert is requested and is provided by the client. This should rarely

if ever be a problem because if you expect and assert the peer should

trust these CAs when verifying you, then you ought to trust them also.

 

 

From: [hidden email] [[hidden email]] On Behalf Of Fahim
Sent: Saturday, January 04, 2014 12:36
To: [hidden email]
Subject: OpenSSL doesn't pass full cert chain

 

Hello,

 

We are looking for a potential tweak or customization of openSSL for an existing project, and I was wondering if I could get your input.

 

Summary: we want to alter or configure openSSL so that it will pass the entire cert chain for authentication instead of just the first certificate. Passing just the first cert appears to be the default, which is not working for our application, but we cannot figure out how to change that particular setting so that the entire certificate chain is sent.

 

Background: We are trying to perform SMPP over SSL connectivity using kannel on the client side and done configuration changes at the kannel side to make it perform as client and created the single cert file with the whole certificate chain (Signed certificate of the server, intermediate certs and the root cert)  and the same currently deployed with kannel. But still clientside  authentication fails because openssl which handles the SSL at the server  passes the first certificate only (in our case it is signed certificate only) to the server side and does not process beyond that. In fact, openSSL must be configured to pass the entire chain (Intermediate certs and root cert), but it fails to do so. It turns out it is the by default behavior of the openSSL .We found at http://gagravarr.org/writing/openssl-certs/general.shtml that “In almost all cases, OpenSSL will assume that there's only one certificate in a given file. As such, it will generally only use the first certificate that it finds, and will ignore all others.” This is the behavior we are trying to figure out how to chain.

 

Does anyone have any suggestions here? I would appreciate your feedback.

 

Thanks in advance,

 

Best Regards,

 

Fahim

Reply | Threaded
Open this post in threaded view
|

RE: OpenSSL doesn't pass full cert chain

Dave Thompson-5
In reply to this post by Fahim

That is much clearer, thank you.

 

Looking quickly at www.kannel.org I don’t see any clear statement that it uses libssl (and libcrypto)

rather than e.g. GnuTLS or NSS, but I’ll trust you’ve already confirmed that. It does describe using

openssl commandline to generate key, CSR and possibly cert, and people who use commandline

often use the library also and vice versa but it’s not technically required. As an aside, the doc

example does 1024-bit RSA key, which was good advice until about 2009; today you technically

need more for a margin of safety, and most standards/authorities have gone to 2048 as the next

convenient size. In particular if you try to get a cert from a public CA, as opposed to a homebrew

or enterprise one, industry standards as of this month say it should reject 1024-bit.

 

http://www.kannel.org/download/kannel-userguide-snapshot/userguide.html#AEN468

describes ssl-client-certkey-file as “A … certificate and private key ….” and “The certificate …”

This wording certainly suggests the code is calling use_certificate_file (which accepts only the

entity cert, not a chain) not use_certificate_chain_file, although only looking at the source

is certain – have you done that, or can you? It is a bit inconsistent that it apparently expects

client cert&key in one file, but has separate files for server cert and key. Maybe those were

written by different people and not coordinated.

 

It also has ssl-trusted-ca-file “… certificates … [will] trust as HTTPS client”. That description

does not exactly match openssl functionality for CAfile, at least through 1.0.1; libssl will

>use< all certs in CAfile to build a chain, but will >trust< (as anchors) only the root certs.

Are you using that parameter and if so do you have the root for the server’s chain in it?

 

Assuming the above, your options are:

 

- change the code to call use_certificate_chain_file either for that config item, or perhaps

some other config item or flag if you prefer – or perhaps the project maintainers,

if you can ask them (I didn’t even look, I wouldn’t have time).

 

- add the chain certs for your client cert to your trusted-ca file. Even though CAfile’s

>primary< purpose is to verify the peer, here the server, libssl >also< uses it to

build out its own chain if necessary and possible.

 

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Fahim
Sent: Tuesday, January 07, 2014 14:15
To: [hidden email]
Subject: RE: OpenSSL doesn't pass full cert chain

 

Hello Dave,

 

I would like to simplify the issue as following.

 

1.       Both client and server performs SSL Handshake using cert chain.

2.       In our case server responds correctly with the entire chain of cert (Server is some proprietary system)

3.       Client also expected to send the entire cert chain, which is already available as a single file in .pem mode (Client is Kannel)

4.       What happens is, seems libssl pass only the first cert in the cert chain file and doesn’t pass the rest.

5.       Need a mechanism  to configure libssl to pass the entire chain, How to implement this?

 

Thanks in advance,

 

Fahim

From: [hidden email] [[hidden email]] On Behalf Of Dave Thompson
Sent: Tuesday, January 07, 2014 4:08 AM
To: [hidden email]
Subject: RE: OpenSSL doesn't pass full cert chain

 

To be certain I’m clear, since your terminology is a bit unusual:

you have a server application using openssl library (libssl), which

has a cert that was issued by a CA using intermediate certs.

The prover (server in nearly all cases, client in rare cases)

per RFC MUST send the full chain except optionally the root

i.e. entity cert and any intermediate/chain cert(s) in order.

In some situations this isn’t actually needed, if the child

cert(s) specify where the parent(s) can be obtained using

AuthorityInfoAcccess extension and the relier implements AIA

(which libssl as relier does not), or if the relier has the lower cert(s)

in >its< truststore (which libssl and some other SSL implementations

can, but I know nothing about your client kannel).

 

Assuming you want to go with the standard approach, a libssl prover

(here your server) will send the full chain if you do either of two

(or maybe three) things:

- call SSL_CTX_use_certificate_chain_file INSTEAD OF use_certificate_file

and provide a file containing first the entity=server cert and then

the chain=intermediate cert(s), and optionally root, all in PEM

- provide a truststore which contains the chain certs, and optionally root,

unambiguosly (i.e. there are NOT two or more certs for the same CA name).

There are two variants of this:

- set up a private CA file and/or CA directory and call load_verify_locations

- put them in your system’s default store and call set_default_verify_paths

Both of these also mean that the provided certs are considered trusted

when verifying the peer, which for a server occurs only if client authentication

aka client cert is requested and is provided by the client. This should rarely

if ever be a problem because if you expect and assert the peer should

trust these CAs when verifying you, then you ought to trust them also.

 

 

From: [hidden email] [[hidden email]] On Behalf Of Fahim
Sent: Saturday, January 04, 2014 12:36
To: [hidden email]
Subject: OpenSSL doesn't pass full cert chain

 

Hello,

 

We are looking for a potential tweak or customization of openSSL for an existing project, and I was wondering if I could get your input.

 

Summary: we want to alter or configure openSSL so that it will pass the entire cert chain for authentication instead of just the first certificate. Passing just the first cert appears to be the default, which is not working for our application, but we cannot figure out how to change that particular setting so that the entire certificate chain is sent.

 

Background: We are trying to perform SMPP over SSL connectivity using kannel on the client side and done configuration changes at the kannel side to make it perform as client and created the single cert file with the whole certificate chain (Signed certificate of the server, intermediate certs and the root cert)  and the same currently deployed with kannel. But still clientside  authentication fails because openssl which handles the SSL at the server  passes the first certificate only (in our case it is signed certificate only) to the server side and does not process beyond that. In fact, openSSL must be configured to pass the entire chain (Intermediate certs and root cert), but it fails to do so. It turns out it is the by default behavior of the openSSL .We found at http://gagravarr.org/writing/openssl-certs/general.shtml that “In almost all cases, OpenSSL will assume that there's only one certificate in a given file. As such, it will generally only use the first certificate that it finds, and will ignore all others.” This is the behavior we are trying to figure out how to chain.

 

Does anyone have any suggestions here? I would appreciate your feedback.

 

Thanks in advance,

 

Best Regards,

 

Fahim