View | Details | Raw Unified | Return to bug 45392
Collapse All | Expand All

(-)a/jni/native/build-outputs.mk (-1 / +2 lines)
Lines 1-5 Link Here
1
# DO NOT EDIT. AUTOMATICALLY GENERATED.
1
# DO NOT EDIT. AUTOMATICALLY GENERATED.
2
2
3
src/ocsp_sock.lo: src/ocsp_sock.c .make.dirs include/ocsp_sock.h
3
src/proc.lo: src/proc.c .make.dirs include/tcn.h include/tcn_api.h
4
src/proc.lo: src/proc.c .make.dirs include/tcn.h include/tcn_api.h
4
src/poll.lo: src/poll.c .make.dirs include/tcn.h include/tcn_api.h
5
src/poll.lo: src/poll.c .make.dirs include/tcn.h include/tcn_api.h
5
src/ssl.lo: src/ssl.c .make.dirs include/tcn.h include/tcn_api.h include/ssl_private.h
6
src/ssl.lo: src/ssl.c .make.dirs include/tcn.h include/tcn_api.h include/ssl_private.h
Lines 26-32 src/os.lo: src/os.c .make.dirs include/t Link Here
26
src/os.lo: src/os.c .make.dirs include/tcn.h include/tcn_api.h
27
src/os.lo: src/os.c .make.dirs include/tcn.h include/tcn_api.h
27
src/pool.lo: src/pool.c .make.dirs include/tcn.h include/tcn_api.h
28
src/pool.lo: src/pool.c .make.dirs include/tcn.h include/tcn_api.h
28
29
29
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
30
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
30
31
31
os/unix/system.lo: os/unix/system.c .make.dirs include/tcn.h include/tcn_api.h
32
os/unix/system.lo: os/unix/system.c .make.dirs include/tcn.h include/tcn_api.h
32
os/unix/uxpipe.lo: os/unix/uxpipe.c .make.dirs include/tcn.h include/tcn_api.h
33
os/unix/uxpipe.lo: os/unix/uxpipe.c .make.dirs include/tcn.h include/tcn_api.h
(-)a5ecf12b8f1e (+22 lines)
Added Link Here
1
/* Licensed to the Apache Software Foundation (ASF) under one or more
2
 * contributor license agreements.  See the NOTICE file distributed with
3
 * this work for additional information regarding copyright ownership.
4
 * The ASF licenses this file to You under the Apache License, Version 2.0
5
 * (the "License"); you may not use this file except in compliance with
6
 * the License.  You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
17
#define OCSP_STATUS_OK        0
18
#define OCSP_STATUS_REVOKED   1
19
#define OCSP_STATUS_UNKNOWN   2
20
21
22
int ocspRequest(X509 *cert, X509 *issuer);
(-)a5ecf12b8f1e (+513 lines)
Added Link Here
1
/* Licensed to the Apache Software Foundation (ASF) under one or more
2
 * contributor license agreements.  See the NOTICE file distributed with
3
 * this work for additional information regarding copyright ownership.
4
 * The ASF licenses this file to You under the Apache License, Version 2.0
5
 * (the "License"); you may not use this file except in compliance with
6
 * the License.  You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
17
#include <stdio.h>
18
#include <stdlib.h>
19
#include <string.h>
20
21
#include <openssl/bio.h>
22
#include <openssl/ocsp.h>
23
#include <openssl/err.h>
24
25
#include "apr_network_io.h"
26
27
#include "ocsp_sock.h"
28
29
/* defines with the values as seen by the asn1parse -dump openssl command */
30
#define ASN1_SEQUENCE 0x30
31
#define ASN1_OID      0x06
32
#define ASN1_STRING   0x86
33
34
35
36
/* Helps with error handling or realloc */
37
static void *xrealloc(void *buf, size_t len)
38
{
39
    void *newp;
40
    if((newp = realloc(buf, len)) == NULL) {
41
        free(buf);
42
        return NULL;
43
    }
44
    return newp;
45
}
46
47
/* parses the ocsp url and updates the ocsp_urls and nocsp_urls variables 
48
   returns 0 on success, 1 on failure */
49
static int parse_ocsp_url(unsigned char *asn1, char ***ocsp_urls, int *nocsp_urls)
50
{
51
    char **new_ocsp_urls, *ocsp_url;
52
    int len, err = 0, new_nocsp_urls;
53
    if(*asn1 == ASN1_STRING) {
54
        len = *++asn1;
55
        asn1++;
56
        new_nocsp_urls = *nocsp_urls+1;
57
        if((new_ocsp_urls = realloc(*ocsp_urls,new_nocsp_urls)) == NULL) 
58
            err = 1;
59
        if(!err) {
60
            *ocsp_urls = new_ocsp_urls;
61
            *nocsp_urls = new_nocsp_urls;
62
            *(*ocsp_urls + *nocsp_urls) = NULL;
63
            if((ocsp_url = malloc((len+1)*sizeof(char))) == NULL)
64
                err = 1;
65
            else {
66
                memcpy(ocsp_url, asn1, len);
67
                *(ocsp_url+len) = '\0';
68
                *(*ocsp_urls + *nocsp_urls -1 ) = ocsp_url;
69
            }
70
        }
71
    }
72
    return err;
73
74
}
75
76
/* parses the ANS1 OID and if it is an OCSP OID then calls the parse_ocsp_url function */
77
static int parse_ASN1_OID(unsigned char *asn1, char ***ocsp_urls, int *nocsp_urls)
78
{
79
    int len, err = 0 ;
80
    const unsigned char OCSP_OID[] = {0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01};
81
82
    len = *++asn1;
83
    asn1++;
84
    if(memcmp(asn1, OCSP_OID, len) == 0 ) {
85
        asn1+=len;
86
        err = parse_ocsp_url(asn1, ocsp_urls, nocsp_urls);
87
    }
88
    return err;
89
}
90
91
92
/* Parses an ASN1 Sequence. It is a recursive function, since if it finds a  sequence
93
   within the sequence it calls recursively itself. This function stops when it finds 
94
   the end of the ASN1 sequence (marked by '\0'), so if there are other sequences within
95
   the same sequence the while loop parses the sequences */
96
97
/* This algo was developped with AIA in mind so it was tested only with this extension */
98
static int parse_ASN1_Sequence(unsigned char *asn1, char ***ocsp_urls, int *nocsp_urls)
99
{
100
    int len, err = 0;
101
    while( !err && *asn1 != '\0') {
102
        switch(*asn1) {
103
        case ASN1_SEQUENCE:
104
            len = *++asn1;
105
            asn1++;
106
            err = parse_ASN1_Sequence(asn1, ocsp_urls, nocsp_urls);
107
            break;
108
        case ASN1_OID:
109
            err = parse_ASN1_OID(asn1,ocsp_urls,nocsp_urls);
110
            return 0;
111
            break;
112
        default:
113
            err = 1; /* we shouldn't have any errors */
114
            break;
115
        }
116
        asn1+=len;
117
    }
118
    return err;
119
}
120
121
/* the main function that gets the ASN1 encoding string and returns
122
   a pointer to a NULL terminated "array" of char *, that contains
123
   the ocsp_urls */
124
static char **decode_OCSP_url(ASN1_OCTET_STRING *os)
125
{
126
    char **response = NULL;
127
    unsigned char *ocsp_urls;
128
    int i, len, err = 0, numofresponses = 0 ;
129
130
    len = ASN1_STRING_length(os);
131
132
    ocsp_urls = malloc((size_t)(len+1)*sizeof(char));
133
    memcpy(ocsp_urls,os->data, (size_t) len);
134
    ocsp_urls[len] = '\0';
135
136
    if ((response = malloc(sizeof(char *))) == NULL)
137
        return NULL;
138
    *response = NULL;
139
140
    err = parse_ASN1_Sequence(ocsp_urls, &response, &numofresponses);
141
    if (err) {
142
        for(i = 0 ; i < numofresponses ; i++)
143
            free(response[i]);
144
        free(response);
145
        response = NULL;
146
    }
147
148
    free(ocsp_urls);
149
    return response;
150
}
151
152
153
154
/* stolen from openssl ocsp command */
155
static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer,
156
  STACK_OF(OCSP_CERTID) *ids)
157
{
158
    OCSP_CERTID *id;
159
    if(!issuer)
160
        return 0;
161
    if(!*req) *req = OCSP_REQUEST_new();
162
    if(!*req) goto err;
163
    id = OCSP_cert_to_id(NULL, cert, issuer);
164
    if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
165
    if(!OCSP_request_add0_id(*req, id)) goto err;
166
    return 1;
167
168
err:
169
    return 0;
170
}
171
172
173
/* Creates the APR socket and connect to the hostname. Returns the 
174
   socket or NULL if there is an error.
175
*/
176
static apr_socket_t *make_socket(char *hostname, int port, apr_pool_t *mp)
177
{
178
    int r = 0;
179
    apr_sockaddr_t *sa_in;
180
    apr_status_t status;
181
    apr_socket_t *sock = NULL;
182
183
184
    status = apr_sockaddr_info_get(&sa_in, hostname, APR_INET, port, 0, mp);
185
186
    if(status == APR_SUCCESS)
187
        status = apr_socket_create(&sock, sa_in->family, SOCK_STREAM, APR_PROTO_TCP, mp);
188
    if(status == APR_SUCCESS)
189
        status = apr_socket_connect(sock, sa_in);
190
191
    if(status == APR_SUCCESS)
192
        return sock;
193
    return NULL;
194
195
}
196
197
198
/* Creates the request in a memory BIO in order to send it to the OCSP server.
199
   Most parts of this function are taken from mod_ssl support for OCSP (with some
200
   minor modifications
201
*/
202
static BIO *serialize_request(OCSP_REQUEST *req, char *host, int port, char *path)
203
{
204
    BIO *bio;
205
    int len;
206
207
    len = i2d_OCSP_REQUEST(req, NULL);
208
209
    bio = BIO_new(BIO_s_mem());
210
211
    BIO_printf(bio, "POST %s HTTP/1.0\r\n"
212
      "Host: %s:%d\r\n"
213
      "Content-Type: application/ocsp-request\r\n"
214
      "Content-Length: %d\r\n"
215
      "\r\n",
216
      path, host, port, len);
217
218
    if (i2d_OCSP_REQUEST_bio(bio, req) != 1) {
219
        BIO_free(bio);
220
        return NULL;
221
    }
222
223
    return bio;
224
}
225
226
227
/* Send the OCSP request to the OCSP server. Taken from mod_ssl OCSP support */
228
#define HUGE_STRING_LENGTH 8192
229
static int ocsp_send_req(apr_socket_t *sock, BIO *req)
230
{
231
    int len;
232
    char buf[HUGE_STRING_LENGTH];
233
    apr_status_t rv;
234
    int ok = 1;
235
236
    while ((len = BIO_read(req, buf, sizeof buf)) > 0) {
237
        char *wbuf = buf;
238
        apr_size_t remain = len;
239
240
        do {
241
            apr_size_t wlen = remain;
242
            rv = apr_socket_send(sock, wbuf, &wlen);
243
            wbuf += remain;
244
            remain -= wlen;
245
        } while (rv == APR_SUCCESS && remain > 0);
246
247
        if (rv != APR_SUCCESS) {
248
            apr_socket_close(sock);
249
            ok = 0;
250
        }
251
    }
252
253
    return ok;
254
}
255
256
257
258
/* Parses the buffer from the response and extracts the OCSP response.
259
   Taken from openssl library */
260
static OCSP_RESPONSE *parse_ocsp_resp(char *buf, int len)
261
{
262
    BIO *mem = NULL;
263
    char tmpbuf[1024];
264
    OCSP_RESPONSE *resp = NULL;
265
    char *p, *q, *r;
266
    int retcode;
267
268
    mem = BIO_new(BIO_s_mem());
269
    if(mem == NULL)
270
        return NULL;
271
272
    BIO_write(mem, buf, len);  /* write the buffer to the bio */
273
    if(BIO_gets(mem, tmpbuf, 512) <= 0) {
274
        OCSPerr(OCSP_F_OCSP_SENDREQ_BIO,OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
275
        goto err;
276
    }
277
    /* Parse the HTTP response. This will look like this:
278
     * "HTTP/1.0 200 OK". We need to obtain the numeric code and
279
     * (optional) informational message.
280
     */
281
282
    /* Skip to first white space (passed protocol info) */
283
    for(p = tmpbuf; *p && !isspace((unsigned char)*p); p++) continue;
284
    if(!*p) {
285
        goto err;
286
    }
287
    /* Skip past white space to start of response code */
288
    while(isspace((unsigned char)*p)) p++;
289
    if(!*p) {
290
        goto err;
291
    }
292
    /* Find end of response code: first whitespace after start of code */
293
    for(q = p; *q && !isspace((unsigned char)*q); q++) continue;
294
    if(!*q) {
295
        goto err;
296
    }
297
    /* Set end of response code and start of message */
298
    *q++ = 0;
299
    /* Attempt to parse numeric code */
300
    retcode = strtoul(p, &r, 10);
301
    if(*r) goto err;
302
    /* Skip over any leading white space in message */
303
    while(isspace((unsigned char)*q))  q++;
304
    if(*q) {
305
        /* Finally zap any trailing white space in message (include CRLF) */
306
        /* We know q has a non white space character so this is OK */
307
        for(r = q + strlen(q) - 1; isspace((unsigned char)*r); r--) *r = 0;
308
    }
309
    if(retcode != 200) {
310
        goto err;
311
    }
312
    /* Find blank line marking beginning of content */
313
    while(BIO_gets(mem, tmpbuf, 512) > 0)
314
    {
315
        for(p = tmpbuf; isspace((unsigned char)*p); p++) continue;
316
        if(!*p) break;
317
    }
318
    if(*p) {
319
        goto err;
320
    }
321
    if(!(resp = d2i_OCSP_RESPONSE_bio(mem, NULL))) {
322
        goto err;
323
    }
324
err:
325
    BIO_free(mem);
326
    return resp;
327
328
329
}
330
331
332
/* Reads the respnse from the APR socket to a buffer, and parses the buffer to
333
   return the OCSP response  */
334
#define ADDLEN 512
335
static OCSP_RESPONSE *ocsp_get_resp(apr_socket_t *sock)
336
{
337
    int buflen = 0, totalread = 0, readlen;
338
    char *buf, tmpbuf[ADDLEN];
339
    apr_status_t rv = APR_SUCCESS;
340
341
    OCSP_RESPONSE *resp;
342
343
    buflen = ADDLEN;
344
    buf = malloc(buflen);
345
    if(buf == NULL)
346
        return NULL;
347
348
    while(rv == APR_SUCCESS ) {
349
        readlen = sizeof(tmpbuf);
350
        rv = apr_socket_recv(sock, tmpbuf, &readlen);
351
        if(rv == APR_SUCCESS) { /* if we have read something .. we can put it in the buffer*/
352
            if((totalread + readlen) >= buflen) {
353
                buflen+=ADDLEN; /* if needed we enlarge the buffer */
354
                buf = xrealloc(buf,buflen);
355
                if (buf == NULL) {
356
                    return NULL;
357
                }
358
            }
359
            memcpy(buf+totalread, tmpbuf, readlen); /* the copy to the buffer */
360
            totalread+=readlen; /* update the total bytes read */
361
        }
362
        else {
363
            if (rv == APR_EOF && readlen == 0 )
364
                ; /* EOF, normal situation */
365
            else if ( readlen == 0 ) {
366
                /* Not success, and readlen == 0 .. some error */
367
                free(buf);
368
                return NULL;
369
            }
370
        }
371
    }
372
373
374
    resp = parse_ocsp_resp(buf, buflen);
375
376
    free(buf);
377
378
    return resp;
379
}
380
381
/* Creates and OCSP request and returns the OCSP_RESPONSE */
382
static OCSP_RESPONSE *get_ocsp_response(X509 *cert, X509 *issuer, char *url)
383
{
384
    OCSP_RESPONSE *ocsp_resp;
385
    OCSP_REQUEST *ocsp_req;
386
    BIO *bio_req;
387
    char *hostname, *path, *c_port;
388
    int port, use_ssl;
389
    STACK_OF(OCSP_CERTID) *ids = NULL;
390
    int ok = 0;
391
392
    apr_socket_t *apr_sock=NULL;
393
394
    apr_pool_t *mp;
395
396
    apr_pool_create(&mp, NULL);
397
398
    ids = sk_OCSP_CERTID_new_null();
399
400
    /* problem parsing the URL */
401
    if(OCSP_parse_url(url,&hostname, &c_port, &path, &use_ssl) == 0 ) {
402
        sk_OCP_CERTID_free(ids);
403
        return NULL;
404
    }
405
406
    /* Create the OCSP request */
407
    if(sscanf(c_port, "%d", &port) != 1)
408
        goto end;
409
    ocsp_req = OCSP_REQUEST_new();
410
    if(ocsp_req == NULL)
411
        return NULL;
412
    if(add_ocsp_cert(&ocsp_req,cert,issuer,ids) == 0 )
413
        goto free_req;
414
415
    /* create the BIO with the request to send */
416
    bio_req = serialize_request(ocsp_req, hostname, port, path);
417
    if(bio_req == NULL) {
418
        goto free_req;
419
    }
420
421
    apr_sock = make_socket(hostname, port, mp);
422
    if (apr_sock == NULL) {
423
        ocsp_resp = NULL;
424
        goto free_bio;
425
    }
426
427
    ok = ocsp_send_req(apr_sock, bio_req);
428
    if(ok)
429
        ocsp_resp = ocsp_get_resp(apr_sock);
430
431
free_bio:
432
    BIO_free(bio_req);
433
434
free_req:
435
    if(apr_sock)
436
        apr_socket_close(apr_sock);
437
438
    apr_pool_destroy(mp);
439
440
    sk_OCSP_CERTID_free(ids);
441
    OCSP_REQUEST_free(ocsp_req);
442
443
end:
444
    return ocsp_resp;
445
}
446
447
/* Process the OCSP_RESPONSE and returns the corresponding
448
   answert according to the status.
449
*/
450
static int processOCSPResponse(OCSP_RESPONSE *ocsp_resp)
451
{
452
    int r, o = V_OCSP_CERTSTATUS_UNKNOWN, i;
453
    OCSP_BASICRESP *bs;
454
    OCSP_SINGLERESP *ss;
455
456
    r = OCSP_response_status(ocsp_resp);
457
458
    if(r != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
459
        OCSP_RESPONSE_free(ocsp_resp);
460
        return OCSP_STATUS_UNKNOWN;
461
    }
462
    bs = OCSP_response_get1_basic(ocsp_resp);
463
464
    ss = OCSP_resp_get0(bs,0); /* we know we have only 1 request */
465
466
    i = OCSP_single_get0_status(ss, NULL, NULL, NULL, NULL);
467
    if ( i == V_OCSP_CERTSTATUS_GOOD )
468
        o =  OCSP_STATUS_OK;
469
    else if ( i == V_OCSP_CERTSTATUS_REVOKED )
470
        o = OCSP_STATUS_REVOKED;
471
    else if ( i == V_OCSP_CERTSTATUS_UNKNOWN)
472
        o = OCSP_STATUS_UNKNOWN;
473
474
    /* we clean up */
475
    OCSP_RESPONSE_free(ocsp_resp);
476
477
    return o;
478
}
479
480
481
int ocspRequest(X509 *cert, X509 *issuer)
482
{
483
    char **ocsp_urls = NULL;
484
    int nid, i;
485
    X509_EXTENSION *ext;
486
    ASN1_OCTET_STRING *os;
487
488
    /* Get the proper extension */
489
    nid = X509_get_ext_by_NID(cert,NID_info_access,-1);
490
    if(nid >= 0 ) {
491
        ext = X509_get_ext(cert,nid);
492
        os = X509_EXTENSION_get_data(ext);
493
494
        ocsp_urls = decode_OCSP_url(os);
495
    }
496
497
    /* if we find the extensions and we can parse it check 
498
       the ocsp status. Otherwise, return OCSP_STATUS_UNKNOWN */
499
    if(ocsp_urls != NULL) {
500
        OCSP_RESPONSE *resp;
501
        /* for the time being just check for the fist response .. a better
502
           approach is to iterate for all the possible ocsp urls */
503
        resp = get_ocsp_response(cert, issuer, ocsp_urls[0]);
504
505
        /* memory clean up */
506
        for(i = 0 ; ocsp_urls[i] != NULL ; i++ )
507
            free(ocsp_urls[i]);
508
        free(ocsp_urls);
509
        if(resp != NULL)
510
            return processOCSPResponse(resp);
511
    }
512
    return OCSP_STATUS_UNKNOWN;
513
}
(-)a/jni/native/src/sslutils.c (-1 / +48 lines)
Lines 31-36 extern int WIN32_SSL_password_prompt(tcn Link Here
31
extern int WIN32_SSL_password_prompt(tcn_pass_cb_t *data);
31
extern int WIN32_SSL_password_prompt(tcn_pass_cb_t *data);
32
#endif
32
#endif
33
33
34
#include "ocsp_sock.h"
34
/*  _________________________________________________________________
35
/*  _________________________________________________________________
35
**
36
**
36
**  Additional High-Level Functions for OpenSSL
37
**  Additional High-Level Functions for OpenSSL
Lines 621-626 static int ssl_verify_CRL(int ok, X509_S Link Here
621
 * This OpenSSL callback function is called when OpenSSL
622
 * This OpenSSL callback function is called when OpenSSL
622
 * does client authentication and verifies the certificate chain.
623
 * does client authentication and verifies the certificate chain.
623
 */
624
 */
625
626
624
int SSL_callback_SSL_verify(int ok, X509_STORE_CTX *ctx)
627
int SSL_callback_SSL_verify(int ok, X509_STORE_CTX *ctx)
625
{
628
{
626
   /* Get Apache context back through OpenSSL context */
629
   /* Get Apache context back through OpenSSL context */
Lines 632-637 int SSL_callback_SSL_verify(int ok, X509 Link Here
632
    int errdepth = X509_STORE_CTX_get_error_depth(ctx);
635
    int errdepth = X509_STORE_CTX_get_error_depth(ctx);
633
    int verify   = con->ctx->verify_mode;
636
    int verify   = con->ctx->verify_mode;
634
    int depth    = con->ctx->verify_depth;
637
    int depth    = con->ctx->verify_depth;
638
    int ocsp_response;
639
    int skip_crl = 0;
635
640
636
    if (verify == SSL_CVERIFY_UNSET ||
641
    if (verify == SSL_CVERIFY_UNSET ||
637
        verify == SSL_CVERIFY_NONE)
642
        verify == SSL_CVERIFY_NONE)
Lines 642-651 int SSL_callback_SSL_verify(int ok, X509 Link Here
642
        ok = 1;
647
        ok = 1;
643
        SSL_set_verify_result(ssl, X509_V_OK);
648
        SSL_set_verify_result(ssl, X509_V_OK);
644
    }
649
    }
650
651
    /* First perform OCSP validation if possible */
652
    if(ok) {
653
        ocsp_response = ssl_verify_OCSP(ok, ctx);
654
        if (ocsp_response == OCSP_STATUS_OK ) {
655
            skip_crl = 1; /* we know it is valid we skip crl evaluation */
656
        }
657
        else if(ocsp_response == OCSP_STATUS_REVOKED ) {
658
            ok = 0 ;
659
            errnum = X509_STORE_CTX_get_error(ctx);
660
        }
661
        else if (ocsp_response == OCSP_STATUS_UNKNOWN) 
662
            ; /* do nothing for time being, continue with CRL */
663
    }
645
    /*
664
    /*
646
     * Additionally perform CRL-based revocation checks
665
     * Additionally perform CRL-based revocation checks
647
     */
666
     */
648
    if (ok && con->ctx->crl) {
667
    if (ok && con->ctx->crl && !skip_crl) {
649
        if (!(ok = ssl_verify_CRL(ok, ctx, con))) {
668
        if (!(ok = ssl_verify_CRL(ok, ctx, con))) {
650
            errnum = X509_STORE_CTX_get_error(ctx);
669
            errnum = X509_STORE_CTX_get_error(ctx);
651
            /* TODO: Log something */
670
            /* TODO: Log something */
Lines 672-675 int SSL_callback_SSL_verify(int ok, X509 Link Here
672
    return ok;
691
    return ok;
673
}
692
}
674
693
694
695
/* Function that is used to do the OCSP verification */
696
int ssl_verify_OCSP(int ok, X509_STORE_CTX *ctx)
697
{
698
    X509 *cert, *issuer;
699
    int r, o;
700
701
    cert = X509_STORE_CTX_get_current_cert(ctx);
702
703
    o = X509_STORE_CTX_get1_issuer(&issuer, ctx, cert);
704
    /* if we can't get the issuer, we cannot perform OCSP verification */
705
    if( o == 1 ) {
706
        r = ocspRequest(cert, issuer);
707
        if (r == OCSP_STATUS_REVOKED )
708
/* we set the error if we know that it is revoked */
709
            X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED);
710
        else
711
            r = OCSP_STATUS_UNKNOWN; /* else we return unknown, so that we can continue with the crl */
712
        X509_free(issuer); /* It appears that we  should free issuer since
713
                              X509_STORE_CTX_get1_issuer() calls X509_OBJECT_up_ref_count()
714
                              on the issuer object (unline X509_STORE_CTX_get_current_cert()
715
                              that just returns the pointer */
716
717
    }
718
719
    return r;
720
}
721
675
#endif
722
#endif

Return to bug 45392