latchset / pkcs11-provider

A pkcs#11 provider for OpenSSL 3.0+
Other
64 stars 39 forks source link

openssl ocsp commad fails #99

Closed gilweis closed 1 year ago

gilweis commented 1 year ago

Describe the bug openssl ocsp commad with yubikey tokens fails

To Reproduce Steps to reproduce the behavior:

  1. create demoCA: $ mkdir -p demoCA/newcerts $ touch demoCA/index.txt $ echo 01 > demoCA/serial

    create openssl.cnf with pkcs11 provider and add:

    [ usr_cert ] authorityInfoAccess = OCSP;URI:http://127.0.0.1:8080

[ v3_OCSP ] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = OCSPSigning

$ export OPENSSL_CONF=openssl.cnf $ openssl genrsa -out rootCA.key 1024 $ openssl req -new -x509 -days 3650 -key rootCA.key -out rootCA.crt $ openssl genrsa -out certKey.key 1024 $ openssl req -new -x509 -days 3650 -key certKey.key -out certificate.crt $ openssl x509 -x509toreq -in certificate.crt -out CSR.csr -signkey certKey.key $ openssl ca -batch -startdate 150813080000Z -enddate 250813090000Z -keyfile rootCA.key -cert rootCA.crt -policy policy_anything -notext -out certificate.crt -infiles CSR.csr

Creating the OCSP server:

$ openssl req -new -key "pkcs11:type=private" -out ocspSigning.csr -sha256 $ openssl ca -keyfile rootCA.key -cert rootCA.crt -in ocspSigning.csr -out ocspSigning.crt

Running the OCSP server:

$ openssl ocsp -index demoCA/index.txt -port 8080 -rsigner ocspSigning.crt -rkey "pkcs11:type=private;id=%02" -CA rootCA.crt -text -out log.txt

Result:

ACCEPT 0.0.0.0:8080 PID=31356 ocsp: waiting for OCSP client connections...

Running client:

$ openssl ocsp -CAfile rootCA.crt -issuer rootCA.crt -cert certificate.crt -url http://127.0.0.1:8080 -resp_text -noverify

Server result:

ocsp: Received request, 1st line: POST / HTTP/1.0 Segmentation fault (core dumped)

simo5 commented 1 year ago

Something is happening in the ocsp responder that ends up returning a NULL resp structure. But the actual error seem hidden somwhere before this point, when the responder tries to find and then sign a cert.

simo5 commented 1 year ago

To be clear I reproduced this and did some gdb, but can't immediately pinpoint where it fails.

simo5 commented 1 year ago

Ok so I found out that again a digest was not being set when requesting a signature (suspect maybe I should have a default in the provider), when adding -rmd sha256 to the server command I do not get a segfault, however I currently get: 4097F1A9557F0000:error:1C80007A:Provider routines:p11prov_sig_op_init:invalid digest:signature.c:581:

So need to figure out if I just configured the wrong hash, or there is some further issue

simo5 commented 1 year ago

It works if I pass -rmd sha1

gilweis commented 1 year ago

sha1: openssl ocsp -index demoCA/index.txt -port 8080 -rsigner ocspSigning.crt -rkey "pkcs11:type=private;id=%02" -CA rootCA.crt -text -out log.txt -rmd sha1 ACCEPT 0.0.0.0:8080 PID=32467 ocsp: waiting for OCSP client connections... ocsp: Received request, 1st line: POST / HTTP/1.0 Segmentation fault (core dumped)

sha256: openssl ocsp -index demoCA/index.txt -port 8080 -rsigner ocspSigning.crt -rkey "pkcs11:type=private;id=%02" -CA rootCA.crt -text -out log.txt -rmd sha256 ACCEPT 0.0.0.0:8080 PID=32486 ocsp: waiting for OCSP client connections... ocsp: Received request, 1st line: POST / HTTP/1.0 40A7971C8C7F0000:error:1C80007A:Provider routines:p11prov_sig_op_init:invalid digest:signature.c:581:

The digest in the csr & certificate files that openssl command create without the provider are sha256 so I assumes that the default is sha256.

gilweis commented 1 year ago

sha1 debug info:

Starting program: /usr/bin/openssl ocsp -index demoCA/index.txt -port 8080 -rsigner ocspSigning.crt -rkey pkcs11:type=private\;id=%02 -CA rootCA.crt -text -out log.txt -rmd sha1 [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". ACCEPT 0.0.0.0:8080 PID=32790 ocsp: waiting for OCSP client connections... ocsp: Received request, 1st line: POST / HTTP/1.0

Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7bd8978 in OCSP_response_status (resp=resp@entry=0x0) at ../crypto/ocsp/ocsp_cl.c:118 Download failed: Invalid argument. Continuing without source file ./build_shared/../crypto/ocsp/ocsp_cl.c. 118 ../crypto/ocsp/ocsp_cl.c: No such file or directory. (gdb)

sha256 debug info:

Starting program: /usr/bin/openssl ocsp -index demoCA/index.txt -port 8080 -rsigner ocspSigning.crt -rkey pkcs11:type=private\;id=%02 -CA rootCA.crt -text -out log.txt -rmd sha256 [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". ACCEPT 0.0.0.0:8080 PID=32835 ocsp: waiting for OCSP client connections... ocsp: Received request, 1st line: POST / HTTP/1.0 4097F0F7FF7F0000:error:1C80007A:Provider routines:p11prov_sig_op_init:invalid digest:signature.c:581: [Inferior 1 (process 32835) exited with code 01] (gdb) backtrace No stack. (gdb)

simo5 commented 1 year ago

I tested this on the branch built against the OpenSSL master tree with the patches for #94 which I think are required in general for all certificate signing work.

On that tree -rmd sha1 works out.

Not sure why sha256 returns invalid digest I'll check it out.

simo5 commented 1 year ago

So, when passing -rmd sha256 the providers gets a name that is not expected: SHA2-256 and fails to match it to an actual digest. It is the first time I see sha256 being internally translated to SHA2-256 ... unclear what causes it. But that's why it fails to initialize. Will investigate this issue...

simo5 commented 1 year ago

So I changed how digest names are resolved, and PR #98 (on openssl master) now works also with sha256 I am afarid though that this will work only once we have the openssl patch merged and we can depend on it because all ca and ocsp functions depend on proper matching of the certs, and that can't work until https://github.com/openssl/openssl/pull/19648 or equivalent is available in the OpenSSL library used.

gilweis commented 1 year ago

Thanks, So maybe create a branch for that? What is the best way to compile the PR #98 on openssl master and test the provider without install the openssl in the OS? make DESTDIR=~/installs install ?

simo5 commented 1 year ago

This is how i build openssl:

./Configure --prefix=$HOME/tmp/openssl --openssldir=$HOME/tmp/openssl/etc/pki/tls \
    enable-rfc3779 enable-md2 enable-rc5 no-mdc2 no-ec2m no-sm2 no-sm4 \
    enable-buildtest-c++ shared -ggdb3 '-DDEVRANDOM="\"/dev/urandom\""'

make all
make install

and this is how I build and test the provider:

export LD_LIBRARY_PATH=$HOME/tmp/openssl/lib64
export PATH=$HOME/tmp/openssl/bin:$PATH
CFLAGS="-I$HOME/tmp/openssl/include" LDFLAGS="-L$HOME/tmp/openssl/lib64" ./configure
make check
gilweis commented 1 year ago

Thanks. The openssl ca command with the provider is working now. The openssl ocsp command still failed: $ gdb --arg openssl ocsp -index demoCA/index.txt -port 8080 -rsigner ocspSigning.crt -rkey "pkcs11:type=private;id=%02" -CA rootCA.crt -text -out log.txt -rmd sha1

ACCEPT 0.0.0.0:8080 PID=5566 ocsp: waiting for OCSP client connections... ocsp: Received request, 1st line: POST / HTTP/1.0 ocsp: Sending response, 1st line: HTTP/1.0 200 OK

Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7aebf48 in OCSP_response_status (resp=resp@entry=0x0) at crypto/ocsp/ocsp_cl.c:118 118 return ASN1_ENUMERATED_get(resp->responseStatus); (gdb) backtrace

0 0x00007ffff7aebf48 in OCSP_response_status (resp=resp@entry=0x0) at crypto/ocsp/ocsp_cl.c:118

1 0x00005555555c0724 in ocsp_main (argc=, argv=) at apps/ocsp.c:771

2 0x00005555555c1a61 in do_cmd (prog=prog@entry=0x55555568af10, argc=argc@entry=16, argv=argv@entry=0x7fffffffdf90) at apps/openssl.c:418

3 0x000055555559c707 in main (argc=, argv=0x7fffffffdf90) at apps/openssl.c:296

gilweis commented 1 year ago

Thanks. The openssl ca command with the provider is working now. The openssl ocsp command still failed: $ gdb --arg openssl ocsp -index demoCA/index.txt -port 8080 -rsigner ocspSigning.crt -rkey "pkcs11:type=private;id=%02" -CA rootCA.crt -text -out log.txt -rmd sha1

ACCEPT 0.0.0.0:8080 PID=5566 ocsp: waiting for OCSP client connections... ocsp: Received request, 1st line: POST / HTTP/1.0 ocsp: Sending response, 1st line: HTTP/1.0 200 OK

Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7aebf48 in OCSP_response_status (resp=resp@entry=0x0) at crypto/ocsp/ocsp_cl.c:118 118 return ASN1_ENUMERATED_get(resp->responseStatus); (gdb) backtrace

0 0x00007ffff7aebf48 in OCSP_response_status (resp=resp@entry=0x0) at crypto/ocsp/ocsp_cl.c:118

1 0x00005555555c0724 in ocsp_main (argc=, argv=) at apps/ocsp.c:771

2 0x00005555555c1a61 in do_cmd (prog=prog@entry=0x55555568af10, argc=argc@entry=16, argv=argv@entry=0x7fffffffdf90) at apps/openssl.c:418

3 0x000055555559c707 in main (argc=, argv=0x7fffffffdf90) at apps/openssl.c:296

https://github.com/openssl/openssl/pull/19660

With this PR: ocsp: waiting for OCSP client connections... ocsp: Received request, 1st line: POST / HTTP/1.0 4097EFF7FF7F0000:error:05800074:x509 certificate routines:ossl_x509_check_private_key:key values mismatch:crypto/x509/x509_cmp.c:413: 4097EFF7FF7F0000:error:1380006E:OCSP routines:OCSP_basic_sign_ctx:private key does not match certificate:crypto/ocsp/ocsp_srv.c:181: 4097EFF7FF7F0000:error:068000DE:asn1 encoding routines:asn1_template_ex_i2d:illegal zero content:crypto/asn1/tasn_enc.c:372: 4097EFF7FF7F0000:error:0688000D:asn1 encoding routines:ASN1_item_pack:ASN1 lib:crypto/asn1/asn_pack.c:36: [Inferior 1 (process 17300) exited with code 01]

gilweis commented 1 year ago

It was my mistake with the ocsp keys. The openssl ocsp command is working with the provider :-) Anyway, there is a bug in OPENSSL that needs to be fixed.

simo5 commented 1 year ago

Yeah I had noticed that issue, thanks for submitting a PR upstream.