ASF Bugzilla – Attachment 22272 Details for
Bug 45392
No OCSP support for client SSL verification
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
OCSP support for apache tomcat
tomcat-native-ocsp-0.2-0.diff (text/plain), 20.21 KB, created by
Aristotelis
on 2008-07-17 07:52:26 UTC
(
hide
)
Description:
OCSP support for apache tomcat
Filename:
MIME Type:
Creator:
Aristotelis
Created:
2008-07-17 07:52:26 UTC
Size:
20.21 KB
patch
obsolete
>diff -r a5ecf12b8f1e jni/native/build-outputs.mk >--- a/jni/native/build-outputs.mk Mon Jul 14 16:50:56 2008 +0300 >+++ b/jni/native/build-outputs.mk Thu Jul 17 17:49:22 2008 +0300 >@@ -1,5 +1,6 @@ > # DO NOT EDIT. AUTOMATICALLY GENERATED. > >+src/ocsp_sock.lo: src/ocsp_sock.c .make.dirs include/ocsp_sock.h > src/proc.lo: src/proc.c .make.dirs include/tcn.h include/tcn_api.h > src/poll.lo: src/poll.c .make.dirs include/tcn.h include/tcn_api.h > src/ssl.lo: src/ssl.c .make.dirs include/tcn.h include/tcn_api.h include/ssl_private.h >@@ -26,7 +27,7 @@ src/os.lo: src/os.c .make.dirs include/t > src/os.lo: src/os.c .make.dirs include/tcn.h include/tcn_api.h > src/pool.lo: src/pool.c .make.dirs include/tcn.h include/tcn_api.h > >-OBJECTS_all = src/proc.lo src/poll.lo src/ssl.lo src/sslutils.lo src/thread.lo src/dir.lo src/network.lo src/sslinfo.lo src/stdlib.lo src/multicast.lo src/error.lo src/lock.lo src/file.lo src/sslcontext.lo src/jnilib.lo src/info.lo src/mmap.lo src/shm.lo src/user.lo src/address.lo src/misc.lo src/bb.lo src/sslnetwork.lo src/os.lo src/pool.lo >+OBJECTS_all = src/ocsp_sock src/proc.lo src/poll.lo src/ssl.lo src/sslutils.lo src/thread.lo src/dir.lo src/network.lo src/sslinfo.lo src/stdlib.lo src/multicast.lo src/error.lo src/lock.lo src/file.lo src/sslcontext.lo src/jnilib.lo src/info.lo src/mmap.lo src/shm.lo src/user.lo src/address.lo src/misc.lo src/bb.lo src/sslnetwork.lo src/os.lo src/pool.lo > > os/unix/system.lo: os/unix/system.c .make.dirs include/tcn.h include/tcn_api.h > os/unix/uxpipe.lo: os/unix/uxpipe.c .make.dirs include/tcn.h include/tcn_api.h >diff -r a5ecf12b8f1e jni/native/include/ocsp_sock.h >--- /dev/null Thu Jan 01 00:00:00 1970 +0000 >+++ b/jni/native/include/ocsp_sock.h Thu Jul 17 17:49:22 2008 +0300 >@@ -0,0 +1,22 @@ >+/* Licensed to the Apache Software Foundation (ASF) under one or more >+ * contributor license agreements. See the NOTICE file distributed with >+ * this work for additional information regarding copyright ownership. >+ * The ASF licenses this file to You under the Apache License, Version 2.0 >+ * (the "License"); you may not use this file except in compliance with >+ * the License. You may obtain a copy of the License at >+ * >+ * http://www.apache.org/licenses/LICENSE-2.0 >+ * >+ * Unless required by applicable law or agreed to in writing, software >+ * distributed under the License is distributed on an "AS IS" BASIS, >+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+ * See the License for the specific language governing permissions and >+ * limitations under the License. >+ */ >+ >+#define OCSP_STATUS_OK 0 >+#define OCSP_STATUS_REVOKED 1 >+#define OCSP_STATUS_UNKNOWN 2 >+ >+ >+int ocspRequest(X509 *cert, X509 *issuer); >diff -r a5ecf12b8f1e jni/native/src/ocsp_sock.c >--- /dev/null Thu Jan 01 00:00:00 1970 +0000 >+++ b/jni/native/src/ocsp_sock.c Thu Jul 17 17:49:22 2008 +0300 >@@ -0,0 +1,513 @@ >+/* Licensed to the Apache Software Foundation (ASF) under one or more >+ * contributor license agreements. See the NOTICE file distributed with >+ * this work for additional information regarding copyright ownership. >+ * The ASF licenses this file to You under the Apache License, Version 2.0 >+ * (the "License"); you may not use this file except in compliance with >+ * the License. You may obtain a copy of the License at >+ * >+ * http://www.apache.org/licenses/LICENSE-2.0 >+ * >+ * Unless required by applicable law or agreed to in writing, software >+ * distributed under the License is distributed on an "AS IS" BASIS, >+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+ * See the License for the specific language governing permissions and >+ * limitations under the License. >+ */ >+ >+#include <stdio.h> >+#include <stdlib.h> >+#include <string.h> >+ >+#include <openssl/bio.h> >+#include <openssl/ocsp.h> >+#include <openssl/err.h> >+ >+#include "apr_network_io.h" >+ >+#include "ocsp_sock.h" >+ >+/* defines with the values as seen by the asn1parse -dump openssl command */ >+#define ASN1_SEQUENCE 0x30 >+#define ASN1_OID 0x06 >+#define ASN1_STRING 0x86 >+ >+ >+ >+/* Helps with error handling or realloc */ >+static void *xrealloc(void *buf, size_t len) >+{ >+ void *newp; >+ if((newp = realloc(buf, len)) == NULL) { >+ free(buf); >+ return NULL; >+ } >+ return newp; >+} >+ >+/* parses the ocsp url and updates the ocsp_urls and nocsp_urls variables >+ returns 0 on success, 1 on failure */ >+static int parse_ocsp_url(unsigned char *asn1, char ***ocsp_urls, int *nocsp_urls) >+{ >+ char **new_ocsp_urls, *ocsp_url; >+ int len, err = 0, new_nocsp_urls; >+ if(*asn1 == ASN1_STRING) { >+ len = *++asn1; >+ asn1++; >+ new_nocsp_urls = *nocsp_urls+1; >+ if((new_ocsp_urls = realloc(*ocsp_urls,new_nocsp_urls)) == NULL) >+ err = 1; >+ if(!err) { >+ *ocsp_urls = new_ocsp_urls; >+ *nocsp_urls = new_nocsp_urls; >+ *(*ocsp_urls + *nocsp_urls) = NULL; >+ if((ocsp_url = malloc((len+1)*sizeof(char))) == NULL) >+ err = 1; >+ else { >+ memcpy(ocsp_url, asn1, len); >+ *(ocsp_url+len) = '\0'; >+ *(*ocsp_urls + *nocsp_urls -1 ) = ocsp_url; >+ } >+ } >+ } >+ return err; >+ >+} >+ >+/* parses the ANS1 OID and if it is an OCSP OID then calls the parse_ocsp_url function */ >+static int parse_ASN1_OID(unsigned char *asn1, char ***ocsp_urls, int *nocsp_urls) >+{ >+ int len, err = 0 ; >+ const unsigned char OCSP_OID[] = {0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01}; >+ >+ len = *++asn1; >+ asn1++; >+ if(memcmp(asn1, OCSP_OID, len) == 0 ) { >+ asn1+=len; >+ err = parse_ocsp_url(asn1, ocsp_urls, nocsp_urls); >+ } >+ return err; >+} >+ >+ >+/* Parses an ASN1 Sequence. It is a recursive function, since if it finds a sequence >+ within the sequence it calls recursively itself. This function stops when it finds >+ the end of the ASN1 sequence (marked by '\0'), so if there are other sequences within >+ the same sequence the while loop parses the sequences */ >+ >+/* This algo was developped with AIA in mind so it was tested only with this extension */ >+static int parse_ASN1_Sequence(unsigned char *asn1, char ***ocsp_urls, int *nocsp_urls) >+{ >+ int len, err = 0; >+ while( !err && *asn1 != '\0') { >+ switch(*asn1) { >+ case ASN1_SEQUENCE: >+ len = *++asn1; >+ asn1++; >+ err = parse_ASN1_Sequence(asn1, ocsp_urls, nocsp_urls); >+ break; >+ case ASN1_OID: >+ err = parse_ASN1_OID(asn1,ocsp_urls,nocsp_urls); >+ return 0; >+ break; >+ default: >+ err = 1; /* we shouldn't have any errors */ >+ break; >+ } >+ asn1+=len; >+ } >+ return err; >+} >+ >+/* the main function that gets the ASN1 encoding string and returns >+ a pointer to a NULL terminated "array" of char *, that contains >+ the ocsp_urls */ >+static char **decode_OCSP_url(ASN1_OCTET_STRING *os) >+{ >+ char **response = NULL; >+ unsigned char *ocsp_urls; >+ int i, len, err = 0, numofresponses = 0 ; >+ >+ len = ASN1_STRING_length(os); >+ >+ ocsp_urls = malloc((size_t)(len+1)*sizeof(char)); >+ memcpy(ocsp_urls,os->data, (size_t) len); >+ ocsp_urls[len] = '\0'; >+ >+ if ((response = malloc(sizeof(char *))) == NULL) >+ return NULL; >+ *response = NULL; >+ >+ err = parse_ASN1_Sequence(ocsp_urls, &response, &numofresponses); >+ if (err) { >+ for(i = 0 ; i < numofresponses ; i++) >+ free(response[i]); >+ free(response); >+ response = NULL; >+ } >+ >+ free(ocsp_urls); >+ return response; >+} >+ >+ >+ >+/* stolen from openssl ocsp command */ >+static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer, >+ STACK_OF(OCSP_CERTID) *ids) >+{ >+ OCSP_CERTID *id; >+ if(!issuer) >+ return 0; >+ if(!*req) *req = OCSP_REQUEST_new(); >+ if(!*req) goto err; >+ id = OCSP_cert_to_id(NULL, cert, issuer); >+ if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err; >+ if(!OCSP_request_add0_id(*req, id)) goto err; >+ return 1; >+ >+err: >+ return 0; >+} >+ >+ >+/* Creates the APR socket and connect to the hostname. Returns the >+ socket or NULL if there is an error. >+*/ >+static apr_socket_t *make_socket(char *hostname, int port, apr_pool_t *mp) >+{ >+ int r = 0; >+ apr_sockaddr_t *sa_in; >+ apr_status_t status; >+ apr_socket_t *sock = NULL; >+ >+ >+ status = apr_sockaddr_info_get(&sa_in, hostname, APR_INET, port, 0, mp); >+ >+ if(status == APR_SUCCESS) >+ status = apr_socket_create(&sock, sa_in->family, SOCK_STREAM, APR_PROTO_TCP, mp); >+ if(status == APR_SUCCESS) >+ status = apr_socket_connect(sock, sa_in); >+ >+ if(status == APR_SUCCESS) >+ return sock; >+ return NULL; >+ >+} >+ >+ >+/* Creates the request in a memory BIO in order to send it to the OCSP server. >+ Most parts of this function are taken from mod_ssl support for OCSP (with some >+ minor modifications >+*/ >+static BIO *serialize_request(OCSP_REQUEST *req, char *host, int port, char *path) >+{ >+ BIO *bio; >+ int len; >+ >+ len = i2d_OCSP_REQUEST(req, NULL); >+ >+ bio = BIO_new(BIO_s_mem()); >+ >+ BIO_printf(bio, "POST %s HTTP/1.0\r\n" >+ "Host: %s:%d\r\n" >+ "Content-Type: application/ocsp-request\r\n" >+ "Content-Length: %d\r\n" >+ "\r\n", >+ path, host, port, len); >+ >+ if (i2d_OCSP_REQUEST_bio(bio, req) != 1) { >+ BIO_free(bio); >+ return NULL; >+ } >+ >+ return bio; >+} >+ >+ >+/* Send the OCSP request to the OCSP server. Taken from mod_ssl OCSP support */ >+#define HUGE_STRING_LENGTH 8192 >+static int ocsp_send_req(apr_socket_t *sock, BIO *req) >+{ >+ int len; >+ char buf[HUGE_STRING_LENGTH]; >+ apr_status_t rv; >+ int ok = 1; >+ >+ while ((len = BIO_read(req, buf, sizeof buf)) > 0) { >+ char *wbuf = buf; >+ apr_size_t remain = len; >+ >+ do { >+ apr_size_t wlen = remain; >+ rv = apr_socket_send(sock, wbuf, &wlen); >+ wbuf += remain; >+ remain -= wlen; >+ } while (rv == APR_SUCCESS && remain > 0); >+ >+ if (rv != APR_SUCCESS) { >+ apr_socket_close(sock); >+ ok = 0; >+ } >+ } >+ >+ return ok; >+} >+ >+ >+ >+/* Parses the buffer from the response and extracts the OCSP response. >+ Taken from openssl library */ >+static OCSP_RESPONSE *parse_ocsp_resp(char *buf, int len) >+{ >+ BIO *mem = NULL; >+ char tmpbuf[1024]; >+ OCSP_RESPONSE *resp = NULL; >+ char *p, *q, *r; >+ int retcode; >+ >+ mem = BIO_new(BIO_s_mem()); >+ if(mem == NULL) >+ return NULL; >+ >+ BIO_write(mem, buf, len); /* write the buffer to the bio */ >+ if(BIO_gets(mem, tmpbuf, 512) <= 0) { >+ OCSPerr(OCSP_F_OCSP_SENDREQ_BIO,OCSP_R_SERVER_RESPONSE_PARSE_ERROR); >+ goto err; >+ } >+ /* Parse the HTTP response. This will look like this: >+ * "HTTP/1.0 200 OK". We need to obtain the numeric code and >+ * (optional) informational message. >+ */ >+ >+ /* Skip to first white space (passed protocol info) */ >+ for(p = tmpbuf; *p && !isspace((unsigned char)*p); p++) continue; >+ if(!*p) { >+ goto err; >+ } >+ /* Skip past white space to start of response code */ >+ while(isspace((unsigned char)*p)) p++; >+ if(!*p) { >+ goto err; >+ } >+ /* Find end of response code: first whitespace after start of code */ >+ for(q = p; *q && !isspace((unsigned char)*q); q++) continue; >+ if(!*q) { >+ goto err; >+ } >+ /* Set end of response code and start of message */ >+ *q++ = 0; >+ /* Attempt to parse numeric code */ >+ retcode = strtoul(p, &r, 10); >+ if(*r) goto err; >+ /* Skip over any leading white space in message */ >+ while(isspace((unsigned char)*q)) q++; >+ if(*q) { >+ /* Finally zap any trailing white space in message (include CRLF) */ >+ /* We know q has a non white space character so this is OK */ >+ for(r = q + strlen(q) - 1; isspace((unsigned char)*r); r--) *r = 0; >+ } >+ if(retcode != 200) { >+ goto err; >+ } >+ /* Find blank line marking beginning of content */ >+ while(BIO_gets(mem, tmpbuf, 512) > 0) >+ { >+ for(p = tmpbuf; isspace((unsigned char)*p); p++) continue; >+ if(!*p) break; >+ } >+ if(*p) { >+ goto err; >+ } >+ if(!(resp = d2i_OCSP_RESPONSE_bio(mem, NULL))) { >+ goto err; >+ } >+err: >+ BIO_free(mem); >+ return resp; >+ >+ >+} >+ >+ >+/* Reads the respnse from the APR socket to a buffer, and parses the buffer to >+ return the OCSP response */ >+#define ADDLEN 512 >+static OCSP_RESPONSE *ocsp_get_resp(apr_socket_t *sock) >+{ >+ int buflen = 0, totalread = 0, readlen; >+ char *buf, tmpbuf[ADDLEN]; >+ apr_status_t rv = APR_SUCCESS; >+ >+ OCSP_RESPONSE *resp; >+ >+ buflen = ADDLEN; >+ buf = malloc(buflen); >+ if(buf == NULL) >+ return NULL; >+ >+ while(rv == APR_SUCCESS ) { >+ readlen = sizeof(tmpbuf); >+ rv = apr_socket_recv(sock, tmpbuf, &readlen); >+ if(rv == APR_SUCCESS) { /* if we have read something .. we can put it in the buffer*/ >+ if((totalread + readlen) >= buflen) { >+ buflen+=ADDLEN; /* if needed we enlarge the buffer */ >+ buf = xrealloc(buf,buflen); >+ if (buf == NULL) { >+ return NULL; >+ } >+ } >+ memcpy(buf+totalread, tmpbuf, readlen); /* the copy to the buffer */ >+ totalread+=readlen; /* update the total bytes read */ >+ } >+ else { >+ if (rv == APR_EOF && readlen == 0 ) >+ ; /* EOF, normal situation */ >+ else if ( readlen == 0 ) { >+ /* Not success, and readlen == 0 .. some error */ >+ free(buf); >+ return NULL; >+ } >+ } >+ } >+ >+ >+ resp = parse_ocsp_resp(buf, buflen); >+ >+ free(buf); >+ >+ return resp; >+} >+ >+/* Creates and OCSP request and returns the OCSP_RESPONSE */ >+static OCSP_RESPONSE *get_ocsp_response(X509 *cert, X509 *issuer, char *url) >+{ >+ OCSP_RESPONSE *ocsp_resp; >+ OCSP_REQUEST *ocsp_req; >+ BIO *bio_req; >+ char *hostname, *path, *c_port; >+ int port, use_ssl; >+ STACK_OF(OCSP_CERTID) *ids = NULL; >+ int ok = 0; >+ >+ apr_socket_t *apr_sock=NULL; >+ >+ apr_pool_t *mp; >+ >+ apr_pool_create(&mp, NULL); >+ >+ ids = sk_OCSP_CERTID_new_null(); >+ >+ /* problem parsing the URL */ >+ if(OCSP_parse_url(url,&hostname, &c_port, &path, &use_ssl) == 0 ) { >+ sk_OCP_CERTID_free(ids); >+ return NULL; >+ } >+ >+ /* Create the OCSP request */ >+ if(sscanf(c_port, "%d", &port) != 1) >+ goto end; >+ ocsp_req = OCSP_REQUEST_new(); >+ if(ocsp_req == NULL) >+ return NULL; >+ if(add_ocsp_cert(&ocsp_req,cert,issuer,ids) == 0 ) >+ goto free_req; >+ >+ /* create the BIO with the request to send */ >+ bio_req = serialize_request(ocsp_req, hostname, port, path); >+ if(bio_req == NULL) { >+ goto free_req; >+ } >+ >+ apr_sock = make_socket(hostname, port, mp); >+ if (apr_sock == NULL) { >+ ocsp_resp = NULL; >+ goto free_bio; >+ } >+ >+ ok = ocsp_send_req(apr_sock, bio_req); >+ if(ok) >+ ocsp_resp = ocsp_get_resp(apr_sock); >+ >+free_bio: >+ BIO_free(bio_req); >+ >+free_req: >+ if(apr_sock) >+ apr_socket_close(apr_sock); >+ >+ apr_pool_destroy(mp); >+ >+ sk_OCSP_CERTID_free(ids); >+ OCSP_REQUEST_free(ocsp_req); >+ >+end: >+ return ocsp_resp; >+} >+ >+/* Process the OCSP_RESPONSE and returns the corresponding >+ answert according to the status. >+*/ >+static int processOCSPResponse(OCSP_RESPONSE *ocsp_resp) >+{ >+ int r, o = V_OCSP_CERTSTATUS_UNKNOWN, i; >+ OCSP_BASICRESP *bs; >+ OCSP_SINGLERESP *ss; >+ >+ r = OCSP_response_status(ocsp_resp); >+ >+ if(r != OCSP_RESPONSE_STATUS_SUCCESSFUL) { >+ OCSP_RESPONSE_free(ocsp_resp); >+ return OCSP_STATUS_UNKNOWN; >+ } >+ bs = OCSP_response_get1_basic(ocsp_resp); >+ >+ ss = OCSP_resp_get0(bs,0); /* we know we have only 1 request */ >+ >+ i = OCSP_single_get0_status(ss, NULL, NULL, NULL, NULL); >+ if ( i == V_OCSP_CERTSTATUS_GOOD ) >+ o = OCSP_STATUS_OK; >+ else if ( i == V_OCSP_CERTSTATUS_REVOKED ) >+ o = OCSP_STATUS_REVOKED; >+ else if ( i == V_OCSP_CERTSTATUS_UNKNOWN) >+ o = OCSP_STATUS_UNKNOWN; >+ >+ /* we clean up */ >+ OCSP_RESPONSE_free(ocsp_resp); >+ >+ return o; >+} >+ >+ >+int ocspRequest(X509 *cert, X509 *issuer) >+{ >+ char **ocsp_urls = NULL; >+ int nid, i; >+ X509_EXTENSION *ext; >+ ASN1_OCTET_STRING *os; >+ >+ /* Get the proper extension */ >+ nid = X509_get_ext_by_NID(cert,NID_info_access,-1); >+ if(nid >= 0 ) { >+ ext = X509_get_ext(cert,nid); >+ os = X509_EXTENSION_get_data(ext); >+ >+ ocsp_urls = decode_OCSP_url(os); >+ } >+ >+ /* if we find the extensions and we can parse it check >+ the ocsp status. Otherwise, return OCSP_STATUS_UNKNOWN */ >+ if(ocsp_urls != NULL) { >+ OCSP_RESPONSE *resp; >+ /* for the time being just check for the fist response .. a better >+ approach is to iterate for all the possible ocsp urls */ >+ resp = get_ocsp_response(cert, issuer, ocsp_urls[0]); >+ >+ /* memory clean up */ >+ for(i = 0 ; ocsp_urls[i] != NULL ; i++ ) >+ free(ocsp_urls[i]); >+ free(ocsp_urls); >+ if(resp != NULL) >+ return processOCSPResponse(resp); >+ } >+ return OCSP_STATUS_UNKNOWN; >+} >diff -r a5ecf12b8f1e jni/native/src/sslutils.c >--- a/jni/native/src/sslutils.c Mon Jul 14 16:50:56 2008 +0300 >+++ b/jni/native/src/sslutils.c Thu Jul 17 17:49:22 2008 +0300 >@@ -31,6 +31,7 @@ extern int WIN32_SSL_password_prompt(tcn > extern int WIN32_SSL_password_prompt(tcn_pass_cb_t *data); > #endif > >+#include "ocsp_sock.h" > /* _________________________________________________________________ > ** > ** Additional High-Level Functions for OpenSSL >@@ -621,6 +622,8 @@ static int ssl_verify_CRL(int ok, X509_S > * This OpenSSL callback function is called when OpenSSL > * does client authentication and verifies the certificate chain. > */ >+ >+ > int SSL_callback_SSL_verify(int ok, X509_STORE_CTX *ctx) > { > /* Get Apache context back through OpenSSL context */ >@@ -632,6 +635,8 @@ int SSL_callback_SSL_verify(int ok, X509 > int errdepth = X509_STORE_CTX_get_error_depth(ctx); > int verify = con->ctx->verify_mode; > int depth = con->ctx->verify_depth; >+ int ocsp_response; >+ int skip_crl = 0; > > if (verify == SSL_CVERIFY_UNSET || > verify == SSL_CVERIFY_NONE) >@@ -642,10 +647,24 @@ int SSL_callback_SSL_verify(int ok, X509 > ok = 1; > SSL_set_verify_result(ssl, X509_V_OK); > } >+ >+ /* First perform OCSP validation if possible */ >+ if(ok) { >+ ocsp_response = ssl_verify_OCSP(ok, ctx); >+ if (ocsp_response == OCSP_STATUS_OK ) { >+ skip_crl = 1; /* we know it is valid we skip crl evaluation */ >+ } >+ else if(ocsp_response == OCSP_STATUS_REVOKED ) { >+ ok = 0 ; >+ errnum = X509_STORE_CTX_get_error(ctx); >+ } >+ else if (ocsp_response == OCSP_STATUS_UNKNOWN) >+ ; /* do nothing for time being, continue with CRL */ >+ } > /* > * Additionally perform CRL-based revocation checks > */ >- if (ok && con->ctx->crl) { >+ if (ok && con->ctx->crl && !skip_crl) { > if (!(ok = ssl_verify_CRL(ok, ctx, con))) { > errnum = X509_STORE_CTX_get_error(ctx); > /* TODO: Log something */ >@@ -672,4 +691,32 @@ int SSL_callback_SSL_verify(int ok, X509 > return ok; > } > >+ >+/* Function that is used to do the OCSP verification */ >+int ssl_verify_OCSP(int ok, X509_STORE_CTX *ctx) >+{ >+ X509 *cert, *issuer; >+ int r, o; >+ >+ cert = X509_STORE_CTX_get_current_cert(ctx); >+ >+ o = X509_STORE_CTX_get1_issuer(&issuer, ctx, cert); >+ /* if we can't get the issuer, we cannot perform OCSP verification */ >+ if( o == 1 ) { >+ r = ocspRequest(cert, issuer); >+ if (r == OCSP_STATUS_REVOKED ) >+/* we set the error if we know that it is revoked */ >+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED); >+ else >+ r = OCSP_STATUS_UNKNOWN; /* else we return unknown, so that we can continue with the crl */ >+ X509_free(issuer); /* It appears that we should free issuer since >+ X509_STORE_CTX_get1_issuer() calls X509_OBJECT_up_ref_count() >+ on the issuer object (unline X509_STORE_CTX_get_current_cert() >+ that just returns the pointer */ >+ >+ } >+ >+ return r; >+} >+ > #endif
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 45392
:
22251
|
22252
|
22253
|
22272
|
22594
|
22611