Hi, Martin! A month ago we implemented our own OCSP verification support
in OpenSSL, integrated into X509 verification. Today I suddenly found
out that there is an alternative implementation you've done (I wish I
found it before writing our own! ;) ).

Our patch is a little bit different and aims on simplicity and
transparency for apps/libs that use openssl, like openldap.

Anyway, it's a good idea to register another one at RT so it won't be
lost somewhere in the Internet.

Patch adds three verification flags:
- X509_V_FLAG_OCSP_CHECK [enable OCSP checks]
- X509_V_FLAG_OCSP_CHECK_ALL [check the whole chain]
- X509_V_FLAG_OCSP_NO_NONCE [disable nonce checks - speedup!]

and one special function X509_set_cert_ocsp_opt(..,const char *filename,
                    const char *ocsp_url, const int ocsp_do_validation)
that allows user to manually control OCSP verification for the CA
specified by it's filename.

You can read more at gmane:
http://comments.gmane.org/gmane.comp.encryption.openssl.devel/21122

I tried to integrate our patch into OpenSSL as much as possible, so some
OCSP procedure internal errors are added to be reported with ERR_print()
routines. Hope someday extended OCSP functionality will go into
upstream, though this will require additional efforts.

Attached patch was tested in our company and seems to work fine.

-- 
Best wishes,
Alexander Komyagin

diff --git a/apps/apps.c b/apps/apps.c
index 4e11915..47f8c2f 100644
--- a/apps/apps.c
+++ b/apps/apps.c
@@ -2338,8 +2338,12 @@ int args_verify(char ***pargs, int *pargc,
 		flags |= X509_V_FLAG_CB_ISSUER_CHECK;
 	else if (!strcmp(arg, "-crl_check"))
 		flags |=  X509_V_FLAG_CRL_CHECK;
+	else if (!strcmp(arg, "-ocsp_check"))
+		flags |=  X509_V_FLAG_OCSP_CHECK;
 	else if (!strcmp(arg, "-crl_check_all"))
 		flags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
+	else if (!strcmp(arg, "-ocsp_check_all"))
+		flags |= X509_V_FLAG_OCSP_CHECK|X509_V_FLAG_OCSP_CHECK_ALL;	
 	else if (!strcmp(arg, "-policy_check"))
 		flags |= X509_V_FLAG_POLICY_CHECK;
 	else if (!strcmp(arg, "-explicit_policy"))
diff --git a/apps/verify.c b/apps/verify.c
index b9749dc..8eeaf7b 100644
--- a/apps/verify.c
+++ b/apps/verify.c
@@ -65,6 +65,8 @@
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 #include <openssl/pem.h>
+#include <openssl/x509_vfy_ocsp.h>
+#include <openssl/ocsp_clnt.h>
 
 #undef PROG
 #define PROG	verify_main
@@ -88,6 +90,8 @@ int MAIN(int argc, char **argv)
 	X509_STORE *cert_ctx=NULL;
 	X509_LOOKUP *lookup=NULL;
 	X509_VERIFY_PARAM *vpm = NULL;
+	char *ocsp_url = NULL;
+	int ocsp_validate = X509_OCSP_VALIDATE_ENABLED;
 #ifndef OPENSSL_NO_ENGINE
 	char *engine=NULL;
 #endif
@@ -95,6 +99,7 @@ int MAIN(int argc, char **argv)
 	cert_ctx=X509_STORE_new();
 	if (cert_ctx == NULL) goto end;
 	X509_STORE_set_verify_cb(cert_ctx,cb);
+	X509_STORE_set_ocsp_process_resp(cert_ctx, &ocsp_process_responder);
 
 	ERR_load_crypto_strings();
 
@@ -123,6 +128,16 @@ int MAIN(int argc, char **argv)
 				if (argc-- < 1) goto end;
 				CAfile= *(++argv);
 				}
+			else if (strcmp(*argv,"-ocsp_url") == 0)
+				{
+				if (argc-- < 1) goto end;
+				ocsp_url= *(++argv);
+				}
+			else if (strcmp(*argv,"-ocsp_validate") == 0)
+				{
+				if (argc-- < 1) goto end;
+				ocsp_validate = atoi(*(++argv));
+				}
 			else if (args_verify(&argv, &argc, &badarg, bio_err,
 									&vpm))
 				{
@@ -222,6 +237,18 @@ int MAIN(int argc, char **argv)
 			goto end;
 		}
 
+	if (ocsp_url && CAfile)
+	{
+		BIO_printf(bio_err, "Setting OCSP params for %s (%s,%d)... ", CAfile, ocsp_url, ocsp_validate);
+		i = X509_set_cert_ocsp_opt(cert_ctx, CAfile, ocsp_url, ocsp_validate);
+		if(!i) {
+			BIO_printf(bio_err, "Error setting OCSP params for %s\n", CAfile);
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+		BIO_printf(bio_err, "Done.\n");
+	}
+
 	if (argc < 1) check(cert_ctx, NULL, untrusted, trusted, crls, e);
 	else
 		for (i=0; i<argc; i++)
diff --git a/crypto/asn1/x_x509.c b/crypto/asn1/x_x509.c
index de3df9e..2074a84 100644
--- a/crypto/asn1/x_x509.c
+++ b/crypto/asn1/x_x509.c
@@ -81,6 +81,10 @@ IMPLEMENT_ASN1_FUNCTIONS(X509_CINF)
 
 extern void policy_cache_free(X509_POLICY_CACHE *cache);
 
+#ifndef OPENSSL_NO_OCSP
+extern void X509_CERT_OCSP_free(X509_CERT_OCSP *ocsp);
+#endif
+
 static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
 								void *exarg)
 {
@@ -102,6 +106,9 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
 		ret->aux = NULL;
 		ret->crldp = NULL;
 		CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
+#ifndef OPENSSL_NO_OCSP
+		ret->ocsp = NULL;
+#endif
 		break;
 
 		case ASN1_OP_D2I_POST:
@@ -122,7 +129,9 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
 		sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free);
 		ASIdentifiers_free(ret->rfc3779_asid);
 #endif
-
+#ifndef OPENSSL_NO_OCSP
+		if (ret->ocsp != NULL) X509_CERT_OCSP_free(ret->ocsp);
+#endif
 		if (ret->name != NULL) OPENSSL_free(ret->name);
 		break;
 
diff --git a/crypto/x509/Makefile b/crypto/x509/Makefile
index 72c8227..5a56e42 100644
--- a/crypto/x509/Makefile
+++ b/crypto/x509/Makefile
@@ -18,13 +18,13 @@ APPS=
 
 LIB=$(TOP)/libcrypto.a
 LIBSRC=	x509_def.c x509_d2.c x509_r2x.c x509_cmp.c \
-	x509_obj.c x509_req.c x509spki.c x509_vfy.c \
+	x509_obj.c x509_req.c x509spki.c x509_vfy.c x509_vfy_ocsp.c \
 	x509_set.c x509cset.c x509rset.c x509_err.c \
 	x509name.c x509_v3.c x509_ext.c x509_att.c \
 	x509type.c x509_lu.c x_all.c x509_txt.c \
 	x509_trs.c by_file.c by_dir.c x509_vpm.c
 LIBOBJ= x509_def.o x509_d2.o x509_r2x.o x509_cmp.o \
-	x509_obj.o x509_req.o x509spki.o x509_vfy.o \
+	x509_obj.o x509_req.o x509spki.o x509_vfy.o x509_vfy_ocsp.o\
 	x509_set.o x509cset.o x509rset.o x509_err.o \
 	x509name.o x509_v3.o x509_ext.o x509_att.o \
 	x509type.o x509_lu.o x_all.o x509_txt.o \
@@ -32,7 +32,7 @@ LIBOBJ= x509_def.o x509_d2.o x509_r2x.o x509_cmp.o \
 
 SRC= $(LIBSRC)
 
-EXHEADER= x509.h x509_vfy.h
+EXHEADER= x509.h x509_vfy.h x509_vfy_ocsp.h
 HEADER=	$(EXHEADER)
 
 ALL=    $(GENERAL) $(SRC) $(HEADER)
@@ -95,7 +95,7 @@ by_dir.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 by_dir.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 by_dir.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 by_dir.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-by_dir.o: ../../include/openssl/x509_vfy.h ../cryptlib.h by_dir.c
+by_dir.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509_vfy_ocsp.h ../cryptlib.h by_dir.c
 by_file.o: ../../e_os.h ../../include/openssl/asn1.h
 by_file.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 by_file.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
@@ -109,7 +109,7 @@ by_file.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
 by_file.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 by_file.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 by_file.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-by_file.o: ../cryptlib.h by_file.c
+by_file.o: ../cryptlib.h ../../include/openssl/x509_vfy_ocsp.h by_file.c
 x509_att.o: ../../e_os.h ../../include/openssl/asn1.h
 x509_att.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 x509_att.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
@@ -311,8 +311,22 @@ x509_vfy.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x509_vfy.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 x509_vfy.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 x509_vfy.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509_vfy.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+x509_vfy.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509_vfy_ocsp.h ../../include/openssl/x509v3.h
 x509_vfy.o: ../cryptlib.h x509_vfy.c
+x509_vfy_ocsp.o: ../../e_os.h ../../include/openssl/asn1.h
+x509_vfy_ocsp.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+x509_vfy_ocsp.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+x509_vfy_ocsp.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+x509_vfy_ocsp.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+x509_vfy_ocsp.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+x509_vfy_ocsp.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x509_vfy_ocsp.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_vfy_ocsp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509_vfy_ocsp.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509_vfy_ocsp.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509_vfy_ocsp.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509_vfy_ocsp.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509_vfy_ocsp.h ../../include/openssl/x509v3.h
+x509_vfy_ocsp.o: ../cryptlib.h ../../include/openssl/ocsp.h x509_vfy_ocsp.c
 x509_vpm.o: ../../e_os.h ../../include/openssl/asn1.h
 x509_vpm.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 x509_vpm.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
@@ -404,4 +418,4 @@ x_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
 x_all.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
 x_all.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 x_all.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x_all.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_all.c
+x_all.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509_vfy_ocsp.h ../cryptlib.h x_all.c
diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h
index 092dd74..e5233fe 100644
--- a/crypto/x509/x509.h
+++ b/crypto/x509/x509.h
@@ -276,6 +276,17 @@ typedef struct x509_cert_aux_st
 	STACK_OF(X509_ALGOR) *other;		/* other unspecified info */
 	} X509_CERT_AUX;
 
+/* This struct represents OCSP-related validation
+ * data that can be manually set for certificate
+ */
+#ifndef OPENSSL_NO_OCSP
+typedef struct x509_cert_ocsp_st
+	{
+	char *ocsp_url; /* forced OCSP URL */
+	int ocsp_validate; /* validation mode: if disabled, one has no OCSP */
+	} X509_CERT_OCSP;
+#endif
+ 
 struct x509_st
 	{
 	X509_CINF *cert_info;
@@ -306,6 +317,9 @@ struct x509_st
 	unsigned char sha1_hash[SHA_DIGEST_LENGTH];
 #endif
 	X509_CERT_AUX *aux;
+#ifndef OPENSSL_NO_OCSP
+	X509_CERT_OCSP *ocsp;
+#endif
 	} /* X509 */;
 
 DECLARE_STACK_OF(X509)
@@ -859,6 +873,10 @@ int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj);
 void X509_trust_clear(X509 *x);
 void X509_reject_clear(X509 *x);
 
+#ifndef OPENSSL_NO_OCSP
+int X509_set0_ocsp(X509 *cert, X509_CERT_OCSP *ocsp);
+#endif
+
 DECLARE_ASN1_FUNCTIONS(X509_REVOKED)
 DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO)
 DECLARE_ASN1_FUNCTIONS(X509_CRL)
diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c
index 38525a8..c2d21e1 100644
--- a/crypto/x509/x509_lu.c
+++ b/crypto/x509/x509_lu.c
@@ -187,6 +187,10 @@ X509_STORE *X509_STORE_new(void)
 	ret->verify=0;
 	ret->verify_cb=0;
 
+#ifndef OPENSSL_NO_OCSP
+	ret->ocsp_process_responder=0;
+#endif
+
 	if ((ret->param = X509_VERIFY_PARAM_new()) == NULL)
 		return NULL;
 
@@ -712,5 +716,13 @@ void X509_STORE_set_verify_cb(X509_STORE *ctx,
 	ctx->verify_cb = verify_cb;
 	}
 
+#ifndef OPENSSL_NO_OCSP
+void X509_STORE_set_ocsp_process_resp(X509_STORE *ctx,
+				  ocsp_process_responder_f func)
+	{
+	ctx->ocsp_process_responder = func;
+	}
+#endif
+
 IMPLEMENT_STACK_OF(X509_LOOKUP)
 IMPLEMENT_STACK_OF(X509_OBJECT)
diff --git a/crypto/x509/x509_txt.c b/crypto/x509/x509_txt.c
index c44f753..4fcb077 100644
--- a/crypto/x509/x509_txt.c
+++ b/crypto/x509/x509_txt.c
@@ -183,6 +183,24 @@ const char *X509_verify_cert_error_string(long n)
 		return("unsupported or invalid name syntax");
 	case X509_V_ERR_CRL_PATH_VALIDATION_ERROR:
 		return("CRL path validation error");
+	case X509_V_ERR_CERT_UNKNOWN:
+		return("certificate is unknown for OCSP");
+	case X509_V_ERR_UNABLE_TO_FIND_OCSP_URL:
+		return("unable to find OCSP responder url");
+	case X509_V_ERR_UNPARSABLE_OCSP_URL:
+		return("failed to parse OCSP responder url");
+	case X509_V_ERR_SSL_USED_FOR_OCSP:
+		return("ssl connections to OCSP servers are not supported");
+	case X509_V_ERR_OCSP_PROCESS_FUNC_NOT_SET:
+		return("OCSP responder process function is not set");
+	case X509_V_ERR_OCSP_RESPONDER_STATUS_FAIL:
+		return("OCSP responder reports fail");
+	case X509_V_ERR_OCSP_NONCE_VERIFY_ERROR:
+		return("OCSP nonce verification failure");
+	case X509_V_ERR_OCSP_RESPONSE_VERIFICATION:
+		return("OCSP response verification failure");
+	case X509_V_ERR_OCSP_RESPONDER_QUERY_FAILED:
+		return("failed to query OCSP responder");
 
 	default:
 		BIO_snprintf(buf,sizeof buf,"error number %ld",n);
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index b0779db..ab970cc 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -70,6 +70,8 @@
 #include <openssl/x509v3.h>
 #include <openssl/objects.h>
 
+#include "x509_vfy_ocsp.h"
+
 /* CRL score values */
 
 /* No unhandled critical extensions */
@@ -669,6 +671,16 @@ static int check_trust(X509_STORE_CTX *ctx)
 static int check_revocation(X509_STORE_CTX *ctx)
 	{
 	int i, last, ok;
+
+#ifndef OPENSSL_NO_OCSP
+	/* Check if we need to check against OCSP */
+	if (ctx->param->flags & X509_V_FLAG_OCSP_CHECK)
+	{
+		ok = check_revocation_ocsp(ctx);
+		if (!ok) return ok;
+	}
+#endif
+
 	if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
 		return 1;
 	if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
@@ -2205,6 +2217,58 @@ void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param)
 	ctx->param = param;
 	}
 
+#ifndef OPENSSL_NO_OCSP
+void X509_CERT_OCSP_free(X509_CERT_OCSP *ocsp)
+	{
+	if (!ocsp)
+		return;
+	if (ocsp->ocsp_url)
+		OPENSSL_free(ocsp->ocsp_url);
+	OPENSSL_free(ocsp);
+	}
+	
+X509_CERT_OCSP *X509_CERT_OCSP_new(void)
+	{
+	X509_CERT_OCSP *ocsp;
+	ocsp = OPENSSL_malloc(sizeof(X509_CERT_OCSP));
+	memset(ocsp, 0, sizeof(X509_CERT_OCSP));
+	ocsp->ocsp_validate = X509_OCSP_VALIDATE_ENABLED;
+	return ocsp;
+	}
+	
+int X509_set0_ocsp(X509 *cert, X509_CERT_OCSP *ocsp)
+	{
+	if (cert->ocsp)
+		X509_CERT_OCSP_free(cert->ocsp);
+	cert->ocsp = ocsp;
+	return 1;
+	}
+	
+int X509_CERT_OCSP_set1_url(X509_CERT_OCSP *ocsp, char* url)
+	{
+	if (ocsp->ocsp_url)
+		OPENSSL_free(ocsp->ocsp_url);
+		
+	if (url == NULL)
+	{
+		ocsp->ocsp_url = NULL;
+		return 1;
+	}
+	
+	ocsp->ocsp_url = BUF_strdup(url);
+	if (ocsp->ocsp_url)
+		return 1;
+
+	return 0;
+	}
+	
+int X509_CERT_OCSP_set_validate(X509_CERT_OCSP *ocsp, int validate)
+	{
+	ocsp->ocsp_validate = validate;
+	return 1;
+	}
+#endif
+
 IMPLEMENT_STACK_OF(X509)
 IMPLEMENT_ASN1_SET_OF(X509)
 
diff --git a/crypto/x509/x509_vfy.h b/crypto/x509/x509_vfy.h
index fe09b30..e70ba76 100644
--- a/crypto/x509/x509_vfy.h
+++ b/crypto/x509/x509_vfy.h
@@ -73,6 +73,10 @@
 #include <openssl/crypto.h>
 #include <openssl/symhacks.h>
 
+#ifndef OPENSSL_NO_OCSP
+#include <openssl/x509_vfy_ocsp.h>
+#endif
+
 #ifdef  __cplusplus
 extern "C" {
 #endif
@@ -206,6 +210,10 @@ struct x509_store_st
 
 	CRYPTO_EX_DATA ex_data;
 	int references;
+
+#ifndef OPENSSL_NO_OCSP
+	ocsp_process_responder_f ocsp_process_responder; /* Connect to OCSP responder */
+#endif
 	} /* X509_STORE */;
 
 int X509_STORE_set_depth(X509_STORE *store, int depth);
@@ -357,6 +365,17 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
 /* The application is not happy */
 #define		X509_V_ERR_APPLICATION_VERIFICATION		50
 
+/* OCSP related errors */
+#define		X509_V_ERR_CERT_UNKNOWN		55
+#define		X509_V_ERR_UNABLE_TO_FIND_OCSP_URL		56
+#define		X509_V_ERR_UNPARSABLE_OCSP_URL		57
+#define		X509_V_ERR_SSL_USED_FOR_OCSP		58
+#define		X509_V_ERR_OCSP_PROCESS_FUNC_NOT_SET		59
+#define		X509_V_ERR_OCSP_RESPONDER_STATUS_FAIL		60
+#define		X509_V_ERR_OCSP_NONCE_VERIFY_ERROR		61
+#define		X509_V_ERR_OCSP_RESPONSE_VERIFICATION		62
+#define		X509_V_ERR_OCSP_RESPONDER_QUERY_FAILED		63
+
 /* Certificate verify flags */
 
 /* Send issuer+subject checks to verify_cb */
@@ -389,6 +408,12 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
 #define X509_V_FLAG_USE_DELTAS			0x2000
 /* Check selfsigned CA signature */
 #define X509_V_FLAG_CHECK_SS_SIGNATURE		0x4000
+/* Check revocation against OCSP */
+#define X509_V_FLAG_OCSP_CHECK			0x8000
+/* Check revocation against OCSP for whole chain */
+#define X509_V_FLAG_OCSP_CHECK_ALL		0x10000
+/* Disable OCSP nonce */
+#define X509_V_FLAG_OCSP_NO_NONCE		0x20000
 
 
 #define X509_VP_FLAG_DEFAULT			0x1
@@ -422,6 +447,11 @@ int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm);
 void X509_STORE_set_verify_cb(X509_STORE *ctx,
 				  int (*verify_cb)(int, X509_STORE_CTX *));
 
+#ifndef OPENSSL_NO_OCSP
+void X509_STORE_set_ocsp_process_resp(X509_STORE *ctx,
+				  ocsp_process_responder_f func);
+#endif
+
 X509_STORE_CTX *X509_STORE_CTX_new(void);
 
 int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
@@ -560,6 +590,13 @@ STACK_OF(POLICYQUALINFO) *
 const X509_POLICY_NODE *
 	X509_policy_node_get0_parent(const X509_POLICY_NODE *node);
 
+#ifndef OPENSSL_NO_OCSP
+X509_CERT_OCSP *X509_CERT_OCSP_new();
+void X509_CERT_OCSP_free(X509_CERT_OCSP *ocsp);
+int X509_CERT_OCSP_set1_url(X509_CERT_OCSP *ocsp, char* url);
+int X509_CERT_OCSP_set_validate(X509_CERT_OCSP *ocsp, int validate);
+#endif
+
 #ifdef  __cplusplus
 }
 #endif
diff --git a/crypto/x509/x509_vfy_ocsp.c b/crypto/x509/x509_vfy_ocsp.c
new file mode 100644
index 0000000..9a9798a
--- /dev/null
+++ b/crypto/x509/x509_vfy_ocsp.c
@@ -0,0 +1,401 @@
+/* crypto/x509/x509_vfy_ocsp.c */
+/* Copyright (C) 2012 Altell Ltd. (komya...@altell.ru)
+ * All rights reserved.
+ *
+ * This file is a helper to incorporate OCSP check into X509
+ * certificate verification process.
+ * Written by Alexander Komyagin (komya...@altell.ru).
+ *
+ */
+
+#ifndef OPENSSL_NO_OCSP
+
+#include <openssl/crypto.h>
+#include <openssl/lhash.h>
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+#include <openssl/ocsp.h>
+#include <openssl/ssl.h>
+#include <stdio.h>
+
+#include "x509_vfy_ocsp.h"
+
+static char *get_ocsp_url(X509 *x, STACK_OF(OPENSSL_STRING) **p_aia)
+{
+	STACK_OF(OPENSSL_STRING) *aia;
+
+	// ok, reading from the cert
+	aia = X509_get1_ocsp(x);
+
+	if (aia)
+	{
+		*p_aia = aia; //thou shalt not lose the given pointer
+		return sk_OPENSSL_STRING_value(aia, 0);
+	}
+
+	return NULL;
+}
+
+int check_cert_ocsp(X509_STORE_CTX *ctx)
+{
+	X509 *x;
+	int cnum;
+	int ok = 1;
+	cnum = ctx->error_depth;
+	x = sk_X509_value(ctx->chain, cnum);
+
+	ctx->current_cert = x;
+	ctx->current_issuer = NULL;
+	ctx->current_crl_score = 0;
+	ctx->current_reasons = 0;
+	ctx->error = 0;
+
+	STACK_OF(OPENSSL_STRING) *aia = NULL;
+	char *url = NULL;
+	char *host = NULL, *port = NULL, *path = NULL;
+	int use_ssl = -1;
+	X509 *px = NULL;
+	OCSP_REQUEST *req = NULL;
+	OCSP_RESPONSE *resp = NULL;
+	OCSP_CERTID *id = NULL;
+	STACK_OF(X509_EXTENSION) *exts;
+	int i;
+	OCSP_BASICRESP *bs = NULL;
+	int status, reason;
+	ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
+	X509_STORE *store = NULL;
+
+	// Get the issuer (must be the next cert in chain)
+	// We know that the last cert in chain is not checked,
+	// so NULL must be an error
+	px = sk_X509_value(ctx->chain, cnum+1);
+	if (! px)
+	{
+		ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
+		goto err1;
+	}
+
+	// See if we got any OCSP settings requested for this CA
+	if (px->ocsp)
+	{
+		// If ocsp is disabled for issuer, pretend everything is ok
+		if (px->ocsp->ocsp_validate == X509_OCSP_VALIDATE_DISABLED)
+		{
+			ctx->error = 0;
+			goto err1;
+		}
+
+		// Check if OCSP url is forced
+		if (px->ocsp->ocsp_url)
+			url = px->ocsp->ocsp_url;
+	}
+
+	// Check for embedded URL. According to RFC2560 (sect 3.1), issuer
+	// SHALL specify it in order to use OCSP.
+	if (! url)
+		url = get_ocsp_url(x, &aia);
+
+	// Build up OCSP query from certificate
+	if (! url)
+	{
+		ctx->error = X509_V_ERR_UNABLE_TO_FIND_OCSP_URL;
+		goto err1;
+	}
+
+	if (!OCSP_parse_url(url, &host, &port, &path, &use_ssl))
+	{
+		ctx->error = X509_V_ERR_UNPARSABLE_OCSP_URL;
+		goto err1;
+	}
+
+	//FIXME: ssl connection to OCSP responder is not supported yet
+	if (use_ssl)
+	{
+		ctx->error = X509_V_ERR_SSL_USED_FOR_OCSP;
+		goto err1;
+	}
+
+	req = OCSP_REQUEST_new();
+	if (!req)
+	{
+		ctx->error = X509_V_ERR_OUT_OF_MEM;
+		goto err1;
+	}
+
+	id = OCSP_cert_to_id(NULL, x, px);
+	if (!id)
+	{
+		DBG("Failed getting OCSP cert id");
+		ctx->error = X509_V_ERR_APPLICATION_VERIFICATION;
+		goto err1;
+	}
+
+	if (!OCSP_request_add0_id(req, id))
+	{
+		DBG("Failed adding id to request");
+		OCSP_CERTID_free(id); //otherwise id seems to be freed by req
+		ctx->error = X509_V_ERR_APPLICATION_VERIFICATION;
+		goto err1;
+	}
+
+	// Query server
+	if (! (ctx->param->flags & X509_V_FLAG_OCSP_NO_NONCE))
+		OCSP_request_add1_nonce(req, NULL, -1);
+
+	// If process func is not set it means ctx hadn't come from SSL_CTX,
+	// or it's a bug
+	if (!ctx->ctx->ocsp_process_responder)
+	{
+		ctx->error = X509_V_ERR_OCSP_PROCESS_FUNC_NOT_SET;
+		goto err1;
+	}
+
+	resp = (OCSP_RESPONSE *)ctx->ctx->ocsp_process_responder((void *)req, host, path, port, use_ssl, NULL, -1);
+	if (!resp)
+	{
+		DBG("OCSP responder processing failure");
+		ctx->error = X509_V_ERR_OCSP_RESPONDER_QUERY_FAILED;
+		goto err1;
+	}
+
+	i = OCSP_response_status(resp);
+
+	if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL)
+	{
+		DBG("Responder Error: %s (%d)",
+				OCSP_response_status_str(i), i);
+		ctx->error = X509_V_ERR_OCSP_RESPONDER_STATUS_FAIL;
+		goto err1;
+	}
+
+	bs = OCSP_response_get1_basic(resp);
+	if (!bs)
+	{
+		DBG("Error parsing response");
+		ctx->error = X509_V_ERR_APPLICATION_VERIFICATION;
+		goto err1;
+	}
+
+	// Validate responder
+	store = ctx->ctx;
+	if(!store)
+	{
+		DBG("Error getting store!");
+		ctx->error = X509_V_ERR_APPLICATION_VERIFICATION;
+		goto err1;
+	}
+
+	if (! (ctx->param->flags & X509_V_FLAG_OCSP_NO_NONCE))
+	{
+		i = OCSP_check_nonce(req, bs);
+		if (i == -1)
+			DBG("WARNING: no nonce in response");
+		else if (i <= 0)
+		{
+			ctx->error = X509_V_ERR_OCSP_NONCE_VERIFY_ERROR;
+			goto err1;
+		}
+	}
+
+	i = OCSP_basic_verify(bs, NULL, store, 0);
+	if(i <= 0)
+	{
+		ctx->error = X509_V_ERR_OCSP_RESPONSE_VERIFICATION;
+		goto err1;
+	}
+	else
+		DBG("Response verify OK\n");
+
+	// Get response status
+	if(!OCSP_resp_find_status(bs, id, &status, &reason,
+					&rev, &thisupd, &nextupd))
+	{
+		DBG("ERROR: No Status found in OCSP response.");
+		ctx->error = X509_V_ERR_APPLICATION_VERIFICATION;
+		goto err1;
+	}
+
+	DBG("Status: %s", OCSP_cert_status_str(status));
+
+	switch(status)
+	{
+		case V_OCSP_CERTSTATUS_GOOD:
+			ctx->error = 0;
+			break;
+		case V_OCSP_CERTSTATUS_REVOKED:
+			ctx->error = X509_V_ERR_CERT_REVOKED;
+			break;
+		case V_OCSP_CERTSTATUS_UNKNOWN:
+		default:
+			ctx->error = X509_V_ERR_CERT_UNKNOWN;
+	}
+
+err1:
+	//call verify callback if needed
+	if (ctx->error != 0)
+		ok = ctx->verify_cb(0, ctx);
+
+	//free occupied resources
+	if (aia)
+		X509_email_free(aia);
+	if (host)
+		OPENSSL_free(host);
+	if (path)
+		OPENSSL_free(path);
+	if (port)
+		OPENSSL_free(port);
+	if (req)
+		OCSP_REQUEST_free(req);
+	if (resp)
+		OCSP_RESPONSE_free(resp);
+	if (bs)
+		OCSP_BASICRESP_free(bs);
+
+	return ok;
+}
+
+int check_revocation_ocsp(X509_STORE_CTX *ctx)
+{
+	int i, last, ok;
+
+	DBG("check_revocation_ocsp: Here");
+
+	if (!(ctx->param->flags & X509_V_FLAG_OCSP_CHECK))
+		return 1;
+
+	if (ctx->param->purpose == X509_PURPOSE_OCSP_HELPER)
+	{
+		DBG("OCSP won't verify itself ;)");
+		return 1;
+	}
+
+	// No OCSP for self-signed certs
+	if (sk_X509_num(ctx->chain) == 1)
+	{
+		DBG("Self-signed cert: OCSP won't be used");
+		return 1;
+	}
+
+	if (ctx->param->flags & X509_V_FLAG_OCSP_CHECK_ALL)
+		last = sk_X509_num(ctx->chain) - 1;
+	else
+	{
+		// If checking CRL paths this isn't the EE certificate
+		if (ctx->parent)
+			return 1;
+		last = 1;
+	}
+
+	// Note that we won't check the last cert in chain, since it makes
+	// little sense to check revocation status for the self-signed 
+	// root certificate ;)
+	for(i = 0; i < last; i++)
+	{
+		ctx->error_depth = i;
+		ok = check_cert_ocsp(ctx);
+		if (!ok) return ok;
+	}
+	return 1;
+}
+
+int X509_set_cert_ocsp_opt(X509_STORE *cert_ctx, const char *name,
+                           const char *ocsp_url, const int ocsp_validate)
+{
+	FILE *fp = NULL;
+    X509 *x = NULL;
+    int ret = 1;
+    X509_OBJECT *obj = NULL;
+
+    X509_OBJECT *obj_orig = NULL;
+    X509_CERT_OCSP *ocsp = NULL;
+    X509 *cert = NULL;
+
+	if (!cert_ctx || !name)
+	{
+		ret = 0;
+		goto err;
+	}
+
+	// check the value before it goes down the hill
+	if ((ocsp_validate != X509_OCSP_VALIDATE_ENABLED) &&
+	    (ocsp_validate != X509_OCSP_VALIDATE_DISABLED))
+	{
+		DBG("Bad ocsp_validate value");
+		ret = 0;
+		goto err;
+	}
+
+	// read cert file
+	fp = fopen(name, "r");
+	// is it PEM?
+	x = PEM_read_X509_AUX(fp, NULL, NULL, NULL);
+	if (!x)
+	{
+		// or maybe DER?
+		x = d2i_X509_fp(fp, NULL);
+	}
+
+	if (!x) //whatever...
+	{
+		DBG("Failed to parse cert %s", name);
+		ret = 0;
+		goto err;
+	}
+
+	obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
+	if (!obj)
+	{
+		DBG("Failed to allocate object");
+		ret = 0;
+		goto err;
+	}
+
+	obj->type = X509_LU_X509;
+	obj->data.x509 = x;
+
+	X509_OBJECT_up_ref_count(obj);
+
+	// try to find it in store
+	obj_orig = X509_OBJECT_retrieve_match(cert_ctx->objs, obj);
+	if (! obj_orig)
+	{
+		DBG("Can't find cert in store");
+		ret = 0;
+		goto err;
+	}
+	cert = obj_orig->data.x509;
+
+	// create ocsp struct, fill and save it
+	ocsp = X509_CERT_OCSP_new();
+	if (!ocsp)
+	{
+		DBG("Failed allocating ocsp struct");
+		ret = 0;
+		goto err;
+	}
+
+	if (! X509_CERT_OCSP_set1_url(ocsp, ocsp_url))
+	{
+		DBG("Failed setting ocsp_url");
+	}
+
+	if (! X509_CERT_OCSP_set_validate(ocsp, ocsp_validate))
+	{
+		DBG("Failed setting ocsp_validate");
+	}
+
+	ret = X509_set0_ocsp(cert, ocsp);
+
+err:
+	if(x)
+		X509_free(x);
+	if(obj)
+		OPENSSL_free(obj);
+	if(fp)
+		fclose(fp);
+
+	return ret;
+}
+#endif
diff --git a/crypto/x509/x509_vfy_ocsp.h b/crypto/x509/x509_vfy_ocsp.h
new file mode 100644
index 0000000..8a79d82
--- /dev/null
+++ b/crypto/x509/x509_vfy_ocsp.h
@@ -0,0 +1,54 @@
+/* crypto/x509/x509_vfy_ocsp.c */
+/* Copyright (C) 2012 Altell Ltd. (komya...@altell.ru)
+ * All rights reserved.
+ *
+ * This file is a helper to incorporate OCSP check into X509
+ * certificate verification process.
+ * Written by Alexander Komyagin (komya...@altell.ru).
+ * 
+ */
+
+
+#ifndef OPENSSL_NO_OCSP
+
+#ifndef HEADER_X509_VFY_OCSP_H
+#define HEADER_X509_VFY_OCSP_H
+
+#ifndef HEADER_X509_H
+#include <openssl/x509.h>
+#endif
+
+//#define OCSP_VFY_DEBUG
+
+#ifdef OCSP_VFY_DEBUG
+  #include <syslog.h>
+  #define DBG(fmt, args...) do { syslog(LOG_INFO, "%s(%d): " fmt, __FUNCTION__, __LINE__, ##args); } while(0)
+#else
+  #define DBG(fmt, args...) do { /* NOP */ } while(0)
+#endif //OCSP_VFY_DEBUG
+
+#define X509_OCSP_VALIDATE_ENABLED 	0
+#define X509_OCSP_VALIDATE_DISABLED	1
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+		
+typedef void * (*ocsp_process_responder_f)(void *,
+			char *, char *, char *, int,
+			void *,
+			int);
+
+int X509_set_cert_ocsp_opt(X509_STORE *cert_ctx, const char *name, 
+							const char *ocsp_url, const int ocsp_validate);
+
+int check_cert_ocsp(X509_STORE_CTX *ctx);
+int check_revocation_ocsp(X509_STORE_CTX *ctx);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif //HEADER_X509_VFY_OCSP_H
+
+#endif //OPENSSL_NO_OCSP
diff --git a/include/openssl/ocsp_clnt.h b/include/openssl/ocsp_clnt.h
new file mode 120000
index 0000000..137121b
--- /dev/null
+++ b/include/openssl/ocsp_clnt.h
@@ -0,0 +1 @@
+../../ssl/ocsp_clnt.h
\ No newline at end of file
diff --git a/include/openssl/x509_vfy_ocsp.h b/include/openssl/x509_vfy_ocsp.h
new file mode 120000
index 0000000..f53b4a1
--- /dev/null
+++ b/include/openssl/x509_vfy_ocsp.h
@@ -0,0 +1 @@
+../../crypto/x509/x509_vfy_ocsp.h
\ No newline at end of file
diff --git a/ssl/Makefile b/ssl/Makefile
index 07e4028..afb486c 100644
--- a/ssl/Makefile
+++ b/ssl/Makefile
@@ -30,7 +30,7 @@ LIBSRC=	\
 	ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \
 	ssl_ciph.c ssl_stat.c ssl_rsa.c \
 	ssl_asn1.c ssl_txt.c ssl_algs.c \
-	bio_ssl.c ssl_err.c kssl.c tls_srp.c t1_reneg.c
+	bio_ssl.c ssl_err.c kssl.c tls_srp.c t1_reneg.c ocsp_clnt.c
 LIBOBJ= \
 	s2_meth.o  s2_srvr.o  s2_clnt.o  s2_lib.o  s2_enc.o s2_pkt.o \
 	s3_meth.o  s3_srvr.o  s3_clnt.o  s3_lib.o  s3_enc.o s3_pkt.o s3_both.o \
@@ -41,11 +41,11 @@ LIBOBJ= \
 	ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \
 	ssl_ciph.o ssl_stat.o ssl_rsa.o \
 	ssl_asn1.o ssl_txt.o ssl_algs.o \
-	bio_ssl.o ssl_err.o kssl.o tls_srp.o t1_reneg.o
+	bio_ssl.o ssl_err.o kssl.o tls_srp.o t1_reneg.o ocsp_clnt.o
 
 SRC= $(LIBSRC)
 
-EXHEADER= ssl.h ssl2.h ssl3.h ssl23.h tls1.h dtls1.h kssl.h srtp.h
+EXHEADER= ssl.h ssl2.h ssl3.h ssl23.h tls1.h dtls1.h kssl.h srtp.h ocsp_clnt.h
 HEADER=	$(EXHEADER) ssl_locl.h kssl_lcl.h
 
 ALL=    $(GENERAL) $(SRC) $(HEADER)
diff --git a/ssl/ocsp_clnt.c b/ssl/ocsp_clnt.c
new file mode 100644
index 0000000..bb40c9a
--- /dev/null
+++ b/ssl/ocsp_clnt.c
@@ -0,0 +1,184 @@
+/* ssl/ocsp_clnt.c */
+/* Copyright (C) 2012 Altell Ltd. (komya...@altell.ru)
+ * All rights reserved.
+ *
+ * This file is a helper to incorporate OCSP proto into libssl.
+ * Written by Alexander Komyagin (komya...@altell.ru).
+ * 
+ */
+
+#ifndef OPENSSL_NO_OCSP
+ 
+#include <openssl/crypto.h>
+#include <openssl/lhash.h>
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/ocsp.h>
+#include <openssl/ssl.h>
+#include <stdio.h>
+
+#ifdef OPENSSL_SYSNAME_WIN32
+#  define openssl_fdset(a,b) FD_SET((unsigned int)a, b)
+#else
+#  define openssl_fdset(a,b) FD_SET(a, b)
+#endif
+
+static OCSP_RESPONSE *query_responder(BIO *cbio, char *path,
+				STACK_OF(CONF_VALUE) *headers,
+				OCSP_REQUEST *req, int req_timeout)
+{
+	int fd;
+	int rv;
+	int i;
+	OCSP_REQ_CTX *ctx = NULL;
+	OCSP_RESPONSE *rsp = NULL;
+	fd_set confds;
+	struct timeval tv;
+
+	if (req_timeout != -1)
+		BIO_set_nbio(cbio, 1);
+
+	rv = BIO_do_connect(cbio);
+
+	if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio)))
+	{
+		DBG("Error connecting BIO");
+		return NULL;
+	}
+
+	if (BIO_get_fd(cbio, &fd) <= 0)
+	{
+		DBG("Can't get connection fd");
+		goto err;
+	}
+
+	if (req_timeout != -1 && rv <= 0)
+	{
+		FD_ZERO(&confds);
+		openssl_fdset(fd, &confds);
+		tv.tv_usec = 0;
+		tv.tv_sec = req_timeout;
+		rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
+		if (rv == 0)
+		{
+			DBG("Timeout on connect");
+			return NULL;
+		}
+	}
+
+	ctx = OCSP_sendreq_new(cbio, path, NULL, -1);
+	if (!ctx)
+	{
+		DBG("OCSP_sendreq_new failed");
+		return NULL;
+	}
+
+	for (i = 0; i < sk_CONF_VALUE_num(headers); i++)
+	{
+		CONF_VALUE *hdr = sk_CONF_VALUE_value(headers, i);
+		if (!OCSP_REQ_CTX_add1_header(ctx, hdr->name, hdr->value))
+		{
+			DBG("OCSP_REQ_CTX_add1_header failed");
+			goto err;
+		}
+	}
+
+	if (!OCSP_REQ_CTX_set1_req(ctx, req))
+	{
+		DBG("OCSP_REQ_CTX_set1_req failed");
+		goto err;
+	}
+	
+	for (;;)
+	{
+		rv = OCSP_sendreq_nbio(&rsp, ctx);
+		if (rv != -1)
+			break;
+		if (req_timeout == -1)
+			continue;
+		FD_ZERO(&confds);
+		openssl_fdset(fd, &confds);
+		tv.tv_usec = 0;
+		tv.tv_sec = req_timeout;
+		if (BIO_should_read(cbio))
+			rv = select(fd + 1, (void *)&confds, NULL, NULL, &tv);
+		else if (BIO_should_write(cbio))
+			rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
+		else
+		{
+			DBG("Unexpected retry condition");
+			goto err;
+		}
+		if (rv == 0)
+		{
+			DBG("Timeout on request");
+			break;
+		}
+		if (rv == -1)
+		{
+			DBG("Select error");
+			break;
+		}
+
+	}
+err:
+	
+	if (ctx)
+		OCSP_REQ_CTX_free(ctx);
+
+	return rsp;
+}
+	
+void *ocsp_process_responder(void *_req,
+			char *host, char *path, char *port, int use_ssl,
+			void *_headers,
+			int req_timeout)
+{
+	BIO *cbio = NULL;
+	SSL_CTX *ctx = NULL;
+	OCSP_RESPONSE *resp = NULL;
+	OCSP_REQUEST *req = (OCSP_REQUEST *)_req;
+	STACK_OF(CONF_VALUE) *headers = (STACK_OF(CONF_VALUE) *)_headers;
+	cbio = BIO_new_connect(host);
+	if (!cbio)
+	{
+		DBG("Error creating connect BIO");
+		goto end;
+	}
+	if (port) BIO_set_conn_port(cbio, port);
+	if (use_ssl == 1)
+	{
+		BIO *sbio;
+#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
+		ctx = SSL_CTX_new(SSLv23_client_method());
+#elif !defined(OPENSSL_NO_SSL3)
+		ctx = SSL_CTX_new(SSLv3_client_method());
+#elif !defined(OPENSSL_NO_SSL2)
+		ctx = SSL_CTX_new(SSLv2_client_method());
+#else
+		DBG("SSL is disabled");
+		goto end;
+#endif
+		if (ctx == NULL)
+		{
+			DBG("Error creating SSL context");
+			goto end;
+		}
+		SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
+		sbio = BIO_new_ssl(ctx, 1);
+		cbio = BIO_push(sbio, cbio);
+	}
+	resp = query_responder(cbio, path, headers, req, req_timeout);
+	if (!resp)
+		DBG("Error querying OCSP responsder");
+
+end:
+	if (cbio)
+		BIO_free_all(cbio);
+	if (ctx)
+		SSL_CTX_free(ctx);
+	return (void *)resp;
+}
+
+#endif
diff --git a/ssl/ocsp_clnt.h b/ssl/ocsp_clnt.h
new file mode 100644
index 0000000..46f2f1e
--- /dev/null
+++ b/ssl/ocsp_clnt.h
@@ -0,0 +1,46 @@
+/* ssl/ocsp_clnt.h */
+/* Copyright (C) 2012 Altell Ltd. (komya...@altell.ru)
+ * All rights reserved.
+ *
+ * This file is a helper to incorporate OCSP check into X509
+ * certificate verification process.
+ * Written by Alexander Komyagin (komya...@altell.ru).
+ * 
+ */
+
+
+#ifndef OPENSSL_NO_OCSP
+
+#ifndef HEADER_OCSP_CLNT_H
+#define HEADER_OCSP_CLNT_H
+
+#ifndef HEADER_X509_H
+#include <openssl/x509.h>
+#endif
+
+#include <openssl/ocsp.h>
+#include <openssl/x509_vfy_ocsp.h>
+
+#ifdef OCSP_VFY_DEBUG
+  #include <syslog.h>
+  #define DBG(fmt, args...) do { syslog(LOG_INFO, "%s(%d): " fmt, __FUNCTION__, __LINE__, ##args); } while(0)
+#else
+  #define DBG(fmt, args...) do { /* NOP */ } while(0)
+#endif //OCSP_VFY_DEBUG
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+void *ocsp_process_responder(void *_req,
+			char *host, char *path, char *port, int use_ssl,
+			void *_headers,
+			int req_timeout);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif //HEADER_OCSP_CLNT_H
+
+#endif //OPENSSL_NO_OCSP
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index f82d071..4808f62 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -160,6 +160,10 @@
 #include <openssl/engine.h>
 #endif
 
+#ifndef OPENSSL_NO_OCSP
+#include <openssl/ocsp_clnt.h>
+#endif
+
 const char *SSL_version_str=OPENSSL_VERSION_TEXT;
 
 SSL3_ENC_METHOD ssl3_undef_enc_method={
@@ -1758,6 +1762,9 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
 	if (ret->sessions == NULL) goto err;
 	ret->cert_store=X509_STORE_new();
 	if (ret->cert_store == NULL) goto err;
+#ifndef OPENSSL_NO_OCSP
+	X509_STORE_set_ocsp_process_resp(ret->cert_store, &ocsp_process_responder);
+#endif
 
 	ssl_create_cipher_list(ret->method,
 		&ret->cipher_list,&ret->cipher_list_by_id,

Reply via email to