Пример #1
0
static int
client_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
{
  char buf[256];
  X509 *err_cert;
  int err, depth;

  err_cert = X509_STORE_CTX_get_current_cert(x509_ctx);
  err = X509_STORE_CTX_get_error(x509_ctx);
  depth = X509_STORE_CTX_get_error_depth(x509_ctx);

  X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
  if (!preverify_ok) {
    lock_file(stderr);
    fprintf(stderr, "verify error:num=%d:%s:depth=%d:%s\n", err,
            X509_verify_cert_error_string(err), depth, buf);
    if (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT) {
      X509_NAME_oneline(X509_get_issuer_name(x509_ctx->current_cert), buf, 256);
      fprintf(stderr, "issuer= %s\n", buf);
    }
    unlock_file(stderr);
    return preverify_ok;
  }
  /* They've passed the preverification */
  /* if there are contents of the cert we wanted to verify, we'd do it here. 
   */
  return preverify_ok;
}
Пример #2
0
static int swSSL_verify_callback(int ok, X509_STORE_CTX *x509_store)
{
#if 0
    char *subject, *issuer;
    int err, depth;
    X509 *cert;
    X509_NAME *sname, *iname;
    X509_STORE_CTX_get_ex_data(x509_store, SSL_get_ex_data_X509_STORE_CTX_idx());
    cert = X509_STORE_CTX_get_current_cert(x509_store);
    err = X509_STORE_CTX_get_error(x509_store);
    depth = X509_STORE_CTX_get_error_depth(x509_store);

    sname = X509_get_subject_name(cert);
    subject = sname ? X509_NAME_oneline(sname, NULL, 0) : "(none)";

    iname = X509_get_issuer_name(cert);
    issuer = iname ? X509_NAME_oneline(iname, NULL, 0) : "(none)";
    swWarn("verify:%d, error:%d, depth:%d, subject:\"%s\", issuer:\"%s\"", ok, err, depth, subject, issuer);

    if (sname)
    {
        OPENSSL_free(subject);
    }
    if (iname)
    {
        OPENSSL_free(issuer);
    }
#endif

    return 1;
}
Пример #3
0
static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
{
    printf("*** Verify callback function called\n");
	char    buf[256];
	X509   *err_cert;
	int     err, depth;
	SSL    *ssl;

	err_cert = X509_STORE_CTX_get_current_cert(ctx);
	err = X509_STORE_CTX_get_error(ctx);
	depth = X509_STORE_CTX_get_error_depth(ctx);

	/*
	 * Retrieve the pointer to the SSL of the connection currently treated
	 * and the application specific data stored into the SSL object.
	 */
	ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
	//mydata = SSL_get_ex_data(ssl, mydata_index);

	X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);

	/*
	 * Catch a too long certificate chain. The depth limit set using
	 * SSL_CTX_set_verify_depth() is by purpose set to "limit+1" so
	 * that whenever the "depth>verify_depth" condition is met, we
	 * have violated the limit and want to log this error condition.
	 * We must do it here, because the CHAIN_TOO_LONG error would not
	 * be found explicitly; only errors introduced by cutting off the
	 * additional certificates would be logged.
	 */
#if 0
	if (depth > mydata->verify_depth) {
		preverify_ok = 0;
		err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
		X509_STORE_CTX_set_error(ctx, err);
	}
#endif
	if (!preverify_ok) {
		printf("verify error:num=%d:%s:depth=%d:%s\n", err,
				X509_verify_cert_error_string(err), depth, buf);
	}

	printf("depth=%d:%s\n", depth, buf);

	/*
	 * At this point, err contains the last verification error. We can use
	 * it for something special
	 */
	if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)) {
		X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
		printf("issuer= %s\n", buf);
	}

#if 0
	if (mydata->always_continue)
		return 1;
	else
#endif
		return preverify_ok;
}
Пример #4
0
/**
 * This callback implements the "continue on error" flag and log the errors.
 */
static int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
{
  int err;
  int verify;
  SSL *ssl;
  SSL_CTX *ctx;
  p_context pctx;
  lua_State *L;

  /* Short-circuit optimization */
  if (preverify_ok)
    return 1;

  ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
    SSL_get_ex_data_X509_STORE_CTX_idx());
  ctx = SSL_get_SSL_CTX(ssl);
  pctx = (p_context)SSL_CTX_get_app_data(ctx);
  L = pctx->L;

  /* Get verify flags */
  luaL_getmetatable(L, "SSL:Verify:Registry");
  lua_pushlightuserdata(L, (void*)ctx);
  lua_gettable(L, -2);
  verify = (int)lua_tonumber(L, -1);

  lua_pop(L, 2); /* Remove values from stack */

  err = X509_STORE_CTX_get_error(x509_ctx);
  if (err != X509_V_OK)
    add_cert_error(L, ssl, err, X509_STORE_CTX_get_error_depth(x509_ctx));

  return (verify & LSEC_VERIFY_CONTINUE ? 1 : preverify_ok);
}
Пример #5
0
int verify_callback(int ok, X509_STORE_CTX *store)
{
    char data[256];
    
    /*
     * succeeds if ok <> 0
     * Only intervene if failed
     */
    if (!ok) {
        // ok = 0
        X509 *cert = X509_STORE_CTX_get_current_cert(store);
        int depth = X509_STORE_CTX_get_error_depth(store);
        int err = X509_STORE_CTX_get_error(store);

        fprintf(stderr, "-Error with certificate at depth: %d\n", depth);
        X509_NAME_oneline(X509_get_issuer_name(cert), data, 256);
        fprintf(stderr, "  issuer = %s\n", data);
        
        X509_NAME_oneline(X509_get_subject_name(cert), data, 256);
        fprintf(stderr, "  subject = %s\n", data);

        fprintf(stderr, "  err %i:%s\n", err, X509_verify_cert_error_string(err));
    }

    return ok;
}
Пример #6
0
static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) {
  int ret = preverify_ok;

  /* determine the status for the current cert */
  X509_STORE_CTX_get_current_cert(ctx);
  int err = X509_STORE_CTX_get_error(ctx);
  int depth = X509_STORE_CTX_get_error_depth(ctx);

  /* conjure the stream & context to use */
  SSL *ssl = (SSL*)X509_STORE_CTX_get_ex_data
    (ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
  SSLSocket *stream =
    (SSLSocket*)SSL_get_ex_data(ssl, SSLSocket::GetSSLExDataIndex());

  /* if allow_self_signed is set, make sure that verification succeeds */
  if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT &&
      stream->getContext()["allow_self_signed"].toBoolean()) {
    ret = 1;
  }

  /* check the depth */
  Variant vdepth = stream->getContext()["verify_depth"];
  if (vdepth.toBoolean() && depth > vdepth.toInt64()) {
    ret = 0;
    X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_CHAIN_TOO_LONG);
  }

  return ret;
}
Пример #7
0
int     tls_verify_certificate_callback(int ok, X509_STORE_CTX *ctx)
{
    char    buf[CCERT_BUFSIZ];
    X509   *cert;
    int     err;
    int     depth;
    int     max_depth;
    SSL    *con;
    TLS_SESS_STATE *TLScontext;

    /* May be NULL as of OpenSSL 1.0, thanks for the API change! */
    cert = X509_STORE_CTX_get_current_cert(ctx);
    err = X509_STORE_CTX_get_error(ctx);
    con = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
    TLScontext = SSL_get_ex_data(con, TLScontext_index);
    depth = X509_STORE_CTX_get_error_depth(ctx);

    /* Don't log the internal root CA unless there's an unexpected error. */
    if (ok && TLScontext->tadepth > 0 && depth > TLScontext->tadepth)
	return (1);

    /*
     * Certificate chain depth limit violations are mis-reported by the
     * OpenSSL library, from SSL_CTX_set_verify(3):
     * 
     * The certificate verification depth set with SSL[_CTX]_verify_depth()
     * stops the verification at a certain depth. The error message produced
     * will be that of an incomplete certificate chain and not
     * X509_V_ERR_CERT_CHAIN_TOO_LONG as may be expected.
     * 
     * We set a limit that is one higher than the user requested limit. If this
     * higher limit is reached, we raise an error even a trusted root CA is
     * present at this depth. This disambiguates trust chain truncation from
     * an incomplete trust chain.
     */
    max_depth = SSL_get_verify_depth(con) - 1;

    /*
     * We never terminate the SSL handshake in the verification callback,
     * rather we allow the TLS handshake to continue, but mark the session as
     * unverified. The application is responsible for closing any sessions
     * with unverified credentials.
     */
    if (max_depth >= 0 && depth > max_depth) {
	X509_STORE_CTX_set_error(ctx, err = X509_V_ERR_CERT_CHAIN_TOO_LONG);
	ok = 0;
    }
    if (ok == 0)
	update_error_state(TLScontext, depth, cert, err);

    if (TLScontext->log_mask & TLS_LOG_VERBOSE) {
	if (cert)
	    X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
	else
	    strcpy(buf, "<unknown>");
	msg_info("%s: depth=%d verify=%d subject=%s",
		 TLScontext->namaddr, depth, ok, printable(buf, '?'));
    }
    return (1);
}
Пример #8
0
int _mosquitto_server_certificate_verify(int preverify_ok, X509_STORE_CTX *ctx)
{
	/* Preverify should have already checked expiry, revocation.
	 * We need to verify the hostname. */
	struct mosquitto *mosq;
	SSL *ssl;
	X509 *cert;

	/* Always reject if preverify_ok has failed. */
	if(!preverify_ok) return 0;

	ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
	mosq = SSL_get_ex_data(ssl, tls_ex_index_mosq);
	if(!mosq) return 0;

	if(mosq->tls_insecure == false){
		if(X509_STORE_CTX_get_error_depth(ctx) == 0){
			/* FIXME - use X509_check_host() etc. for sufficiently new openssl (>=1.1.x) */
			cert = X509_STORE_CTX_get_current_cert(ctx);
			/* This is the peer certificate, all others are upwards in the chain. */
#if defined(WITH_BROKER)
			return _mosquitto_verify_certificate_hostname(cert, mosq->bridge->addresses[mosq->bridge->cur_address].address);
#else
			return _mosquitto_verify_certificate_hostname(cert, mosq->host);
#endif
		}else{
			return preverify_ok;
		}
	}else{
		return preverify_ok;
	}
}
Пример #9
0
NOEXPORT int cert_check(X509_STORE_CTX *callback_ctx, int preverify_ok) {
    SSL *ssl=X509_STORE_CTX_get_ex_data(callback_ctx,
        SSL_get_ex_data_X509_STORE_CTX_idx());
    CLI *c=SSL_get_ex_data(ssl, cli_index);
    int depth=X509_STORE_CTX_get_error_depth(callback_ctx);

    if(preverify_ok) {
        s_log(LOG_DEBUG, "CERT: preverify ok");
    } else {
        /* remote site sent an invalid certificate */
        if(c->opt->verify_level>=4 && depth>0) {
            s_log(LOG_INFO, "CERT: Invalid CA certificate ignored");
            return 1; /* accept */
        } else {
            s_log(LOG_WARNING, "CERT: Verification error: %s",
                X509_verify_cert_error_string(
                    X509_STORE_CTX_get_error(callback_ctx)));
            /* retain the STORE_CTX error produced by pre-verification */
            return 0; /* reject */
        }
    }
    if(c->opt->verify_level>=3 && depth==0)
        if(!cert_check_local(callback_ctx))
            return 0; /* reject */
    return 1; /* accept */
}
Пример #10
0
int OsSSL::verifyCallback(int valid,            // validity so far from openssl
                          X509_STORE_CTX* store // certificate information db
                          )
{
   X509* cert = X509_STORE_CTX_get_current_cert(store);

   if (valid)
   {
      // apply any additional logic we want
   }
   else
   {
      // log the details of why openssl thinks this is not valid
      char issuer[256];
      char subject[256];

      X509_NAME_oneline(X509_get_issuer_name(cert), issuer, sizeof(issuer));
      X509_NAME_oneline(X509_get_subject_name(cert), subject, sizeof(subject));
      OsSysLog::add(FAC_KERNEL, PRI_ERR,
                    "OsSSL::verifyCallback invalid certificate at depth %d\n"
                    "       error='%s'\n"
                    "       issuer='%s'\n"
                    "       subject='%s'",
                    X509_STORE_CTX_get_error_depth(store),
                    X509_verify_cert_error_string(X509_STORE_CTX_get_error(store)),
                    issuer, subject);
   }

   return valid;
}
Пример #11
0
NOEXPORT int verify_checks(int preverify_ok, X509_STORE_CTX *callback_ctx) {
    X509 *cert;
    int depth;
    char *subject;

    cert=X509_STORE_CTX_get_current_cert(callback_ctx);
    depth=X509_STORE_CTX_get_error_depth(callback_ctx);
    subject=X509_NAME2text(X509_get_subject_name(cert));

    s_log(LOG_DEBUG, "Verification started at depth=%d: %s", depth, subject);

    if(!cert_check(callback_ctx, preverify_ok)) {
        s_log(LOG_WARNING, "Rejected by CERT at depth=%d: %s", depth, subject);
        str_free(subject);
        return 0; /* reject */
    }
    if(!crl_check(callback_ctx)) {
        s_log(LOG_WARNING, "Rejected by CRL at depth=%d: %s", depth, subject);
        str_free(subject);
        return 0; /* reject */
    }
#ifndef OPENSSL_NO_OCSP
    if(!ocsp_check(callback_ctx)) {
        s_log(LOG_WARNING, "Rejected by OCSP at depth=%d: %s", depth, subject);
        str_free(subject);
        return 0; /* reject */
    }
#endif /* !defined(OPENSSL_NO_OCSP) */

    s_log(depth ? LOG_INFO : LOG_NOTICE,
        "Certificate accepted at depth=%d: %s", depth, subject);
    str_free(subject);
    return 1; /* accept */
}
Пример #12
0
int verify_callback(int ok, X509_STORE_CTX *ctx) {
    int err, depth;
    char buf[1024];
    X509 *thecert;

    thecert = X509_STORE_CTX_get_current_cert(ctx);
    err = X509_STORE_CTX_get_error(ctx);
    depth = X509_STORE_CTX_get_error_depth(ctx);
    
    /* things to do: */

    X509_NAME_oneline(X509_get_subject_name(thecert), buf, sizeof(buf));
    DEBUGMSGTL(("dtlsudp_x509",
                "Cert: %s\n", buf));


    DEBUGMSGTL(("dtlsudp_x509",
                " verify value: %d, depth=%d, error code=%d, error string=%s\n",
                ok, depth, err, _x509_get_error(err, "verify callback")));

    /* check if we allow self-signed certs */
    if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
                               NETSNMP_DS_LIB_ALLOW_SELF_SIGNED) &&
        (X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT == err ||
         X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN == err)) {
        DEBUGMSGTL(("dtlsudp_x509", "  accepting a self-signed certificate\n"));
        return 1;
    }
    
    
    DEBUGMSGTL(("dtlsudp_x509", "  returing the passed in value of %d\n", ok));
    return(ok);
}
Пример #13
0
static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx)
	{
	int err;
	X509 *err_cert;

	/* it is ok to use a self signed certificate
	 * This case will catch both the initial ok == 0 and the
	 * final ok == 1 calls to this function */
	err=X509_STORE_CTX_get_error(ctx);
	if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
		return 1;

	/* BAD we should have gotten an error.  Normally if everything
	 * worked X509_STORE_CTX_get_error(ctx) will still be set to
	 * DEPTH_ZERO_SELF_.... */
	if (ok)
		{
		BIO_printf(bio_err,"error with certificate to be certified - should be self signed\n");
		return 0;
		}
	else
		{
		err_cert=X509_STORE_CTX_get_current_cert(ctx);
		print_name(bio_err, NULL, X509_get_subject_name(err_cert),0);
		BIO_printf(bio_err,"error with certificate - error %d at depth %d\n%s\n",
			err,X509_STORE_CTX_get_error_depth(ctx),
			X509_verify_cert_error_string(err));
		return 1;
		}
	}
Пример #14
0
static int my_verify_callback(int ok, X509_STORE_CTX *ctx)
{
  X509 *check_cert;
  SSL *ssl;
  MYSQL *mysql;

  ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
  mysql= (MYSQL *)SSL_get_app_data(ssl);

  /* skip verification if no ca_file/path was specified */
  if (!mysql->options.ssl_ca && !mysql->options.ssl_capath)
  {
    ok= 1;
    return 1;
  }

  if (!ok)
  {
    uint depth;
    if (!(check_cert= X509_STORE_CTX_get_current_cert(ctx)))
      return 0;
    depth= X509_STORE_CTX_get_error_depth(ctx);
    if (depth == 0)
      ok= 1;
  }

  return ok;
}
Пример #15
0
int
verify_callback(int ok, X509_STORE_CTX * ctx)
{
	X509 *err_cert;
	int err, depth;

	err_cert = X509_STORE_CTX_get_current_cert(ctx);
	err = X509_STORE_CTX_get_error(ctx);
	depth = X509_STORE_CTX_get_error_depth(ctx);

	BIO_printf(bio_err, "depth=%d ", depth);
	if (err_cert) {
		X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert),
		    0, XN_FLAG_ONELINE);
		BIO_puts(bio_err, "\n");
	} else
		BIO_puts(bio_err, "<no cert>\n");
	if (!ok) {
		BIO_printf(bio_err, "verify error:num=%d:%s\n", err,
		    X509_verify_cert_error_string(err));
		if (verify_depth >= depth) {
			if (!verify_return_error)
				ok = 1;
			verify_error = X509_V_OK;
		} else {
			ok = 0;
			verify_error = X509_V_ERR_CERT_CHAIN_TOO_LONG;
		}
	}
	switch (err) {
	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
		BIO_puts(bio_err, "issuer= ");
		X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert),
		    0, XN_FLAG_ONELINE);
		BIO_puts(bio_err, "\n");
		break;
	case X509_V_ERR_CERT_NOT_YET_VALID:
	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
		BIO_printf(bio_err, "notBefore=");
		ASN1_TIME_print(bio_err, X509_get_notBefore(err_cert));
		BIO_printf(bio_err, "\n");
		break;
	case X509_V_ERR_CERT_HAS_EXPIRED:
	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
		BIO_printf(bio_err, "notAfter=");
		ASN1_TIME_print(bio_err, X509_get_notAfter(err_cert));
		BIO_printf(bio_err, "\n");
		break;
	case X509_V_ERR_NO_EXPLICIT_POLICY:
		policies_print(bio_err, ctx);
		break;
	}
	if (err == X509_V_OK && ok == 2)
		policies_print(bio_err, ctx);

	BIO_printf(bio_err, "verify return:%d\n", ok);
	return (ok);
}
Пример #16
0
int _qvd_verify_cert_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
{
  
  SSL    *ssl;
  SSL_CTX *sslctx;
  qvdclient *qvd ;

  ssl = X509_STORE_CTX_get_ex_data(x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
  sslctx = SSL_get_SSL_CTX(ssl);
  qvd = SSL_CTX_get_ex_data(sslctx, _qvd_ssl_index); 
 
  X509 *cert = X509_STORE_CTX_get_current_cert(x509_ctx);
  int depth = X509_STORE_CTX_get_error_depth(x509_ctx);
  int err = X509_STORE_CTX_get_error(x509_ctx);

  /* save the certificate by incrementing the reference count and
   * keeping a pointer */
  if (depth < MAX_CERTS && !certificate[depth]) {
    certificate[depth] = cert;
    certificate_error[depth] = err;
    cert->references++;
  }

  /* See http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html# */
  if (preverify_ok)
    {
      qvd_printf("_qvd_verify_cert_callback: Certificate was validated\n");
      return preverify_ok;
    }
  if (qvd->ssl_verify_callback == NULL)
    {
      qvd_printf("_qvd_verify_cert_callback: No callback specified returning false (specify if you wissh callbacks for unknown certs with qvd_set_unknown_cert_callback)\n");
      return 0;
    }

  BIO *bio_out = BIO_new(BIO_s_mem());
  BUF_MEM *biomem;
  int result;
  PEM_write_bio_X509(bio_out, certificate[depth]);
  BIO_get_mem_ptr(bio_out, &biomem);
  char cert_info[1024];
  char issuer[256], subject[256];
  X509_NAME_oneline(X509_get_issuer_name(certificate[depth]), issuer, 256);
  X509_NAME_oneline(X509_get_subject_name(certificate[depth]), subject, 256);

  snprintf(cert_info, 1023, "Serial: %lu\n\nIssuer: %s\n\nValidity:\n\tNot before: %s\n\tNot after: %s\n\nSubject: %s\n",
	   ASN1_INTEGER_get(X509_get_serialNumber(certificate[depth])), issuer, 
	   X509_get_notBefore(certificate[depth])->data, X509_get_notAfter(cert)->data, subject);
  cert_info[1023] = '\0';
  result = qvd->ssl_verify_callback(qvd, cert_info, biomem->data);
  if (result)
    {
      _qvd_save_certificate(qvd, certificate[depth], depth, biomem);
    }

  BIO_free(bio_out);
  return result;
}
Пример #17
0
/*****************************************************************************************
* Authorization routines
*****************************************************************************************/
int ossl_verify_cb (int ok, X509_STORE_CTX *ctx)
{
    int cert_error = X509_STORE_CTX_get_error(ctx);
    X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);

    EST_LOG_INFO("enter function: ok=%d cert_error=%d", ok, cert_error);

    if (!ok) {
        if (current_cert) {
            X509_NAME_print_ex_fp(stdout,
                                  X509_get_subject_name(current_cert),
                                  0, XN_FLAG_ONELINE);
            printf("\n");
        }
        EST_LOG_INFO("%serror %d at %d depth lookup: %s",
                     X509_STORE_CTX_get0_parent_ctx(ctx) ? "[CRL path]" : "",
                     cert_error,
                     X509_STORE_CTX_get_error_depth(ctx),
                     X509_verify_cert_error_string(cert_error));
        switch (cert_error) {
        case X509_V_ERR_UNABLE_TO_GET_CRL:
            /*
             * We've enabled CRL checking in the TLS stack.  If
             * the application hasn't loaded a CRL, then this
             * verify error can occur.  The peer's cert is valid,
             * but we can't confirm if it was revoked.  We'll
             * warn the application.
             */
            EST_LOG_WARN("No CRL loaded, TLS peer will be allowed.");
            ok = 1;
            break;
        case X509_V_ERR_NO_EXPLICIT_POLICY:
        case X509_V_ERR_CERT_HAS_EXPIRED:

        /* since we are just checking the certificates, it is
         * ok if they are self signed. But we should still warn
         * the user.
         */

        case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
        /* Continue after extension errors too */
        case X509_V_ERR_INVALID_CA:
        case X509_V_ERR_INVALID_NON_CA:
        case X509_V_ERR_PATH_LENGTH_EXCEEDED:
        case X509_V_ERR_INVALID_PURPOSE:
        case X509_V_ERR_CRL_HAS_EXPIRED:
        case X509_V_ERR_CRL_NOT_YET_VALID:
        case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
        case X509_V_ERR_CERT_REVOKED:
        default:
            EST_LOG_WARN("Certificate verify failed (reason=%d)",
                         cert_error);
            break;
        }
        return ok;
    }
    return (ok);
}
Пример #18
0
static VALUE 
ossl_x509stctx_get_err_depth(VALUE self)
{
    X509_STORE_CTX *ctx;

    GetX509StCtx(self, ctx);

    return INT2FIX(X509_STORE_CTX_get_error_depth(ctx));
}
Пример #19
0
/* find the issuer certificate without lookups */
NOEXPORT X509 *get_current_issuer(X509_STORE_CTX *callback_ctx) {
    STACK_OF(X509) *chain;
    int depth;

    chain=X509_STORE_CTX_get_chain(callback_ctx);
    depth=X509_STORE_CTX_get_error_depth(callback_ctx);
    if(depth<sk_X509_num(chain)-1) /* not the root CA cert */
        ++depth; /* index of the issuer cert */
    return sk_X509_value(chain, depth);
}
Пример #20
0
bool nano::rpc_secure::on_verify_certificate (bool preverified, boost::asio::ssl::verify_context & ctx)
{
	X509_STORE_CTX * cts = ctx.native_handle ();
	auto error (X509_STORE_CTX_get_error (cts));
	switch (error)
	{
		case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
			logger.always_log ("TLS: Unable to get issuer");
			break;
		case X509_V_ERR_CERT_NOT_YET_VALID:
		case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
			logger.always_log ("TLS: Certificate not yet valid");
			break;
		case X509_V_ERR_CERT_HAS_EXPIRED:
		case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
			logger.always_log ("TLS: Certificate expired");
			break;
		case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
			if (config.secure.verbose_logging)
			{
				logger.always_log ("TLS: self signed certificate in chain");
			}

			// Allow self-signed certificates
			preverified = true;
			break;
		case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
			logger.always_log ("TLS: Self signed certificate not in the list of trusted certs (forgot to subject-hash certificate filename?)");
			break;
		default:
			break;
	}

	if (config.secure.verbose_logging)
	{
		if (error != 0)
		{
			logger.always_log ("TLS: Error: ", X509_verify_cert_error_string (error));
			logger.always_log ("TLS: Error chain depth : ", X509_STORE_CTX_get_error_depth (cts));
		}

		X509 * cert = X509_STORE_CTX_get_current_cert (cts);
		char subject_name[512];
		X509_NAME_oneline (X509_get_subject_name (cert), subject_name, sizeof (subject_name) - 1);
		logger.always_log ("TLS: Verifying: ", subject_name);
		logger.always_log ("TLS: Verification: ", preverified);
	}
	else if (!preverified)
	{
		logger.always_log ("TLS: Pre-verification failed. Turn on verbose logging for more information.");
	}

	return preverified;
}
Пример #21
0
static int
tlso_verify_cb( int ok, X509_STORE_CTX *ctx )
{
	X509 *cert;
	int errnum;
	int errdepth;
	X509_NAME *subject;
	X509_NAME *issuer;
	char *sname;
	char *iname;
	char *certerr = NULL;

	cert = X509_STORE_CTX_get_current_cert( ctx );
	errnum = X509_STORE_CTX_get_error( ctx );
	errdepth = X509_STORE_CTX_get_error_depth( ctx );

	/*
	 * X509_get_*_name return pointers to the internal copies of
	 * those things requested.  So do not free them.
	 */
	subject = X509_get_subject_name( cert );
	issuer = X509_get_issuer_name( cert );
	/* X509_NAME_oneline, if passed a NULL buf, allocate memomry */
	sname = X509_NAME_oneline( subject, NULL, 0 );
	iname = X509_NAME_oneline( issuer, NULL, 0 );
	if ( !ok ) certerr = (char *)X509_verify_cert_error_string( errnum );
#ifdef HAVE_EBCDIC
	if ( sname ) __etoa( sname );
	if ( iname ) __etoa( iname );
	if ( certerr ) {
		certerr = LDAP_STRDUP( certerr );
		__etoa( certerr );
	}
#endif
	Debug( LDAP_DEBUG_TRACE,
		   "TLS certificate verification: depth: %d, err: %d, subject: %s,",
		   errdepth, errnum,
		   sname ? sname : "-unknown-" );
	Debug( LDAP_DEBUG_TRACE, " issuer: %s\n", iname ? iname : "-unknown-", 0, 0 );
	if ( !ok ) {
		Debug( LDAP_DEBUG_ANY,
			"TLS certificate verification: Error, %s\n",
			certerr, 0, 0 );
	}
	if ( sname )
		CRYPTO_free ( sname );
	if ( iname )
		CRYPTO_free ( iname );
#ifdef HAVE_EBCDIC
	if ( certerr ) LDAP_FREE( certerr );
#endif
	return ok;
}
Пример #22
0
bool verify_cert_chain_platform_specific(boost::asio::ssl::verify_context &verifyCtx, const std::string &hostName)
{
    X509_STORE_CTX *storeContext = verifyCtx.native_handle();
    int currentDepth = X509_STORE_CTX_get_error_depth(storeContext);
    if (currentDepth != 0)
    {
        return true;
    }

    STACK_OF(X509) *certStack = X509_STORE_CTX_get_chain(storeContext);
    const int numCerts = sk_X509_num(certStack);
    if (numCerts < 0)
    {
        return false;
    }

    std::vector<std::string> certChain;
    certChain.reserve(numCerts);
    for (int i = 0; i < numCerts; ++i)
    {
        X509 *cert = sk_X509_value(certStack, i);

        // Encode into DER format into raw memory.
        int len = i2d_X509(cert, nullptr);
        if (len < 0)
        {
            return false;
        }

        std::string certData;
        certData.resize(len);
        unsigned char * buffer = reinterpret_cast<unsigned char *>(&certData[0]);
        len = i2d_X509(cert, &buffer);
        if (len < 0)
        {
            return false;
        }

        certChain.push_back(std::move(certData));
    }

    auto verify_result = verify_X509_cert_chain(certChain, hostName);

    // The Windows Crypto APIs don't do host name checks, use Boost's implementation.
#if defined(_WIN32)
    if (verify_result)
    {
        boost::asio::ssl::rfc2818_verification rfc2818(hostName);
        verify_result = rfc2818(verify_result, verifyCtx);
    }
#endif
    return verify_result;
}
Пример #23
0
static int
_hssl_cert_verify_callback(int prev_ok, X509_STORE_CTX * ctx)
{
/*
    if ((X509_STORE_CTX_get_error(ctx) = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN))
    {
        log_verbose1("Self signed cert in chain");
        return 1;
    }
*/
  log_verbose2("Cert depth = %d", X509_STORE_CTX_get_error_depth(ctx));
  if (X509_STORE_CTX_get_error_depth(ctx) == 0)
  {
    return _hssl_verify_cert(X509_STORE_CTX_get_current_cert(ctx));
  }
  else
  {
    log_verbose1("Cert ok (prev)");
    return prev_ok;
  }
}
Пример #24
0
/* Add certificate chain and errors to certs array */
int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) {
    X509 *cert = X509_STORE_CTX_get_current_cert(x509_ctx);
    int depth = X509_STORE_CTX_get_error_depth(x509_ctx);
    int err = X509_STORE_CTX_get_error(x509_ctx);
    if (depth < MAX_CERTS && !certificates[depth]) {
        certificates[depth] = cert;
        certificates_error[depth] = err;
        cert->references++;
    }
  (void) preverify_ok;
  return 1;
}
Пример #25
0
static int verify_callback(int preverify_ok, X509_STORE_CTX * ctx)
{

	typedef struct {
		int verbose_mode;
		int verify_depth;
		int always_continue;
	} mydata_t;

	char buf[256];
	X509 *err_cert;
	int err, depth, mydata_index=0;
	SSL *ssl;
	mydata_t *mydata;



	err_cert = X509_STORE_CTX_get_current_cert(ctx);
	depth = X509_STORE_CTX_get_error_depth(ctx);
	ssl =
	    X509_STORE_CTX_get_ex_data(ctx,
				       SSL_get_ex_data_X509_STORE_CTX_idx
				       ());
	err = X509_STORE_CTX_get_error(ctx);
	fprintf(stderr, "  err %i:%s\n", err,
		X509_verify_cert_error_string(err));

	mydata = SSL_get_ex_data(ssl, mydata_index);

	/*
	   X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
	   or */
	X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
	printf("issuer= %s\n", buf);




	err = X509_STORE_CTX_get_error(ctx);
	fprintf(stderr, "X509_verify_cert_error_string=(%s)\n",
		X509_verify_cert_error_string(err));

	/* Return 1 accept the connection. 
	   Return 0 reject the connection 

	   This isn't the only place this decision is made to continue.

	 */

	preverify_ok = 1;
	return preverify_ok;
}
Пример #26
0
static
int tls_verify_cb(int ok, X509_STORE_CTX *store)
{
  if (!ok)
  {
    char data[256];

    X509 *cert = X509_STORE_CTX_get_current_cert(store);
    int  depth = X509_STORE_CTX_get_error_depth(store);
    int  err = X509_STORE_CTX_get_error(store);
    int  sslidx = SSL_get_ex_data_X509_STORE_CTX_idx();
    SSL  *ssl = X509_STORE_CTX_get_ex_data(store, sslidx);
    tls_t *tls = SSL_get_ex_data(ssl, tls_ex_data_idx);

    assert(tls);

#define TLS_VERIFY_CB_CLEAR_ERROR(OK,ERR,STORE) \
                   do {\
                     OK = 1;\
		     ERR = X509_V_OK;\
		     X509_STORE_CTX_set_error(STORE,ERR);\
		   } while (0)

    if (tls->accept && !tls->verify_incoming)
      TLS_VERIFY_CB_CLEAR_ERROR(ok, err, store);
    else if (!tls->accept && !tls->verify_outgoing)
      TLS_VERIFY_CB_CLEAR_ERROR(ok, err, store);
    else switch (err) {
      case X509_V_ERR_CERT_NOT_YET_VALID:
      case X509_V_ERR_CERT_HAS_EXPIRED:
      case X509_V_ERR_CRL_NOT_YET_VALID:
      case X509_V_ERR_CRL_HAS_EXPIRED:
        if (!tls->verify_date)
	  TLS_VERIFY_CB_CLEAR_ERROR(ok, err, store);

      default:
        break;
    }

    if (!ok) {
      SU_DEBUG_3(("-Error with certificate at depth: %i\n", depth));
      X509_NAME_oneline(X509_get_issuer_name(cert), data, 256);
      SU_DEBUG_3(("  issuer   = %s\n", data));
      X509_NAME_oneline(X509_get_subject_name(cert), data, 256);
      SU_DEBUG_3(("  subject  = %s\n", data));
      SU_DEBUG_3(("  err %i:%s\n", err, X509_verify_cert_error_string(err)));
    }

  }

  return ok;
}
Пример #27
0
/* OpenSSL cert verification callback.  This is invoked for *each*
 * error which is encoutered whilst verifying the cert chain; multiple
 * invocations for any particular cert in the chain are possible. */
static int verify_callback(int ok, X509_STORE_CTX *ctx)
{
    /* OpenSSL, living in its own little happy world of global state,
     * where userdata was just a twinkle in the eye of an API designer
     * yet to be born.  Or... "Seriously, wtf?"  */
    SSL *ssl = X509_STORE_CTX_get_ex_data(ctx, 
                                          SSL_get_ex_data_X509_STORE_CTX_idx());
    ne_session *sess = SSL_get_app_data(ssl);
    int depth = X509_STORE_CTX_get_error_depth(ctx);
    int err = X509_STORE_CTX_get_error(ctx);
    int failures = 0;

    /* If there's no error, nothing to do here. */
    if (ok) return ok;

    NE_DEBUG(NE_DBG_SSL, "ssl: Verify callback @ %d => %d\n", depth, err);

    /* Map the error code onto any of the exported cert validation
     * errors, if possible. */
    switch (err) {
    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
    case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
    case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
    case X509_V_ERR_CERT_UNTRUSTED:
    case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
        failures |= NE_SSL_UNTRUSTED;
        break;
    case X509_V_ERR_CERT_NOT_YET_VALID:
        failures |= depth > 0 ? NE_SSL_BADCHAIN : NE_SSL_NOTYETVALID;
        break;
    case X509_V_ERR_CERT_HAS_EXPIRED:
        failures |= depth > 0 ? NE_SSL_BADCHAIN : NE_SSL_EXPIRED;
        break;
    case X509_V_OK:
        break;
    default:
        /* Clear the failures bitmask so check_certificate knows this
         * is a bailout. */
        sess->ssl_context->failures |= NE_SSL_UNHANDLED;
        NE_DEBUG(NE_DBG_SSL, "ssl: Unhandled verification error %d -> %s\n", 
                 err, X509_verify_cert_error_string(err));
        return 0;
    }

    sess->ssl_context->failures |= failures;

    NE_DEBUG(NE_DBG_SSL, "ssl: Verify failures |= %d => %d\n", failures,
             sess->ssl_context->failures);
    
    return 1;
}
Пример #28
0
static int verify_cb(int ok, X509_STORE_CTX *ctx) {
    char *buf = NULL;
    X509 *err_cert;
    int err, depth;

    err_cert = X509_STORE_CTX_get_current_cert(ctx);
    err = X509_STORE_CTX_get_error(ctx);
    depth = X509_STORE_CTX_get_error_depth(ctx);

    if (depth > MAX_CERT_DEPTH) {
	ok = 0;
	err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
	X509_STORE_CTX_set_error(ctx, err);
    }

    if (!ok) {
	if (err_cert)
	    buf = X509_NAME_oneline(X509_get_subject_name(err_cert), NULL, 0);
	debug(DBG_WARN, "verify error: num=%d:%s:depth=%d:%s", err, X509_verify_cert_error_string(err), depth, buf ? buf : "");
	free(buf);
	buf = NULL;

	switch (err) {
	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
	    if (err_cert) {
		buf = X509_NAME_oneline(X509_get_issuer_name(err_cert), NULL, 0);
		if (buf) {
		    debug(DBG_WARN, "\tIssuer=%s", buf);
		    free(buf);
		    buf = NULL;
		}
	    }
	    break;
	case X509_V_ERR_CERT_NOT_YET_VALID:
	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
	    debug(DBG_WARN, "\tCertificate not yet valid");
	    break;
	case X509_V_ERR_CERT_HAS_EXPIRED:
	    debug(DBG_WARN, "Certificate has expired");
	    break;
	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
	    debug(DBG_WARN, "Certificate no longer valid (after notAfter)");
	    break;
	case X509_V_ERR_NO_EXPLICIT_POLICY:
	    debug(DBG_WARN, "No Explicit Certificate Policy");
	    break;
	}
    }
    return ok;
}
Пример #29
0
/* Verify certificate callback.  Gets invoked by crypto/x509/x509_vfy.c:
 * internal_verify() after it checks the signature and the time of 
 * the certificate.  Copied from apps/s_cb.c.  Configured through 
 * verify_depth and verify_error, initialized in main().  Doesn't
 * really do much other than print verify errors to the screen and
 * ignore errors down to verify_depth.  Mainly an example of how
 * OpenSSL let's your app have a say in certificate validating.
 * At this point OpenSSL has checked the signature and dates are 
 * good, so you don't need to do that.  One thing you could do 
 * here would be to verify the certificate status with an on-line
 * service, e.g. via OCSP.
 */
int verify_cb(int ok, X509_STORE_CTX *ctx) {
  char buf[256];
  X509 *err_cert;
  int err,depth;
  BIO* bio_err;
	int verify_error = X509_V_OK, verify_depth = 0;

  if ((bio_err=BIO_new(BIO_s_file())) == NULL) return(0);

  BIO_set_fp(bio_err,stderr,BIO_NOCLOSE);

  err_cert=X509_STORE_CTX_get_current_cert(ctx);
  err=X509_STORE_CTX_get_error(ctx);
  depth=X509_STORE_CTX_get_error_depth(ctx);

  X509_NAME_oneline(X509_get_subject_name(err_cert),buf,256);
  BIO_printf(bio_err,"depth=%d %s\n",depth,buf);
  if (!ok) {
    BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
               X509_verify_cert_error_string(err));
    if (depth > verify_depth) {
      verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG;
    } else {
      ok=1;
      verify_error=X509_V_OK;
    }
  }
  switch (ctx->error) {
  case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
    X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256);
    BIO_printf(bio_err,"issuer= %s\n",buf);
    break;
  case X509_V_ERR_CERT_NOT_YET_VALID:
  case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
    BIO_printf(bio_err,"notBefore=");
    ASN1_TIME_print(bio_err,X509_get_notBefore(ctx->current_cert));
    BIO_printf(bio_err,"\n");
    break;
  case X509_V_ERR_CERT_HAS_EXPIRED:
  case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
    BIO_printf(bio_err,"notAfter=");
    ASN1_TIME_print(bio_err,X509_get_notAfter(ctx->current_cert));
    BIO_printf(bio_err,"\n");
    break;
  }
  BIO_printf(bio_err,"verify return:%d\n",ok);
  BIO_free(bio_err);
  return(ok);
}
Пример #30
0
int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
	{
	char buf[256];
	X509 *err_cert;
	int err,depth;

	err_cert=X509_STORE_CTX_get_current_cert(ctx);
	err=	X509_STORE_CTX_get_error(ctx);
	depth=	X509_STORE_CTX_get_error_depth(ctx);

	X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof buf);
	BIO_printf(bio_err,"depth=%d %s\n",depth,buf);
	if (!ok)
		{
		BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
			X509_verify_cert_error_string(err));
		if (verify_depth >= depth)
			{
			ok=1;
			verify_error=X509_V_OK;
			}
		else
			{
			ok=0;
			verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG;
			}
		}
	switch (ctx->error)
		{
	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
		X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,sizeof buf);
		BIO_printf(bio_err,"issuer= %s\n",buf);
		break;
	case X509_V_ERR_CERT_NOT_YET_VALID:
	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
		BIO_printf(bio_err,"notBefore=");
		ASN1_TIME_print(bio_err,X509_get_notBefore(ctx->current_cert));
		BIO_printf(bio_err,"\n");
		break;
	case X509_V_ERR_CERT_HAS_EXPIRED:
	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
		BIO_printf(bio_err,"notAfter=");
		ASN1_TIME_print(bio_err,X509_get_notAfter(ctx->current_cert));
		BIO_printf(bio_err,"\n");
		break;
		}
	BIO_printf(bio_err,"verify return:%d\n",ok);
	return(ok);
	}