Fix typo.
[openssl.git] / apps / ocsp.c
index cec2f2b8090f65a5c837498bbd53614be7b104b0..723e0dc9ab9554d381f22771aabd0107cd96b5c2 100644 (file)
@@ -61,6 +61,7 @@
 #include <openssl/pem.h>
 #include <openssl/ocsp.h>
 #include <openssl/err.h>
+#include <openssl/ssl.h>
 #include "apps.h"
 
 static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer,
@@ -78,12 +79,12 @@ int MAIN(int, char **);
 int MAIN(int argc, char **argv)
        {
        char **args;
-       char *host = NULL, *path = "/";
+       char *host = NULL, *port = NULL, *path = "/";
        char *reqin = NULL, *respin = NULL;
        char *reqout = NULL, *respout = NULL;
        char *signfile = NULL, *keyfile = NULL;
        char *outfile = NULL;
-       int add_nonce = 1, noverify = 0;
+       int add_nonce = 1, noverify = 0, use_ssl = -1;
        OCSP_REQUEST *req = NULL;
        OCSP_RESPONSE *resp = NULL;
        OCSP_BASICRESP *bs = NULL;
@@ -95,13 +96,17 @@ int MAIN(int argc, char **argv)
        int req_text = 0, resp_text = 0;
        char *CAfile = NULL, *CApath = NULL;
        X509_STORE *store = NULL;
+       SSL_CTX *ctx = NULL;
+       STACK_OF(X509) *sign_other = NULL, *verify_other = NULL;
+       char *sign_certfile = NULL, *verify_certfile = NULL;
+       unsigned long sign_flags = 0, verify_flags = 0;
        int ret = 1;
        int badarg = 0;
        int i;
        STACK *reqnames = NULL;
        STACK_OF(OCSP_CERTID) *ids = NULL;
        if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
-       ERR_load_crypto_strings();
+       SSL_load_error_strings();
        args = argv + 1;
        reqnames = sk_new_null();
        ids = sk_OCSP_CERTID_new_null();
@@ -116,6 +121,19 @@ int MAIN(int argc, char **argv)
                                }
                        else badarg = 1;
                        }
+               else if (!strcmp(*args, "-url"))
+                       {
+                       if (args[1])
+                               {
+                               args++;
+                               if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl))
+                                       {
+                                       BIO_printf(bio_err, "Error parsing URL\n");
+                                       badarg = 1;
+                                       }
+                               }
+                       else badarg = 1;
+                       }
                else if (!strcmp(*args, "-host"))
                        {
                        if (args[1])
@@ -131,6 +149,22 @@ int MAIN(int argc, char **argv)
                        add_nonce = 2;
                else if (!strcmp(*args, "-no_nonce"))
                        add_nonce = 0;
+               else if (!strcmp(*args, "-no_certs"))
+                       sign_flags |= OCSP_NOCERTS;
+               else if (!strcmp(*args, "-no_signature_verify"))
+                       verify_flags |= OCSP_NOSIGS;
+               else if (!strcmp(*args, "-no_cert_verify"))
+                       verify_flags |= OCSP_NOVERIFY;
+               else if (!strcmp(*args, "-no_chain"))
+                       verify_flags |= OCSP_NOCHAIN;
+               else if (!strcmp(*args, "-no_cert_checks"))
+                       verify_flags |= OCSP_NOCHECKS;
+               else if (!strcmp(*args, "-no_explicit"))
+                       verify_flags |= OCSP_NOEXPLICIT;
+               else if (!strcmp(*args, "-trust_other"))
+                       verify_flags |= OCSP_TRUSTOTHER;
+               else if (!strcmp(*args, "-no_intern"))
+                       verify_flags |= OCSP_NOINTERN;
                else if (!strcmp(*args, "-text"))
                        {
                        req_text = 1;
@@ -167,6 +201,34 @@ int MAIN(int argc, char **argv)
                                }
                        else badarg = 1;
                        }
+               else if (!strcmp (*args, "-VAfile"))
+                       {
+                       if (args[1])
+                               {
+                               args++;
+                               verify_certfile = *args;
+                               verify_flags |= OCSP_TRUSTOTHER;
+                               }
+                       else badarg = 1;
+                       }
+               else if (!strcmp(*args, "-sign_other"))
+                       {
+                       if (args[1])
+                               {
+                               args++;
+                               sign_certfile = *args;
+                               }
+                       else badarg = 1;
+                       }
+               else if (!strcmp(*args, "-verify_other"))
+                       {
+                       if (args[1])
+                               {
+                               args++;
+                               verify_certfile = *args;
+                               }
+                       else badarg = 1;
+                       }
                else if (!strcmp (*args, "-CAfile"))
                        {
                        if (args[1])
@@ -271,26 +333,37 @@ int MAIN(int argc, char **argv)
                BIO_printf (bio_err, "OCSP utility\n");
                BIO_printf (bio_err, "Usage ocsp [options]\n");
                BIO_printf (bio_err, "where options are\n");
-               BIO_printf (bio_err, "-out file     output filename\n");
-               BIO_printf (bio_err, "-issuer file  issuer certificate\n");
-               BIO_printf (bio_err, "-cert file    certificate to check\n");
-               BIO_printf (bio_err, "-serial n     serial number to check\n");
-               BIO_printf (bio_err, "-signer file  certificate to sign OCSP request with\n");
-               BIO_printf (bio_err, "-signkey file private key to sign OCSP request with\n");
-               BIO_printf (bio_err, "-req_text     print text form of request\n");
-               BIO_printf (bio_err, "-resp_text    print text form of response\n");
-               BIO_printf (bio_err, "-text         print text form of request and response\n");
-               BIO_printf (bio_err, "-reqout file  write DER encoded OCSP request to \"file\"\n");
-               BIO_printf (bio_err, "-respout file write DER encoded OCSP reponse to \"file\"\n");
-               BIO_printf (bio_err, "-reqin file   read DER encoded OCSP request from \"file\"\n");
-               BIO_printf (bio_err, "-respin file  read DER encoded OCSP reponse from \"file\"\n");
-               BIO_printf (bio_err, "-nonce        add OCSP nonce to request\n");
-               BIO_printf (bio_err, "-no_nonce     don't add OCSP nonce to request\n");
-               BIO_printf (bio_err, "-host host:n  send OCSP request to host on port n\n");
-               BIO_printf (bio_err, "-path         path to use in OCSP request\n");
-               BIO_printf (bio_err, "-CApath dir   trusted certificates directory\n");
-               BIO_printf (bio_err, "-CAfile file  trusted certificates file\n");
-               BIO_printf (bio_err, "-noverify     don't verify response\n");
+               BIO_printf (bio_err, "-out file          output filename\n");
+               BIO_printf (bio_err, "-issuer file       issuer certificate\n");
+               BIO_printf (bio_err, "-cert file         certificate to check\n");
+               BIO_printf (bio_err, "-serial n          serial number to check\n");
+               BIO_printf (bio_err, "-signer file       certificate to sign OCSP request with\n");
+               BIO_printf (bio_err, "-signkey file      private key to sign OCSP request with\n");
+               BIO_printf (bio_err, "-sign_certs file   additional certificates to include in signed request\n");
+               BIO_printf (bio_err, "-no_certs          don't include any certificates in signed request\n");
+               BIO_printf (bio_err, "-req_text          print text form of request\n");
+               BIO_printf (bio_err, "-resp_text         print text form of response\n");
+               BIO_printf (bio_err, "-text              print text form of request and response\n");
+               BIO_printf (bio_err, "-reqout file       write DER encoded OCSP request to \"file\"\n");
+               BIO_printf (bio_err, "-respout file      write DER encoded OCSP reponse to \"file\"\n");
+               BIO_printf (bio_err, "-reqin file        read DER encoded OCSP request from \"file\"\n");
+               BIO_printf (bio_err, "-respin file       read DER encoded OCSP reponse from \"file\"\n");
+               BIO_printf (bio_err, "-nonce             add OCSP nonce to request\n");
+               BIO_printf (bio_err, "-no_nonce          don't add OCSP nonce to request\n");
+               BIO_printf (bio_err, "-url URL           OCSP responder URL\n");
+               BIO_printf (bio_err, "-host host:n       send OCSP request to host on port n\n");
+               BIO_printf (bio_err, "-path              path to use in OCSP request\n");
+               BIO_printf (bio_err, "-CApath dir        trusted certificates directory\n");
+               BIO_printf (bio_err, "-CAfile file       trusted certificates file\n");
+               BIO_printf (bio_err, "-VAfile file       validator certificates file\n");
+               BIO_printf (bio_err, "-noverify          don't verify response at all\n");
+               BIO_printf (bio_err, "-verify_certs file additional certificates to search for signer\n");
+               BIO_printf (bio_err, "-trust_other       don't verify additional certificates\n");
+               BIO_printf (bio_err, "-no_intern         don't search certificates contained in response for signer\n");
+               BIO_printf (bio_err, "-no_sig_verify     don't check signature on response\n");
+               BIO_printf (bio_err, "-no_cert_verify    don't check signing certificate\n");
+               BIO_printf (bio_err, "-no_chain          don't chain verify response\n");
+               BIO_printf (bio_err, "-no_cert_checks    don't do additional checks on signing certificate\n");
                goto end;
                }
 
@@ -339,13 +412,18 @@ int MAIN(int argc, char **argv)
                        BIO_printf(bio_err, "Error loading signer certificate\n");
                        goto end;
                        }
+               if (sign_certfile)
+                       {
+                       sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM);
+                       if (!sign_other) goto end;
+                       }
                key = load_key(bio_err, keyfile, FORMAT_PEM, NULL, NULL);
                if (!key)
                        {
                        BIO_printf(bio_err, "Error loading signer private key\n");
                        goto end;
                        }
-               if (!OCSP_request_sign(req, signer, key, EVP_sha1(), NULL, 0))
+               if (!OCSP_request_sign(req, signer, key, EVP_sha1(), sign_other, sign_flags))
                        {
                        BIO_printf(bio_err, "Error signing OCSP request\n");
                        goto end;
@@ -374,13 +452,22 @@ int MAIN(int argc, char **argv)
                        BIO_printf(bio_err, "Error creating connect BIO\n");
                        goto end;
                        }
+               if (port) BIO_set_conn_port(cbio, port);
+               if (use_ssl == 1)
+                       {
+                       BIO *sbio;
+                       ctx = SSL_CTX_new(SSLv23_client_method());
+                       SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
+                       sbio = BIO_new_ssl(ctx, 1);
+                       cbio = BIO_push(sbio, cbio);
+                       }
                if (BIO_do_connect(cbio) <= 0)
                        {
                        BIO_printf(bio_err, "Error connecting BIO\n");
                        goto end;
                        }
                resp = OCSP_sendreq_bio(cbio, path, req);
-               BIO_free(cbio);
+               BIO_free_all(cbio);
                cbio = NULL;
                if (!resp)
                        {
@@ -437,6 +524,11 @@ int MAIN(int argc, char **argv)
 
        store = setup_verify(bio_err, CAfile, CApath);
        if(!store) goto end;
+       if (verify_certfile)
+               {
+               verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM);
+               if (!verify_other) goto end;
+               }
 
        bs = OCSP_response_get1_basic(resp);
 
@@ -448,13 +540,19 @@ int MAIN(int argc, char **argv)
 
        if (!noverify)
                {
-               if (req && (OCSP_check_nonce(req, bs) <= 0))
+               if (req && ((i = OCSP_check_nonce(req, bs)) <= 0))
                        {
-                       BIO_printf(bio_err, "Nonce Verify error\n");
-                       goto end;
+                       if (i == -1)
+                               BIO_printf(bio_err, "WARNING: no nonce in response\n");
+                       else
+                               {
+                               BIO_printf(bio_err, "Nonce Verify error\n");
+                               goto end;
+                               }
                        }
 
-               i = OCSP_basic_verify(bs, NULL, store, 0);
+               i = OCSP_basic_verify(bs, verify_other, store, verify_flags);
+                if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0);
 
                if(i <= 0)
                        {
@@ -478,13 +576,23 @@ end:
        EVP_PKEY_free(key);
        X509_free(issuer);
        X509_free(cert);
-       BIO_free(cbio);
+       BIO_free_all(cbio);
        BIO_free(out);
        OCSP_REQUEST_free(req);
        OCSP_RESPONSE_free(resp);
        OCSP_BASICRESP_free(bs);
        sk_free(reqnames);
        sk_OCSP_CERTID_free(ids);
+       sk_X509_pop_free(sign_other, X509_free);
+       sk_X509_pop_free(verify_other, X509_free);
+
+       if (use_ssl != -1)
+               {
+               OPENSSL_free(host);
+               OPENSSL_free(port);
+               OPENSSL_free(path);
+               SSL_CTX_free(ctx);
+               }
 
        EXIT(ret);
 }
@@ -578,7 +686,7 @@ static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
                if(nextupd)
                        {
                        BIO_puts(out, "\tNext Update: ");
-                       ASN1_GENERALIZEDTIME_print(out, thisupd);
+                       ASN1_GENERALIZEDTIME_print(out, nextupd);
                        BIO_puts(out, "\n");
                        }