Пример #1
0
int
tls_session_verify_dn(X509_STORE_CTX *ctx)
{
  SSL *ssl = X509_STORE_CTX_get_app_data(ctx);
  TLSSession *self = SSL_get_app_data(ssl);
  gboolean match = FALSE;
  GList *current_dn = self->ctx->trusted_dn_list;
  X509 *cert = X509_STORE_CTX_get_current_cert(ctx);
  GString *dn;

  if (!current_dn || !cert)
    return TRUE;

  dn = g_string_sized_new(128);
  tls_x509_format_dn(X509_get_subject_name(cert), dn);

  do
    {
      if (g_pattern_match_simple((const gchar *) current_dn->data, dn->str))
        {
          match = TRUE;
          break;
        }
    }
  while ((current_dn = g_list_next(current_dn)) != NULL);
  return match;
}
Пример #2
0
int verify_cb(int ok, X509_STORE_CTX* store) {
	SSL* ssl = (SSL *)X509_STORE_CTX_get_app_data(store);
	SSL_CTX* ssl_ctx = ssl_ctx = SSL_get_SSL_CTX(ssl);
	void* p = SSL_CTX_get_ex_data(ssl_ctx, get_ssl_ctx_idx());
	// get the pointer to the go Ctx object and pass it back into the thunk
	return verify_cb_thunk(p, ok, store);
}
Пример #3
0
/*============================================================================
 * verify_callback
 *===========================================================================*/
static OpcUa_Int OpcUa_P_OpenSSL_CertificateStore_Verify_Callback(int a_ok, X509_STORE_CTX* a_pStore)
{
    OpcUa_P_OpenSSL_CertificateStore_Config*    pCertificateStoreCfg;

    pCertificateStoreCfg = X509_STORE_CTX_get_app_data(a_pStore);
    if(a_ok == 0)
    {
        /* certificate not ok */
        char    buf[256];
        X509*   err_cert;
        int     err;
        int     depth;

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

        X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
        OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "\nverify error:\n\tnum=%d:%s\n\tdepth=%d\n\t%s\n", err, X509_verify_cert_error_string(err), depth, buf);

        X509_NAME_oneline(X509_get_issuer_name(a_pStore->current_cert), buf, 256);
        OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "\tissuer=%s\n", buf);

        switch (err)
        {
            case X509_V_ERR_UNABLE_TO_GET_CRL:
                if (pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_SUPPRESS_CRL_NOT_FOUND_ERROR)
                    a_ok = 1;
                break;

            case X509_V_ERR_CRL_NOT_YET_VALID:
            case X509_V_ERR_CRL_HAS_EXPIRED:
                if (pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_SUPPRESS_CRL_VALIDITY_PERIOD_CHECK)
                    a_ok = 1;
                break;

            case X509_V_ERR_CERT_NOT_YET_VALID:
            case X509_V_ERR_CERT_HAS_EXPIRED:
                if (pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_SUPPRESS_CERT_VALIDITY_PERIOD_CHECK)
                    a_ok = 1;
                break;
        }
    }

    return a_ok;
}
Пример #4
0
/**
 * OpenSSL Certificate verification callback
 *
 * Called for each certificate in a chain being verified. OpenSSL
 * calls this in deepest first order from the certificate authority to
 * the peer certificate at position 0.
 *
 * Each certificate is stored in the fetch context the first time it
 * is presented. If an error is encountered it is only returned for
 * the peer certificate at position 0 allowing the enumeration of the
 * entire chain not stopping early at the depth of the erroring
 * certificate.
 *
 * \param verify_ok 0 if the caller has already determined the chain
 *                   has errors else 1
 * \param x509_ctx certificate context being verified
 * \return 1 to indicate verification should continue and 0 to indicate
 *          verification should stop.
 */
static int
fetch_curl_verify_callback(int verify_ok, X509_STORE_CTX *x509_ctx)
{
	int depth;
	struct curl_fetch_info *fetch;

	depth = X509_STORE_CTX_get_error_depth(x509_ctx);
	fetch = X509_STORE_CTX_get_app_data(x509_ctx);

	/* record the max depth */
	if (depth > fetch->cert_depth) {
		fetch->cert_depth = depth;
	}

	/* certificate chain is excessively deep so fail verification */
	if (depth >= MAX_CERTS) {
		X509_STORE_CTX_set_error(x509_ctx,
					 X509_V_ERR_CERT_CHAIN_TOO_LONG);
		return 0;
	}

	/* save the certificate by incrementing the reference count and
	 * keeping a pointer.
	 */
	if (!fetch->cert_data[depth].cert) {
		fetch->cert_data[depth].cert = X509_STORE_CTX_get_current_cert(x509_ctx);
		fetch->cert_data[depth].cert->references++;
		fetch->cert_data[depth].err = X509_STORE_CTX_get_error(x509_ctx);
	}

	/* allow certificate chain to be completed */
	if (depth > 0) {
		verify_ok = 1;
	} else {
		/* search for deeper certificates in the chain with errors */
		for (depth = fetch->cert_depth; depth > 0; depth--) {
			if (fetch->cert_data[depth].err != 0) {
				/* error in previous certificate so fail verification */
				verify_ok = 0;
				X509_STORE_CTX_set_error(x509_ctx, fetch->cert_data[depth].err);
			}
		}
	}

	return verify_ok;
}
Пример #5
0
/**
 * OpenSSL Certificate verification callback
 * Stores certificate details in fetch struct.
 */
static int
fetch_curl_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);
	struct curl_fetch_info *f = X509_STORE_CTX_get_app_data(x509_ctx);

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

	return preverify_ok;
}
Пример #6
0
int
tls_session_verify_callback(int ok, X509_STORE_CTX *ctx)
{
  SSL *ssl = X509_STORE_CTX_get_app_data(ctx);
  TLSSession *self = SSL_get_app_data(ssl);
  /* NOTE: Sometimes libssl calls this function
     with no current_cert. This happens when
     some global error is happen. At this situation
     we do not need to call any other check and callback
   */
  if (X509_STORE_CTX_get_current_cert(ctx) == NULL)
    {
    switch (ctx->error)
      {
      case X509_V_ERR_NO_EXPLICIT_POLICY:
        /* NOTE: Because we set the CHECK_POLICY_FLAG if the
           certificate contains ExplicitPolicy constraint
           we would get this error. But this error is because
           we do not set the policy what we want to check for.
         */
        ok = 1;
        break;
      default:
        msg_notice("Error occured during certificate validation",
                    evt_tag_int("error", ctx->error),
                    NULL);
        break;
      }
    }
  else
    {
      ok = tls_session_verify(self, ok, ctx);

      tls_log_certificate_validation_progress(ok, ctx);

      if (self->verify_func)
        return self->verify_func(ok, ctx, self->verify_data);
    }
  return ok;
}
Пример #7
0
static int _tnet_dtls_verify_cert(int preverify_ok, X509_STORE_CTX *ctx)
{
	SSL *ssl;
	tnet_dtls_socket_t* socket;

	TSK_DEBUG_INFO("_tnet_dtls_verify_cert");

	ssl = X509_STORE_CTX_get_app_data(ctx);
	socket = (tnet_dtls_socket_t*)SSL_get_app_data(ssl);
	if (!ssl || !socket){
		TSK_DEBUG_ERROR("Not expected");
		return 0;
	}
	tsk_safeobj_lock(socket);
	if (_tnet_dtls_is_fingerprint_matching(ctx->cert, &socket->remote.fp, socket->remote.hash) == tsk_false) {
		TSK_DEBUG_ERROR("Failed to match fingerprint");
		tsk_safeobj_unlock(socket);
		return 0;
	}
	tsk_safeobj_unlock(socket);
	return 1;
}
Пример #8
0
int
tls_session_verify_fingerprint(X509_STORE_CTX *ctx)
{
  SSL *ssl = X509_STORE_CTX_get_app_data(ctx);
  TLSSession *self = SSL_get_app_data(ssl);
  GList *current_fingerprint = self->ctx->trusted_fingerpint_list;
  GString *hash;
  gboolean match = FALSE;
  X509 *cert = X509_STORE_CTX_get_current_cert(ctx);

  if (!current_fingerprint)
    {
      return TRUE;
    }

  if (!cert)
    return match;

  hash = g_string_sized_new(EVP_MAX_MD_SIZE * 3);

  if (tls_get_x509_digest(cert, hash))
    {
      do
        {
          if (strcmp((const gchar*)(current_fingerprint->data), hash->str) == 0)
            {
              match = TRUE;
              break;
            }
        }
      while ((current_fingerprint = g_list_next(current_fingerprint)) != NULL);
    }

  g_string_free(hash, TRUE);
  return match;
}
Пример #9
0
///
///	Called to verify X509 client certificates
///
static int verifyX509Certificate(int ok, X509_STORE_CTX *xContext)
{
	X509			*cert;
	SSL				*ssl;
	MaOpenSslSocket	*sslSocket;
	MaOpenSslConfig	*config;
	char			subject[260], issuer[260], peer[260];
	int				error, depth;

	subject[0] = issuer[0] = '\0';

	ssl = (SSL*) X509_STORE_CTX_get_app_data(xContext);
	sslSocket = (MaOpenSslSocket*) SSL_get_app_data(ssl);
	config = (MaOpenSslConfig*) sslSocket->getConfig();

	cert = X509_STORE_CTX_get_current_cert(xContext);
	depth =	X509_STORE_CTX_get_error_depth(xContext);
	error = X509_STORE_CTX_get_error(xContext);

	if (X509_NAME_oneline(X509_get_subject_name(cert), subject, 
			sizeof(subject) - 1) < 0) {
		ok = 0;
	}
	//
	//	FUTURE -- should compare subject name and host name. Need smart compare
	//
	if (X509_NAME_oneline(X509_get_issuer_name(xContext->current_cert), issuer, 
			sizeof(issuer) - 1) < 0) {
		ok = 0;
	}
	if (X509_NAME_get_text_by_NID(X509_get_subject_name(xContext->current_cert),
		 	NID_commonName, peer, sizeof(peer) - 1) < 0) {
		ok = 0;
	}

	//
	//	Customizers: add your own code here to validate client certificates
	//
	if (ok && config->verifyDepth < depth) {
		if (error == 0) {
			error = X509_V_ERR_CERT_CHAIN_TOO_LONG;
		}
		ok = 0;
	}

	if (error != 0) {
		mprAssert(!ok);
	}

#if UNUSED
	switch (error) {
	case X509_V_ERR_CERT_HAS_EXPIRED:
	case X509_V_ERR_CERT_NOT_YET_VALID:
	case X509_V_ERR_CERT_REJECTED:
	case X509_V_ERR_CERT_SIGNATURE_FAILURE:
	case X509_V_ERR_CERT_UNTRUSTED:
	case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
	case X509_V_ERR_INVALID_CA:
	case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
	default:
		ok = 0;
		break;
	}
#endif

	if (!ok) {
		mprLog(0, "SSL: Certification failed: subject %s\n", subject);
		mprLog(4, "SSL: Issuer: %s\n", issuer);
		mprLog(4, "SSL: Peer: %s\n", peer);
		mprLog(4, "SSL: Error: %d: %s\n", error, 
			X509_verify_cert_error_string(error));

	} else {
		mprLog(0, "SSL: Certificate verified: subject %s\n", subject);
		mprLog(4, "SSL: Issuer: %s\n", issuer);
		mprLog(4, "SSL: Peer: %s\n", peer);
	}
	return ok;
}
Пример #10
0
/*
 * Globally defined verify callback
 *
 * Arguments: ok       - True everything is OK "so far", false otherwise
 *            x509_ctx - Contains the certificate being checked, the current
 *                       error number and depth, and the Connection we're
 *                       dealing with
 * Returns:   True if everything is okay, false otherwise
 */
static int global_verify_callback( int ok, X509_STORE_CTX * x509_ctx )
{
	PyObject *argv, *ret;

	SSL *ssl;

	ssl_ConnectionObj *conn;

	crypto_X509Obj *cert;

	X509 *x509;

	int errnum = X509_STORE_CTX_get_error(x509_ctx);

	int errdepth = X509_STORE_CTX_get_error_depth(x509_ctx);

#ifdef GSI_HANDSHAKE_DEBUG
	logMsg( 0, "GVC %d errnum %d errdepth", errnum, errdepth );
#endif

	ssl = (SSL *) X509_STORE_CTX_get_app_data(x509_ctx);
	conn = (ssl_ConnectionObj *) SSL_get_app_data(ssl);
	OBJ_END_THREADS( conn );
	Py_INCREF( conn );

	if ( conn->context->verify_callback != Py_None )
	{
		x509 = X509_STORE_CTX_get_current_cert(x509_ctx);

		cert = crypto_X509_New(x509, 0);
		argv = Py_BuildValue("(OOiii)", (PyObject *) conn, (PyObject *) cert,
				errnum, errdepth, ok);
		Py_DECREF(cert);
		/* We need to get back our thread state before calling the callback */
		ret = PyEval_CallObject(conn->context->verify_callback, argv);
		Py_DECREF(argv);

		if ( ret == NULL )
		{
			ok = 0;
		}
		else
		{
			if ( PyObject_IsTrue(ret) )
			{
				X509_STORE_CTX_set_error(x509_ctx, X509_V_OK);
				ok = 1;
			}
			else
				ok = 0;

			Py_DECREF(ret);
		}
	}

	//Set the remove verification flag in the end
	if ( errdepth == 0 && ok )
	{
		conn->remoteCertVerified = 1;
	}

	Py_DECREF( conn );
	OBJ_BEGIN_THREADS( conn );

	return ok;
}
Пример #11
0
static int verifyPeerCertificate(int ok, X509_STORE_CTX *xctx)
{
    X509            *cert;
    SSL             *handle;
    OpenSocket      *osp;
    MprSocket       *sp;
    MprSsl          *ssl;
    char            subject[512], issuer[512], peerName[512];
    int             error, depth;

    subject[0] = issuer[0] = '\0';

    handle = (SSL*) X509_STORE_CTX_get_app_data(xctx);
    osp = (OpenSocket*) SSL_get_app_data(handle);
    sp = osp->sock;
    ssl = sp->ssl;

    cert = X509_STORE_CTX_get_current_cert(xctx);
    depth = X509_STORE_CTX_get_error_depth(xctx);
    error = X509_STORE_CTX_get_error(xctx);

    ok = 1;
    if (X509_NAME_oneline(X509_get_subject_name(cert), subject, sizeof(subject) - 1) < 0) {
        sp->errorMsg = sclone("Cannot get subject name");
        ok = 0;
    }
    if (X509_NAME_oneline(X509_get_issuer_name(cert), issuer, sizeof(issuer) - 1) < 0) {
        sp->errorMsg = sclone("Cannot get issuer name");
        ok = 0;
    }
    if (X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_commonName, peerName, sizeof(peerName) - 1) == 0) {
        sp->errorMsg = sclone("Cannot get peer name");
        ok = 0;
    }
    if (ok && ssl->verifyDepth < depth) {
        if (error == 0) {
            error = X509_V_ERR_CERT_CHAIN_TOO_LONG;
        }
    }
    switch (error) {
    case X509_V_OK:
        break;
    case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
    case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
        /* Normal self signed certificate */
        if (ssl->verifyIssuer) {
            sp->errorMsg = sclone("Self-signed certificate");
            ok = 0;
        }
        break;

    case X509_V_ERR_CERT_UNTRUSTED:
    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
        if (ssl->verifyIssuer) {
            /* Issuer cannot be verified */
            sp->errorMsg = sclone("Certificate not trusted");
            ok = 0;
        }
        break;

    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
    case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
        if (ssl->verifyIssuer) {
            /* Issuer cannot be verified */
            sp->errorMsg = sclone("Certificate not trusted");
            ok = 0;
        }
        break;

    case X509_V_ERR_CERT_HAS_EXPIRED:
        sp->errorMsg = sfmt("Certificate has expired");
        ok = 0;
        break;
            
#ifdef X509_V_ERR_HOSTNAME_MISMATCH
    case X509_V_ERR_HOSTNAME_MISMATCH:
        sp->errorMsg = sfmt("Certificate hostname mismatch. Expecting %s got %s", osp->requiredPeerName, peerName);
        ok = 0;
        break;
#endif
    case X509_V_ERR_CERT_CHAIN_TOO_LONG:
    case X509_V_ERR_CERT_NOT_YET_VALID:
    case X509_V_ERR_CERT_REJECTED:
    case X509_V_ERR_CERT_SIGNATURE_FAILURE:
    case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
    case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
    case X509_V_ERR_INVALID_CA:
    default:
        sp->errorMsg = sfmt("Certificate verification error %d", error);
        ok = 0;
        break;
    }
    if (!ok) {
        sp->flags |= MPR_SOCKET_CERT_ERROR;
    }
    return ok;
}