diff options
author | beck <> | 2016-11-02 15:18:42 +0000 |
---|---|---|
committer | beck <> | 2016-11-02 15:18:42 +0000 |
commit | 8cc868305fe197edb9f01ce424e355d76be91b22 (patch) | |
tree | d759e28afc9aedffba6861487c1680a3f8e3331d /src | |
parent | 90c573eba184fe31184d14ce10367f810fa1d417 (diff) | |
download | openbsd-8cc868305fe197edb9f01ce424e355d76be91b22.tar.gz openbsd-8cc868305fe197edb9f01ce424e355d76be91b22.tar.bz2 openbsd-8cc868305fe197edb9f01ce424e355d76be91b22.zip |
Add OCSP client side support to libtls.
- Provide access to certificate OCSP URL
- Provide ability to check a raw OCSP reply against an
established TLS ctx
- Check and validate OCSP stapling info in the TLS handshake
if a stapled OCSP response is provided.`
Add example code to show OCSP URL and stapled info
into netcat.
ok jsing@
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libtls/Makefile | 3 | ||||
-rw-r--r-- | src/lib/libtls/tls.c | 7 | ||||
-rw-r--r-- | src/lib/libtls/tls.h | 37 | ||||
-rw-r--r-- | src/lib/libtls/tls_client.c | 12 | ||||
-rw-r--r-- | src/lib/libtls/tls_init.3 | 121 | ||||
-rw-r--r-- | src/lib/libtls/tls_internal.h | 33 | ||||
-rw-r--r-- | src/lib/libtls/tls_ocsp.c | 399 | ||||
-rw-r--r-- | src/usr.bin/nc/netcat.c | 38 |
8 files changed, 641 insertions, 9 deletions
diff --git a/src/lib/libtls/Makefile b/src/lib/libtls/Makefile index 245b1def6e..f90c57d53f 100644 --- a/src/lib/libtls/Makefile +++ b/src/lib/libtls/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: Makefile,v 1.25 2016/09/19 03:25:22 bcook Exp $ | 1 | # $OpenBSD: Makefile,v 1.26 2016/11/02 15:18:42 beck Exp $ |
2 | 2 | ||
3 | CFLAGS+= -Wall -Werror -Wimplicit | 3 | CFLAGS+= -Wall -Werror -Wimplicit |
4 | CFLAGS+= -DLIBRESSL_INTERNAL | 4 | CFLAGS+= -DLIBRESSL_INTERNAL |
@@ -20,6 +20,7 @@ SRCS= tls.c \ | |||
20 | tls_peer.c \ | 20 | tls_peer.c \ |
21 | tls_server.c \ | 21 | tls_server.c \ |
22 | tls_util.c \ | 22 | tls_util.c \ |
23 | tls_ocsp.c \ | ||
23 | tls_verify.c | 24 | tls_verify.c |
24 | 25 | ||
25 | MAN= tls_init.3 | 26 | MAN= tls_init.3 |
diff --git a/src/lib/libtls/tls.c b/src/lib/libtls/tls.c index 00564edb3c..cccdb00531 100644 --- a/src/lib/libtls/tls.c +++ b/src/lib/libtls/tls.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls.c,v 1.49 2016/09/04 12:26:43 bcook Exp $ */ | 1 | /* $OpenBSD: tls.c,v 1.50 2016/11/02 15:18:42 beck Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -419,6 +419,9 @@ tls_reset(struct tls *ctx) | |||
419 | tls_conninfo_free(ctx->conninfo); | 419 | tls_conninfo_free(ctx->conninfo); |
420 | ctx->conninfo = NULL; | 420 | ctx->conninfo = NULL; |
421 | 421 | ||
422 | tls_ocsp_ctx_free(ctx->ocsp_ctx); | ||
423 | ctx->ocsp_ctx = NULL; | ||
424 | |||
422 | for (sni = ctx->sni_ctx; sni != NULL; sni = nsni) { | 425 | for (sni = ctx->sni_ctx; sni != NULL; sni = nsni) { |
423 | nsni = sni->next; | 426 | nsni = sni->next; |
424 | tls_sni_ctx_free(sni); | 427 | tls_sni_ctx_free(sni); |
@@ -499,6 +502,8 @@ tls_handshake(struct tls *ctx) | |||
499 | ctx->ssl_peer_cert = SSL_get_peer_certificate(ctx->ssl_conn); | 502 | ctx->ssl_peer_cert = SSL_get_peer_certificate(ctx->ssl_conn); |
500 | if (tls_conninfo_populate(ctx) == -1) | 503 | if (tls_conninfo_populate(ctx) == -1) |
501 | rv = -1; | 504 | rv = -1; |
505 | if (ctx->ocsp_ctx == NULL) | ||
506 | ctx->ocsp_ctx = tls_ocsp_setup_from_peer(ctx); | ||
502 | } | 507 | } |
503 | out: | 508 | out: |
504 | /* Prevent callers from performing incorrect error handling */ | 509 | /* Prevent callers from performing incorrect error handling */ |
diff --git a/src/lib/libtls/tls.h b/src/lib/libtls/tls.h index 6cc3d0d6f8..3929cb848e 100644 --- a/src/lib/libtls/tls.h +++ b/src/lib/libtls/tls.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls.h,v 1.38 2016/09/13 13:40:58 tedu Exp $ */ | 1 | /* $OpenBSD: tls.h,v 1.39 2016/11/02 15:18:42 beck Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -41,6 +41,31 @@ extern "C" { | |||
41 | #define TLS_WANT_POLLIN -2 | 41 | #define TLS_WANT_POLLIN -2 |
42 | #define TLS_WANT_POLLOUT -3 | 42 | #define TLS_WANT_POLLOUT -3 |
43 | 43 | ||
44 | /* RFC 6960 Section 2.3 */ | ||
45 | #define TLS_OCSP_RESPONSE_SUCCESSFUL 0 | ||
46 | #define TLS_OCSP_RESPONSE_MALFORMED 1 | ||
47 | #define TLS_OCSP_RESPONSE_INTERNALERROR 2 | ||
48 | #define TLS_OCSP_RESPONSE_TRYLATER 3 | ||
49 | #define TLS_OCSP_RESPONSE_SIGREQUIRED 4 | ||
50 | #define TLS_OCSP_RESPONSE_UNAUTHORIZED 5 | ||
51 | |||
52 | /* RFC 6960 Section 2.2 */ | ||
53 | #define TLS_OCSP_CERT_GOOD 0 | ||
54 | #define TLS_OCSP_CERT_REVOKED 1 | ||
55 | #define TLS_OCSP_CERT_UNKNOWN 2 | ||
56 | |||
57 | /* RFC 5280 Section 5.3.1 */ | ||
58 | #define TLS_CRL_REASON_UNSPECIFIED 0 | ||
59 | #define TLS_CRL_REASON_KEY_COMPROMISE 1 | ||
60 | #define TLS_CRL_REASON_CA_COMPROMISE 2 | ||
61 | #define TLS_CRL_REASON_AFFILIATION_CHANGED 3 | ||
62 | #define TLS_CRL_REASON_SUPERSEDED 4 | ||
63 | #define TLS_CRL_REASON_CESSATION_OF_OPERATION 5 | ||
64 | #define TLS_CRL_REASON_CERTIFICATE_HOLD 6 | ||
65 | #define TLS_CRL_REASON_REMOVE_FROM_CRL 8 | ||
66 | #define TLS_CRL_REASON_PRIVILEGE_WITHDRAWN 9 | ||
67 | #define TLS_CRL_REASON_AA_COMPROMISE 10 | ||
68 | |||
44 | struct tls; | 69 | struct tls; |
45 | struct tls_config; | 70 | struct tls_config; |
46 | 71 | ||
@@ -138,6 +163,16 @@ const char *tls_conn_version(struct tls *_ctx); | |||
138 | 163 | ||
139 | uint8_t *tls_load_file(const char *_file, size_t *_len, char *_password); | 164 | uint8_t *tls_load_file(const char *_file, size_t *_len, char *_password); |
140 | 165 | ||
166 | int tls_ocsp_process_response(struct tls *_ctx, const unsigned char *_response, size_t _size); | ||
167 | int tls_peer_ocsp_cert_status(struct tls *_ctx); | ||
168 | int tls_peer_ocsp_crl_reason(struct tls *_ctx); | ||
169 | time_t tls_peer_ocsp_next_update(struct tls *_ctx); | ||
170 | int tls_peer_ocsp_response_status(struct tls *_ctx); | ||
171 | const char *tls_peer_ocsp_result(struct tls *_ctx); | ||
172 | time_t tls_peer_ocsp_revocation_time(struct tls *_ctx); | ||
173 | time_t tls_peer_ocsp_this_update(struct tls *_ctx); | ||
174 | const char *tls_peer_ocsp_url(struct tls *_ctx); | ||
175 | |||
141 | #ifdef __cplusplus | 176 | #ifdef __cplusplus |
142 | } | 177 | } |
143 | #endif | 178 | #endif |
diff --git a/src/lib/libtls/tls_client.c b/src/lib/libtls/tls_client.c index a1bceb7d97..84f4e91740 100644 --- a/src/lib/libtls/tls_client.c +++ b/src/lib/libtls/tls_client.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls_client.c,v 1.36 2016/09/04 13:20:56 jsing Exp $ */ | 1 | /* $OpenBSD: tls_client.c,v 1.37 2016/11/02 15:18:42 beck Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -200,6 +200,11 @@ tls_connect_common(struct tls *ctx, const char *servername) | |||
200 | SSL_VERIFY_PEER) == -1)) | 200 | SSL_VERIFY_PEER) == -1)) |
201 | goto err; | 201 | goto err; |
202 | 202 | ||
203 | if (SSL_CTX_set_tlsext_status_cb(ctx->ssl_ctx, tls_ocsp_verify_cb) != 1) { | ||
204 | tls_set_errorx(ctx, "ssl OCSP verification setup failure"); | ||
205 | goto err; | ||
206 | } | ||
207 | |||
203 | if ((ctx->ssl_conn = SSL_new(ctx->ssl_ctx)) == NULL) { | 208 | if ((ctx->ssl_conn = SSL_new(ctx->ssl_ctx)) == NULL) { |
204 | tls_set_errorx(ctx, "ssl connection failure"); | 209 | tls_set_errorx(ctx, "ssl connection failure"); |
205 | goto err; | 210 | goto err; |
@@ -210,6 +215,11 @@ tls_connect_common(struct tls *ctx, const char *servername) | |||
210 | goto err; | 215 | goto err; |
211 | } | 216 | } |
212 | 217 | ||
218 | if (SSL_set_tlsext_status_type(ctx->ssl_conn, TLSEXT_STATUSTYPE_ocsp) != 1) { | ||
219 | tls_set_errorx(ctx, "ssl OCSP extension setup failure"); | ||
220 | goto err; | ||
221 | } | ||
222 | |||
213 | /* | 223 | /* |
214 | * RFC4366 (SNI): Literal IPv4 and IPv6 addresses are not | 224 | * RFC4366 (SNI): Literal IPv4 and IPv6 addresses are not |
215 | * permitted in "HostName". | 225 | * permitted in "HostName". |
diff --git a/src/lib/libtls/tls_init.3 b/src/lib/libtls/tls_init.3 index 6059c3f8a0..2f6ca3d802 100644 --- a/src/lib/libtls/tls_init.3 +++ b/src/lib/libtls/tls_init.3 | |||
@@ -1,4 +1,4 @@ | |||
1 | .\" $OpenBSD: tls_init.3,v 1.72 2016/09/13 13:40:58 tedu Exp $ | 1 | .\" $OpenBSD: tls_init.3,v 1.73 2016/11/02 15:18:42 beck Exp $ |
2 | .\" | 2 | .\" |
3 | .\" Copyright (c) 2014 Ted Unangst <tedu@openbsd.org> | 3 | .\" Copyright (c) 2014 Ted Unangst <tedu@openbsd.org> |
4 | .\" | 4 | .\" |
@@ -14,7 +14,7 @@ | |||
14 | .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | 14 | .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
15 | .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 15 | .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
16 | .\" | 16 | .\" |
17 | .Dd $Mdocdate: September 13 2016 $ | 17 | .Dd $Mdocdate: November 2 2016 $ |
18 | .Dt TLS_INIT 3 | 18 | .Dt TLS_INIT 3 |
19 | .Os | 19 | .Os |
20 | .Sh NAME | 20 | .Sh NAME |
@@ -50,6 +50,7 @@ | |||
50 | .Nm tls_config_verify , | 50 | .Nm tls_config_verify , |
51 | .Nm tls_config_verify_client , | 51 | .Nm tls_config_verify_client , |
52 | .Nm tls_config_verify_client_optional , | 52 | .Nm tls_config_verify_client_optional , |
53 | .Nm tls_ocsp_process_response, | ||
53 | .Nm tls_peer_cert_provided , | 54 | .Nm tls_peer_cert_provided , |
54 | .Nm tls_peer_cert_contains_name , | 55 | .Nm tls_peer_cert_contains_name , |
55 | .Nm tls_peer_cert_issuer , | 56 | .Nm tls_peer_cert_issuer , |
@@ -57,6 +58,14 @@ | |||
57 | .Nm tls_peer_cert_hash , | 58 | .Nm tls_peer_cert_hash , |
58 | .Nm tls_peer_cert_notbefore , | 59 | .Nm tls_peer_cert_notbefore , |
59 | .Nm tls_peer_cert_notafter , | 60 | .Nm tls_peer_cert_notafter , |
61 | .Nm tls_peer_ocsp_cert_status, | ||
62 | .Nm tls_peer_ocsp_crl_reason, | ||
63 | .Nm tls_peer_ocsp_next_update, | ||
64 | .Nm tls_peer_ocsp_response_status, | ||
65 | .Nm tls_peer_ocsp_result_msg, | ||
66 | .Nm tls_peer_ocsp_revocation_time, | ||
67 | .Nm tls_peer_ocsp_this_update, | ||
68 | .Nm tls_peer_ocsp_url, | ||
60 | .Nm tls_conn_alpn_selected , | 69 | .Nm tls_conn_alpn_selected , |
61 | .Nm tls_conn_cipher , | 70 | .Nm tls_conn_cipher , |
62 | .Nm tls_conn_servername , | 71 | .Nm tls_conn_servername , |
@@ -160,6 +169,24 @@ | |||
160 | .Fn tls_peer_cert_notbefore "struct tls *ctx" | 169 | .Fn tls_peer_cert_notbefore "struct tls *ctx" |
161 | .Ft "time_t" | 170 | .Ft "time_t" |
162 | .Fn tls_peer_cert_notafter "struct tls *ctx" | 171 | .Fn tls_peer_cert_notafter "struct tls *ctx" |
172 | .Ft "int" | ||
173 | .Fn tls_ocsp_process_response "struct tls *ctx" "const unsigned char *response" "size_t size" | ||
174 | .Ft "int" | ||
175 | .Fn tls_peer_ocsp_cert_status "struct tls *ctx" | ||
176 | .Ft "int" | ||
177 | .Fn tls_peer_ocsp_crl_reason "struct tls *ctx" | ||
178 | .Ft time_t | ||
179 | .Fn tls_peer_ocsp_next_update "struct tls *ctx" | ||
180 | .Ft "int" | ||
181 | .Fn tls_peer_ocsp_response_status "struct tls *ctx" | ||
182 | .Ft "const char *" | ||
183 | .Fn tls_peer_ocsp_result_msg "struct tls *ctx" | ||
184 | .Ft "time_t" | ||
185 | .Fn tls_peer_ocsp_revocation_time "struct tls *ctx" | ||
186 | .Ft "time_t" | ||
187 | .Fn tls_peer_ocsp_this_update" struct tls *ctx" | ||
188 | .Ft "const char *" | ||
189 | .Fn tls_peer_ocsp_url "struct tls *ctx" | ||
163 | .Ft "const char *" | 190 | .Ft "const char *" |
164 | .Fn tls_conn_alpn_selected "struct tls *ctx" | 191 | .Fn tls_conn_alpn_selected "struct tls *ctx" |
165 | .Ft "const char *" | 192 | .Ft "const char *" |
@@ -513,6 +540,53 @@ the peer certificate from | |||
513 | returns the time corresponding to the end of the validity period of | 540 | returns the time corresponding to the end of the validity period of |
514 | the peer certificate from | 541 | the peer certificate from |
515 | .Ar ctx . | 542 | .Ar ctx . |
543 | .Ed | ||
544 | .It | ||
545 | .Fn tls_ocsp_process_response | ||
546 | processes a raw ocsp response in | ||
547 | .Ar response | ||
548 | of size | ||
549 | .Ar size | ||
550 | to check the revocation status of the peer certificate from | ||
551 | .Ar ctx . | ||
552 | A successful return code of 0 indicates that the certificate has not been revoked. | ||
553 | .Ed | ||
554 | .It | ||
555 | .Fn tls_peer_ocsp_url | ||
556 | returns the URL for OCSP validation of the peer certificate from | ||
557 | .Ar ctx | ||
558 | .El | ||
559 | .Pp | ||
560 | The following functions return informaiton about the peer certificate from | ||
561 | .Ar ctx | ||
562 | tha was obtained by validating a stapled OCSP response during the handshake, or | ||
563 | via a previous call to | ||
564 | .Xr tls_ocsp_process_response | ||
565 | .Bl -bullet -offset four | ||
566 | .It | ||
567 | .Fn tls_peer_ocsp_cert_status | ||
568 | returns the OCSP certificate status code as per RFC 6960 section 2.2 | ||
569 | .Ed | ||
570 | .It | ||
571 | .Fn tls_peer_ocsp_crl_reason | ||
572 | returns the OCSP certificate revocation reason status code as per RFC 5280 | ||
573 | section 5.3.1 | ||
574 | .Ed | ||
575 | .It | ||
576 | .Fn tls_peer_ocsp_next_update | ||
577 | returns the OCSP next update time | ||
578 | .Ed | ||
579 | .It | ||
580 | .Fn tls_peer_ocsp_response_status | ||
581 | returns the OCSP response status as per RFC 6960 section 2.3 | ||
582 | .Ed | ||
583 | .It | ||
584 | .Fn tls_peer_ocsp_revocation_time | ||
585 | returns the OCSP revocation time | ||
586 | .Ed | ||
587 | .It | ||
588 | .Fn tls_peer_ocsp_this_update | ||
589 | returns the OCSP this update time | ||
516 | .El | 590 | .El |
517 | .Pp | 591 | .Pp |
518 | The following are TLS related utility functions: | 592 | The following are TLS related utility functions: |
@@ -616,16 +690,57 @@ The | |||
616 | and | 690 | and |
617 | .Fn tls_peer_cert_contains_name | 691 | .Fn tls_peer_cert_contains_name |
618 | functions return 1 if the check succeeds, and 0 if it does not. | 692 | functions return 1 if the check succeeds, and 0 if it does not. |
693 | .Pp | ||
619 | Functions that return a | 694 | Functions that return a |
620 | .Vt time_t | 695 | .Vt time_t |
621 | will return a time in epoch-seconds on success, and -1 on error. | 696 | will return a time in epoch-seconds on success, and -1 on error. |
697 | .Pp | ||
622 | Functions that return a | 698 | Functions that return a |
623 | .Vt ssize_t | 699 | .Vt ssize_t |
624 | will return a size on success, and -1 on error. | 700 | will return a size on success, and -1 on error. |
701 | .Pp | ||
702 | The | ||
703 | .Fn tls_peer_ocsp_response_status | ||
704 | function returns one of | ||
705 | .Ar TLS_OCSP_RESPONSE_SUCCESSFUL , | ||
706 | .Ar TLS_OCSP_RESPONSE_MALFORMED , | ||
707 | .Ar TLS_OCSP_RESPONSE_INTERNALERROR , | ||
708 | .Ar TLS_OCSP_RESPONSE_TRYLATER , | ||
709 | .Ar TLS_OCSP_RESPONSE_SIGREQUIRED , | ||
710 | or | ||
711 | .AR TLS_OCSP_RESPONSE_UNAUTHORIZED | ||
712 | on success, and -1 on error. | ||
713 | .Pp | ||
714 | The | ||
715 | .Fn tls_peer_ocsp_cert_status | ||
716 | function returns one of | ||
717 | .Ar TLS_OCSP_CERT_GOOD , | ||
718 | .Ar TLS_OCSP_CERT_REVOKED , | ||
719 | or | ||
720 | .Ar TLS_OCSP_CERT_UNKNOWN | ||
721 | on success, and -1 on error. | ||
722 | .Pp | ||
723 | The | ||
724 | .Fn tls_peer_ocsp_crl_reason | ||
725 | function returns one of | ||
726 | .Ar TLS_CRL_REASON_UNSPECIFIED , | ||
727 | .Ar TLS_CRL_REASON_KEY_COMPROMISE , | ||
728 | .Ar TLS_CRL_REASON_CA_COMPROMISE , | ||
729 | .Ar TLS_CRL_REASON_AFFILIATION_CHANGED , | ||
730 | .Ar TLS_CRL_REASON_SUPERSEDED , | ||
731 | .Ar TLS_CRL_REASON_CESSATION_OF_OPERATION , | ||
732 | .Ar TLS_CRL_REASON_CERTIFICATE_HOLD , | ||
733 | .Ar TLS_CRL_REASON_REMOVE_FROM_CRL , | ||
734 | .Ar TLS_CRL_REASON_PRIVILEGE_WITHDRAWN , | ||
735 | or | ||
736 | .Ar TLS_CRL_REASON_AA_COMPROMISE | ||
737 | on success, and -1 on error. | ||
738 | .Pp | ||
625 | All other functions that return | 739 | All other functions that return |
626 | .Vt int | 740 | .Vt int |
627 | will return 0 on success and -1 on error. | 741 | will return 0 on success and -1 on error. |
628 | Functions that return a pointer will return NULL on error, which indicates an | 742 | .Pp |
743 | Functions that return a pointer will return NULL on error or an | ||
629 | out of memory condition. | 744 | out of memory condition. |
630 | .Pp | 745 | .Pp |
631 | The | 746 | The |
diff --git a/src/lib/libtls/tls_internal.h b/src/lib/libtls/tls_internal.h index c272038055..df35db37f2 100644 --- a/src/lib/libtls/tls_internal.h +++ b/src/lib/libtls/tls_internal.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls_internal.h,v 1.43 2016/09/04 12:26:43 bcook Exp $ */ | 1 | /* $OpenBSD: tls_internal.h,v 1.44 2016/11/02 15:18:42 beck Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org> | 3 | * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org> |
4 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 4 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
@@ -92,6 +92,31 @@ struct tls_conninfo { | |||
92 | #define TLS_EOF_NO_CLOSE_NOTIFY (1 << 0) | 92 | #define TLS_EOF_NO_CLOSE_NOTIFY (1 << 0) |
93 | #define TLS_HANDSHAKE_COMPLETE (1 << 1) | 93 | #define TLS_HANDSHAKE_COMPLETE (1 << 1) |
94 | 94 | ||
95 | struct tls_ocsp_result { | ||
96 | const char *result_msg; | ||
97 | int response_status; | ||
98 | int cert_status; | ||
99 | int crl_reason; | ||
100 | time_t this_update; | ||
101 | time_t next_update; | ||
102 | time_t revocation_time; | ||
103 | }; | ||
104 | |||
105 | struct tls_ocsp_ctx { | ||
106 | /* responder location */ | ||
107 | char *ocsp_url; | ||
108 | |||
109 | /* request blob */ | ||
110 | uint8_t *request_data; | ||
111 | size_t request_size; | ||
112 | |||
113 | /* cert data, this struct does not own these */ | ||
114 | X509 *main_cert; | ||
115 | STACK_OF(X509) *extra_certs; | ||
116 | |||
117 | struct tls_ocsp_result *ocsp_result; | ||
118 | }; | ||
119 | |||
95 | struct tls_sni_ctx { | 120 | struct tls_sni_ctx { |
96 | struct tls_sni_ctx *next; | 121 | struct tls_sni_ctx *next; |
97 | 122 | ||
@@ -118,6 +143,8 @@ struct tls { | |||
118 | 143 | ||
119 | struct tls_conninfo *conninfo; | 144 | struct tls_conninfo *conninfo; |
120 | 145 | ||
146 | struct tls_ocsp_ctx *ocsp_ctx; | ||
147 | |||
121 | tls_read_cb read_cb; | 148 | tls_read_cb read_cb; |
122 | tls_write_cb write_cb; | 149 | tls_write_cb write_cb; |
123 | void *cb_arg; | 150 | void *cb_arg; |
@@ -172,6 +199,10 @@ int tls_ssl_error(struct tls *ctx, SSL *ssl_conn, int ssl_ret, | |||
172 | int tls_conninfo_populate(struct tls *ctx); | 199 | int tls_conninfo_populate(struct tls *ctx); |
173 | void tls_conninfo_free(struct tls_conninfo *conninfo); | 200 | void tls_conninfo_free(struct tls_conninfo *conninfo); |
174 | 201 | ||
202 | int tls_ocsp_verify_cb(SSL *ssl, void *arg); | ||
203 | void tls_ocsp_ctx_free(struct tls_ocsp_ctx *ctx); | ||
204 | struct tls_ocsp_ctx *tls_ocsp_setup_from_peer(struct tls *ctx); | ||
205 | |||
175 | int asn1_time_parse(const char *, size_t, struct tm *, int); | 206 | int asn1_time_parse(const char *, size_t, struct tm *, int); |
176 | 207 | ||
177 | #endif /* HEADER_TLS_INTERNAL_H */ | 208 | #endif /* HEADER_TLS_INTERNAL_H */ |
diff --git a/src/lib/libtls/tls_ocsp.c b/src/lib/libtls/tls_ocsp.c new file mode 100644 index 0000000000..113ab0dd3d --- /dev/null +++ b/src/lib/libtls/tls_ocsp.c | |||
@@ -0,0 +1,399 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2015 Marko Kreen <markokr@gmail.com> | ||
3 | * Copyright (c) 2016 Bob Beck <beck@openbsd.org> | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | #include <sys/types.h> | ||
19 | |||
20 | #include <arpa/inet.h> | ||
21 | #include <netinet/in.h> | ||
22 | |||
23 | #include <openssl/err.h> | ||
24 | #include <openssl/ocsp.h> | ||
25 | #include <openssl/x509.h> | ||
26 | |||
27 | #include <tls.h> | ||
28 | #include "tls_internal.h" | ||
29 | |||
30 | #define MAXAGE_SEC (14*24*60*60) | ||
31 | #define JITTER_SEC (60) | ||
32 | |||
33 | /* | ||
34 | * State for request. | ||
35 | */ | ||
36 | |||
37 | static struct tls_ocsp_ctx * | ||
38 | tls_ocsp_ctx_new(void) | ||
39 | { | ||
40 | return (calloc(1, sizeof(struct tls_ocsp_ctx))); | ||
41 | } | ||
42 | |||
43 | void | ||
44 | tls_ocsp_ctx_free(struct tls_ocsp_ctx *ocsp_ctx) | ||
45 | { | ||
46 | if (ocsp_ctx == NULL) | ||
47 | return; | ||
48 | |||
49 | free(ocsp_ctx->ocsp_result); | ||
50 | ocsp_ctx->ocsp_result = NULL; | ||
51 | free(ocsp_ctx->ocsp_url); | ||
52 | ocsp_ctx->ocsp_url = NULL; | ||
53 | free(ocsp_ctx->request_data); | ||
54 | ocsp_ctx->request_data = NULL; | ||
55 | free(ocsp_ctx); | ||
56 | } | ||
57 | |||
58 | static int | ||
59 | tls_ocsp_asn1_parse_time(struct tls *ctx, ASN1_GENERALIZEDTIME *gt, time_t *time) | ||
60 | { | ||
61 | struct tm tm; | ||
62 | |||
63 | if (gt == NULL) | ||
64 | return -1; | ||
65 | /* RFC 6960 specifies that all times in OCSP must be GENERALIZEDTIME */ | ||
66 | if (asn1_time_parse(gt->data, gt->length, &tm, | ||
67 | V_ASN1_GENERALIZEDTIME) == -1) | ||
68 | return -1; | ||
69 | if ((*time = timegm(&tm)) == -1) | ||
70 | return -1; | ||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | static int | ||
75 | tls_ocsp_fill_info(struct tls *ctx, int response_status, int cert_status, | ||
76 | int crl_reason, ASN1_GENERALIZEDTIME *revtime, | ||
77 | ASN1_GENERALIZEDTIME *thisupd, ASN1_GENERALIZEDTIME *nextupd) | ||
78 | { | ||
79 | struct tls_ocsp_result *info = NULL; | ||
80 | |||
81 | free(ctx->ocsp_ctx->ocsp_result); | ||
82 | ctx->ocsp_ctx->ocsp_result = NULL; | ||
83 | |||
84 | if ((info = calloc(1, sizeof (struct tls_ocsp_result))) == NULL) { | ||
85 | tls_set_error(ctx, "calloc"); | ||
86 | return -1; | ||
87 | } | ||
88 | info->response_status = response_status; | ||
89 | info->cert_status = cert_status; | ||
90 | info->crl_reason = crl_reason; | ||
91 | if (info->response_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { | ||
92 | info->result_msg = | ||
93 | OCSP_response_status_str(info->response_status); | ||
94 | } else if (info->cert_status != V_OCSP_CERTSTATUS_REVOKED) { | ||
95 | info->result_msg = OCSP_cert_status_str(info->cert_status); | ||
96 | } else { | ||
97 | info->result_msg = OCSP_crl_reason_str(info->crl_reason); | ||
98 | } | ||
99 | info->revocation_time = info->this_update = info->next_update = -1; | ||
100 | if (revtime != NULL && | ||
101 | tls_ocsp_asn1_parse_time(ctx, revtime, &info->revocation_time) != 0) { | ||
102 | tls_set_error(ctx, | ||
103 | "unable to parse revocation time in OCSP reply"); | ||
104 | goto error; | ||
105 | } | ||
106 | if (thisupd != NULL && | ||
107 | tls_ocsp_asn1_parse_time(ctx, thisupd, &info->this_update) != 0) { | ||
108 | tls_set_error(ctx, | ||
109 | "unable to parse this update time in OCSP reply"); | ||
110 | goto error; | ||
111 | } | ||
112 | if (nextupd != NULL && | ||
113 | tls_ocsp_asn1_parse_time(ctx, nextupd, &info->next_update) != 0) { | ||
114 | tls_set_error(ctx, | ||
115 | "unable to parse next update time in OCSP reply"); | ||
116 | goto error; | ||
117 | } | ||
118 | ctx->ocsp_ctx->ocsp_result = info; | ||
119 | return 0; | ||
120 | error: | ||
121 | free(info); | ||
122 | return -1; | ||
123 | } | ||
124 | |||
125 | static OCSP_CERTID * | ||
126 | tls_ocsp_get_certid(X509 *main_cert, STACK_OF(X509) *extra_certs, | ||
127 | SSL_CTX *ssl_ctx) | ||
128 | { | ||
129 | X509_NAME *issuer_name; | ||
130 | X509 *issuer; | ||
131 | X509_STORE_CTX storectx; | ||
132 | X509_OBJECT tmpobj; | ||
133 | OCSP_CERTID *cid = NULL; | ||
134 | X509_STORE *store; | ||
135 | |||
136 | if ((issuer_name = X509_get_issuer_name(main_cert)) == NULL) | ||
137 | return NULL; | ||
138 | |||
139 | if (extra_certs != NULL) { | ||
140 | issuer = X509_find_by_subject(extra_certs, issuer_name); | ||
141 | if (issuer != NULL) | ||
142 | return OCSP_cert_to_id(NULL, main_cert, issuer); | ||
143 | } | ||
144 | |||
145 | if ((store = SSL_CTX_get_cert_store(ssl_ctx)) == NULL) | ||
146 | return NULL; | ||
147 | if (X509_STORE_CTX_init(&storectx, store, main_cert, extra_certs) != 1) | ||
148 | return NULL; | ||
149 | if (X509_STORE_get_by_subject(&storectx, X509_LU_X509, issuer_name, | ||
150 | &tmpobj) == 1) { | ||
151 | cid = OCSP_cert_to_id(NULL, main_cert, tmpobj.data.x509); | ||
152 | X509_OBJECT_free_contents(&tmpobj); | ||
153 | } | ||
154 | X509_STORE_CTX_cleanup(&storectx); | ||
155 | return cid; | ||
156 | } | ||
157 | |||
158 | struct tls_ocsp_ctx * | ||
159 | tls_ocsp_setup_from_peer(struct tls *ctx) | ||
160 | { | ||
161 | struct tls_ocsp_ctx *ocsp_ctx = NULL; | ||
162 | STACK_OF(OPENSSL_STRING) *ocsp_urls = NULL; | ||
163 | |||
164 | if ((ocsp_ctx = tls_ocsp_ctx_new()) == NULL) | ||
165 | goto failed; | ||
166 | |||
167 | /* steal state from ctx struct */ | ||
168 | ocsp_ctx->main_cert = SSL_get_peer_certificate(ctx->ssl_conn); | ||
169 | ocsp_ctx->extra_certs = SSL_get_peer_cert_chain(ctx->ssl_conn); | ||
170 | if (ocsp_ctx->main_cert == NULL) { | ||
171 | tls_set_errorx(ctx, "no peer certificate for OCSP"); | ||
172 | goto failed; | ||
173 | } | ||
174 | |||
175 | ocsp_urls = X509_get1_ocsp(ocsp_ctx->main_cert); | ||
176 | if (ocsp_urls == NULL) | ||
177 | goto failed; | ||
178 | ocsp_ctx->ocsp_url = strdup(sk_OPENSSL_STRING_value(ocsp_urls, 0)); | ||
179 | if (ocsp_ctx->ocsp_url == NULL) { | ||
180 | tls_set_errorx(ctx, "out of memory"); | ||
181 | goto failed; | ||
182 | } | ||
183 | |||
184 | X509_email_free(ocsp_urls); | ||
185 | return ocsp_ctx; | ||
186 | |||
187 | failed: | ||
188 | tls_ocsp_ctx_free(ocsp_ctx); | ||
189 | X509_email_free(ocsp_urls); | ||
190 | return NULL; | ||
191 | } | ||
192 | |||
193 | static int | ||
194 | tls_ocsp_verify_response(struct tls *ctx, OCSP_RESPONSE *resp) | ||
195 | { | ||
196 | OCSP_BASICRESP *br = NULL; | ||
197 | ASN1_GENERALIZEDTIME *revtime = NULL, *thisupd = NULL, *nextupd = NULL; | ||
198 | OCSP_CERTID *cid = NULL; | ||
199 | STACK_OF(X509) *combined = NULL; | ||
200 | int response_status=0, cert_status=0, crl_reason=0; | ||
201 | int ret = -1; | ||
202 | unsigned long flags; | ||
203 | |||
204 | if ((br = OCSP_response_get1_basic(resp)) == NULL) { | ||
205 | tls_set_errorx(ctx, "cannot load ocsp reply"); | ||
206 | goto error; | ||
207 | } | ||
208 | |||
209 | /* | ||
210 | * Skip validation of 'extra_certs' as this should be done | ||
211 | * already as part of main handshake. | ||
212 | */ | ||
213 | flags = OCSP_TRUSTOTHER; | ||
214 | |||
215 | /* now verify */ | ||
216 | if (OCSP_basic_verify(br, ctx->ocsp_ctx->extra_certs, | ||
217 | SSL_CTX_get_cert_store(ctx->ssl_ctx), flags) != 1) { | ||
218 | tls_set_error(ctx, "ocsp verify failed"); | ||
219 | goto error; | ||
220 | } | ||
221 | |||
222 | /* signature OK, look inside */ | ||
223 | response_status = OCSP_response_status(resp); | ||
224 | if (response_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { | ||
225 | tls_set_errorx(ctx, "ocsp verify failed: response - %s", | ||
226 | OCSP_response_status_str(response_status)); | ||
227 | goto error; | ||
228 | } | ||
229 | |||
230 | cid = tls_ocsp_get_certid(ctx->ocsp_ctx->main_cert, | ||
231 | ctx->ocsp_ctx->extra_certs, ctx->ssl_ctx); | ||
232 | if (cid == NULL) { | ||
233 | tls_set_errorx(ctx, "ocsp verify failed: no issuer cert"); | ||
234 | goto error; | ||
235 | } | ||
236 | |||
237 | if (OCSP_resp_find_status(br, cid, &cert_status, &crl_reason, | ||
238 | &revtime, &thisupd, &nextupd) != 1) { | ||
239 | tls_set_errorx(ctx, "ocsp verify failed: no result for cert"); | ||
240 | goto error; | ||
241 | } | ||
242 | |||
243 | if (OCSP_check_validity(thisupd, nextupd, JITTER_SEC, | ||
244 | MAXAGE_SEC) != 1) { | ||
245 | tls_set_errorx(ctx, | ||
246 | "ocsp verify failed: ocsp response not current"); | ||
247 | goto error; | ||
248 | } | ||
249 | |||
250 | if (tls_ocsp_fill_info(ctx, response_status, cert_status, | ||
251 | crl_reason, revtime, thisupd, nextupd) != 0) | ||
252 | goto error; | ||
253 | |||
254 | /* finally can look at status */ | ||
255 | if (cert_status != V_OCSP_CERTSTATUS_GOOD && cert_status != | ||
256 | V_OCSP_CERTSTATUS_UNKNOWN) { | ||
257 | tls_set_errorx(ctx, "ocsp verify failed: revoked cert - %s", | ||
258 | OCSP_crl_reason_str(crl_reason)); | ||
259 | goto error; | ||
260 | } | ||
261 | |||
262 | ret = 0; | ||
263 | |||
264 | error: | ||
265 | sk_X509_free(combined); | ||
266 | OCSP_CERTID_free(cid); | ||
267 | OCSP_BASICRESP_free(br); | ||
268 | return ret; | ||
269 | } | ||
270 | |||
271 | /* TLS handshake verification callback for stapled requests */ | ||
272 | int | ||
273 | tls_ocsp_verify_cb(SSL *ssl, void *arg) | ||
274 | { | ||
275 | const unsigned char *raw = NULL; | ||
276 | int size, res = -1; | ||
277 | struct tls *ctx; | ||
278 | |||
279 | if ((ctx = SSL_get_app_data(ssl)) == NULL) | ||
280 | return -1; | ||
281 | |||
282 | size = SSL_get_tlsext_status_ocsp_resp(ssl, &raw); | ||
283 | if (size <= 0) | ||
284 | return 1; | ||
285 | |||
286 | tls_ocsp_ctx_free(ctx->ocsp_ctx); | ||
287 | ctx->ocsp_ctx = tls_ocsp_setup_from_peer(ctx); | ||
288 | if (ctx->ocsp_ctx != NULL) | ||
289 | res = tls_ocsp_process_response(ctx, raw, size); | ||
290 | |||
291 | return (res == 0) ? 1 : 0; | ||
292 | } | ||
293 | |||
294 | /* | ||
295 | * Public API | ||
296 | */ | ||
297 | |||
298 | /* Retrieve OSCP URL from peer certificate, if present */ | ||
299 | const char * | ||
300 | tls_peer_ocsp_url(struct tls *ctx) | ||
301 | { | ||
302 | if (ctx->ocsp_ctx == NULL) | ||
303 | return NULL; | ||
304 | return ctx->ocsp_ctx->ocsp_url; | ||
305 | } | ||
306 | |||
307 | const char * | ||
308 | tls_peer_ocsp_result(struct tls *ctx) | ||
309 | { | ||
310 | if (ctx->ocsp_ctx == NULL) | ||
311 | return NULL; | ||
312 | if (ctx->ocsp_ctx->ocsp_result == NULL) | ||
313 | return NULL; | ||
314 | return ctx->ocsp_ctx->ocsp_result->result_msg; | ||
315 | } | ||
316 | |||
317 | int | ||
318 | tls_peer_ocsp_response_status(struct tls *ctx) | ||
319 | { | ||
320 | if (ctx->ocsp_ctx == NULL) | ||
321 | return -1; | ||
322 | if (ctx->ocsp_ctx->ocsp_result == NULL) | ||
323 | return -1; | ||
324 | return ctx->ocsp_ctx->ocsp_result->response_status; | ||
325 | } | ||
326 | |||
327 | int | ||
328 | tls_peer_ocsp_cert_status(struct tls *ctx) | ||
329 | { | ||
330 | if (ctx->ocsp_ctx == NULL) | ||
331 | return -1; | ||
332 | if (ctx->ocsp_ctx->ocsp_result == NULL) | ||
333 | return -1; | ||
334 | return ctx->ocsp_ctx->ocsp_result->cert_status; | ||
335 | } | ||
336 | |||
337 | int | ||
338 | tls_peer_ocsp_crl_reason(struct tls *ctx) | ||
339 | { | ||
340 | if (ctx->ocsp_ctx == NULL) | ||
341 | return -1; | ||
342 | if (ctx->ocsp_ctx->ocsp_result == NULL) | ||
343 | return -1; | ||
344 | return ctx->ocsp_ctx->ocsp_result->crl_reason; | ||
345 | } | ||
346 | |||
347 | time_t | ||
348 | tls_peer_ocsp_this_update(struct tls *ctx) | ||
349 | { | ||
350 | if (ctx->ocsp_ctx == NULL) | ||
351 | return -1; | ||
352 | if (ctx->ocsp_ctx->ocsp_result == NULL) | ||
353 | return -1; | ||
354 | return ctx->ocsp_ctx->ocsp_result->this_update; | ||
355 | } | ||
356 | |||
357 | time_t | ||
358 | tls_peer_ocsp_next_update(struct tls *ctx) | ||
359 | { | ||
360 | if (ctx->ocsp_ctx == NULL) | ||
361 | return -1; | ||
362 | if (ctx->ocsp_ctx->ocsp_result == NULL) | ||
363 | return -1; | ||
364 | return ctx->ocsp_ctx->ocsp_result->next_update; | ||
365 | } | ||
366 | |||
367 | time_t | ||
368 | tls_peer_ocsp_revocation_time(struct tls *ctx) | ||
369 | { | ||
370 | if (ctx->ocsp_ctx == NULL) | ||
371 | return -1; | ||
372 | if (ctx->ocsp_ctx->ocsp_result == NULL) | ||
373 | return -1; | ||
374 | return ctx->ocsp_ctx->ocsp_result->revocation_time; | ||
375 | } | ||
376 | |||
377 | /* | ||
378 | * Process a raw OCSP response from an OCSP server request. | ||
379 | * OCSP details can then be retrieved with tls_peer_ocsp_* functions. | ||
380 | * returns 0 if certificate ok, -1 otherwise. | ||
381 | */ | ||
382 | int | ||
383 | tls_ocsp_process_response(struct tls *ctx, const unsigned char *response, | ||
384 | size_t size) | ||
385 | { | ||
386 | int ret; | ||
387 | OCSP_RESPONSE *resp; | ||
388 | |||
389 | resp = d2i_OCSP_RESPONSE(NULL, &response, size); | ||
390 | if (resp == NULL) { | ||
391 | tls_ocsp_ctx_free(ctx->ocsp_ctx); | ||
392 | ctx->ocsp_ctx = NULL; | ||
393 | tls_set_error(ctx, "unable to parse OCSP response"); | ||
394 | return -1; | ||
395 | } | ||
396 | ret = tls_ocsp_verify_response(ctx, resp); | ||
397 | OCSP_RESPONSE_free(resp); | ||
398 | return ret; | ||
399 | } | ||
diff --git a/src/usr.bin/nc/netcat.c b/src/usr.bin/nc/netcat.c index 3af7d50374..64e77a8b52 100644 --- a/src/usr.bin/nc/netcat.c +++ b/src/usr.bin/nc/netcat.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: netcat.c,v 1.163 2016/09/03 17:35:34 bcook Exp $ */ | 1 | /* $OpenBSD: netcat.c,v 1.164 2016/11/02 15:18:42 beck Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> | 3 | * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> |
4 | * Copyright (c) 2015 Bob Beck. All rights reserved. | 4 | * Copyright (c) 2015 Bob Beck. All rights reserved. |
@@ -1518,6 +1518,8 @@ void | |||
1518 | report_tls(struct tls * tls_ctx, char * host, char *tls_expectname) | 1518 | report_tls(struct tls * tls_ctx, char * host, char *tls_expectname) |
1519 | { | 1519 | { |
1520 | time_t t; | 1520 | time_t t; |
1521 | const char *ocsp_url; | ||
1522 | |||
1521 | fprintf(stderr, "TLS handshake negotiated %s/%s with host %s\n", | 1523 | fprintf(stderr, "TLS handshake negotiated %s/%s with host %s\n", |
1522 | tls_conn_version(tls_ctx), tls_conn_cipher(tls_ctx), host); | 1524 | tls_conn_version(tls_ctx), tls_conn_cipher(tls_ctx), host); |
1523 | fprintf(stderr, "Peer name: %s\n", | 1525 | fprintf(stderr, "Peer name: %s\n", |
@@ -1535,6 +1537,40 @@ report_tls(struct tls * tls_ctx, char * host, char *tls_expectname) | |||
1535 | if (tls_peer_cert_hash(tls_ctx)) | 1537 | if (tls_peer_cert_hash(tls_ctx)) |
1536 | fprintf(stderr, "Cert Hash: %s\n", | 1538 | fprintf(stderr, "Cert Hash: %s\n", |
1537 | tls_peer_cert_hash(tls_ctx)); | 1539 | tls_peer_cert_hash(tls_ctx)); |
1540 | ocsp_url = tls_peer_ocsp_url(tls_ctx); | ||
1541 | fprintf(stderr, "OCSP URL: %s\n", ocsp_url == NULL ? "" : ocsp_url); | ||
1542 | fprintf(stderr, "OCSP Stapling:"); | ||
1543 | switch (tls_peer_ocsp_response_status(tls_ctx)) { | ||
1544 | case TLS_OCSP_RESPONSE_SUCCESSFUL: | ||
1545 | fprintf(stderr, " %s\n", | ||
1546 | tls_peer_ocsp_result(tls_ctx) == NULL ? "" : | ||
1547 | tls_peer_ocsp_result(tls_ctx)); | ||
1548 | fprintf(stderr, | ||
1549 | " response_status=%d cert_status=%d crl_reason=%d\n", | ||
1550 | tls_peer_ocsp_response_status(tls_ctx), | ||
1551 | tls_peer_ocsp_cert_status(tls_ctx), | ||
1552 | tls_peer_ocsp_crl_reason(tls_ctx)); | ||
1553 | t = tls_peer_ocsp_this_update(tls_ctx); | ||
1554 | fprintf(stderr, " this update: %s", | ||
1555 | t != -1 ? ctime(&t) : "\n"); | ||
1556 | t = tls_peer_ocsp_next_update(tls_ctx); | ||
1557 | fprintf(stderr, " next update: %s", | ||
1558 | t != -1 ? ctime(&t) : "\n"); | ||
1559 | t = tls_peer_ocsp_revocation_time(tls_ctx); | ||
1560 | fprintf(stderr, " revocation: %s", | ||
1561 | t != -1 ? ctime(&t) : "\n"); | ||
1562 | break; | ||
1563 | case -1: | ||
1564 | fprintf(stderr, "\n"); | ||
1565 | break; | ||
1566 | default: | ||
1567 | fprintf(stderr, " failure - response_status %d (%s)\n", | ||
1568 | tls_peer_ocsp_response_status(tls_ctx), | ||
1569 | tls_peer_ocsp_result(tls_ctx) == NULL ? "" : | ||
1570 | tls_peer_ocsp_result(tls_ctx)); | ||
1571 | break; | ||
1572 | |||
1573 | } | ||
1538 | } | 1574 | } |
1539 | 1575 | ||
1540 | void | 1576 | void |