Пример #1
0
/**
 * Print info about the verification engine
 */
static void verify_info(ssl_server_connection *ssl_server) {

    STACK_OF(X509_NAME) *stack;

    stack=SSL_CTX_get_client_CA_list(ssl_server->ctx);
    log("%s: verify_info(): Found %d client certificates\n", prog,
        sk_X509_NAME_num(stack));

}
Пример #2
0
/**
 * Initializes a ssl connection for server use.
 * @param pemfilename Filename for the key/cert file
 * @return An ssl connection, or NULL if an error occured.
 */
ssl_server_connection *init_ssl_server(char *pemfile, char *clientpemfile) {
        ASSERT(pemfile);
        if (!ssl_initialized)
                start_ssl();
        ssl_server_connection *ssl_server = new_ssl_server_connection(pemfile, clientpemfile);
        if (!(ssl_server->method = SSLv23_server_method())) {
                LogError("Cannot initialize the SSL method -- %s\n", SSLERROR);
                goto sslerror;
        }
        if (!(ssl_server->ctx = SSL_CTX_new(ssl_server->method))) {
                LogError("Cannot initialize SSL server certificate handler -- %s\n", SSLERROR);
                goto sslerror;
        }
        if (SSL_CTX_use_certificate_chain_file(ssl_server->ctx, pemfile) != 1) {
                LogError("Cannot initialize SSL server certificate -- %s\n", SSLERROR);
                goto sslerror;
        }
        if (SSL_CTX_use_PrivateKey_file(ssl_server->ctx, pemfile, SSL_FILETYPE_PEM) != 1) {
                LogError("Cannot initialize SSL server private key -- %s\n", SSLERROR);
                goto sslerror;
        }
        if (SSL_CTX_check_private_key(ssl_server->ctx) != 1) {
                LogError("The private key doesn't match the certificate public key -- %s\n", SSLERROR);
                goto sslerror;
        }
        if (SSL_CTX_set_cipher_list(ssl_server->ctx, CIPHER_LIST) != 1) {
                LogError("Error setting cipher list '%s' (no valid ciphers)\n", CIPHER_LIST);
                goto sslerror;
        }
        SSL_CTX_set_options(ssl_server->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); // Disable SSLv2 and SSLv3 for security reasons
        SSL_CTX_set_session_cache_mode(ssl_server->ctx, SSL_SESS_CACHE_OFF); // Disable session cache
        /*
         * We need this to force transmission of client certs
         */
        if (!verify_init(ssl_server)) {
                LogError("Verification engine was not properly initialized -- %s\n", SSLERROR);
                goto sslerror;
        }
        if (ssl_server->clientpemfile) {
                STACK_OF(X509_NAME) *stack = SSL_CTX_get_client_CA_list(ssl_server->ctx);
                LogInfo("Found %d client certificates\n", sk_X509_NAME_num(stack));
        }
        return ssl_server;
sslerror:
        delete_ssl_server_socket(ssl_server);
        return NULL;
}
Пример #3
0
static int
cert_select_callback (SSL *ssl, void *arg)
{
	MonoBtlsSslCtx *ptr = (MonoBtlsSslCtx*)arg;
	STACK_OF(X509_NAME) *ca_list;
	int *sizes = NULL;
	void **cadata = NULL;
	int count = 0;
	int ret = 1;
	int i;

	debug_printf (ptr, "cert_select_callback(): %p\n", ptr->select_func);

	// SSL_get_client_CA_list() may only be called during this callback.
	ca_list = SSL_get_client_CA_list (ssl);
	if (ca_list) {
		count = (int)sk_X509_NAME_num (ca_list);
		cadata = OPENSSL_malloc (sizeof (void *) * (count + 1));
		sizes = OPENSSL_malloc (sizeof (int) * (count + 1));
		if (!cadata || !sizes) {
			ret = 0;
			goto out;
		}
		for (i = 0; i < count; i++) {
			X509_NAME *name = sk_X509_NAME_value (ca_list, i);
			cadata[i] = name->bytes->data;
			sizes[i] = (int)name->bytes->length;
		}
	}

	debug_printf (ptr, "cert_select_callback() #1: %p\n", ca_list);

	if (ptr->select_func)
		ret = ptr->select_func (ptr->instance, count, sizes, cadata);
	debug_printf (ptr, "cert_select_callback() #1: %d\n", ret);

out:
	if (cadata)
		OPENSSL_free (cadata);
	if (sizes)
		OPENSSL_free (sizes);

	return ret;
}
Пример #4
0
static PyObject *
ssl_Connection_get_client_ca_list(ssl_ConnectionObj *self, PyObject *args) {
    STACK_OF(X509_NAME) *CANames;
    PyObject *CAList;
    int i, n;

    if (!PyArg_ParseTuple(args, ":get_client_ca_list")) {
        return NULL;
    }
    CANames = SSL_get_client_CA_list(self->ssl);
    if (CANames == NULL) {
        return PyList_New(0);
    }
    n = sk_X509_NAME_num(CANames);
    CAList = PyList_New(n);
    if (CAList == NULL) {
        return NULL;
    }
    for (i = 0; i < n; i++) {
        X509_NAME *CAName;
        PyObject *CA;

        CAName = X509_NAME_dup(sk_X509_NAME_value(CANames, i));
        if (CAName == NULL) {
            Py_DECREF(CAList);
            exception_from_error_queue(ssl_Error);
            return NULL;
        }
        CA = (PyObject *)new_x509name(CAName, 1);
        if (CA == NULL) {
            X509_NAME_free(CAName);
            Py_DECREF(CAList);
            return NULL;
        }
        if (PyList_SetItem(CAList, i, CA)) {
            Py_DECREF(CA);
            Py_DECREF(CAList);
            return NULL;
        }
    }
    return CAList;
}
Пример #5
0
static void print_stuff(BIO *bio, SSL *s, int full)
{
    X509 *peer=NULL;
    char *p;
    static const char *space="                ";
    char buf[BUFSIZ];
    STACK_OF(X509) *sk;
    STACK_OF(X509_NAME) *sk2;
    SSL_CIPHER *c;
    X509_NAME *xn;
    int j,i;
#ifndef OPENSSL_NO_COMP
    const COMP_METHOD *comp, *expansion;
#endif

    if (full)
    {
        int got_a_chain = 0;

        sk=SSL_get_peer_cert_chain(s);
        if (sk != NULL)
        {
            got_a_chain = 1; /* we don't have it for SSL2 (yet) */

            BIO_printf(bio,"---\nCertificate chain\n");
            for (i=0; i<sk_X509_num(sk); i++)
            {
                X509_NAME_oneline(X509_get_subject_name(
                                      sk_X509_value(sk,i)),buf,sizeof buf);
                BIO_printf(bio,"%2d s:%s\n",i,buf);
                X509_NAME_oneline(X509_get_issuer_name(
                                      sk_X509_value(sk,i)),buf,sizeof buf);
                BIO_printf(bio,"   i:%s\n",buf);
                if (c_showcerts)
                    PEM_write_bio_X509(bio,sk_X509_value(sk,i));
            }
        }

        BIO_printf(bio,"---\n");
        peer=SSL_get_peer_certificate(s);
        if (peer != NULL)
        {
            BIO_printf(bio,"Server certificate\n");
            if (!(c_showcerts && got_a_chain)) /* Redundant if we showed the whole chain */
                PEM_write_bio_X509(bio,peer);
            X509_NAME_oneline(X509_get_subject_name(peer),
                              buf,sizeof buf);
            BIO_printf(bio,"subject=%s\n",buf);
            X509_NAME_oneline(X509_get_issuer_name(peer),
                              buf,sizeof buf);
            BIO_printf(bio,"issuer=%s\n",buf);
        }
        else
            BIO_printf(bio,"no peer certificate available\n");

        sk2=SSL_get_client_CA_list(s);
        if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0))
        {
            BIO_printf(bio,"---\nAcceptable client certificate CA names\n");
            for (i=0; i<sk_X509_NAME_num(sk2); i++)
            {
                xn=sk_X509_NAME_value(sk2,i);
                X509_NAME_oneline(xn,buf,sizeof(buf));
                BIO_write(bio,buf,strlen(buf));
                BIO_write(bio,"\n",1);
            }
        }
        else
        {
            BIO_printf(bio,"---\nNo client certificate CA names sent\n");
        }
        p=SSL_get_shared_ciphers(s,buf,sizeof buf);
        if (p != NULL)
        {
            /* This works only for SSL 2.  In later protocol
             * versions, the client does not know what other
             * ciphers (in addition to the one to be used
             * in the current connection) the server supports. */

            BIO_printf(bio,"---\nCiphers common between both SSL endpoints:\n");
            j=i=0;
            while (*p)
            {
                if (*p == ':')
                {
                    BIO_write(bio,space,15-j%25);
                    i++;
                    j=0;
                    BIO_write(bio,((i%3)?" ":"\n"),1);
                }
                else
                {
                    BIO_write(bio,p,1);
                    j++;
                }
                p++;
            }
            BIO_write(bio,"\n",1);
        }

        BIO_printf(bio,"---\nSSL handshake has read %ld bytes and written %ld bytes\n",
                   BIO_number_read(SSL_get_rbio(s)),
                   BIO_number_written(SSL_get_wbio(s)));
    }
    BIO_printf(bio,((s->hit)?"---\nReused, ":"---\nNew, "));
    c=SSL_get_current_cipher(s);
    BIO_printf(bio,"%s, Cipher is %s\n",
               SSL_CIPHER_get_version(c),
               SSL_CIPHER_get_name(c));
    if (peer != NULL) {
        EVP_PKEY *pktmp;
        pktmp = X509_get_pubkey(peer);
        BIO_printf(bio,"Server public key is %d bit\n",
                   EVP_PKEY_bits(pktmp));
        EVP_PKEY_free(pktmp);
    }
#ifndef OPENSSL_NO_COMP
    comp=SSL_get_current_compression(s);
    expansion=SSL_get_current_expansion(s);
    BIO_printf(bio,"Compression: %s\n",
               comp ? SSL_COMP_get_name(comp) : "NONE");
    BIO_printf(bio,"Expansion: %s\n",
               expansion ? SSL_COMP_get_name(expansion) : "NONE");
#endif
    SSL_SESSION_print(bio,SSL_get_session(s));
    BIO_printf(bio,"---\n");
    if (peer != NULL)
        X509_free(peer);
    /* flush, or debugging output gets mixed with http response */
    (void)BIO_flush(bio);
}
Пример #6
0
static void ssl_init_ctx_verify(server_rec *s,
                                apr_pool_t *p,
                                apr_pool_t *ptemp,
                                modssl_ctx_t *mctx)
{
    SSL_CTX *ctx = mctx->ssl_ctx;

    int verify = SSL_VERIFY_NONE;
    STACK_OF(X509_NAME) *ca_list;

    if (mctx->auth.verify_mode == SSL_CVERIFY_UNSET) {
        mctx->auth.verify_mode = SSL_CVERIFY_NONE;
    }

    if (mctx->auth.verify_depth == UNSET) {
        mctx->auth.verify_depth = 1;
    }

    /*
     *  Configure callbacks for SSL context
     */
    if (mctx->auth.verify_mode == SSL_CVERIFY_REQUIRE) {
        verify |= SSL_VERIFY_PEER_STRICT;
    }

    if ((mctx->auth.verify_mode == SSL_CVERIFY_OPTIONAL) ||
        (mctx->auth.verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA))
    {
        verify |= SSL_VERIFY_PEER;
    }

    SSL_CTX_set_verify(ctx, verify, ssl_callback_SSLVerify);

    /*
     * Configure Client Authentication details
     */
    if (mctx->auth.ca_cert_file || mctx->auth.ca_cert_path) {
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                     "Configuring client authentication");

        if (!SSL_CTX_load_verify_locations(ctx,
                         MODSSL_PCHAR_CAST mctx->auth.ca_cert_file,
                         MODSSL_PCHAR_CAST mctx->auth.ca_cert_path))
        {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                    "Unable to configure verify locations "
                    "for client authentication");
            ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
            ssl_die();
        }

        if (mctx->pks && (mctx->pks->ca_name_file || mctx->pks->ca_name_path)) {
            ca_list = ssl_init_FindCAList(s, ptemp,
                                          mctx->pks->ca_name_file,
                                          mctx->pks->ca_name_path);
        } else
            ca_list = ssl_init_FindCAList(s, ptemp,
                                          mctx->auth.ca_cert_file,
                                          mctx->auth.ca_cert_path);
        if (!ca_list) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                    "Unable to determine list of acceptable "
                    "CA certificates for client authentication");
            ssl_die();
        }

        SSL_CTX_set_client_CA_list(ctx, (STACK *)ca_list);
    }

    /*
     * Give a warning when no CAs were configured but client authentication
     * should take place. This cannot work.
     */
    if (mctx->auth.verify_mode == SSL_CVERIFY_REQUIRE) {
        ca_list = (STACK_OF(X509_NAME) *)SSL_CTX_get_client_CA_list(ctx);

        if (sk_X509_NAME_num(ca_list) == 0) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
                         "Init: Oops, you want to request client "
                         "authentication, but no CAs are known for "
                         "verification!?  [Hint: SSLCACertificate*]");
        }
    }
Пример #7
0
void
tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file,
    const char *ca_file_inline,
    const char *ca_path, bool tls_server
    )
{
  STACK_OF(X509_INFO) *info_stack = NULL;
  STACK_OF(X509_NAME) *cert_names = NULL;
  X509_LOOKUP *lookup = NULL;
  X509_STORE *store = NULL;
  X509_NAME *xn = NULL;
  BIO *in = NULL;
  int i, added = 0;

  ASSERT(NULL != ctx);

  store = SSL_CTX_get_cert_store(ctx->ctx);
  if (!store)
    msg(M_SSLERR, "Cannot get certificate store (SSL_CTX_get_cert_store)");

  /* Try to add certificates and CRLs from ca_file */
  if (ca_file)
    {
      if (!strcmp (ca_file, INLINE_FILE_TAG) && ca_file_inline)
        in = BIO_new_mem_buf ((char *)ca_file_inline, -1);
      else
        in = BIO_new_file (ca_file, "r");

      if (in)
        info_stack = PEM_X509_INFO_read_bio (in, NULL, NULL, NULL);

      if (info_stack)
        {
          for (i = 0; i < sk_X509_INFO_num (info_stack); i++)
            {
              X509_INFO *info = sk_X509_INFO_value (info_stack, i);
              if (info->crl)
                  X509_STORE_add_crl (store, info->crl);

              if (info->x509)
                {
                  X509_STORE_add_cert (store, info->x509);
                  added++;

                  if (!tls_server)
                    continue;

                  /* Use names of CAs as a client CA list */
                  if (cert_names == NULL)
                    {
                      cert_names = sk_X509_NAME_new (sk_x509_name_cmp);
                      if (!cert_names)
                        continue;
                    }

                  xn = X509_get_subject_name (info->x509);
                  if (!xn)
                    continue;

                  /* Don't add duplicate CA names */
                  if (sk_X509_NAME_find (cert_names, xn) == -1)
                    {
                      xn = X509_NAME_dup (xn);
                      if (!xn)
                        continue;
                      sk_X509_NAME_push (cert_names, xn);
                    }
                }
            }
          sk_X509_INFO_pop_free (info_stack, X509_INFO_free);
        }

      if (tls_server)
        SSL_CTX_set_client_CA_list (ctx->ctx, cert_names);

      if (!added || (tls_server && sk_X509_NAME_num (cert_names) != added))
        msg (M_SSLERR, "Cannot load CA certificate file %s", np(ca_file));
      if (in)
        BIO_free (in);
    }

  /* Set a store for certs (CA & CRL) with a lookup on the "capath" hash directory */
  if (ca_path)
    {
      lookup = X509_STORE_add_lookup (store, X509_LOOKUP_hash_dir ());
      if (lookup && X509_LOOKUP_add_dir (lookup, ca_path, X509_FILETYPE_PEM))
        msg(M_WARN, "WARNING: experimental option --capath %s", ca_path);
      else
        msg(M_SSLERR, "Cannot add lookup at --capath %s", ca_path);
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
      X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
#else
      msg(M_WARN, "WARNING: this version of OpenSSL cannot handle CRL files in capath");
#endif
    }
}
Пример #8
0
/**
 * Initializes a ssl connection for server use.
 * @param pemfilename Filename for the key/cert file
 * @return An ssl connection, or NULL if an error occured.
 */
ssl_server_connection *init_ssl_server(char *pemfile, char *clientpemfile) {
  SSL_METHOD *server_method = NULL;
  ssl_server_connection *ssl_server;

  ASSERT(pemfile);

  if (!ssl_initialized)
    start_ssl();

  ssl_server = new_ssl_server_connection(pemfile, clientpemfile);
#ifdef OPENSSL_FIPS
  if (FIPS_mode())
    server_method = TLSv1_server_method();
  else
#endif
    server_method = SSLv23_server_method();
  if (!(ssl_server->method = server_method)) {
    LogError("%s: Cannot initialize the SSL method -- %s\n", prog, SSLERROR);
    goto sslerror;
  }

  if (!(ssl_server->ctx = SSL_CTX_new(ssl_server->method))) {
    LogError("%s: Cannot initialize SSL server certificate handler -- %s\n", prog, SSLERROR);
    goto sslerror;
  }

  if (SSL_CTX_use_certificate_chain_file(ssl_server->ctx, pemfile) != 1) {
    LogError("%s: Cannot initialize SSL server certificate -- %s\n", prog, SSLERROR);
    goto sslerror;
  }

  if (SSL_CTX_use_PrivateKey_file(ssl_server->ctx, pemfile, SSL_FILETYPE_PEM) != 1) {
    LogError("%s: Cannot initialize SSL server private key -- %s\n", prog, SSLERROR);
    goto sslerror;
  }

  if (SSL_CTX_check_private_key(ssl_server->ctx) != 1) {
    LogError("%s: The private key doesn't match the certificate public key -- %s\n", prog, SSLERROR);
    goto sslerror;
  }

  /* Disable session cache */
  SSL_CTX_set_session_cache_mode(ssl_server->ctx, SSL_SESS_CACHE_OFF);

  /*
   * We need this to force transmission of client certs
   */
  if (!verify_init(ssl_server)) {
    LogError("%s: Verification engine was not properly initialized -- %s\n", prog, SSLERROR);
    goto sslerror;
  }

  if (ssl_server->clientpemfile) {
    STACK_OF(X509_NAME) *stack = SSL_CTX_get_client_CA_list(ssl_server->ctx);
    LogInfo("%s: Found %d client certificates\n", prog, sk_X509_NAME_num(stack));
  }

  return ssl_server;

sslerror:
  delete_ssl_server_socket(ssl_server);
  return NULL;
}
Пример #9
0
static void
print_stuff(BIO * bio, SSL * s, int full)
{
	X509 *peer = NULL;
	char *p;
	static const char *space = "                ";
	char buf[BUFSIZ];
	STACK_OF(X509) * sk;
	STACK_OF(X509_NAME) * sk2;
	const SSL_CIPHER *c;
	X509_NAME *xn;
	int j, i;
	unsigned char *exportedkeymat;

	if (full) {
		int got_a_chain = 0;

		sk = SSL_get_peer_cert_chain(s);
		if (sk != NULL) {
			got_a_chain = 1;	/* we don't have it for SSL2
						 * (yet) */

			BIO_printf(bio, "---\nCertificate chain\n");
			for (i = 0; i < sk_X509_num(sk); i++) {
				X509_NAME_oneline(X509_get_subject_name(
					sk_X509_value(sk, i)), buf, sizeof buf);
				BIO_printf(bio, "%2d s:%s\n", i, buf);
				X509_NAME_oneline(X509_get_issuer_name(
					sk_X509_value(sk, i)), buf, sizeof buf);
				BIO_printf(bio, "   i:%s\n", buf);
				if (c_showcerts)
					PEM_write_bio_X509(bio, sk_X509_value(sk, i));
			}
		}
		BIO_printf(bio, "---\n");
		peer = SSL_get_peer_certificate(s);
		if (peer != NULL) {
			BIO_printf(bio, "Server certificate\n");
			if (!(c_showcerts && got_a_chain))	/* Redundant if we
								 * showed the whole
								 * chain */
				PEM_write_bio_X509(bio, peer);
			X509_NAME_oneline(X509_get_subject_name(peer),
			    buf, sizeof buf);
			BIO_printf(bio, "subject=%s\n", buf);
			X509_NAME_oneline(X509_get_issuer_name(peer),
			    buf, sizeof buf);
			BIO_printf(bio, "issuer=%s\n", buf);
		} else
			BIO_printf(bio, "no peer certificate available\n");

		sk2 = SSL_get_client_CA_list(s);
		if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0)) {
			BIO_printf(bio, "---\nAcceptable client certificate CA names\n");
			for (i = 0; i < sk_X509_NAME_num(sk2); i++) {
				xn = sk_X509_NAME_value(sk2, i);
				X509_NAME_oneline(xn, buf, sizeof(buf));
				BIO_write(bio, buf, strlen(buf));
				BIO_write(bio, "\n", 1);
			}
		} else {
			BIO_printf(bio, "---\nNo client certificate CA names sent\n");
		}
		p = SSL_get_shared_ciphers(s, buf, sizeof buf);
		if (p != NULL) {
			/*
			 * This works only for SSL 2.  In later protocol
			 * versions, the client does not know what other
			 * ciphers (in addition to the one to be used in the
			 * current connection) the server supports.
			 */

			BIO_printf(bio, "---\nCiphers common between both SSL endpoints:\n");
			j = i = 0;
			while (*p) {
				if (*p == ':') {
					BIO_write(bio, space, 15 - j % 25);
					i++;
					j = 0;
					BIO_write(bio, ((i % 3) ? " " : "\n"), 1);
				} else {
					BIO_write(bio, p, 1);
					j++;
				}
				p++;
			}
			BIO_write(bio, "\n", 1);
		}
		BIO_printf(bio, "---\nSSL handshake has read %ld bytes and written %ld bytes\n",
		    BIO_number_read(SSL_get_rbio(s)),
		    BIO_number_written(SSL_get_wbio(s)));
	}
	BIO_printf(bio, (SSL_cache_hit(s) ? "---\nReused, " : "---\nNew, "));
	c = SSL_get_current_cipher(s);
	BIO_printf(bio, "%s, Cipher is %s\n",
	    SSL_CIPHER_get_version(c),
	    SSL_CIPHER_get_name(c));
	if (peer != NULL) {
		EVP_PKEY *pktmp;
		pktmp = X509_get_pubkey(peer);
		BIO_printf(bio, "Server public key is %d bit\n",
		    EVP_PKEY_bits(pktmp));
		EVP_PKEY_free(pktmp);
	}
	BIO_printf(bio, "Secure Renegotiation IS%s supported\n",
	    SSL_get_secure_renegotiation_support(s) ? "" : " NOT");

	/* Compression is not supported and will always be none. */
	BIO_printf(bio, "Compression: NONE\n");
	BIO_printf(bio, "Expansion: NONE\n");

#ifdef SSL_DEBUG
	{
		/* Print out local port of connection: useful for debugging */
		int sock;
		struct sockaddr_in ladd;
		socklen_t ladd_size = sizeof(ladd);
		sock = SSL_get_fd(s);
		getsockname(sock, (struct sockaddr *) & ladd, &ladd_size);
		BIO_printf(bio_c_out, "LOCAL PORT is %u\n", ntohs(ladd.sin_port));
	}
#endif

#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
	if (next_proto.status != -1) {
		const unsigned char *proto;
		unsigned int proto_len;
		SSL_get0_next_proto_negotiated(s, &proto, &proto_len);
		BIO_printf(bio, "Next protocol: (%d) ", next_proto.status);
		BIO_write(bio, proto, proto_len);
		BIO_write(bio, "\n", 1);
	}
#endif

#ifndef OPENSSL_NO_SRTP
	{
		SRTP_PROTECTION_PROFILE *srtp_profile = SSL_get_selected_srtp_profile(s);

		if (srtp_profile)
			BIO_printf(bio, "SRTP Extension negotiated, profile=%s\n",
			    srtp_profile->name);
	}
#endif

	SSL_SESSION_print(bio, SSL_get_session(s));
	if (keymatexportlabel != NULL) {
		BIO_printf(bio, "Keying material exporter:\n");
		BIO_printf(bio, "    Label: '%s'\n", keymatexportlabel);
		BIO_printf(bio, "    Length: %i bytes\n", keymatexportlen);
		exportedkeymat = malloc(keymatexportlen);
		if (exportedkeymat != NULL) {
			if (!SSL_export_keying_material(s, exportedkeymat,
				keymatexportlen,
				keymatexportlabel,
				strlen(keymatexportlabel),
				NULL, 0, 0)) {
				BIO_printf(bio, "    Error\n");
			} else {
				BIO_printf(bio, "    Keying material: ");
				for (i = 0; i < keymatexportlen; i++)
					BIO_printf(bio, "%02X",
					    exportedkeymat[i]);
				BIO_printf(bio, "\n");
			}
			free(exportedkeymat);
		}
	}
	BIO_printf(bio, "---\n");
	if (peer != NULL)
		X509_free(peer);
	/* flush, or debugging output gets mixed with http response */
	(void) BIO_flush(bio);
}
Пример #10
0
int verify_init(SERVICE_OPTIONS *section) {
    STACK_OF(X509_NAME) *ca_dn;
    char *ca_name;
    int i;

    if(section->verify_level<0)
        return 0; /* OK - no certificate verification */

    if(section->verify_level>=2 && !section->ca_file && !section->ca_dir) {
        s_log(LOG_ERR,
            "Either CApath or CAfile has to be used for authentication");
        return 1; /* FAILED */
    }

    section->revocation_store=X509_STORE_new();
    if(!section->revocation_store) {
        sslerror("X509_STORE_new");
        return 1; /* FAILED */
    }

    if(section->ca_file) {
        if(!SSL_CTX_load_verify_locations(section->ctx,
                section->ca_file, NULL)) {
            s_log(LOG_ERR, "Error loading verify certificates from %s",
                section->ca_file);
            sslerror("SSL_CTX_load_verify_locations");
            return 1; /* FAILED */
        }
        /* revocation store needs CA certificates for CRL validation */
        if(load_file_lookup(section->revocation_store, section->ca_file))
            return 1; /* FAILED */
        /* trusted CA names sent to clients for client cert selection */
        if(!section->option.client) { /* only performed on server */
            s_log(LOG_DEBUG, "Client CA list: %s",
                section->ca_file);
            ca_dn=SSL_load_client_CA_file(section->ca_file);
            for (i=0; i<sk_X509_NAME_num(ca_dn); ++i) {
                ca_name=X509_NAME2text(sk_X509_NAME_value(ca_dn, i));
                s_log(LOG_INFO, "Client CA: %s", ca_name);
                str_free(ca_name);
            }
            SSL_CTX_set_client_CA_list(section->ctx, ca_dn);
        }
    }

    if(section->ca_dir) {
        if(!SSL_CTX_load_verify_locations(section->ctx,
                NULL, section->ca_dir)) {
            s_log(LOG_ERR, "Error setting verify directory to %s",
                section->ca_dir);
            sslerror("SSL_CTX_load_verify_locations");
            return 1; /* FAILED */
        }
        s_log(LOG_DEBUG, "Verify directory set to %s", section->ca_dir);
        add_dir_lookup(section->revocation_store, section->ca_dir);
    }

    if(section->crl_file)
        if(load_file_lookup(section->revocation_store, section->crl_file))
            return 1; /* FAILED */

    if(section->crl_dir) {
        section->revocation_store->cache=0; /* don't cache CRLs */
        add_dir_lookup(section->revocation_store, section->crl_dir);
    }

    SSL_CTX_set_verify(section->ctx, SSL_VERIFY_PEER |
        (section->verify_level>=2 ? SSL_VERIFY_FAIL_IF_NO_PEER_CERT : 0),
        verify_callback);

    if(section->ca_dir && section->verify_level>=3)
        s_log(LOG_INFO, "Peer certificate location %s", section->ca_dir);
    return 0; /* OK */
}