Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

SSL_VERIFY_PEER and self-signed certificates

1,057 views
Skip to first unread message

Brice André

unread,
May 27, 2013, 2:47:38 PM5/27/13
to
Hello everyone,

I am writing a client-server application in C++ with open-ssl to
secure the connection.

At this stage I successfully implemented all communication between my
server and client with ssl encryption, but I am still missing a
feature : checking the certificate of my server.

As I am using this for securing a connection between my server and my
client application installed on different machines, I do not plan to
get a certificate from verisign or another ssl authority : I plan to
generate my self-signed certificate and to embed it in my client.

Now, my problem is that, when I configure openssl to check the peer
certificate, with the SSL_set_verify command and the SSL_VERIFY_PEER
option, I get the error X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT when
handshaking the connection on the client side.

My understanding of this error is that, by default, open-ssl is not
accepting self-signed certificates.

So, my question is how can I configure open-ssl to accept self-signed
certificates ?

Thanks in advance,
Brice
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openss...@openssl.org
Automated List Manager majo...@openssl.org

Dave Thompson

unread,
May 27, 2013, 10:51:46 PM5/27/13
to
> From: owner-ope...@openssl.org On Behalf Of Brice André
> Sent: Monday, 27 May, 2013 14:48

> I am writing a client-server application <snip> I plan to
> generate my self-signed certificate and to embed it in my client.
>
To be clear, a self-signed cert for (used by) the server.
A self-signed cert for the client would be different, but
client-auth is rarely used and I expect you would have said so.

> Now, my problem is that, when I configure openssl to check the peer
> certificate, with the SSL_set_verify command and the SSL_VERIFY_PEER
> option, I get the error X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT when
> handshaking the connection on the client side.
>
> My understanding of this error is that, by default, open-ssl is not
> accepting self-signed certificates.
>
Are you setting up the client truststore, and how? By default
openssl doesn't trust *any* peer cert, self-signed or not.
If you are setting up truststore, you aren't doing it right.

> So, my question is how can I configure open-ssl to accept self-signed
> certificates ?
>
Put a self-signed entity cert, like a CA root (also self-signed),
in the (client's) truststore using _default_verify_paths,
_load_verify_locations, or "by hand", as applicable.

One gotcha specific to self-signed EE certs at least in openssl:
if the KeyUsage extension is present it must include CertSign (in
addition to digSign and maybe keyEnc needed in a CA-issued EE cert).

Brice André

unread,
May 27, 2013, 11:45:02 PM5/27/13
to
Hello Dave,

Thank you for your answer.

You are right, I am using a self-signed certificate for use by my
server. In fact, I do not perform client authentication in my
application : only the server shall be authentified by ssl. The client
is authentified by another mechanism.

Here are how I generate my RSA key and my certificate:

openssl genrsa -des -out server.key 2048
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 20000 -in server.csr -signkey server.key -out server.crt

The only file that I transmit to my client is server.crt.

I think that all those files are OK because, on the server side, once
everything is initialised, the command SSL_CTX_check_private_key is
happy with it.

In order to initialise the truststore of my client, I copy the
server.crt file somewhere, and I execute the following command :

SSL_CTX_use_certificate_file(ctx,path_to_file, SSL_FILETYPE_PEM);

Do I have to generate another file ? Or do I have to perform another
configuration in my client ?

Regards,
Brice


2013/5/28 Dave Thompson <dtho...@prinpay.com>:

Dave Thompson

unread,
May 28, 2013, 3:39:59 PM5/28/13
to
> From: owner-ope...@openssl.org On Behalf Of Brice André
> Sent: Monday, 27 May, 2013 23:45

> You are right, I am using a self-signed certificate for use by my
> server. In fact, I do not perform client authentication in my
> application : only the server shall be authentified by ssl. The client
> is authentified by another mechanism.
>
> Here are how I generate my RSA key and my certificate:
>
> openssl genrsa -des -out server.key 2048
> openssl req -new -key server.key -out server.csr
> openssl x509 -req -days 20000 -in server.csr -signkey
> server.key -out server.crt
>
Asides: you could combine those:
req -new -newkey rsa:2048 replaces genrsa
req -new -x509 replaces x509 -signkey
but the way you have it works.
Also, 54+ years is a pretty long period!

> The only file that I transmit to my client is server.crt.
>
Good.

> I think that all those files are OK because, on the server side, once
> everything is initialised, the command SSL_CTX_check_private_key is
> happy with it.
>
> In order to initialise the truststore of my client, I copy the
> server.crt file somewhere, and I execute the following command :
>
> SSL_CTX_use_certificate_file(ctx,path_to_file, SSL_FILETYPE_PEM);
>
Bad. That attempts to use the cert as the *client's* cert, which
has no effect because you didn't give the client the privatekey,
and rightly (the client shouldn't have the server's privatekey,
and you say you don't want ssl-level client-auth anyway).

> Do I have to generate another file ? Or do I have to perform another
> configuration in my client ?
>
There are two "standard" ways to set up a truststore for openssl lib,
in your case the client's truststore to trust the server.

SSL_CTX_load_verify_locations (ctx, fileornull, pathornull)
tells openssl to use the (selfsigned root and/or EE) certs
concatenated in one PEM file named by fileornull if not null,
and/or stored in individual PEM files using the subjecthash
for link or name in directory pathornull if not null.

SSL_CTX_set_default_verify_paths (ctx) does something similar but
using environment-variable settings or compiled default values
for the file and/or path, usually "systemwide" places (for all
apps on the system) something like /etc/openssl/cert.pem and
/etc/openssl/certdir .

Most of the commandline utilities allow you to specify -CAfile
and/or -CApath for the first way, or default to the second way.
Since you have one cert in one PEM file, the fileornull (CAfile)
approach is simplest.

Brice André

unread,
May 29, 2013, 3:14:29 AM5/29/13
to
Hello Dave,

Once again, thanks for your help.

I performed a test yesterday with the instruction
SSL_CTX_use_certificate_file(tx,path_to_file, SSL_FILETYPE_PEM);
replaced by
SSL_CTX_load_verify_locations(ctx, path_to_file, NULL);

Where path_to_file points to my file "server.crt". The function
returns 1 so, I expect my certificate to be properly initialised.

But, whn I perform the connect, I get an error. The corresponding
error message is :
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate
verify failed

After the connect failed, the function SSL_get_peer_certificate(ssl)
returns NULL and the function SSL_get_verify_result(ssl) returns 18
(X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT), which is exactly the same
problem as before.

My server is also printing an error message:
error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca

Regards,
Brice

2013/5/28 Dave Thompson <dtho...@prinpay.com>:

Jakob Bohm

unread,
May 29, 2013, 3:29:21 AM5/29/13
to
Hello,

Just a little hint:

Your questions would be much clear if you state, at each step,
which end of the connection each thing applies to, like at what
end did you call SSL_CTX_load_verify_locations, at what end did
you get which error messages etc.

I suspect this may be the cause of some confusion here.
Enjoy

Jakob
--
Jakob Bohm, CIO, Partner, WiseMo A/S. http://www.wisemo.com
Transformervej 29, 2730 Herlev, Denmark. Direct +45 31 13 16 10
This public discussion message is non-binding and may contain errors.
WiseMo - Remote Service Management for PCs, Phones and Embedded

Brice André

unread,
May 29, 2013, 4:05:33 AM5/29/13
to
Hello Jakob,

All commands described in my mail are executed from the client.

I only try to perform server authentication by certificate, and my
problem is that the client is not able to perform this authentication.
I think that my server code is ok (but I may be wrong). On the server
side, the private key and certificate are initialised as follows:
SSL_CTX_use_PrivateKey_file(ctx, "server.key", SSL_FILETYPE_PEM)
SSL_CTX_use_certificate_file(ctx, "server.crt", SSL_FILETYPE_PEM)

All commands return proper exit code and I added the following call to
check if everything is properly initialised :
SSL_CTX_check_private_key(ctx)
And it also returns proper exit code.

Regards,
Brice

2013/5/29 Jakob Bohm <jb-op...@wisemo.com>:

Dave Thompson

unread,
May 29, 2013, 4:38:00 PM5/29/13
to
> From: owner-ope...@openssl.org On Behalf Of Brice André
> Sent: Wednesday, 29 May, 2013 03:14

> I performed a test yesterday with the instruction
> SSL_CTX_use_certificate_file(tx,path_to_file, SSL_FILETYPE_PEM);
> replaced by
> SSL_CTX_load_verify_locations(ctx, path_to_file, NULL);
>
> Where path_to_file points to my file "server.crt". The function
> returns 1 so, I expect my certificate to be properly initialised.
>
To be exact, the client's trustore containing your cert.

One possible problem here: _load_verify_ accepts a sequence of
(PEM) certs, including zero, skipping any invalid format(s).
Make sure the client's file is/contains an exact copy of the
server's certfile, at least the lines from dash-BEGIN to dash-END,
including eol (either NL or CRLF okay) after each line (including
the dash-END line) and body lines not longer than 76 characters.
If you copied the content by cut-and-paste or sending in an email
or something like that, these sometimes go wrong. If you transferred
the file using FTP or SCP or similar, they shouldn't. (FTP mode A
may convert but not add/delete/move eols, and that is okay.)

> But, whn I perform the connect, I get an error. The corresponding
> error message is :
> error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate
> verify failed
>
> After the connect failed, the function SSL_get_peer_certificate(ssl)
> returns NULL and the function SSL_get_verify_result(ssl) returns 18
> (X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT), which is exactly the same
> problem as before.
>
It should work and does for me, as long as the client CAfile is
exactly the (selfsigned) cert the server is using; and you don't have
KeyUsage excluding certSign, but that gives a different error.

If it isn't damaged per above and you have commandline on the client try
openssl s_client -connect host:port -CAfile same.server.crt.file
and see what it says for Verify return code at the end of SSL-session
(note s_client unlike a real app will proceed even if verify error).

> My server is also printing an error message:
> error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca
>
That's consistent; if the client decides the server cert is bad,
the client aborts the handshake with an alert like that.
(The exact alert may vary SSL vs TLS, but always some alert.)

Brice André

unread,
May 30, 2013, 4:07:38 AM5/30/13
to
Hello,

I tested your small program and it seems to work properly, which, I
suppose, means that the problem resides in my client code. I
copy-pasted the output below.

I just find something strange on the server : to write my server code,
I followed a tuto where they initialised a diffie-helman key in the
server side. I was not sure of the utility of that and thus, I
performed several tests with the command you provided : with and
without this initialisation on the server side. In both cases, this
works properly. So, I am a little bit confused about that. I would
want to remove that part, but I am not sure if it may be useful...

I joined my client code. The interesting function is
"wxSSLSocketClient::InitiateSSLSession". This code uses the wxWidgets
library and thus, it uses the wxSocketClient (wxWidgets socket
implementation) with a dedicated BIO so that openssl can handle it.
This code is extracted from the wxEMail project (I am the maintaniner
of this project). But, in this project, I did not implement the server
certificate check stuff. Thus, this version is slighlty modified to
perform those additional checks.

You will easily identify which part is original code and which one is
not because original code was designed to work in static link as well
as dynamic link (with a manual load of library). So, in original code,
all ssl calls are encapsulated in a macro. The modified version
currenlty only support static link, and thus ssl calls are not
encapsulated in the macro.

Note that this code allows performing ssl connection on different
servers and thus, I really think that the BIO part and so on is OK.
The only part that has never been tested is the new part performing
the server certificate check.

Thanks for your help.

Regards,
Brice


D:\home\DbSync1>C:\OpenSSL-Win32\bin\openssl s_client -connect localhost:1212 -C
Afile server.crt
Loading 'screen' into random state - done
CONNECTED(00000738)
depth=0 C = BE, ST = Hainaut, L = Charleroi, O = AMS-Solutions, CN = Brice Andre
, emailAddress = brice...@xxx.be
verify return:1
---
Certificate chain
0 s:/C=BE/ST=Hainaut/L=Charleroi/O=AMS-Solutions/CN=Brice Andre/emailAddress=br
ice....@xxx.be
i:/C=BE/ST=Hainaut/L=Charleroi/O=AMS-Solutions/CN=Brice Andre/emailAddress=br
ice....@xxx.be
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIDnDCCAoQCCQDc4fMRV+0qfzANBgkqhkiG9w0BAQUFADCBjjELMAkGA1UEBhMC
QkUxEDAOBgNVBAgTB0hhaW5hdXQxEjAQBgNVBAcTCUNoYXJsZXJvaTEWMBQGA1UE
ChMNQU1TLVNvbHV0aW9uczEUMBIGA1UEAxMLQnJpY2UgQW5kcmUxKzApBgkqhkiG
9w0BCQEWHGJyaWNlLmFuZHJlQGFtcy1zb2x1dGlvbnMuYmUwIBcNMTMwNTI2MDUw
MzUyWhgPMjA2ODAyMjcwNTAzNTJaMIGOMQswCQYDVQQGEwJCRTEQMA4GA1UECBMH
SGFpbmF1dDESMBAGA1UEBxMJQ2hhcmxlcm9pMRYwFAYDVQQKEw1BTVMtU29sdXRp
b25zMRQwEgYDVQQDEwtCcmljZSBBbmRyZTErMCkGCSqGSIb3DQEJARYcYnJpY2Uu
YW5kcmVAYW1zLXNvbHV0aW9ucy5iZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAKEDpEF1+IOPim2EPvgVjOtdnSal4UjSdl1Bg2dTpGWZpUAwacoCT7kB
sTwkGqgSHs/3Zt171oa14qZrBequpjcMCKOD/JLsMYNZaJLIhLIMHUbNiq0xEIeu
dwy81MhwzKIKm/4SAta++x6/wLVGsgJ+GgLMEs7oDpAVgiOot1xV4SEUfsanrl8e
QQkjP43pPTtWbdDsTZ4XKl2LStH5hFVnYAC7Y6KEbZJvkqcfMG92mSsOR/4JrSWe
0WtjBjoDhkPxnmlpuFkyfk5EFep5/Qg7Ut+fi0k4/9O28POXbFEwnstDqTbSJdsN
N0C665u9167J+AmkeZ3n7z41HGgB1TcCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
K7t53eIY+rMjyCk9IDtcD+SUDa4AltuVcSq0xADzjjtH+11QQvI4/l20eDBV/bnm
HpbNZP2Z8jBnbrCn7bEOqY1HzQrc9KBipy+kbNHknq1MzcteB6b1qIOgr92A0e6A
qVqaULuXKsIj0Ot/g6eh//e4IBJGOg+kbSpB3mDO9G9utP3W8KB7leUDmsBRW1ld
tQ4wtmqknr1WZSXkxa4JDFDBwP6DWymbSl0S7xQO9/5kPWIubL77FxxUZ73jC/G+
iz+rAM2LrqN3Lppp3aH7gkH9pKTWciE7f8kEHfSUKU7LQ87bood0R8XOTvE5xuJq
lJSl3bu6XXt/u/ZibObTyw==
-----END CERTIFICATE-----
subject=/C=BE/ST=Hainaut/L=Charleroi/O=AMS-Solutions/CN=Brice Andre/emailAddress
=brice...@xxx.be
issuer=/C=BE/ST=Hainaut/L=Charleroi/O=AMS-Solutions/CN=Brice Andre/emailAddress=
brice...@xxx.be
---
No client certificate CA names sent
---
SSL handshake has read 1774 bytes and written 519 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : DHE-RSA-AES256-SHA
Session-ID: 6F265E53749453BE5C3DD2BFFF4B99A1DBDA559AF76E8C8974A90ABEEED34AF1

Session-ID-ctx:
Master-Key: 142C4C0BA297D034922C619C9C6EF658D66C476386CE0FECD502B3B990FD01BE
FA3C6B067055860A7BD8632B69E49810
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket:
0000 - 86 89 a4 c4 44 8f a9 e4-0d 76 5f 7e 95 3c 3d aa ....D....v_~.<=.
0010 - 05 4b f0 33 bc 09 7e 08-42 0d f6 81 41 52 81 62 .K.3..~.B...AR.b
0020 - 0f cc 2d de 32 84 b2 57-28 fc c3 2c cc 4b 26 42 ..-.2..W(..,.K&B
0030 - 8b f0 8e 99 37 8e fb 63-50 fe ee c6 10 b1 37 da ....7..cP.....7.
0040 - 90 1c 03 ad cb 08 db ff-93 dc 40 1c a1 7a e1 43 ..........@..z.C
0050 - f2 fc d2 3d 86 46 9a 88-d6 6f 25 62 aa 59 41 a9 ...=.F...o%b.YA.
0060 - a6 29 45 dc 47 3b a9 2f-60 bb 34 d2 42 74 d7 48 .)E.G;./`.4.Bt.H
0070 - d7 82 71 66 d5 5c 1d fb-84 86 10 93 d9 59 d1 cd ..qf.\.......Y..
0080 - 72 ac be d8 bc af 23 a1-00 90 a7 4b 68 ef 58 69 r.....#....Kh.Xi
0090 - f5 e7 75 b0 be 33 d4 19-d8 e0 81 b4 b8 37 bc 79 ..u..3.......7.y

Start Time: 1369897977
Timeout : 300 (sec)
Verify return code: 0 (ok)
---

2013/5/29 Dave Thompson <dtho...@prinpay.com>:
wxSSLSocketClient.cpp

Dave Thompson

unread,
May 30, 2013, 7:18:24 PM5/30/13
to
> From: owner-ope...@openssl.org On Behalf Of Brice André
> Sent: Thursday, 30 May, 2013 04:08

> I tested [s_client] and it seems to work properly, which, I
> suppose, means that the problem resides in my client code. I
> copy-pasted the output below.
>
I think so; see more below.

> I just find something strange on the server : to write my server code,
> I followed a tuto where they initialised a diffie-helman key in the
> server side. I was not sure of the utility of that and thus, I
> performed several tests with the command you provided : with and
> without this initialisation on the server side. In both cases, this
> works properly. So, I am a little bit confused about that. I would
> want to remove that part, but I am not sure if it may be useful...
>
I presume you mean *temporary* Diffie-Hellman *parameters* i.e.
SSL_CTX_set_tmp_dh (or _callback). The actual key using those
parameters is generated inside openssl. This is for ciphersuites
using "ephemeral" or "anonymous" DH key-exchange, abbreviated
EDH or DHE (better to avoid confusing EDH with ECDH which is
different) and ADH. SSL/TLS also defines ciphersuites using
static Diffie-Hellman, but openssl does not implement them;
plus you can't have a selfsigned cert for a (static) DH key.

Your key is RSA so s_client by default and your client as posted
supports both ciphersuites with DHE (DHE-RSA) and without (RSA, or
akRSA to avoid ambiguity). Other kinds of key/cert would differ.
I believe (but didn't check) that both will prefer DHE-RSA; thus
you might observe the difference if either endpoint displays
SSL_get_cipher_name(ssl) or equivalent after handshake, or
when you use s_client which displays this among other things.

The advantage of DHE-RSA over akRSA is "perfect forward secrecy":
assuming the endpoints (together) put sufficient entropy into
their DHE keys, the session keys cannot be recovered and thus
logged session data cannot be decrypted even if the (server's)
privatekey is later compromised. Google for more. In a situation
where you're doing both endpoints (no interop) and trust your
own key management, PFS probably doesn't have any benefit.

> I joined my client code. The interesting function is
> "wxSSLSocketClient::InitiateSSLSession". This code uses the wxWidgets
> library and thus, it uses the wxSocketClient (wxWidgets socket
> implementation) with a dedicated BIO so that openssl can handle it.
> This code is extracted from the wxEMail project (I am the maintaniner
> of this project). But, in this project, I did not implement the server
> certificate check stuff. Thus, this version is slighlty modified to
> perform those additional checks.
>
> You will easily identify which part is original code and which one is
> not because original code was designed to work in static link as well
> as dynamic link (with a manual load of library). So, in original code,
> all ssl calls are encapsulated in a macro. The modified version
> currenlty only support static link, and thus ssl calls are not
> encapsulated in the macro.
>
It's a bit difficult to read through the clutter, but I don't see
anything here which should cause the cert lookup to fail. If some
calls were going to a different version openssl library(ies) somehow
that might explain it, but with OPEN_SSL_STATIC_LINK defined
I don't see how that would happen.

Two things I do notice:

- SSL_set_connect_state is redundant when using SSL_connect.
(It is needed for "transparent" or "automatic" handshake.)

- SSL_set_cipher_list "ALL" includes the anonymous suites that
provide no authentication, which may conflict with your goal.
Do you want your client to verify the server unconditionally, or
only if the server "agrees" by choosing an authenticating suite?

> Note that this code allows performing ssl connection on different
> servers and thus, I really think that the BIO part and so on is OK.
> The only part that has never been tested is the new part performing
> the server certificate check.
>

I think you're down to an ordinary debugging problem here.
In your shoes I would:

- cut down the code to the minimum that reproduces the problem;
your special BIO logically shouldn't matter, but cut it out
anyway to be certain and simplify the code

- use a (re)build with symbols and step through it using a good
debugger (preferably gdb); in particular, after _load_verify
ctx->cert_store->objs->stack should have num=1 (and data should
point to a pointer that's actually to an X509_OBJECT that contains
a pointer to the desired cert, but that's harder to look at),
and the first time you get to X509_STORE_CTX_get1_issuer from
X509_verify_cert for this case ctx->ctx->objs->stack the same.
(The first ctx is a store_ctx and the second actually a store,
which is confusing.) If not then backtrack to see why not; if so
then step forward to see why it's not matched and accepted.

- if I get to a point where what the debugger says happened
is not what the source code directs, look at the machine code
and registers etc. as needed. This is a last resort.

Good luck.

<snip>
> D:\home\DbSync1>C:\OpenSSL-Win32\bin\openssl s_client
> -connect localhost:1212 -CAfile server.crt
> Loading 'screen' into random state - done
> CONNECTED(00000738)
> depth=0 C = BE, ST = Hainaut, L = Charleroi, O = AMS-Solutions,
> CN = Brice Andre, emailAddress = brice...@xxx.be
> verify return:1
<snip most>
> New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
> Server public key is 2048 bit
> Secure Renegotiation IS supported
> Compression: NONE
> Expansion: NONE
> SSL-Session:
> Protocol : TLSv1
> Cipher : DHE-RSA-AES256-SHA
<snip rest>

If the server doesn't have a temp-DH key (or callback) this ciphersuite
won't be the one selected. You'll get RSA-something, almost certainly
RSA-AES256-SHA, instead.

Brice André

unread,
May 31, 2013, 6:00:21 AM5/31/13
to
Hello Dave,

Thanks for this info.

I compiled my own openssl lib with debug support and started debugging.

The problem seems indeed to be located in the call to
X509_STORE_CTX_get1_issuer. In this function, the function
X509_STORE_get_by_subject returns an error. When digging into this
code, the following loop is executed once :

for (i=vs->current_method; i<sk_X509_LOOKUP_num(ctx->get_cert_methods); i++)

In the only iteration it performs, the function
sk_X509_LOOKUP_value(ctx->get_cert_methods,i) returns a struct
initialised with "by_file.c" X509 handler, which looks like this :
X509_LOOKUP_METHOD x509_file_lookup=
{
"Load file into cache",
NULL, /* new */
NULL, /* free */
NULL, /* init */
NULL, /* shutdown */
by_file_ctrl, /* ctrl */
NULL, /* get_by_subject */
NULL, /* get_by_issuer_serial */
NULL, /* get_by_fingerprint */
NULL, /* get_by_alias */
};

Thus, the call to X509_LOOKUP_by_subject fails as the provided handler
does not support this method.

From that point, I am a little stuck... I do not see any error in the
"SSL_CTX_load_verify_locations" function call that would explain why
my store is initialised with a handler that does not support
"get_by_subject" method, and I do not find any reason why the call to
X509_STORE_CTX_get1_issuer chooses this method instead of another. So,
I really find no may to avoid this problem.

I have the feeling that, if I use the "CApath" field instead of the
"CAFile" field of function "SSL_CTX_load_verify_locations", this could
solve my problem, as the "by_dir.c" supports the get_by_subject but :
- I have no idea on how to initialise a directory with proper files
(in production, I will have a PEM file containing more than one
certificate)
- I suppose there should be a way to use openssl like I am doing now...

Any help would be higly appreciated, as I am currently completely stuck...

Thanks in advance,
Brice

2013/5/31 Dave Thompson <dtho...@prinpay.com>:

Dave Thompson

unread,
May 31, 2013, 7:03:25 PM5/31/13
to
> From: owner-ope...@openssl.org On Behalf Of Brice André
> Sent: Friday, 31 May, 2013 06:00
<snip>
> The problem seems indeed to be located in the call to
> X509_STORE_CTX_get1_issuer. In this function, the function
> X509_STORE_get_by_subject returns an error. When digging into this
> code, the following loop is executed once :
>
> for (i=vs->current_method;
> i<sk_X509_LOOKUP_num(ctx->get_cert_methods); i++)
[and does nothing because by_file method handler is null]

You've already gone too far. See next.

> From that point, I am a little stuck... I do not see any error in the
> "SSL_CTX_load_verify_locations" function call that would explain why
> my store is initialised with a handler that does not support
> "get_by_subject" method, and I do not find any reason why the call to
> X509_STORE_CTX_get1_issuer chooses this method instead of another. So,
> I really find no may to avoid this problem.
>
by_file and by_dir work differently:

If you call SSL_CTX_load_verify_locations thence X509_STORE_load_locations
with CAfile, it puts the by_file "lookup" method in the store and also
reads the file, converting all the certs and CRLs to in-memory structures
in store.objs which is a STACK_OF(X509_OBJECT) under your SSL_CTX.
When the handshake occurs and X509_verify_cert via _get1_issuer calls
X509_STORE_get_by_subject using that store, the second statement is
tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,...) which is hard to
debug at least on my machine because it is inlined but should find
the loaded cert in .objs, so a few lines later if(tmp==NULL...)
skips over the loop you looked at and found to be ineffective.

If you use CApath, _load_locations just puts the by_dir lookup method
in the store. At verify time, X509_STORE_get_by_subject finds nothing
in store.objs, so the loop does call the by_dir get_cert_by_subject
routine which looks in the specified dir(s) for a suitable file.

> I have the feeling that, if I use the "CApath" field instead of the
> "CAFile" field of function "SSL_CTX_load_verify_locations", this could
> solve my problem, as the "by_dir.c" supports the get_by_subject but :
> - I have no idea on how to initialise a directory with proper files
> (in production, I will have a PEM file containing more than one
> certificate)
> - I suppose there should be a way to use openssl like I am
> doing now...
>
If you do want to use CApath & by_dir, choose or create a directory,
put each cert or CRL you want in a separate PEM file there and either:
- name each file <subjecthash>.<n> for a cert where subjecthash is
calculated by x509 -subject_hash and <n> is the 0 for the first
or only cert with that hash and 1,2... etc for any duplicates, or
<issuerhash>.r<n> for a CRL with crl -hash and 0,1,2... similarly.
- name each file anything you like such as FredServer.cer and create
a symlink to it using the hashname as above
- Windows doesn't have symlinks that people can use (although NTFS
does internally) so you must use the first method
- Unix does have symlinks and if you want the second method there is
a script c_rehash which goes through and computes and creates
the hashnamed links for you.
- the manpage for SSL_CTX_load_verify_locations has some of this

> Any help would be higly appreciated, as I am currently
> completely stuck...
>
> Thanks in advance,
> Brice
>
> 2013/5/31 Dave Thompson <dtho...@prinpay.com>:

> > - use a (re)build with symbols and step through it using a good
> > debugger (preferably gdb); in particular, after _load_verify
> > ctx->cert_store->objs->stack should have num=1 (and data should
> > point to a pointer that's actually to an X509_OBJECT that contains
> > a pointer to the desired cert, but that's harder to look at),
> > and the first time you get to X509_STORE_CTX_get1_issuer from
> > X509_verify_cert for this case ctx->ctx->objs->stack the same.
> > (The first ctx is a store_ctx and the second actually a store,
> > which is confusing.) If not then backtrack to see why not; if so
> > then step forward to see why it's not matched and accepted.
> >
Thus I proposed you check that _load_verify_(ctx,CAfile,)
successfully gets the cert into store.objs in the sslctx,
and it's still in that store when lookup needs to find it.

Brice André

unread,
Jun 1, 2013, 3:08:07 AM6/1/13
to
Dear Dave,

Thanks for your help.

I solved my problem and I am very ashamed...

I tried with the ssl client command line of my freshly compiled
openssl version and got the same error. After investigation, I
realised that the official windows binary client failed too. Thus, I
was wondering why it worked a few days before and realised that, when
I performed this test first, I downloaded my server certificate
directly from my server, whilst when testing it today, I took the
certificate used by my C++ client application.

After a small check, I realised that this C++ client certificate was corrupted.

So, I think that my first problem was the initialisation of the cert
store, but you helped me solving it a few days before. But, in the
mean time, when investigating my problem, I probably did a mistake
that corrupted the copy of my certificate located on the client side
(client and server are not on the same computer). As the error was the
same, and as this error let me think that the problem was linked to
the fact that the certificate was self-signed, I did not realise this
stupid thing.

Sorry to have bothered you with such stupid problem.

Regards,
Brice

2013/6/1 Dave Thompson <dtho...@prinpay.com>:
0 new messages