1*0Sstevel@tonic-gate /* ocsp.c */ 2*0Sstevel@tonic-gate /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL 3*0Sstevel@tonic-gate * project 2000. 4*0Sstevel@tonic-gate */ 5*0Sstevel@tonic-gate /* ==================================================================== 6*0Sstevel@tonic-gate * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 7*0Sstevel@tonic-gate * 8*0Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 9*0Sstevel@tonic-gate * modification, are permitted provided that the following conditions 10*0Sstevel@tonic-gate * are met: 11*0Sstevel@tonic-gate * 12*0Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright 13*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 14*0Sstevel@tonic-gate * 15*0Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 16*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in 17*0Sstevel@tonic-gate * the documentation and/or other materials provided with the 18*0Sstevel@tonic-gate * distribution. 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this 21*0Sstevel@tonic-gate * software must display the following acknowledgment: 22*0Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 23*0Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24*0Sstevel@tonic-gate * 25*0Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26*0Sstevel@tonic-gate * endorse or promote products derived from this software without 27*0Sstevel@tonic-gate * prior written permission. For written permission, please contact 28*0Sstevel@tonic-gate * licensing@OpenSSL.org. 29*0Sstevel@tonic-gate * 30*0Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL" 31*0Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written 32*0Sstevel@tonic-gate * permission of the OpenSSL Project. 33*0Sstevel@tonic-gate * 34*0Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following 35*0Sstevel@tonic-gate * acknowledgment: 36*0Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 37*0Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38*0Sstevel@tonic-gate * 39*0Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40*0Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42*0Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43*0Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44*0Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45*0Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46*0Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47*0Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48*0Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49*0Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50*0Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE. 51*0Sstevel@tonic-gate * ==================================================================== 52*0Sstevel@tonic-gate * 53*0Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young 54*0Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim 55*0Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com). 56*0Sstevel@tonic-gate * 57*0Sstevel@tonic-gate */ 58*0Sstevel@tonic-gate #ifndef OPENSSL_NO_OCSP 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gate #include <stdio.h> 61*0Sstevel@tonic-gate #include <string.h> 62*0Sstevel@tonic-gate #include "apps.h" 63*0Sstevel@tonic-gate #include <openssl/pem.h> 64*0Sstevel@tonic-gate #include <openssl/ocsp.h> 65*0Sstevel@tonic-gate #include <openssl/err.h> 66*0Sstevel@tonic-gate #include <openssl/ssl.h> 67*0Sstevel@tonic-gate 68*0Sstevel@tonic-gate /* Maximum leeway in validity period: default 5 minutes */ 69*0Sstevel@tonic-gate #define MAX_VALIDITY_PERIOD (5 * 60) 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gate static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer, 72*0Sstevel@tonic-gate STACK_OF(OCSP_CERTID) *ids); 73*0Sstevel@tonic-gate static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer, 74*0Sstevel@tonic-gate STACK_OF(OCSP_CERTID) *ids); 75*0Sstevel@tonic-gate static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, 76*0Sstevel@tonic-gate STACK *names, STACK_OF(OCSP_CERTID) *ids, 77*0Sstevel@tonic-gate long nsec, long maxage); 78*0Sstevel@tonic-gate 79*0Sstevel@tonic-gate static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db, 80*0Sstevel@tonic-gate X509 *ca, X509 *rcert, EVP_PKEY *rkey, 81*0Sstevel@tonic-gate STACK_OF(X509) *rother, unsigned long flags, 82*0Sstevel@tonic-gate int nmin, int ndays); 83*0Sstevel@tonic-gate 84*0Sstevel@tonic-gate static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser); 85*0Sstevel@tonic-gate static BIO *init_responder(char *port); 86*0Sstevel@tonic-gate static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port); 87*0Sstevel@tonic-gate static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp); 88*0Sstevel@tonic-gate 89*0Sstevel@tonic-gate #undef PROG 90*0Sstevel@tonic-gate #define PROG ocsp_main 91*0Sstevel@tonic-gate 92*0Sstevel@tonic-gate int MAIN(int, char **); 93*0Sstevel@tonic-gate 94*0Sstevel@tonic-gate int MAIN(int argc, char **argv) 95*0Sstevel@tonic-gate { 96*0Sstevel@tonic-gate ENGINE *e = NULL; 97*0Sstevel@tonic-gate char **args; 98*0Sstevel@tonic-gate char *host = NULL, *port = NULL, *path = "/"; 99*0Sstevel@tonic-gate char *reqin = NULL, *respin = NULL; 100*0Sstevel@tonic-gate char *reqout = NULL, *respout = NULL; 101*0Sstevel@tonic-gate char *signfile = NULL, *keyfile = NULL; 102*0Sstevel@tonic-gate char *rsignfile = NULL, *rkeyfile = NULL; 103*0Sstevel@tonic-gate char *outfile = NULL; 104*0Sstevel@tonic-gate int add_nonce = 1, noverify = 0, use_ssl = -1; 105*0Sstevel@tonic-gate OCSP_REQUEST *req = NULL; 106*0Sstevel@tonic-gate OCSP_RESPONSE *resp = NULL; 107*0Sstevel@tonic-gate OCSP_BASICRESP *bs = NULL; 108*0Sstevel@tonic-gate X509 *issuer = NULL, *cert = NULL; 109*0Sstevel@tonic-gate X509 *signer = NULL, *rsigner = NULL; 110*0Sstevel@tonic-gate EVP_PKEY *key = NULL, *rkey = NULL; 111*0Sstevel@tonic-gate BIO *acbio = NULL, *cbio = NULL; 112*0Sstevel@tonic-gate BIO *derbio = NULL; 113*0Sstevel@tonic-gate BIO *out = NULL; 114*0Sstevel@tonic-gate int req_text = 0, resp_text = 0; 115*0Sstevel@tonic-gate long nsec = MAX_VALIDITY_PERIOD, maxage = -1; 116*0Sstevel@tonic-gate char *CAfile = NULL, *CApath = NULL; 117*0Sstevel@tonic-gate X509_STORE *store = NULL; 118*0Sstevel@tonic-gate SSL_CTX *ctx = NULL; 119*0Sstevel@tonic-gate STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL; 120*0Sstevel@tonic-gate char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL; 121*0Sstevel@tonic-gate unsigned long sign_flags = 0, verify_flags = 0, rflags = 0; 122*0Sstevel@tonic-gate int ret = 1; 123*0Sstevel@tonic-gate int accept_count = -1; 124*0Sstevel@tonic-gate int badarg = 0; 125*0Sstevel@tonic-gate int i; 126*0Sstevel@tonic-gate int ignore_err = 0; 127*0Sstevel@tonic-gate STACK *reqnames = NULL; 128*0Sstevel@tonic-gate STACK_OF(OCSP_CERTID) *ids = NULL; 129*0Sstevel@tonic-gate 130*0Sstevel@tonic-gate X509 *rca_cert = NULL; 131*0Sstevel@tonic-gate char *ridx_filename = NULL; 132*0Sstevel@tonic-gate char *rca_filename = NULL; 133*0Sstevel@tonic-gate CA_DB *rdb = NULL; 134*0Sstevel@tonic-gate int nmin = 0, ndays = -1; 135*0Sstevel@tonic-gate 136*0Sstevel@tonic-gate if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 137*0Sstevel@tonic-gate 138*0Sstevel@tonic-gate if (!load_config(bio_err, NULL)) 139*0Sstevel@tonic-gate goto end; 140*0Sstevel@tonic-gate SSL_load_error_strings(); 141*0Sstevel@tonic-gate args = argv + 1; 142*0Sstevel@tonic-gate reqnames = sk_new_null(); 143*0Sstevel@tonic-gate ids = sk_OCSP_CERTID_new_null(); 144*0Sstevel@tonic-gate while (!badarg && *args && *args[0] == '-') 145*0Sstevel@tonic-gate { 146*0Sstevel@tonic-gate if (!strcmp(*args, "-out")) 147*0Sstevel@tonic-gate { 148*0Sstevel@tonic-gate if (args[1]) 149*0Sstevel@tonic-gate { 150*0Sstevel@tonic-gate args++; 151*0Sstevel@tonic-gate outfile = *args; 152*0Sstevel@tonic-gate } 153*0Sstevel@tonic-gate else badarg = 1; 154*0Sstevel@tonic-gate } 155*0Sstevel@tonic-gate else if (!strcmp(*args, "-url")) 156*0Sstevel@tonic-gate { 157*0Sstevel@tonic-gate if (args[1]) 158*0Sstevel@tonic-gate { 159*0Sstevel@tonic-gate args++; 160*0Sstevel@tonic-gate if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl)) 161*0Sstevel@tonic-gate { 162*0Sstevel@tonic-gate BIO_printf(bio_err, "Error parsing URL\n"); 163*0Sstevel@tonic-gate badarg = 1; 164*0Sstevel@tonic-gate } 165*0Sstevel@tonic-gate } 166*0Sstevel@tonic-gate else badarg = 1; 167*0Sstevel@tonic-gate } 168*0Sstevel@tonic-gate else if (!strcmp(*args, "-host")) 169*0Sstevel@tonic-gate { 170*0Sstevel@tonic-gate if (args[1]) 171*0Sstevel@tonic-gate { 172*0Sstevel@tonic-gate args++; 173*0Sstevel@tonic-gate host = *args; 174*0Sstevel@tonic-gate } 175*0Sstevel@tonic-gate else badarg = 1; 176*0Sstevel@tonic-gate } 177*0Sstevel@tonic-gate else if (!strcmp(*args, "-port")) 178*0Sstevel@tonic-gate { 179*0Sstevel@tonic-gate if (args[1]) 180*0Sstevel@tonic-gate { 181*0Sstevel@tonic-gate args++; 182*0Sstevel@tonic-gate port = *args; 183*0Sstevel@tonic-gate } 184*0Sstevel@tonic-gate else badarg = 1; 185*0Sstevel@tonic-gate } 186*0Sstevel@tonic-gate else if (!strcmp(*args, "-ignore_err")) 187*0Sstevel@tonic-gate ignore_err = 1; 188*0Sstevel@tonic-gate else if (!strcmp(*args, "-noverify")) 189*0Sstevel@tonic-gate noverify = 1; 190*0Sstevel@tonic-gate else if (!strcmp(*args, "-nonce")) 191*0Sstevel@tonic-gate add_nonce = 2; 192*0Sstevel@tonic-gate else if (!strcmp(*args, "-no_nonce")) 193*0Sstevel@tonic-gate add_nonce = 0; 194*0Sstevel@tonic-gate else if (!strcmp(*args, "-resp_no_certs")) 195*0Sstevel@tonic-gate rflags |= OCSP_NOCERTS; 196*0Sstevel@tonic-gate else if (!strcmp(*args, "-resp_key_id")) 197*0Sstevel@tonic-gate rflags |= OCSP_RESPID_KEY; 198*0Sstevel@tonic-gate else if (!strcmp(*args, "-no_certs")) 199*0Sstevel@tonic-gate sign_flags |= OCSP_NOCERTS; 200*0Sstevel@tonic-gate else if (!strcmp(*args, "-no_signature_verify")) 201*0Sstevel@tonic-gate verify_flags |= OCSP_NOSIGS; 202*0Sstevel@tonic-gate else if (!strcmp(*args, "-no_cert_verify")) 203*0Sstevel@tonic-gate verify_flags |= OCSP_NOVERIFY; 204*0Sstevel@tonic-gate else if (!strcmp(*args, "-no_chain")) 205*0Sstevel@tonic-gate verify_flags |= OCSP_NOCHAIN; 206*0Sstevel@tonic-gate else if (!strcmp(*args, "-no_cert_checks")) 207*0Sstevel@tonic-gate verify_flags |= OCSP_NOCHECKS; 208*0Sstevel@tonic-gate else if (!strcmp(*args, "-no_explicit")) 209*0Sstevel@tonic-gate verify_flags |= OCSP_NOEXPLICIT; 210*0Sstevel@tonic-gate else if (!strcmp(*args, "-trust_other")) 211*0Sstevel@tonic-gate verify_flags |= OCSP_TRUSTOTHER; 212*0Sstevel@tonic-gate else if (!strcmp(*args, "-no_intern")) 213*0Sstevel@tonic-gate verify_flags |= OCSP_NOINTERN; 214*0Sstevel@tonic-gate else if (!strcmp(*args, "-text")) 215*0Sstevel@tonic-gate { 216*0Sstevel@tonic-gate req_text = 1; 217*0Sstevel@tonic-gate resp_text = 1; 218*0Sstevel@tonic-gate } 219*0Sstevel@tonic-gate else if (!strcmp(*args, "-req_text")) 220*0Sstevel@tonic-gate req_text = 1; 221*0Sstevel@tonic-gate else if (!strcmp(*args, "-resp_text")) 222*0Sstevel@tonic-gate resp_text = 1; 223*0Sstevel@tonic-gate else if (!strcmp(*args, "-reqin")) 224*0Sstevel@tonic-gate { 225*0Sstevel@tonic-gate if (args[1]) 226*0Sstevel@tonic-gate { 227*0Sstevel@tonic-gate args++; 228*0Sstevel@tonic-gate reqin = *args; 229*0Sstevel@tonic-gate } 230*0Sstevel@tonic-gate else badarg = 1; 231*0Sstevel@tonic-gate } 232*0Sstevel@tonic-gate else if (!strcmp(*args, "-respin")) 233*0Sstevel@tonic-gate { 234*0Sstevel@tonic-gate if (args[1]) 235*0Sstevel@tonic-gate { 236*0Sstevel@tonic-gate args++; 237*0Sstevel@tonic-gate respin = *args; 238*0Sstevel@tonic-gate } 239*0Sstevel@tonic-gate else badarg = 1; 240*0Sstevel@tonic-gate } 241*0Sstevel@tonic-gate else if (!strcmp(*args, "-signer")) 242*0Sstevel@tonic-gate { 243*0Sstevel@tonic-gate if (args[1]) 244*0Sstevel@tonic-gate { 245*0Sstevel@tonic-gate args++; 246*0Sstevel@tonic-gate signfile = *args; 247*0Sstevel@tonic-gate } 248*0Sstevel@tonic-gate else badarg = 1; 249*0Sstevel@tonic-gate } 250*0Sstevel@tonic-gate else if (!strcmp (*args, "-VAfile")) 251*0Sstevel@tonic-gate { 252*0Sstevel@tonic-gate if (args[1]) 253*0Sstevel@tonic-gate { 254*0Sstevel@tonic-gate args++; 255*0Sstevel@tonic-gate verify_certfile = *args; 256*0Sstevel@tonic-gate verify_flags |= OCSP_TRUSTOTHER; 257*0Sstevel@tonic-gate } 258*0Sstevel@tonic-gate else badarg = 1; 259*0Sstevel@tonic-gate } 260*0Sstevel@tonic-gate else if (!strcmp(*args, "-sign_other")) 261*0Sstevel@tonic-gate { 262*0Sstevel@tonic-gate if (args[1]) 263*0Sstevel@tonic-gate { 264*0Sstevel@tonic-gate args++; 265*0Sstevel@tonic-gate sign_certfile = *args; 266*0Sstevel@tonic-gate } 267*0Sstevel@tonic-gate else badarg = 1; 268*0Sstevel@tonic-gate } 269*0Sstevel@tonic-gate else if (!strcmp(*args, "-verify_other")) 270*0Sstevel@tonic-gate { 271*0Sstevel@tonic-gate if (args[1]) 272*0Sstevel@tonic-gate { 273*0Sstevel@tonic-gate args++; 274*0Sstevel@tonic-gate verify_certfile = *args; 275*0Sstevel@tonic-gate } 276*0Sstevel@tonic-gate else badarg = 1; 277*0Sstevel@tonic-gate } 278*0Sstevel@tonic-gate else if (!strcmp (*args, "-CAfile")) 279*0Sstevel@tonic-gate { 280*0Sstevel@tonic-gate if (args[1]) 281*0Sstevel@tonic-gate { 282*0Sstevel@tonic-gate args++; 283*0Sstevel@tonic-gate CAfile = *args; 284*0Sstevel@tonic-gate } 285*0Sstevel@tonic-gate else badarg = 1; 286*0Sstevel@tonic-gate } 287*0Sstevel@tonic-gate else if (!strcmp (*args, "-CApath")) 288*0Sstevel@tonic-gate { 289*0Sstevel@tonic-gate if (args[1]) 290*0Sstevel@tonic-gate { 291*0Sstevel@tonic-gate args++; 292*0Sstevel@tonic-gate CApath = *args; 293*0Sstevel@tonic-gate } 294*0Sstevel@tonic-gate else badarg = 1; 295*0Sstevel@tonic-gate } 296*0Sstevel@tonic-gate else if (!strcmp (*args, "-validity_period")) 297*0Sstevel@tonic-gate { 298*0Sstevel@tonic-gate if (args[1]) 299*0Sstevel@tonic-gate { 300*0Sstevel@tonic-gate args++; 301*0Sstevel@tonic-gate nsec = atol(*args); 302*0Sstevel@tonic-gate if (nsec < 0) 303*0Sstevel@tonic-gate { 304*0Sstevel@tonic-gate BIO_printf(bio_err, 305*0Sstevel@tonic-gate "Illegal validity period %s\n", 306*0Sstevel@tonic-gate *args); 307*0Sstevel@tonic-gate badarg = 1; 308*0Sstevel@tonic-gate } 309*0Sstevel@tonic-gate } 310*0Sstevel@tonic-gate else badarg = 1; 311*0Sstevel@tonic-gate } 312*0Sstevel@tonic-gate else if (!strcmp (*args, "-status_age")) 313*0Sstevel@tonic-gate { 314*0Sstevel@tonic-gate if (args[1]) 315*0Sstevel@tonic-gate { 316*0Sstevel@tonic-gate args++; 317*0Sstevel@tonic-gate maxage = atol(*args); 318*0Sstevel@tonic-gate if (maxage < 0) 319*0Sstevel@tonic-gate { 320*0Sstevel@tonic-gate BIO_printf(bio_err, 321*0Sstevel@tonic-gate "Illegal validity age %s\n", 322*0Sstevel@tonic-gate *args); 323*0Sstevel@tonic-gate badarg = 1; 324*0Sstevel@tonic-gate } 325*0Sstevel@tonic-gate } 326*0Sstevel@tonic-gate else badarg = 1; 327*0Sstevel@tonic-gate } 328*0Sstevel@tonic-gate else if (!strcmp(*args, "-signkey")) 329*0Sstevel@tonic-gate { 330*0Sstevel@tonic-gate if (args[1]) 331*0Sstevel@tonic-gate { 332*0Sstevel@tonic-gate args++; 333*0Sstevel@tonic-gate keyfile = *args; 334*0Sstevel@tonic-gate } 335*0Sstevel@tonic-gate else badarg = 1; 336*0Sstevel@tonic-gate } 337*0Sstevel@tonic-gate else if (!strcmp(*args, "-reqout")) 338*0Sstevel@tonic-gate { 339*0Sstevel@tonic-gate if (args[1]) 340*0Sstevel@tonic-gate { 341*0Sstevel@tonic-gate args++; 342*0Sstevel@tonic-gate reqout = *args; 343*0Sstevel@tonic-gate } 344*0Sstevel@tonic-gate else badarg = 1; 345*0Sstevel@tonic-gate } 346*0Sstevel@tonic-gate else if (!strcmp(*args, "-respout")) 347*0Sstevel@tonic-gate { 348*0Sstevel@tonic-gate if (args[1]) 349*0Sstevel@tonic-gate { 350*0Sstevel@tonic-gate args++; 351*0Sstevel@tonic-gate respout = *args; 352*0Sstevel@tonic-gate } 353*0Sstevel@tonic-gate else badarg = 1; 354*0Sstevel@tonic-gate } 355*0Sstevel@tonic-gate else if (!strcmp(*args, "-path")) 356*0Sstevel@tonic-gate { 357*0Sstevel@tonic-gate if (args[1]) 358*0Sstevel@tonic-gate { 359*0Sstevel@tonic-gate args++; 360*0Sstevel@tonic-gate path = *args; 361*0Sstevel@tonic-gate } 362*0Sstevel@tonic-gate else badarg = 1; 363*0Sstevel@tonic-gate } 364*0Sstevel@tonic-gate else if (!strcmp(*args, "-issuer")) 365*0Sstevel@tonic-gate { 366*0Sstevel@tonic-gate if (args[1]) 367*0Sstevel@tonic-gate { 368*0Sstevel@tonic-gate args++; 369*0Sstevel@tonic-gate X509_free(issuer); 370*0Sstevel@tonic-gate issuer = load_cert(bio_err, *args, FORMAT_PEM, 371*0Sstevel@tonic-gate NULL, e, "issuer certificate"); 372*0Sstevel@tonic-gate if(!issuer) goto end; 373*0Sstevel@tonic-gate } 374*0Sstevel@tonic-gate else badarg = 1; 375*0Sstevel@tonic-gate } 376*0Sstevel@tonic-gate else if (!strcmp (*args, "-cert")) 377*0Sstevel@tonic-gate { 378*0Sstevel@tonic-gate if (args[1]) 379*0Sstevel@tonic-gate { 380*0Sstevel@tonic-gate args++; 381*0Sstevel@tonic-gate X509_free(cert); 382*0Sstevel@tonic-gate cert = load_cert(bio_err, *args, FORMAT_PEM, 383*0Sstevel@tonic-gate NULL, e, "certificate"); 384*0Sstevel@tonic-gate if(!cert) goto end; 385*0Sstevel@tonic-gate if(!add_ocsp_cert(&req, cert, issuer, ids)) 386*0Sstevel@tonic-gate goto end; 387*0Sstevel@tonic-gate if(!sk_push(reqnames, *args)) 388*0Sstevel@tonic-gate goto end; 389*0Sstevel@tonic-gate } 390*0Sstevel@tonic-gate else badarg = 1; 391*0Sstevel@tonic-gate } 392*0Sstevel@tonic-gate else if (!strcmp(*args, "-serial")) 393*0Sstevel@tonic-gate { 394*0Sstevel@tonic-gate if (args[1]) 395*0Sstevel@tonic-gate { 396*0Sstevel@tonic-gate args++; 397*0Sstevel@tonic-gate if(!add_ocsp_serial(&req, *args, issuer, ids)) 398*0Sstevel@tonic-gate goto end; 399*0Sstevel@tonic-gate if(!sk_push(reqnames, *args)) 400*0Sstevel@tonic-gate goto end; 401*0Sstevel@tonic-gate } 402*0Sstevel@tonic-gate else badarg = 1; 403*0Sstevel@tonic-gate } 404*0Sstevel@tonic-gate else if (!strcmp(*args, "-index")) 405*0Sstevel@tonic-gate { 406*0Sstevel@tonic-gate if (args[1]) 407*0Sstevel@tonic-gate { 408*0Sstevel@tonic-gate args++; 409*0Sstevel@tonic-gate ridx_filename = *args; 410*0Sstevel@tonic-gate } 411*0Sstevel@tonic-gate else badarg = 1; 412*0Sstevel@tonic-gate } 413*0Sstevel@tonic-gate else if (!strcmp(*args, "-CA")) 414*0Sstevel@tonic-gate { 415*0Sstevel@tonic-gate if (args[1]) 416*0Sstevel@tonic-gate { 417*0Sstevel@tonic-gate args++; 418*0Sstevel@tonic-gate rca_filename = *args; 419*0Sstevel@tonic-gate } 420*0Sstevel@tonic-gate else badarg = 1; 421*0Sstevel@tonic-gate } 422*0Sstevel@tonic-gate else if (!strcmp (*args, "-nmin")) 423*0Sstevel@tonic-gate { 424*0Sstevel@tonic-gate if (args[1]) 425*0Sstevel@tonic-gate { 426*0Sstevel@tonic-gate args++; 427*0Sstevel@tonic-gate nmin = atol(*args); 428*0Sstevel@tonic-gate if (nmin < 0) 429*0Sstevel@tonic-gate { 430*0Sstevel@tonic-gate BIO_printf(bio_err, 431*0Sstevel@tonic-gate "Illegal update period %s\n", 432*0Sstevel@tonic-gate *args); 433*0Sstevel@tonic-gate badarg = 1; 434*0Sstevel@tonic-gate } 435*0Sstevel@tonic-gate } 436*0Sstevel@tonic-gate if (ndays == -1) 437*0Sstevel@tonic-gate ndays = 0; 438*0Sstevel@tonic-gate else badarg = 1; 439*0Sstevel@tonic-gate } 440*0Sstevel@tonic-gate else if (!strcmp (*args, "-nrequest")) 441*0Sstevel@tonic-gate { 442*0Sstevel@tonic-gate if (args[1]) 443*0Sstevel@tonic-gate { 444*0Sstevel@tonic-gate args++; 445*0Sstevel@tonic-gate accept_count = atol(*args); 446*0Sstevel@tonic-gate if (accept_count < 0) 447*0Sstevel@tonic-gate { 448*0Sstevel@tonic-gate BIO_printf(bio_err, 449*0Sstevel@tonic-gate "Illegal accept count %s\n", 450*0Sstevel@tonic-gate *args); 451*0Sstevel@tonic-gate badarg = 1; 452*0Sstevel@tonic-gate } 453*0Sstevel@tonic-gate } 454*0Sstevel@tonic-gate else badarg = 1; 455*0Sstevel@tonic-gate } 456*0Sstevel@tonic-gate else if (!strcmp (*args, "-ndays")) 457*0Sstevel@tonic-gate { 458*0Sstevel@tonic-gate if (args[1]) 459*0Sstevel@tonic-gate { 460*0Sstevel@tonic-gate args++; 461*0Sstevel@tonic-gate ndays = atol(*args); 462*0Sstevel@tonic-gate if (ndays < 0) 463*0Sstevel@tonic-gate { 464*0Sstevel@tonic-gate BIO_printf(bio_err, 465*0Sstevel@tonic-gate "Illegal update period %s\n", 466*0Sstevel@tonic-gate *args); 467*0Sstevel@tonic-gate badarg = 1; 468*0Sstevel@tonic-gate } 469*0Sstevel@tonic-gate } 470*0Sstevel@tonic-gate else badarg = 1; 471*0Sstevel@tonic-gate } 472*0Sstevel@tonic-gate else if (!strcmp(*args, "-rsigner")) 473*0Sstevel@tonic-gate { 474*0Sstevel@tonic-gate if (args[1]) 475*0Sstevel@tonic-gate { 476*0Sstevel@tonic-gate args++; 477*0Sstevel@tonic-gate rsignfile = *args; 478*0Sstevel@tonic-gate } 479*0Sstevel@tonic-gate else badarg = 1; 480*0Sstevel@tonic-gate } 481*0Sstevel@tonic-gate else if (!strcmp(*args, "-rkey")) 482*0Sstevel@tonic-gate { 483*0Sstevel@tonic-gate if (args[1]) 484*0Sstevel@tonic-gate { 485*0Sstevel@tonic-gate args++; 486*0Sstevel@tonic-gate rkeyfile = *args; 487*0Sstevel@tonic-gate } 488*0Sstevel@tonic-gate else badarg = 1; 489*0Sstevel@tonic-gate } 490*0Sstevel@tonic-gate else if (!strcmp(*args, "-rother")) 491*0Sstevel@tonic-gate { 492*0Sstevel@tonic-gate if (args[1]) 493*0Sstevel@tonic-gate { 494*0Sstevel@tonic-gate args++; 495*0Sstevel@tonic-gate rcertfile = *args; 496*0Sstevel@tonic-gate } 497*0Sstevel@tonic-gate else badarg = 1; 498*0Sstevel@tonic-gate } 499*0Sstevel@tonic-gate else badarg = 1; 500*0Sstevel@tonic-gate args++; 501*0Sstevel@tonic-gate } 502*0Sstevel@tonic-gate 503*0Sstevel@tonic-gate /* Have we anything to do? */ 504*0Sstevel@tonic-gate if (!req && !reqin && !respin && !(port && ridx_filename)) badarg = 1; 505*0Sstevel@tonic-gate 506*0Sstevel@tonic-gate if (badarg) 507*0Sstevel@tonic-gate { 508*0Sstevel@tonic-gate BIO_printf (bio_err, "OCSP utility\n"); 509*0Sstevel@tonic-gate BIO_printf (bio_err, "Usage ocsp [options]\n"); 510*0Sstevel@tonic-gate BIO_printf (bio_err, "where options are\n"); 511*0Sstevel@tonic-gate BIO_printf (bio_err, "-out file output filename\n"); 512*0Sstevel@tonic-gate BIO_printf (bio_err, "-issuer file issuer certificate\n"); 513*0Sstevel@tonic-gate BIO_printf (bio_err, "-cert file certificate to check\n"); 514*0Sstevel@tonic-gate BIO_printf (bio_err, "-serial n serial number to check\n"); 515*0Sstevel@tonic-gate BIO_printf (bio_err, "-signer file certificate to sign OCSP request with\n"); 516*0Sstevel@tonic-gate BIO_printf (bio_err, "-signkey file private key to sign OCSP request with\n"); 517*0Sstevel@tonic-gate BIO_printf (bio_err, "-sign_other file additional certificates to include in signed request\n"); 518*0Sstevel@tonic-gate BIO_printf (bio_err, "-no_certs don't include any certificates in signed request\n"); 519*0Sstevel@tonic-gate BIO_printf (bio_err, "-req_text print text form of request\n"); 520*0Sstevel@tonic-gate BIO_printf (bio_err, "-resp_text print text form of response\n"); 521*0Sstevel@tonic-gate BIO_printf (bio_err, "-text print text form of request and response\n"); 522*0Sstevel@tonic-gate BIO_printf (bio_err, "-reqout file write DER encoded OCSP request to \"file\"\n"); 523*0Sstevel@tonic-gate BIO_printf (bio_err, "-respout file write DER encoded OCSP reponse to \"file\"\n"); 524*0Sstevel@tonic-gate BIO_printf (bio_err, "-reqin file read DER encoded OCSP request from \"file\"\n"); 525*0Sstevel@tonic-gate BIO_printf (bio_err, "-respin file read DER encoded OCSP reponse from \"file\"\n"); 526*0Sstevel@tonic-gate BIO_printf (bio_err, "-nonce add OCSP nonce to request\n"); 527*0Sstevel@tonic-gate BIO_printf (bio_err, "-no_nonce don't add OCSP nonce to request\n"); 528*0Sstevel@tonic-gate BIO_printf (bio_err, "-url URL OCSP responder URL\n"); 529*0Sstevel@tonic-gate BIO_printf (bio_err, "-host host:n send OCSP request to host on port n\n"); 530*0Sstevel@tonic-gate BIO_printf (bio_err, "-path path to use in OCSP request\n"); 531*0Sstevel@tonic-gate BIO_printf (bio_err, "-CApath dir trusted certificates directory\n"); 532*0Sstevel@tonic-gate BIO_printf (bio_err, "-CAfile file trusted certificates file\n"); 533*0Sstevel@tonic-gate BIO_printf (bio_err, "-VAfile file validator certificates file\n"); 534*0Sstevel@tonic-gate BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n"); 535*0Sstevel@tonic-gate BIO_printf (bio_err, "-status_age n maximum status age in seconds\n"); 536*0Sstevel@tonic-gate BIO_printf (bio_err, "-noverify don't verify response at all\n"); 537*0Sstevel@tonic-gate BIO_printf (bio_err, "-verify_other file additional certificates to search for signer\n"); 538*0Sstevel@tonic-gate BIO_printf (bio_err, "-trust_other don't verify additional certificates\n"); 539*0Sstevel@tonic-gate BIO_printf (bio_err, "-no_intern don't search certificates contained in response for signer\n"); 540*0Sstevel@tonic-gate BIO_printf (bio_err, "-no_signature_verify don't check signature on response\n"); 541*0Sstevel@tonic-gate BIO_printf (bio_err, "-no_cert_verify don't check signing certificate\n"); 542*0Sstevel@tonic-gate BIO_printf (bio_err, "-no_chain don't chain verify response\n"); 543*0Sstevel@tonic-gate BIO_printf (bio_err, "-no_cert_checks don't do additional checks on signing certificate\n"); 544*0Sstevel@tonic-gate BIO_printf (bio_err, "-port num port to run responder on\n"); 545*0Sstevel@tonic-gate BIO_printf (bio_err, "-index file certificate status index file\n"); 546*0Sstevel@tonic-gate BIO_printf (bio_err, "-CA file CA certificate\n"); 547*0Sstevel@tonic-gate BIO_printf (bio_err, "-rsigner file responder certificate to sign responses with\n"); 548*0Sstevel@tonic-gate BIO_printf (bio_err, "-rkey file responder key to sign responses with\n"); 549*0Sstevel@tonic-gate BIO_printf (bio_err, "-rother file other certificates to include in response\n"); 550*0Sstevel@tonic-gate BIO_printf (bio_err, "-resp_no_certs don't include any certificates in response\n"); 551*0Sstevel@tonic-gate BIO_printf (bio_err, "-nmin n number of minutes before next update\n"); 552*0Sstevel@tonic-gate BIO_printf (bio_err, "-ndays n number of days before next update\n"); 553*0Sstevel@tonic-gate BIO_printf (bio_err, "-resp_key_id identify reponse by signing certificate key ID\n"); 554*0Sstevel@tonic-gate BIO_printf (bio_err, "-nrequest n number of requests to accept (default unlimited)\n"); 555*0Sstevel@tonic-gate goto end; 556*0Sstevel@tonic-gate } 557*0Sstevel@tonic-gate 558*0Sstevel@tonic-gate if(outfile) out = BIO_new_file(outfile, "w"); 559*0Sstevel@tonic-gate else out = BIO_new_fp(stdout, BIO_NOCLOSE); 560*0Sstevel@tonic-gate 561*0Sstevel@tonic-gate if(!out) 562*0Sstevel@tonic-gate { 563*0Sstevel@tonic-gate BIO_printf(bio_err, "Error opening output file\n"); 564*0Sstevel@tonic-gate goto end; 565*0Sstevel@tonic-gate } 566*0Sstevel@tonic-gate 567*0Sstevel@tonic-gate if (!req && (add_nonce != 2)) add_nonce = 0; 568*0Sstevel@tonic-gate 569*0Sstevel@tonic-gate if (!req && reqin) 570*0Sstevel@tonic-gate { 571*0Sstevel@tonic-gate derbio = BIO_new_file(reqin, "rb"); 572*0Sstevel@tonic-gate if (!derbio) 573*0Sstevel@tonic-gate { 574*0Sstevel@tonic-gate BIO_printf(bio_err, "Error Opening OCSP request file\n"); 575*0Sstevel@tonic-gate goto end; 576*0Sstevel@tonic-gate } 577*0Sstevel@tonic-gate req = d2i_OCSP_REQUEST_bio(derbio, NULL); 578*0Sstevel@tonic-gate BIO_free(derbio); 579*0Sstevel@tonic-gate if(!req) 580*0Sstevel@tonic-gate { 581*0Sstevel@tonic-gate BIO_printf(bio_err, "Error reading OCSP request\n"); 582*0Sstevel@tonic-gate goto end; 583*0Sstevel@tonic-gate } 584*0Sstevel@tonic-gate } 585*0Sstevel@tonic-gate 586*0Sstevel@tonic-gate if (!req && port) 587*0Sstevel@tonic-gate { 588*0Sstevel@tonic-gate acbio = init_responder(port); 589*0Sstevel@tonic-gate if (!acbio) 590*0Sstevel@tonic-gate goto end; 591*0Sstevel@tonic-gate } 592*0Sstevel@tonic-gate 593*0Sstevel@tonic-gate if (rsignfile && !rdb) 594*0Sstevel@tonic-gate { 595*0Sstevel@tonic-gate if (!rkeyfile) rkeyfile = rsignfile; 596*0Sstevel@tonic-gate rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM, 597*0Sstevel@tonic-gate NULL, e, "responder certificate"); 598*0Sstevel@tonic-gate if (!rsigner) 599*0Sstevel@tonic-gate { 600*0Sstevel@tonic-gate BIO_printf(bio_err, "Error loading responder certificate\n"); 601*0Sstevel@tonic-gate goto end; 602*0Sstevel@tonic-gate } 603*0Sstevel@tonic-gate rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM, 604*0Sstevel@tonic-gate NULL, e, "CA certificate"); 605*0Sstevel@tonic-gate if (rcertfile) 606*0Sstevel@tonic-gate { 607*0Sstevel@tonic-gate rother = load_certs(bio_err, rcertfile, FORMAT_PEM, 608*0Sstevel@tonic-gate NULL, e, "responder other certificates"); 609*0Sstevel@tonic-gate if (!rother) goto end; 610*0Sstevel@tonic-gate } 611*0Sstevel@tonic-gate rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, NULL, 612*0Sstevel@tonic-gate "responder private key"); 613*0Sstevel@tonic-gate if (!rkey) 614*0Sstevel@tonic-gate goto end; 615*0Sstevel@tonic-gate } 616*0Sstevel@tonic-gate if(acbio) 617*0Sstevel@tonic-gate BIO_printf(bio_err, "Waiting for OCSP client connections...\n"); 618*0Sstevel@tonic-gate 619*0Sstevel@tonic-gate redo_accept: 620*0Sstevel@tonic-gate 621*0Sstevel@tonic-gate if (acbio) 622*0Sstevel@tonic-gate { 623*0Sstevel@tonic-gate if (!do_responder(&req, &cbio, acbio, port)) 624*0Sstevel@tonic-gate goto end; 625*0Sstevel@tonic-gate if (!req) 626*0Sstevel@tonic-gate { 627*0Sstevel@tonic-gate resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL); 628*0Sstevel@tonic-gate send_ocsp_response(cbio, resp); 629*0Sstevel@tonic-gate goto done_resp; 630*0Sstevel@tonic-gate } 631*0Sstevel@tonic-gate } 632*0Sstevel@tonic-gate 633*0Sstevel@tonic-gate if (!req && (signfile || reqout || host || add_nonce || ridx_filename)) 634*0Sstevel@tonic-gate { 635*0Sstevel@tonic-gate BIO_printf(bio_err, "Need an OCSP request for this operation!\n"); 636*0Sstevel@tonic-gate goto end; 637*0Sstevel@tonic-gate } 638*0Sstevel@tonic-gate 639*0Sstevel@tonic-gate if (req && add_nonce) OCSP_request_add1_nonce(req, NULL, -1); 640*0Sstevel@tonic-gate 641*0Sstevel@tonic-gate if (signfile) 642*0Sstevel@tonic-gate { 643*0Sstevel@tonic-gate if (!keyfile) keyfile = signfile; 644*0Sstevel@tonic-gate signer = load_cert(bio_err, signfile, FORMAT_PEM, 645*0Sstevel@tonic-gate NULL, e, "signer certificate"); 646*0Sstevel@tonic-gate if (!signer) 647*0Sstevel@tonic-gate { 648*0Sstevel@tonic-gate BIO_printf(bio_err, "Error loading signer certificate\n"); 649*0Sstevel@tonic-gate goto end; 650*0Sstevel@tonic-gate } 651*0Sstevel@tonic-gate if (sign_certfile) 652*0Sstevel@tonic-gate { 653*0Sstevel@tonic-gate sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM, 654*0Sstevel@tonic-gate NULL, e, "signer certificates"); 655*0Sstevel@tonic-gate if (!sign_other) goto end; 656*0Sstevel@tonic-gate } 657*0Sstevel@tonic-gate key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, NULL, 658*0Sstevel@tonic-gate "signer private key"); 659*0Sstevel@tonic-gate if (!key) 660*0Sstevel@tonic-gate goto end; 661*0Sstevel@tonic-gate if (!OCSP_request_sign(req, signer, key, EVP_sha1(), sign_other, sign_flags)) 662*0Sstevel@tonic-gate { 663*0Sstevel@tonic-gate BIO_printf(bio_err, "Error signing OCSP request\n"); 664*0Sstevel@tonic-gate goto end; 665*0Sstevel@tonic-gate } 666*0Sstevel@tonic-gate } 667*0Sstevel@tonic-gate 668*0Sstevel@tonic-gate if (req_text && req) OCSP_REQUEST_print(out, req, 0); 669*0Sstevel@tonic-gate 670*0Sstevel@tonic-gate if (reqout) 671*0Sstevel@tonic-gate { 672*0Sstevel@tonic-gate derbio = BIO_new_file(reqout, "wb"); 673*0Sstevel@tonic-gate if(!derbio) 674*0Sstevel@tonic-gate { 675*0Sstevel@tonic-gate BIO_printf(bio_err, "Error opening file %s\n", reqout); 676*0Sstevel@tonic-gate goto end; 677*0Sstevel@tonic-gate } 678*0Sstevel@tonic-gate i2d_OCSP_REQUEST_bio(derbio, req); 679*0Sstevel@tonic-gate BIO_free(derbio); 680*0Sstevel@tonic-gate } 681*0Sstevel@tonic-gate 682*0Sstevel@tonic-gate if (ridx_filename && (!rkey || !rsigner || !rca_cert)) 683*0Sstevel@tonic-gate { 684*0Sstevel@tonic-gate BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n"); 685*0Sstevel@tonic-gate goto end; 686*0Sstevel@tonic-gate } 687*0Sstevel@tonic-gate 688*0Sstevel@tonic-gate if (ridx_filename && !rdb) 689*0Sstevel@tonic-gate { 690*0Sstevel@tonic-gate rdb = load_index(ridx_filename, NULL); 691*0Sstevel@tonic-gate if (!rdb) goto end; 692*0Sstevel@tonic-gate if (!index_index(rdb)) goto end; 693*0Sstevel@tonic-gate } 694*0Sstevel@tonic-gate 695*0Sstevel@tonic-gate if (rdb) 696*0Sstevel@tonic-gate { 697*0Sstevel@tonic-gate i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays); 698*0Sstevel@tonic-gate if (cbio) 699*0Sstevel@tonic-gate send_ocsp_response(cbio, resp); 700*0Sstevel@tonic-gate } 701*0Sstevel@tonic-gate else if (host) 702*0Sstevel@tonic-gate { 703*0Sstevel@tonic-gate #ifndef OPENSSL_NO_SOCK 704*0Sstevel@tonic-gate cbio = BIO_new_connect(host); 705*0Sstevel@tonic-gate #else 706*0Sstevel@tonic-gate BIO_printf(bio_err, "Error creating connect BIO - sockets not supported.\n"); 707*0Sstevel@tonic-gate goto end; 708*0Sstevel@tonic-gate #endif 709*0Sstevel@tonic-gate if (!cbio) 710*0Sstevel@tonic-gate { 711*0Sstevel@tonic-gate BIO_printf(bio_err, "Error creating connect BIO\n"); 712*0Sstevel@tonic-gate goto end; 713*0Sstevel@tonic-gate } 714*0Sstevel@tonic-gate if (port) BIO_set_conn_port(cbio, port); 715*0Sstevel@tonic-gate if (use_ssl == 1) 716*0Sstevel@tonic-gate { 717*0Sstevel@tonic-gate BIO *sbio; 718*0Sstevel@tonic-gate #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) 719*0Sstevel@tonic-gate ctx = SSL_CTX_new(SSLv23_client_method()); 720*0Sstevel@tonic-gate #elif !defined(OPENSSL_NO_SSL3) 721*0Sstevel@tonic-gate ctx = SSL_CTX_new(SSLv3_client_method()); 722*0Sstevel@tonic-gate #elif !defined(OPENSSL_NO_SSL2) 723*0Sstevel@tonic-gate ctx = SSL_CTX_new(SSLv2_client_method()); 724*0Sstevel@tonic-gate #else 725*0Sstevel@tonic-gate BIO_printf(bio_err, "SSL is disabled\n"); 726*0Sstevel@tonic-gate goto end; 727*0Sstevel@tonic-gate #endif 728*0Sstevel@tonic-gate SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); 729*0Sstevel@tonic-gate sbio = BIO_new_ssl(ctx, 1); 730*0Sstevel@tonic-gate cbio = BIO_push(sbio, cbio); 731*0Sstevel@tonic-gate } 732*0Sstevel@tonic-gate if (BIO_do_connect(cbio) <= 0) 733*0Sstevel@tonic-gate { 734*0Sstevel@tonic-gate BIO_printf(bio_err, "Error connecting BIO\n"); 735*0Sstevel@tonic-gate goto end; 736*0Sstevel@tonic-gate } 737*0Sstevel@tonic-gate resp = OCSP_sendreq_bio(cbio, path, req); 738*0Sstevel@tonic-gate BIO_free_all(cbio); 739*0Sstevel@tonic-gate cbio = NULL; 740*0Sstevel@tonic-gate if (!resp) 741*0Sstevel@tonic-gate { 742*0Sstevel@tonic-gate BIO_printf(bio_err, "Error querying OCSP responsder\n"); 743*0Sstevel@tonic-gate goto end; 744*0Sstevel@tonic-gate } 745*0Sstevel@tonic-gate } 746*0Sstevel@tonic-gate else if (respin) 747*0Sstevel@tonic-gate { 748*0Sstevel@tonic-gate derbio = BIO_new_file(respin, "rb"); 749*0Sstevel@tonic-gate if (!derbio) 750*0Sstevel@tonic-gate { 751*0Sstevel@tonic-gate BIO_printf(bio_err, "Error Opening OCSP response file\n"); 752*0Sstevel@tonic-gate goto end; 753*0Sstevel@tonic-gate } 754*0Sstevel@tonic-gate resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); 755*0Sstevel@tonic-gate BIO_free(derbio); 756*0Sstevel@tonic-gate if(!resp) 757*0Sstevel@tonic-gate { 758*0Sstevel@tonic-gate BIO_printf(bio_err, "Error reading OCSP response\n"); 759*0Sstevel@tonic-gate goto end; 760*0Sstevel@tonic-gate } 761*0Sstevel@tonic-gate 762*0Sstevel@tonic-gate } 763*0Sstevel@tonic-gate else 764*0Sstevel@tonic-gate { 765*0Sstevel@tonic-gate ret = 0; 766*0Sstevel@tonic-gate goto end; 767*0Sstevel@tonic-gate } 768*0Sstevel@tonic-gate 769*0Sstevel@tonic-gate done_resp: 770*0Sstevel@tonic-gate 771*0Sstevel@tonic-gate if (respout) 772*0Sstevel@tonic-gate { 773*0Sstevel@tonic-gate derbio = BIO_new_file(respout, "wb"); 774*0Sstevel@tonic-gate if(!derbio) 775*0Sstevel@tonic-gate { 776*0Sstevel@tonic-gate BIO_printf(bio_err, "Error opening file %s\n", respout); 777*0Sstevel@tonic-gate goto end; 778*0Sstevel@tonic-gate } 779*0Sstevel@tonic-gate i2d_OCSP_RESPONSE_bio(derbio, resp); 780*0Sstevel@tonic-gate BIO_free(derbio); 781*0Sstevel@tonic-gate } 782*0Sstevel@tonic-gate 783*0Sstevel@tonic-gate i = OCSP_response_status(resp); 784*0Sstevel@tonic-gate 785*0Sstevel@tonic-gate if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) 786*0Sstevel@tonic-gate { 787*0Sstevel@tonic-gate BIO_printf(out, "Responder Error: %s (%ld)\n", 788*0Sstevel@tonic-gate OCSP_response_status_str(i), i); 789*0Sstevel@tonic-gate if (ignore_err) 790*0Sstevel@tonic-gate goto redo_accept; 791*0Sstevel@tonic-gate ret = 0; 792*0Sstevel@tonic-gate goto end; 793*0Sstevel@tonic-gate } 794*0Sstevel@tonic-gate 795*0Sstevel@tonic-gate if (resp_text) OCSP_RESPONSE_print(out, resp, 0); 796*0Sstevel@tonic-gate 797*0Sstevel@tonic-gate /* If running as responder don't verify our own response */ 798*0Sstevel@tonic-gate if (cbio) 799*0Sstevel@tonic-gate { 800*0Sstevel@tonic-gate if (accept_count > 0) 801*0Sstevel@tonic-gate accept_count--; 802*0Sstevel@tonic-gate /* Redo if more connections needed */ 803*0Sstevel@tonic-gate if (accept_count) 804*0Sstevel@tonic-gate { 805*0Sstevel@tonic-gate BIO_free_all(cbio); 806*0Sstevel@tonic-gate cbio = NULL; 807*0Sstevel@tonic-gate OCSP_REQUEST_free(req); 808*0Sstevel@tonic-gate req = NULL; 809*0Sstevel@tonic-gate OCSP_RESPONSE_free(resp); 810*0Sstevel@tonic-gate resp = NULL; 811*0Sstevel@tonic-gate goto redo_accept; 812*0Sstevel@tonic-gate } 813*0Sstevel@tonic-gate goto end; 814*0Sstevel@tonic-gate } 815*0Sstevel@tonic-gate 816*0Sstevel@tonic-gate if (!store) 817*0Sstevel@tonic-gate store = setup_verify(bio_err, CAfile, CApath); 818*0Sstevel@tonic-gate if (!store) 819*0Sstevel@tonic-gate goto end; 820*0Sstevel@tonic-gate if (verify_certfile) 821*0Sstevel@tonic-gate { 822*0Sstevel@tonic-gate verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM, 823*0Sstevel@tonic-gate NULL, e, "validator certificate"); 824*0Sstevel@tonic-gate if (!verify_other) goto end; 825*0Sstevel@tonic-gate } 826*0Sstevel@tonic-gate 827*0Sstevel@tonic-gate bs = OCSP_response_get1_basic(resp); 828*0Sstevel@tonic-gate 829*0Sstevel@tonic-gate if (!bs) 830*0Sstevel@tonic-gate { 831*0Sstevel@tonic-gate BIO_printf(bio_err, "Error parsing response\n"); 832*0Sstevel@tonic-gate goto end; 833*0Sstevel@tonic-gate } 834*0Sstevel@tonic-gate 835*0Sstevel@tonic-gate if (!noverify) 836*0Sstevel@tonic-gate { 837*0Sstevel@tonic-gate if (req && ((i = OCSP_check_nonce(req, bs)) <= 0)) 838*0Sstevel@tonic-gate { 839*0Sstevel@tonic-gate if (i == -1) 840*0Sstevel@tonic-gate BIO_printf(bio_err, "WARNING: no nonce in response\n"); 841*0Sstevel@tonic-gate else 842*0Sstevel@tonic-gate { 843*0Sstevel@tonic-gate BIO_printf(bio_err, "Nonce Verify error\n"); 844*0Sstevel@tonic-gate goto end; 845*0Sstevel@tonic-gate } 846*0Sstevel@tonic-gate } 847*0Sstevel@tonic-gate 848*0Sstevel@tonic-gate i = OCSP_basic_verify(bs, verify_other, store, verify_flags); 849*0Sstevel@tonic-gate if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0); 850*0Sstevel@tonic-gate 851*0Sstevel@tonic-gate if(i <= 0) 852*0Sstevel@tonic-gate { 853*0Sstevel@tonic-gate BIO_printf(bio_err, "Response Verify Failure\n", i); 854*0Sstevel@tonic-gate ERR_print_errors(bio_err); 855*0Sstevel@tonic-gate } 856*0Sstevel@tonic-gate else 857*0Sstevel@tonic-gate BIO_printf(bio_err, "Response verify OK\n"); 858*0Sstevel@tonic-gate 859*0Sstevel@tonic-gate } 860*0Sstevel@tonic-gate 861*0Sstevel@tonic-gate if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage)) 862*0Sstevel@tonic-gate goto end; 863*0Sstevel@tonic-gate 864*0Sstevel@tonic-gate ret = 0; 865*0Sstevel@tonic-gate 866*0Sstevel@tonic-gate end: 867*0Sstevel@tonic-gate ERR_print_errors(bio_err); 868*0Sstevel@tonic-gate X509_free(signer); 869*0Sstevel@tonic-gate X509_STORE_free(store); 870*0Sstevel@tonic-gate EVP_PKEY_free(key); 871*0Sstevel@tonic-gate EVP_PKEY_free(rkey); 872*0Sstevel@tonic-gate X509_free(issuer); 873*0Sstevel@tonic-gate X509_free(cert); 874*0Sstevel@tonic-gate X509_free(rsigner); 875*0Sstevel@tonic-gate X509_free(rca_cert); 876*0Sstevel@tonic-gate free_index(rdb); 877*0Sstevel@tonic-gate BIO_free_all(cbio); 878*0Sstevel@tonic-gate BIO_free_all(acbio); 879*0Sstevel@tonic-gate BIO_free(out); 880*0Sstevel@tonic-gate OCSP_REQUEST_free(req); 881*0Sstevel@tonic-gate OCSP_RESPONSE_free(resp); 882*0Sstevel@tonic-gate OCSP_BASICRESP_free(bs); 883*0Sstevel@tonic-gate sk_free(reqnames); 884*0Sstevel@tonic-gate sk_OCSP_CERTID_free(ids); 885*0Sstevel@tonic-gate sk_X509_pop_free(sign_other, X509_free); 886*0Sstevel@tonic-gate sk_X509_pop_free(verify_other, X509_free); 887*0Sstevel@tonic-gate 888*0Sstevel@tonic-gate if (use_ssl != -1) 889*0Sstevel@tonic-gate { 890*0Sstevel@tonic-gate OPENSSL_free(host); 891*0Sstevel@tonic-gate OPENSSL_free(port); 892*0Sstevel@tonic-gate OPENSSL_free(path); 893*0Sstevel@tonic-gate SSL_CTX_free(ctx); 894*0Sstevel@tonic-gate } 895*0Sstevel@tonic-gate 896*0Sstevel@tonic-gate OPENSSL_EXIT(ret); 897*0Sstevel@tonic-gate } 898*0Sstevel@tonic-gate 899*0Sstevel@tonic-gate static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer, 900*0Sstevel@tonic-gate STACK_OF(OCSP_CERTID) *ids) 901*0Sstevel@tonic-gate { 902*0Sstevel@tonic-gate OCSP_CERTID *id; 903*0Sstevel@tonic-gate if(!issuer) 904*0Sstevel@tonic-gate { 905*0Sstevel@tonic-gate BIO_printf(bio_err, "No issuer certificate specified\n"); 906*0Sstevel@tonic-gate return 0; 907*0Sstevel@tonic-gate } 908*0Sstevel@tonic-gate if(!*req) *req = OCSP_REQUEST_new(); 909*0Sstevel@tonic-gate if(!*req) goto err; 910*0Sstevel@tonic-gate id = OCSP_cert_to_id(NULL, cert, issuer); 911*0Sstevel@tonic-gate if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err; 912*0Sstevel@tonic-gate if(!OCSP_request_add0_id(*req, id)) goto err; 913*0Sstevel@tonic-gate return 1; 914*0Sstevel@tonic-gate 915*0Sstevel@tonic-gate err: 916*0Sstevel@tonic-gate BIO_printf(bio_err, "Error Creating OCSP request\n"); 917*0Sstevel@tonic-gate return 0; 918*0Sstevel@tonic-gate } 919*0Sstevel@tonic-gate 920*0Sstevel@tonic-gate static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer, 921*0Sstevel@tonic-gate STACK_OF(OCSP_CERTID) *ids) 922*0Sstevel@tonic-gate { 923*0Sstevel@tonic-gate OCSP_CERTID *id; 924*0Sstevel@tonic-gate X509_NAME *iname; 925*0Sstevel@tonic-gate ASN1_BIT_STRING *ikey; 926*0Sstevel@tonic-gate ASN1_INTEGER *sno; 927*0Sstevel@tonic-gate if(!issuer) 928*0Sstevel@tonic-gate { 929*0Sstevel@tonic-gate BIO_printf(bio_err, "No issuer certificate specified\n"); 930*0Sstevel@tonic-gate return 0; 931*0Sstevel@tonic-gate } 932*0Sstevel@tonic-gate if(!*req) *req = OCSP_REQUEST_new(); 933*0Sstevel@tonic-gate if(!*req) goto err; 934*0Sstevel@tonic-gate iname = X509_get_subject_name(issuer); 935*0Sstevel@tonic-gate ikey = X509_get0_pubkey_bitstr(issuer); 936*0Sstevel@tonic-gate sno = s2i_ASN1_INTEGER(NULL, serial); 937*0Sstevel@tonic-gate if(!sno) 938*0Sstevel@tonic-gate { 939*0Sstevel@tonic-gate BIO_printf(bio_err, "Error converting serial number %s\n", serial); 940*0Sstevel@tonic-gate return 0; 941*0Sstevel@tonic-gate } 942*0Sstevel@tonic-gate id = OCSP_cert_id_new(EVP_sha1(), iname, ikey, sno); 943*0Sstevel@tonic-gate ASN1_INTEGER_free(sno); 944*0Sstevel@tonic-gate if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err; 945*0Sstevel@tonic-gate if(!OCSP_request_add0_id(*req, id)) goto err; 946*0Sstevel@tonic-gate return 1; 947*0Sstevel@tonic-gate 948*0Sstevel@tonic-gate err: 949*0Sstevel@tonic-gate BIO_printf(bio_err, "Error Creating OCSP request\n"); 950*0Sstevel@tonic-gate return 0; 951*0Sstevel@tonic-gate } 952*0Sstevel@tonic-gate 953*0Sstevel@tonic-gate static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, 954*0Sstevel@tonic-gate STACK *names, STACK_OF(OCSP_CERTID) *ids, 955*0Sstevel@tonic-gate long nsec, long maxage) 956*0Sstevel@tonic-gate { 957*0Sstevel@tonic-gate OCSP_CERTID *id; 958*0Sstevel@tonic-gate char *name; 959*0Sstevel@tonic-gate int i; 960*0Sstevel@tonic-gate 961*0Sstevel@tonic-gate int status, reason; 962*0Sstevel@tonic-gate 963*0Sstevel@tonic-gate ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; 964*0Sstevel@tonic-gate 965*0Sstevel@tonic-gate if (!bs || !req || !sk_num(names) || !sk_OCSP_CERTID_num(ids)) 966*0Sstevel@tonic-gate return 1; 967*0Sstevel@tonic-gate 968*0Sstevel@tonic-gate for (i = 0; i < sk_OCSP_CERTID_num(ids); i++) 969*0Sstevel@tonic-gate { 970*0Sstevel@tonic-gate id = sk_OCSP_CERTID_value(ids, i); 971*0Sstevel@tonic-gate name = sk_value(names, i); 972*0Sstevel@tonic-gate BIO_printf(out, "%s: ", name); 973*0Sstevel@tonic-gate 974*0Sstevel@tonic-gate if(!OCSP_resp_find_status(bs, id, &status, &reason, 975*0Sstevel@tonic-gate &rev, &thisupd, &nextupd)) 976*0Sstevel@tonic-gate { 977*0Sstevel@tonic-gate BIO_puts(out, "ERROR: No Status found.\n"); 978*0Sstevel@tonic-gate continue; 979*0Sstevel@tonic-gate } 980*0Sstevel@tonic-gate 981*0Sstevel@tonic-gate /* Check validity: if invalid write to output BIO so we 982*0Sstevel@tonic-gate * know which response this refers to. 983*0Sstevel@tonic-gate */ 984*0Sstevel@tonic-gate if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage)) 985*0Sstevel@tonic-gate { 986*0Sstevel@tonic-gate BIO_puts(out, "WARNING: Status times invalid.\n"); 987*0Sstevel@tonic-gate ERR_print_errors(out); 988*0Sstevel@tonic-gate } 989*0Sstevel@tonic-gate BIO_printf(out, "%s\n", OCSP_cert_status_str(status)); 990*0Sstevel@tonic-gate 991*0Sstevel@tonic-gate BIO_puts(out, "\tThis Update: "); 992*0Sstevel@tonic-gate ASN1_GENERALIZEDTIME_print(out, thisupd); 993*0Sstevel@tonic-gate BIO_puts(out, "\n"); 994*0Sstevel@tonic-gate 995*0Sstevel@tonic-gate if(nextupd) 996*0Sstevel@tonic-gate { 997*0Sstevel@tonic-gate BIO_puts(out, "\tNext Update: "); 998*0Sstevel@tonic-gate ASN1_GENERALIZEDTIME_print(out, nextupd); 999*0Sstevel@tonic-gate BIO_puts(out, "\n"); 1000*0Sstevel@tonic-gate } 1001*0Sstevel@tonic-gate 1002*0Sstevel@tonic-gate if (status != V_OCSP_CERTSTATUS_REVOKED) 1003*0Sstevel@tonic-gate continue; 1004*0Sstevel@tonic-gate 1005*0Sstevel@tonic-gate if (reason != -1) 1006*0Sstevel@tonic-gate BIO_printf(out, "\tReason: %s\n", 1007*0Sstevel@tonic-gate OCSP_crl_reason_str(reason)); 1008*0Sstevel@tonic-gate 1009*0Sstevel@tonic-gate BIO_puts(out, "\tRevocation Time: "); 1010*0Sstevel@tonic-gate ASN1_GENERALIZEDTIME_print(out, rev); 1011*0Sstevel@tonic-gate BIO_puts(out, "\n"); 1012*0Sstevel@tonic-gate } 1013*0Sstevel@tonic-gate 1014*0Sstevel@tonic-gate return 1; 1015*0Sstevel@tonic-gate } 1016*0Sstevel@tonic-gate 1017*0Sstevel@tonic-gate 1018*0Sstevel@tonic-gate static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db, 1019*0Sstevel@tonic-gate X509 *ca, X509 *rcert, EVP_PKEY *rkey, 1020*0Sstevel@tonic-gate STACK_OF(X509) *rother, unsigned long flags, 1021*0Sstevel@tonic-gate int nmin, int ndays) 1022*0Sstevel@tonic-gate { 1023*0Sstevel@tonic-gate ASN1_TIME *thisupd = NULL, *nextupd = NULL; 1024*0Sstevel@tonic-gate OCSP_CERTID *cid, *ca_id = NULL; 1025*0Sstevel@tonic-gate OCSP_BASICRESP *bs = NULL; 1026*0Sstevel@tonic-gate int i, id_count, ret = 1; 1027*0Sstevel@tonic-gate 1028*0Sstevel@tonic-gate 1029*0Sstevel@tonic-gate id_count = OCSP_request_onereq_count(req); 1030*0Sstevel@tonic-gate 1031*0Sstevel@tonic-gate if (id_count <= 0) 1032*0Sstevel@tonic-gate { 1033*0Sstevel@tonic-gate *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL); 1034*0Sstevel@tonic-gate goto end; 1035*0Sstevel@tonic-gate } 1036*0Sstevel@tonic-gate 1037*0Sstevel@tonic-gate ca_id = OCSP_cert_to_id(EVP_sha1(), NULL, ca); 1038*0Sstevel@tonic-gate 1039*0Sstevel@tonic-gate bs = OCSP_BASICRESP_new(); 1040*0Sstevel@tonic-gate thisupd = X509_gmtime_adj(NULL, 0); 1041*0Sstevel@tonic-gate if (ndays != -1) 1042*0Sstevel@tonic-gate nextupd = X509_gmtime_adj(NULL, nmin * 60 + ndays * 3600 * 24 ); 1043*0Sstevel@tonic-gate 1044*0Sstevel@tonic-gate /* Examine each certificate id in the request */ 1045*0Sstevel@tonic-gate for (i = 0; i < id_count; i++) 1046*0Sstevel@tonic-gate { 1047*0Sstevel@tonic-gate OCSP_ONEREQ *one; 1048*0Sstevel@tonic-gate ASN1_INTEGER *serial; 1049*0Sstevel@tonic-gate char **inf; 1050*0Sstevel@tonic-gate one = OCSP_request_onereq_get0(req, i); 1051*0Sstevel@tonic-gate cid = OCSP_onereq_get0_id(one); 1052*0Sstevel@tonic-gate /* Is this request about our CA? */ 1053*0Sstevel@tonic-gate if (OCSP_id_issuer_cmp(ca_id, cid)) 1054*0Sstevel@tonic-gate { 1055*0Sstevel@tonic-gate OCSP_basic_add1_status(bs, cid, 1056*0Sstevel@tonic-gate V_OCSP_CERTSTATUS_UNKNOWN, 1057*0Sstevel@tonic-gate 0, NULL, 1058*0Sstevel@tonic-gate thisupd, nextupd); 1059*0Sstevel@tonic-gate continue; 1060*0Sstevel@tonic-gate } 1061*0Sstevel@tonic-gate OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid); 1062*0Sstevel@tonic-gate inf = lookup_serial(db, serial); 1063*0Sstevel@tonic-gate if (!inf) 1064*0Sstevel@tonic-gate OCSP_basic_add1_status(bs, cid, 1065*0Sstevel@tonic-gate V_OCSP_CERTSTATUS_UNKNOWN, 1066*0Sstevel@tonic-gate 0, NULL, 1067*0Sstevel@tonic-gate thisupd, nextupd); 1068*0Sstevel@tonic-gate else if (inf[DB_type][0] == DB_TYPE_VAL) 1069*0Sstevel@tonic-gate OCSP_basic_add1_status(bs, cid, 1070*0Sstevel@tonic-gate V_OCSP_CERTSTATUS_GOOD, 1071*0Sstevel@tonic-gate 0, NULL, 1072*0Sstevel@tonic-gate thisupd, nextupd); 1073*0Sstevel@tonic-gate else if (inf[DB_type][0] == DB_TYPE_REV) 1074*0Sstevel@tonic-gate { 1075*0Sstevel@tonic-gate ASN1_OBJECT *inst = NULL; 1076*0Sstevel@tonic-gate ASN1_TIME *revtm = NULL; 1077*0Sstevel@tonic-gate ASN1_GENERALIZEDTIME *invtm = NULL; 1078*0Sstevel@tonic-gate OCSP_SINGLERESP *single; 1079*0Sstevel@tonic-gate int reason = -1; 1080*0Sstevel@tonic-gate unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]); 1081*0Sstevel@tonic-gate single = OCSP_basic_add1_status(bs, cid, 1082*0Sstevel@tonic-gate V_OCSP_CERTSTATUS_REVOKED, 1083*0Sstevel@tonic-gate reason, revtm, 1084*0Sstevel@tonic-gate thisupd, nextupd); 1085*0Sstevel@tonic-gate if (invtm) 1086*0Sstevel@tonic-gate OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date, invtm, 0, 0); 1087*0Sstevel@tonic-gate else if (inst) 1088*0Sstevel@tonic-gate OCSP_SINGLERESP_add1_ext_i2d(single, NID_hold_instruction_code, inst, 0, 0); 1089*0Sstevel@tonic-gate ASN1_OBJECT_free(inst); 1090*0Sstevel@tonic-gate ASN1_TIME_free(revtm); 1091*0Sstevel@tonic-gate ASN1_GENERALIZEDTIME_free(invtm); 1092*0Sstevel@tonic-gate } 1093*0Sstevel@tonic-gate } 1094*0Sstevel@tonic-gate 1095*0Sstevel@tonic-gate OCSP_copy_nonce(bs, req); 1096*0Sstevel@tonic-gate 1097*0Sstevel@tonic-gate OCSP_basic_sign(bs, rcert, rkey, EVP_sha1(), rother, flags); 1098*0Sstevel@tonic-gate 1099*0Sstevel@tonic-gate *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs); 1100*0Sstevel@tonic-gate 1101*0Sstevel@tonic-gate end: 1102*0Sstevel@tonic-gate ASN1_TIME_free(thisupd); 1103*0Sstevel@tonic-gate ASN1_TIME_free(nextupd); 1104*0Sstevel@tonic-gate OCSP_CERTID_free(ca_id); 1105*0Sstevel@tonic-gate OCSP_BASICRESP_free(bs); 1106*0Sstevel@tonic-gate return ret; 1107*0Sstevel@tonic-gate 1108*0Sstevel@tonic-gate } 1109*0Sstevel@tonic-gate 1110*0Sstevel@tonic-gate static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser) 1111*0Sstevel@tonic-gate { 1112*0Sstevel@tonic-gate int i; 1113*0Sstevel@tonic-gate BIGNUM *bn = NULL; 1114*0Sstevel@tonic-gate char *itmp, *row[DB_NUMBER],**rrow; 1115*0Sstevel@tonic-gate for (i = 0; i < DB_NUMBER; i++) row[i] = NULL; 1116*0Sstevel@tonic-gate bn = ASN1_INTEGER_to_BN(ser,NULL); 1117*0Sstevel@tonic-gate if (BN_is_zero(bn)) 1118*0Sstevel@tonic-gate itmp = BUF_strdup("00"); 1119*0Sstevel@tonic-gate else 1120*0Sstevel@tonic-gate itmp = BN_bn2hex(bn); 1121*0Sstevel@tonic-gate row[DB_serial] = itmp; 1122*0Sstevel@tonic-gate BN_free(bn); 1123*0Sstevel@tonic-gate rrow=TXT_DB_get_by_index(db->db,DB_serial,row); 1124*0Sstevel@tonic-gate OPENSSL_free(itmp); 1125*0Sstevel@tonic-gate return rrow; 1126*0Sstevel@tonic-gate } 1127*0Sstevel@tonic-gate 1128*0Sstevel@tonic-gate /* Quick and dirty OCSP server: read in and parse input request */ 1129*0Sstevel@tonic-gate 1130*0Sstevel@tonic-gate static BIO *init_responder(char *port) 1131*0Sstevel@tonic-gate { 1132*0Sstevel@tonic-gate BIO *acbio = NULL, *bufbio = NULL; 1133*0Sstevel@tonic-gate bufbio = BIO_new(BIO_f_buffer()); 1134*0Sstevel@tonic-gate if (!bufbio) 1135*0Sstevel@tonic-gate goto err; 1136*0Sstevel@tonic-gate #ifndef OPENSSL_NO_SOCK 1137*0Sstevel@tonic-gate acbio = BIO_new_accept(port); 1138*0Sstevel@tonic-gate #else 1139*0Sstevel@tonic-gate BIO_printf(bio_err, "Error setting up accept BIO - sockets not supported.\n"); 1140*0Sstevel@tonic-gate #endif 1141*0Sstevel@tonic-gate if (!acbio) 1142*0Sstevel@tonic-gate goto err; 1143*0Sstevel@tonic-gate BIO_set_accept_bios(acbio, bufbio); 1144*0Sstevel@tonic-gate bufbio = NULL; 1145*0Sstevel@tonic-gate 1146*0Sstevel@tonic-gate if (BIO_do_accept(acbio) <= 0) 1147*0Sstevel@tonic-gate { 1148*0Sstevel@tonic-gate BIO_printf(bio_err, "Error setting up accept BIO\n"); 1149*0Sstevel@tonic-gate ERR_print_errors(bio_err); 1150*0Sstevel@tonic-gate goto err; 1151*0Sstevel@tonic-gate } 1152*0Sstevel@tonic-gate 1153*0Sstevel@tonic-gate return acbio; 1154*0Sstevel@tonic-gate 1155*0Sstevel@tonic-gate err: 1156*0Sstevel@tonic-gate BIO_free_all(acbio); 1157*0Sstevel@tonic-gate BIO_free(bufbio); 1158*0Sstevel@tonic-gate return NULL; 1159*0Sstevel@tonic-gate } 1160*0Sstevel@tonic-gate 1161*0Sstevel@tonic-gate static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port) 1162*0Sstevel@tonic-gate { 1163*0Sstevel@tonic-gate int have_post = 0, len; 1164*0Sstevel@tonic-gate OCSP_REQUEST *req = NULL; 1165*0Sstevel@tonic-gate char inbuf[1024]; 1166*0Sstevel@tonic-gate BIO *cbio = NULL; 1167*0Sstevel@tonic-gate 1168*0Sstevel@tonic-gate if (BIO_do_accept(acbio) <= 0) 1169*0Sstevel@tonic-gate { 1170*0Sstevel@tonic-gate BIO_printf(bio_err, "Error accepting connection\n"); 1171*0Sstevel@tonic-gate ERR_print_errors(bio_err); 1172*0Sstevel@tonic-gate return 0; 1173*0Sstevel@tonic-gate } 1174*0Sstevel@tonic-gate 1175*0Sstevel@tonic-gate cbio = BIO_pop(acbio); 1176*0Sstevel@tonic-gate *pcbio = cbio; 1177*0Sstevel@tonic-gate 1178*0Sstevel@tonic-gate for(;;) 1179*0Sstevel@tonic-gate { 1180*0Sstevel@tonic-gate len = BIO_gets(cbio, inbuf, sizeof inbuf); 1181*0Sstevel@tonic-gate if (len <= 0) 1182*0Sstevel@tonic-gate return 1; 1183*0Sstevel@tonic-gate /* Look for "POST" signalling start of query */ 1184*0Sstevel@tonic-gate if (!have_post) 1185*0Sstevel@tonic-gate { 1186*0Sstevel@tonic-gate if(strncmp(inbuf, "POST", 4)) 1187*0Sstevel@tonic-gate { 1188*0Sstevel@tonic-gate BIO_printf(bio_err, "Invalid request\n"); 1189*0Sstevel@tonic-gate return 1; 1190*0Sstevel@tonic-gate } 1191*0Sstevel@tonic-gate have_post = 1; 1192*0Sstevel@tonic-gate } 1193*0Sstevel@tonic-gate /* Look for end of headers */ 1194*0Sstevel@tonic-gate if ((inbuf[0] == '\r') || (inbuf[0] == '\n')) 1195*0Sstevel@tonic-gate break; 1196*0Sstevel@tonic-gate } 1197*0Sstevel@tonic-gate 1198*0Sstevel@tonic-gate /* Try to read OCSP request */ 1199*0Sstevel@tonic-gate 1200*0Sstevel@tonic-gate req = d2i_OCSP_REQUEST_bio(cbio, NULL); 1201*0Sstevel@tonic-gate 1202*0Sstevel@tonic-gate if (!req) 1203*0Sstevel@tonic-gate { 1204*0Sstevel@tonic-gate BIO_printf(bio_err, "Error parsing OCSP request\n"); 1205*0Sstevel@tonic-gate ERR_print_errors(bio_err); 1206*0Sstevel@tonic-gate } 1207*0Sstevel@tonic-gate 1208*0Sstevel@tonic-gate *preq = req; 1209*0Sstevel@tonic-gate 1210*0Sstevel@tonic-gate return 1; 1211*0Sstevel@tonic-gate 1212*0Sstevel@tonic-gate } 1213*0Sstevel@tonic-gate 1214*0Sstevel@tonic-gate static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp) 1215*0Sstevel@tonic-gate { 1216*0Sstevel@tonic-gate char http_resp[] = 1217*0Sstevel@tonic-gate "HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n" 1218*0Sstevel@tonic-gate "Content-Length: %d\r\n\r\n"; 1219*0Sstevel@tonic-gate if (!cbio) 1220*0Sstevel@tonic-gate return 0; 1221*0Sstevel@tonic-gate BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL)); 1222*0Sstevel@tonic-gate i2d_OCSP_RESPONSE_bio(cbio, resp); 1223*0Sstevel@tonic-gate BIO_flush(cbio); 1224*0Sstevel@tonic-gate return 1; 1225*0Sstevel@tonic-gate } 1226*0Sstevel@tonic-gate 1227*0Sstevel@tonic-gate #endif 1228