full-chain ocsp stapling

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

full-chain ocsp stapling

Jeremy Harris
Looking at implementing the above, under TLSv1.3 and (at least
initially) server-side.  I'm currently using

    SSL_CTX_set_tlsext_status_cb()
    SSL_set_tlsext_status_ocsp_resp(   a DER blob )

and the problem is: will this accept a
(DER-wrapped, basicresp-wrapped) stack of singleresp
where the stack has >1 element?

If so, and that is the preferred way to load such
a stapling, how can such a blob be constructed?

I have separate PEM files for each ocsp resp for
the certificate chain, currently.  Converting
to DER and pulling out the singleresp is feasible;
it's building a multi-resp blob that looks hard.


Alternatively, can SSL_set_tlsext_status_ocsp_resp()
be called repeatedly, with distinct blobs for the
stapling chain elements?  The manpage does not suggest it
so it seems unlikely.


Alternatively^2, is there some way to get such a blob from
a tool (openssl ocsp, or similar) ready built?   For this
purpose, I am the CA.
--
Cheers,
  Jeremy
Reply | Threaded
Open this post in threaded view
|

Re: full-chain ocsp stapling

Matt Caswell-2


On 30/09/2019 14:49, Jeremy Harris wrote:
> Looking at implementing the above, under TLSv1.3 and (at least
> initially) server-side.  I'm currently using
>
>     SSL_CTX_set_tlsext_status_cb()
>     SSL_set_tlsext_status_ocsp_resp(   a DER blob )
>
> and the problem is: will this accept a
> (DER-wrapped, basicresp-wrapped) stack of singleresp
> where the stack has >1 element?

It's an OCSPResponse object (see RFC2560) - represented by the OCSP_RESPONSE
type in OpenSSL. That can itself wrap a BasicOCSPResponse which can contain
multiple SingleResponses.

>
> If so, and that is the preferred way to load such
> a stapling, how can such a blob be constructed?

If you want to construct it from scratch you might want to take a look at how
the ocsp app does it:

https://github.com/openssl/openssl/blob/84f471ecab76a16281a16c53d259bbcae358816f/apps/ocsp.c#L1146-L1287


>
> I have separate PEM files for each ocsp resp for
> the certificate chain, currently.  Converting
> to DER and pulling out the singleresp is feasible;
> it's building a multi-resp blob that looks hard.
>
> Alternatively, can SSL_set_tlsext_status_ocsp_resp()
> be called repeatedly, with distinct blobs for the
> stapling chain elements?  The manpage does not suggest it
> so it seems unlikely.

No, this isn't possible.

>
> Alternatively^2, is there some way to get such a blob from
> a tool (openssl ocsp, or similar) ready built?   For this
> purpose, I am the CA.
>

Yes, you can do this. For example see the "respout" option in the ocsp command.

From the examples in the ocsp man page:

    Send a query to an OCSP responder with URL http://ocsp.myhost.com/ save the
    response to a file, print it out in text form, and verify the response:

    openssl ocsp -issuer issuer.pem -cert c1.pem -cert c2.pem \
        -url http://ocsp.myhost.com/ -resp_text -respout resp.der

    Read in an OCSP response and print out text form:

    openssl ocsp -respin resp.der -text -noverify

https://www.openssl.org/docs/man1.1.1/man1/openssl-ocsp.html

Matt
Reply | Threaded
Open this post in threaded view
|

Re: full-chain ocsp stapling

Jeremy Harris
On 30/09/2019 17:02, Matt Caswell wrote:
>     openssl ocsp -issuer issuer.pem -cert c1.pem -cert c2.pem \
>         -url http://ocsp.myhost.com/ -resp_text -respout resp.der

Ah, I hadn't realised that -cert could be given multiple times.
--
Thanks,
  Jeremy
Reply | Threaded
Open this post in threaded view
|

Re: full-chain ocsp stapling

Jeremy Harris
In reply to this post by Matt Caswell-2
On 30/09/2019 17:02, Matt Caswell wrote:

>> Alternatively^2, is there some way to get such a blob from a tool
>> (openssl ocsp, or similar) ready built?   For this purpose, I am
>> the CA.
>>
>
> Yes, you can do this. For example see the "respout" option in the
> ocsp command.
>
> From the examples in the ocsp man page:
>
> Send a query to an OCSP responder with URL http://ocsp.myhost.com/ 
> save the response to a file, print it out in text form, and verify
> the response:
>
> openssl ocsp -issuer issuer.pem -cert c1.pem -cert c2.pem \ -url
> http://ocsp.myhost.com/ -resp_text -respout resp.der

I'm using the indexfile variant.  It seems that the -CA argument
needs to be the signer of the cert, not the CA for the chain; and
you cannot give -CA multiple times.  So you don't get good OCSP status
for all elements in the chain:

$ cat $ifile
V       130110200751Z           65      unknown CN=server1.example.com
V       130110200751Z           66      unknown CN=revoked1.example.com
V       130110200751Z           67      unknown CN=expired1.example.com
V       130110200751Z           c9      unknown CN=server2.example.com
V       130110200751Z           ca      unknown CN=revoked2.example.com
V       130110200751Z           cb      unknown CN=expired2.example.com
V       130110200751Z           42      unknown CN=clica Signing Cert rsa
V       130110200751Z           41      unknown CN=clica CA rsa
$
$ openssl ocsp -sha256 -no_nonce -issuer $CADIR/Signer.pem -cert
$leafcert -issuer $CADIR/CA.pem -cert $CADIR/Signer.pem -cert
$CADIR/CA.pem -reqout $REQ -req_text
OCSP Request Data:
    Version: 1 (0x0)
    Requestor List:
        Certificate ID:
          Hash Algorithm: sha256
          Issuer Name Hash:
5AF082E51D62FE01FD706BAEBEB878DB64E68F76E74A36F36D914297DDEE24B8
          Issuer Key Hash:
333DB14364B98E78A33DD8A4FAE8D8378EA9B0F5FBCA97B25685AA0D32116091
          Serial Number: 65
        Certificate ID:
          Hash Algorithm: sha256
          Issuer Name Hash:
BFA7275A566EFD4BE2DF82DBD9D1290D470186F6FF2ACD8C16659F342AB56109
          Issuer Key Hash:
208F9D28C7C0BC914144DFA8C0BE3D5B3BFCEBB622C8A8DC27E865FC06CA0E12
          Serial Number: 42
        Certificate ID:
          Hash Algorithm: sha256
          Issuer Name Hash:
BFA7275A566EFD4BE2DF82DBD9D1290D470186F6FF2ACD8C16659F342AB56109
          Issuer Key Hash:
208F9D28C7C0BC914144DFA8C0BE3D5B3BFCEBB622C8A8DC27E865FC06CA0E12
          Serial Number: 41
$
$ openssl ocsp -index $ifile -rsigner $CADIR/CA.pem -rkey $CADIR/CA.key
-CA $CADIR/CA.pem -resp_no_certs -noverify         -ndays 3652 -reqin
$REQ -respout $RESP -resp_text | egrep '(Serial|Status)'
    OCSP Response Status: successful (0x0)
      Serial Number: 65
    Cert Status: unknown
      Serial Number: 42
    Cert Status: good
      Serial Number: 41
    Cert Status: good
$


--
Cheers,
  Jeremy
Reply | Threaded
Open this post in threaded view
|

Re: full-chain ocsp stapling

Jeremy Harris
On 01/10/2019 12:21, Jeremy Harris wrote:

> On 30/09/2019 17:02, Matt Caswell wrote:
>>> Alternatively^2, is there some way to get such a blob from a tool
>>> (openssl ocsp, or similar) ready built?   For this purpose, I am
>>> the CA.
>>>
>>
>> Yes, you can do this. For example see the "respout" option in the
>> ocsp command.
>>
>> From the examples in the ocsp man page:
>>
>> Send a query to an OCSP responder with URL http://ocsp.myhost.com/ 
>> save the response to a file, print it out in text form, and verify
>> the response:
>>
>> openssl ocsp -issuer issuer.pem -cert c1.pem -cert c2.pem \ -url
>> http://ocsp.myhost.com/ -resp_text -respout resp.der
>
> I'm using the indexfile variant.  It seems that the -CA argument
> needs to be the signer of the cert, not the CA for the chain; and
> you cannot give -CA multiple times.  So you don't get good OCSP status
> for all elements in the chain:
>
> $ cat $ifile
> V       130110200751Z           65      unknown CN=server1.example.com
> V       130110200751Z           66      unknown CN=revoked1.example.com
> V       130110200751Z           67      unknown CN=expired1.example.com
> V       130110200751Z           c9      unknown CN=server2.example.com
> V       130110200751Z           ca      unknown CN=revoked2.example.com
> V       130110200751Z           cb      unknown CN=expired2.example.com
> V       130110200751Z           42      unknown CN=clica Signing Cert rsa
> V       130110200751Z           41      unknown CN=clica CA rsa
> $
> $ openssl ocsp -sha256 -no_nonce -issuer $CADIR/Signer.pem -cert
> $leafcert -issuer $CADIR/CA.pem -cert $CADIR/Signer.pem -cert
> $CADIR/CA.pem -reqout $REQ -req_text
> OCSP Request Data:
>     Version: 1 (0x0)
>     Requestor List:
>         Certificate ID:
>           Hash Algorithm: sha256
>           Issuer Name Hash:
> 5AF082E51D62FE01FD706BAEBEB878DB64E68F76E74A36F36D914297DDEE24B8
>           Issuer Key Hash:
> 333DB14364B98E78A33DD8A4FAE8D8378EA9B0F5FBCA97B25685AA0D32116091
>           Serial Number: 65
>         Certificate ID:
>           Hash Algorithm: sha256
>           Issuer Name Hash:
> BFA7275A566EFD4BE2DF82DBD9D1290D470186F6FF2ACD8C16659F342AB56109
>           Issuer Key Hash:
> 208F9D28C7C0BC914144DFA8C0BE3D5B3BFCEBB622C8A8DC27E865FC06CA0E12
>           Serial Number: 42
>         Certificate ID:
>           Hash Algorithm: sha256
>           Issuer Name Hash:
> BFA7275A566EFD4BE2DF82DBD9D1290D470186F6FF2ACD8C16659F342AB56109
>           Issuer Key Hash:
> 208F9D28C7C0BC914144DFA8C0BE3D5B3BFCEBB622C8A8DC27E865FC06CA0E12
>           Serial Number: 41
> $
> $ openssl ocsp -index $ifile -rsigner $CADIR/CA.pem -rkey $CADIR/CA.key
> -CA $CADIR/CA.pem -resp_no_certs -noverify         -ndays 3652 -reqin
> $REQ -respout $RESP -resp_text | egrep '(Serial|Status)'
>     OCSP Response Status: successful (0x0)
>       Serial Number: 65
>     Cert Status: unknown
>       Serial Number: 42
>     Cert Status: good
>       Serial Number: 41
>     Cert Status: good
> $
>
>

No answers on how to get ocsp responses for all elements of a
certificate chain?

--
Cheers,
  Jeremy
Reply | Threaded
Open this post in threaded view
|

Re: full-chain ocsp stapling

Jeremy Harris
In reply to this post by Jeremy Harris
On 01/10/2019 12:21, Jeremy Harris wrote:
> I'm using the indexfile variant.  It seems that the -CA argument
> needs to be the signer of the cert, not the CA for the chain; and
> you cannot give -CA multiple times.  So you don't get good OCSP status
> for all elements in the chain:

> $ openssl ocsp -sha256 -no_nonce -issuer $CADIR/Signer.pem -cert
> $leafcert -issuer $CADIR/CA.pem -cert $CADIR/Signer.pem -cert
> $CADIR/CA.pem -reqout $REQ -req_text

Further experimentation finds that the "-CA" argument can be
a PEM with multiple issuers, and this gets me a resp with all
of the Cert Status values "good" rather than some "unknown".

   [ The "openssl ocsp" manpage could possibly use more info
     on the situation ]

However, in trying to use that, I'm now less certain it was what
was wanted.  It results in a server TLS1.3 Certificates record
having a single extension, placed after the first certificate
of the three bundled in my testcase (leaf, signer, root).
The extension is a certificate-status with three single-response
items.
This contrasts with the situation I had developed using GnuTLS
(which accepts a multi-PEM file for proofs); it placed an extension
with a single status after each of the three certificates.

Are both layouts of the TLS1.3 Certificates record valid?


FWIW, feeding this same multi-resp to GnuTLS makes it bahave
the same way as OpenSSL.  The triplet of single-responses is
_also_ visible in a TLS1.2 Certificate Status record.

--
Cheers,
  Jeremy
Reply | Threaded
Open this post in threaded view
|

Re: full-chain ocsp stapling

Matt Caswell-2


On 10/10/2019 22:53, Jeremy Harris wrote:

> On 01/10/2019 12:21, Jeremy Harris wrote:
>> I'm using the indexfile variant.  It seems that the -CA argument
>> needs to be the signer of the cert, not the CA for the chain; and
>> you cannot give -CA multiple times.  So you don't get good OCSP status
>> for all elements in the chain:
>
>> $ openssl ocsp -sha256 -no_nonce -issuer $CADIR/Signer.pem -cert
>> $leafcert -issuer $CADIR/CA.pem -cert $CADIR/Signer.pem -cert
>> $CADIR/CA.pem -reqout $REQ -req_text
>
> Further experimentation finds that the "-CA" argument can be
> a PEM with multiple issuers, and this gets me a resp with all
> of the Cert Status values "good" rather than some "unknown".
>
>    [ The "openssl ocsp" manpage could possibly use more info
>      on the situation ]
>
> However, in trying to use that, I'm now less certain it was what
> was wanted.  It results in a server TLS1.3 Certificates record
> having a single extension, placed after the first certificate
> of the three bundled in my testcase (leaf, signer, root).
> The extension is a certificate-status with three single-response
> items.
> This contrasts with the situation I had developed using GnuTLS
> (which accepts a multi-PEM file for proofs); it placed an extension
> with a single status after each of the three certificates.

OpenSSL does not currently support that. You can only place a status response
after the first certificate.

Matt


>
> Are both layouts of the TLS1.3 Certificates record valid?
>
>
> FWIW, feeding this same multi-resp to GnuTLS makes it bahave
> the same way as OpenSSL.  The triplet of single-responses is
> _also_ visible in a TLS1.2 Certificate Status record.
>
Reply | Threaded
Open this post in threaded view
|

Re: full-chain ocsp stapling

Jeremy Harris
On 11/10/2019 09:57, Matt Caswell wrote:
> OpenSSL does not currently support that. You can only place a status response
> after the first certificate.
>
> Matt


That's why I asked:

>> Are both layouts of the TLS1.3 Certificates record valid?

--
Cheers,
  Jeremy
Reply | Threaded
Open this post in threaded view
|

Re: full-chain ocsp stapling

Matt Caswell-2


On 11/10/2019 10:10, Jeremy Harris wrote:

> On 11/10/2019 09:57, Matt Caswell wrote:
>> OpenSSL does not currently support that. You can only place a status response
>> after the first certificate.
>>
>> Matt
>
>
> That's why I asked:
>
>>> Are both layouts of the TLS1.3 Certificates record valid?
>

RFC8446 is not really very clear in this regards. All it says is:

   "In TLS 1.3, the server's OCSP information
   is carried in an extension in the CertificateEntry containing the
   associated certificate.  Specifically, the body of the
   "status_request" extension from the server MUST be a
   CertificateStatus structure as defined in [RFC6066], which is
   interpreted as defined in [RFC6960]."

Putting everything in a single CertificateEntry gives you equivalence with what
can be achieved in TLSv1.2 and is allowed by the syntax of a CertificateStatus
structure. So I *think* this is ok.

It is not described how one should interpret a single CertificateStatus covering
the whole chain, vs individual CertificateStatus entries, one for each Certificate.

Matt