Пример #1
0
static int certificate_verify_callback(int preverify_ok, X509_STORE_CTX * ctx) {
    char fnm[FILE_PATH_SIZE];
    DIR * dir = NULL;
    int err = 0;
    int found = 0;

    snprintf(fnm, sizeof(fnm), "%s/ssl", tcf_dir);
    if (!err && (dir = opendir(fnm)) == NULL) err = errno;
    while (!err && !found) {
        int l = 0;
        X509 * cert = NULL;
        FILE * fp = NULL;
        struct dirent * ent = readdir(dir);
        if (ent == NULL) break;
        l = strlen(ent->d_name);
        if (l < 5 || strcmp(ent->d_name + l -5 , ".cert") != 0) continue;
        snprintf(fnm, sizeof(fnm), "%s/ssl/%s", tcf_dir, ent->d_name);
        if (!err && (fp = fopen(fnm, "r")) == NULL) err = errno;
        if (!err && (cert = PEM_read_X509(fp, NULL, NULL, NULL)) == NULL) err = set_ssl_errno();
        if (!err && fclose(fp) != 0) err = errno;
        if (!err && X509_cmp(X509_STORE_CTX_get_current_cert(ctx), cert) == 0) found = 1;
    }
    if (dir != NULL && closedir(dir) < 0 && !err) err = errno;
    if (err) trace(LOG_ALWAYS, "Cannot read certificate %s: %s", fnm, errno_to_str(err));
    else if (!found) trace(LOG_ALWAYS, "Authentication failure: invalid certificate");
    return err == 0 && found;
}
Пример #2
0
int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert)
{
    CMS_CertificateChoices *cch;
    STACK_OF(CMS_CertificateChoices) **pcerts;
    int i;
    pcerts = cms_get0_certificate_choices(cms);
    if (!pcerts)
        return 0;
    for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) {
        cch = sk_CMS_CertificateChoices_value(*pcerts, i);
        if (cch->type == CMS_CERTCHOICE_CERT) {
            if (!X509_cmp(cch->d.certificate, cert)) {
                CMSerr(CMS_F_CMS_ADD0_CERT,
                       CMS_R_CERTIFICATE_ALREADY_PRESENT);
                return 0;
            }
        }
    }
    cch = CMS_add0_CertificateChoices(cms);
    if (!cch)
        return 0;
    cch->type = CMS_CERTCHOICE_CERT;
    cch->d.certificate = cert;
    return 1;
}
Пример #3
0
/*
 *	Returns: 	0 if successfully matching certificate to TLSA record bytes
 *				-1 if there was no match
 */
int ca_constraint(const SSL *con, const X509 *tlsa_cert, int usage) {
	STACK_OF(X509) *cert_chain = NULL;
	cert_chain = SSL_get_peer_cert_chain(con);
	BIO_printf(b_err, "DANE ca_constraint() chain of %d length\n", 
		sk_X509_num(cert_chain));
	int ret_val;
	ret_val = 0;
	
	if (cert_chain != NULL) {
		int i;
		for (i = 0; i < sk_X509_num(cert_chain); i++) {			
			BIO_printf(b_err, "DANE ca_constraint() cert %d of %d.\n",
				i, sk_X509_num(cert_chain));
			/*
			BIO_printf(b_err, "DANE CXN Certificate\n");
			PEM_write_bio_X509(b_err, sk_X509_value(cert_chain, i));
			BIO_printf(b_err, "DANE TLSA Certificate\n");
			PEM_write_bio_X509(b_err, tlsa_cert);
			*/
			if (X509_cmp(tlsa_cert, sk_X509_value(cert_chain, i)) < 0) {
				ret_val = -1;
				BIO_printf(b_err, "DANE ca_constraint() certificates didn't match\n");
			} else {
				BIO_printf(b_err, "DANE ca_constraint() certificates matches\n");
				if (usage == 0)
					return 0;
				
				/*	For this to be a trust anchor, the following characteristics applies:
				 * 	1. Issuer name is the same as Subject name
				 * 	2. Either or both
				 *	a) the Key Usage field is set to keyCertSign (KU_KEY_CERT_SIGN)
				 *	b) the basicConstraints field has the attribute cA set to True (EXFLAG_CA)
				 */
				X509_NAME *issuer_name, *subject_name;
				issuer_name = X509_get_issuer_name(tlsa_cert);
				subject_name = X509_get_subject_name(tlsa_cert);
				
				if (X509_name_cmp(issuer_name, subject_name) == 0) {
					BIO_printf(b_err, "DANE issuer == subject\n");
					
					if (tlsa_cert->ex_flags & EXFLAG_CA) {
						BIO_printf(b_err, "DANE ca_constraint() EXFLAG_CA set\n");
						return 0;
					}
/*	Left unimplemented since I don't have a CA certificate to work with.*/
					int ext_count, j;
					ext_count = X509_get_ext_count(tlsa_cert);
					BIO_printf(b_err, "DANE ca_constraint() %d certificate extensions\n");

				} else {
					return 0;
				}
			}
		}
	}
	return ret_val;
}
Пример #4
0
static int test_resp_signer(void)
{
    OCSP_BASICRESP *bs = NULL;
    X509 *signer = NULL, *tmp;
    EVP_PKEY *key = NULL;
    STACK_OF(X509) *extra_certs = NULL;
    int ret = 0;

    /*
     * Test a response with no certs at all; get the signer from the
     * extra certs given to OCSP_resp_get0_signer().
     */
    bs = make_dummy_resp();
    extra_certs = sk_X509_new_null();
    if (!TEST_ptr(bs)
        || !TEST_ptr(extra_certs)
        || !TEST_true(get_cert_and_key(&signer, &key))
        || !TEST_true(sk_X509_push(extra_certs, signer))
        || !TEST_true(OCSP_basic_sign(bs, signer, key, EVP_sha1(),
                                      NULL, OCSP_NOCERTS)))
        goto err;
    if (!TEST_true(OCSP_resp_get0_signer(bs, &tmp, extra_certs))
        || !TEST_int_eq(X509_cmp(tmp, signer), 0))
        goto err;
    OCSP_BASICRESP_free(bs);

    /* Do it again but include the signer cert */
    bs = make_dummy_resp();
    tmp = NULL;
    if (!TEST_ptr(bs)
        || !TEST_true(OCSP_basic_sign(bs, signer, key, EVP_sha1(),
                                      NULL, 0)))
        goto err;
    if (!TEST_true(OCSP_resp_get0_signer(bs, &tmp, NULL))
        || !TEST_int_eq(X509_cmp(tmp, signer), 0))
        goto err;
    ret = 1;
 err:
    OCSP_BASICRESP_free(bs);
    sk_X509_free(extra_certs);
    X509_free(signer);
    EVP_PKEY_free(key);
    return ret;
}
Пример #5
0
static int ssl_certificate_compare(SSLCertificate *cert_a,
	SSLCertificate *cert_b)
{
	if (cert_a == NULL || cert_b == NULL)
		return FALSE;
	else if (!X509_cmp(cert_a->x509_cert, cert_b->x509_cert))
		return TRUE;
	else
		return FALSE;
}
bool SSLConnection::checkCertCache() {
  unsigned char peermd[EVP_MAX_MD_SIZE];
  unsigned int peermdlen;
  size_t i;

  if (!X509_digest (cert, EVP_sha1(), peermd, &peermdlen)) 
    return false;

  for (i=0; i<Certs.size(); i++) {
    if (X509_cmp(Certs[i],peermd,peermdlen)) {
      DEBUGPRINT(D_SOCKET,("found cached cert at %d",i));
      return true;
    }
  }
  return false;
}
bool SSLConnection::checkCertDigest() {
  unsigned char peermd[EVP_MAX_MD_SIZE];
  unsigned int peermdlen;
  X509 *c = NULL; 
  bool pass = false;
  FILE *fp;
  buffer_t msg;

  buffer_init(&msg);
  /* expiration check */
  if (X509_cmp_current_time (X509_get_notBefore (cert)) >= 0) {
    buffer_shrink(&msg,0);
    buffer_add_str(&msg,_("Server certificate is not yet valid."),-1);
    displayError.emit(&msg);
    buffer_free(&msg);
    return 0;
  }
  if (X509_cmp_current_time (X509_get_notAfter (cert)) <= 0) { 
    buffer_shrink(&msg,0);
    buffer_add_str(&msg,_("Server certificate has expired."),-1);
    displayError.emit(&msg);
    buffer_free(&msg);
    return 0;
  }
  buffer_free(&msg);

  if ((fp = fopen (SSLCertFile, "rt")) == NULL)
    return false;

  if (!X509_digest (cert, EVP_sha1 (), peermd, &peermdlen)) {
    fclose (fp);
    return false;
  }

  while ((c = READ_X509_KEY (fp, &c)) != NULL) { 
    pass = X509_cmp (c, peermd, peermdlen);
    if (pass)
      break;
  }

  X509_free(c);
  fclose (fp);

  return pass;
}
Пример #8
0
//int service_cert_constraint(const SSL *con, const unsigned char *tlsa_bytes, int tlsa_len) {
int service_cert_constraint(const X509 *con_cert, const X509 *tlsa_cert) {
	int ret_val;
	ret_val = 0;
	
	if (con_cert != NULL) {
		if (X509_cmp(tlsa_cert, con_cert) != 0) {
			ret_val = -1;
			BIO_printf(b_err, "DANE server_cert_constraint() certificates didn't match\n");
		} else {
			BIO_printf(b_err, "DANE server_cert_constraint() certificates matches\n");
			// Must return immediately in case there are non-matching certificates
			return 0;
		}
	} else
		BIO_printf(b_err,"DANE:no peer certificate available\n");
		
	return ret_val;
}
Пример #9
0
/*
 * Compare two X509 certificates.
 * return:
 *	 1 - certificates are not NULL and equal
 *	 0 - certificates are not NULL and differ
 *	-1 - both certificates are NULL
 *	-2 - x509_cert1 is NULL, x509_cert2 is not NULL
 *	-3 - x509_cert1 in not NULL, x509_cert2 is NULL
 */
static int ssl_X509_cmp(X509 *x509_cert1, X509 *x509_cert2)
{
	/* X509_cmp() will crash if any of its args are NULL
	 */
	if (x509_cert1 != NULL) {
		if (x509_cert2 == NULL) {
			return -3; /* x509_cert1 in not NULL, x509_cert2 is NULL */
		} else {
			if (X509_cmp(x509_cert1, x509_cert2)) {
				return 0; /* certificates are differ */
			} else {
				return 1; /* certificates are equal */
			}
		}
	} else {
		if (x509_cert2 == NULL) {
			return -1; /* both certificates are NULL */
		} else {
			return -2; /* x509_cert1 is NULL, x509_cert2 is not NULL */
		}
	}
}
Пример #10
0
int X509_verify_cert(X509_STORE_CTX *ctx)
	{
	X509 *x,*xtmp,*chain_ss=NULL;
	X509_NAME *xn;
	int depth,i,ok=0;
	int num;
	int (*cb)();
	STACK_OF(X509) *sktmp=NULL;

	if (ctx->cert == NULL)
		{
		X509err(X509_F_X509_VERIFY_CERT,X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
		return -1;
		}

	cb=ctx->verify_cb;

	/* first we make sure the chain we are going to build is
	 * present and that the first entry is in place */
	if (ctx->chain == NULL)
		{
		if (	((ctx->chain=sk_X509_new_null()) == NULL) ||
			(!sk_X509_push(ctx->chain,ctx->cert)))
			{
			X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
			goto end;
			}
		CRYPTO_add(&ctx->cert->references,1,CRYPTO_LOCK_X509);
		ctx->last_untrusted=1;
		}

	/* We use a temporary STACK so we can chop and hack at it */
	if (ctx->untrusted != NULL
	    && (sktmp=sk_X509_dup(ctx->untrusted)) == NULL)
		{
		X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
		goto end;
		}

	num=sk_X509_num(ctx->chain);
	x=sk_X509_value(ctx->chain,num-1);
	depth=ctx->depth;


	for (;;)
		{
		/* If we have enough, we break */
		if (depth < num) break; /* FIXME: If this happens, we should take
		                         * note of it and, if appropriate, use the
		                         * X509_V_ERR_CERT_CHAIN_TOO_LONG error
		                         * code later.
		                         */

		/* If we are self signed, we break */
		xn=X509_get_issuer_name(x);
		if (ctx->check_issued(ctx, x,x)) break;

		/* If we were passed a cert chain, use it first */
		if (ctx->untrusted != NULL)
			{
			xtmp=find_issuer(ctx, sktmp,x);
			if (xtmp != NULL)
				{
				if (!sk_X509_push(ctx->chain,xtmp))
					{
					X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
					goto end;
					}
				CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509);
				sk_X509_delete_ptr(sktmp,xtmp);
				ctx->last_untrusted++;
				x=xtmp;
				num++;
				/* reparse the full chain for
				 * the next one */
				continue;
				}
			}
		break;
		}

	/* at this point, chain should contain a list of untrusted
	 * certificates.  We now need to add at least one trusted one,
	 * if possible, otherwise we complain. */

	/* Examine last certificate in chain and see if it
 	 * is self signed.
 	 */

	i=sk_X509_num(ctx->chain);
	x=sk_X509_value(ctx->chain,i-1);
	xn = X509_get_subject_name(x);
	if (ctx->check_issued(ctx, x, x))
		{
		/* we have a self signed certificate */
		if (sk_X509_num(ctx->chain) == 1)
			{
			/* We have a single self signed certificate: see if
			 * we can find it in the store. We must have an exact
			 * match to avoid possible impersonation.
			 */
			ok = ctx->get_issuer(&xtmp, ctx, x);
			if ((ok <= 0) || X509_cmp(x, xtmp)) 
				{
				ctx->error=X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
				ctx->current_cert=x;
				ctx->error_depth=i-1;
				if (ok == 1) X509_free(xtmp);
				ok=cb(0,ctx);
				if (!ok) goto end;
				}
			else 
				{
				/* We have a match: replace certificate with store version
				 * so we get any trust settings.
				 */
				X509_free(x);
				x = xtmp;
				sk_X509_set(ctx->chain, i - 1, x);
				ctx->last_untrusted=0;
				}
			}
		else
			{
			/* extract and save self signed certificate for later use */
			chain_ss=sk_X509_pop(ctx->chain);
			ctx->last_untrusted--;
			num--;
			x=sk_X509_value(ctx->chain,num-1);
			}
		}

	/* We now lookup certs from the certificate store */
	for (;;)
		{
		/* If we have enough, we break */
		if (depth < num) break;

		/* If we are self signed, we break */
		xn=X509_get_issuer_name(x);
		if (ctx->check_issued(ctx,x,x)) break;

		ok = ctx->get_issuer(&xtmp, ctx, x);

		if (ok < 0) return ok;
		if (ok == 0) break;

		x = xtmp;
		if (!sk_X509_push(ctx->chain,x))
			{
			X509_free(xtmp);
			X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
			return 0;
			}
		num++;
		}

	/* we now have our chain, lets check it... */
	xn=X509_get_issuer_name(x);

	/* Is last certificate looked up self signed? */
	if (!ctx->check_issued(ctx,x,x))
		{
		if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss))
			{
			if (ctx->last_untrusted >= num)
				ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
			else
				ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
			ctx->current_cert=x;
			}
		else
			{

			sk_X509_push(ctx->chain,chain_ss);
			num++;
			ctx->last_untrusted=num;
			ctx->current_cert=chain_ss;
			ctx->error=X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
			chain_ss=NULL;
			}

		ctx->error_depth=num-1;
		ok=cb(0,ctx);
		if (!ok) goto end;
		}

	/* We have the chain complete: now we need to check its purpose */
	ok = check_chain_extensions(ctx);

	if (!ok) goto end;

	/* The chain extensions are OK: check trust */

	if (ctx->trust > 0) ok = check_trust(ctx);

	if (!ok) goto end;

	/* We may as well copy down any DSA parameters that are required */
	X509_get_pubkey_parameters(NULL,ctx->chain);

	/* Check revocation status: we do this after copying parameters
	 * because they may be needed for CRL signature verification.
	 */

	ok = ctx->check_revocation(ctx);
	if(!ok) goto end;

	/* At this point, we have a chain and just need to verify it */
	if (ctx->verify != NULL)
		ok=ctx->verify(ctx);
	else
		ok=internal_verify(ctx);
	if (0)
		{
end:
		X509_get_pubkey_parameters(NULL,ctx->chain);
		}
	if (sktmp != NULL) sk_X509_free(sktmp);
	if (chain_ss != NULL) X509_free(chain_ss);
	return ok;
	}
Пример #11
0
/*============================================================================
 * OpcUa_P_OpenSSL_PKI_ValidateCertificate
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_PKI_ValidateCertificate(
    OpcUa_PKIProvider*          a_pProvider,
    OpcUa_ByteString*           a_pCertificate,
    OpcUa_Void*                 a_pCertificateStore,
    OpcUa_Int*                  a_pValidationCode /* Validation return codes from OpenSSL */
    )
{
    OpcUa_P_OpenSSL_CertificateStore_Config*    pCertificateStoreCfg;

    const unsigned char* p;

    X509*               pX509Certificate        = OpcUa_Null;
    STACK_OF(X509)*     pX509Chain              = OpcUa_Null;
    X509_STORE_CTX*     verify_ctx              = OpcUa_Null;    /* holds data used during verification process */
    char                CertFile[MAX_PATH];
    struct dirent **dirlist = NULL;
    int numCertificates = 0, i;

OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "PKI_ValidateCertificate");

    OpcUa_ReturnErrorIfArgumentNull(a_pProvider);
    OpcUa_ReturnErrorIfArgumentNull(a_pProvider->Handle);
    OpcUa_ReturnErrorIfArgumentNull(a_pCertificate);
    OpcUa_ReturnErrorIfArgumentNull(a_pCertificateStore);
    OpcUa_ReturnErrorIfArgumentNull(a_pValidationCode);

    pCertificateStoreCfg = (OpcUa_P_OpenSSL_CertificateStore_Config*)a_pProvider->Handle;

    /* convert DER encoded bytestring certificate to openssl X509 certificate */
    p = a_pCertificate->Data;
    if(!(pX509Certificate = d2i_X509((X509**)OpcUa_Null, &p, a_pCertificate->Length)))
    {
        OpcUa_GotoErrorWithStatus(OpcUa_Bad);
    }

    while(p < a_pCertificate->Data + a_pCertificate->Length)
    {
        X509* pX509AddCertificate;
        if(!(pX509AddCertificate = d2i_X509((X509**)OpcUa_Null, &p, a_pCertificate->Data + a_pCertificate->Length - p)))
        {
            OpcUa_GotoErrorWithStatus(OpcUa_Bad);
        }
        if(pX509Chain == NULL)
        {
            pX509Chain = sk_X509_new_null();
            OpcUa_GotoErrorIfAllocFailed(pX509Chain);
        }
        if(!sk_X509_push(pX509Chain, pX509AddCertificate))
        {
            X509_free(pX509AddCertificate);
            OpcUa_GotoErrorWithStatus(OpcUa_Bad);
        }
    }

    /* create verification context and initialize it */
    if(!(verify_ctx = X509_STORE_CTX_new()))
    {
        OpcUa_GotoErrorWithStatus(OpcUa_Bad);
    }

#if (OPENSSL_VERSION_NUMBER > 0x00907000L)
    if(X509_STORE_CTX_init(verify_ctx, (X509_STORE*)a_pCertificateStore, pX509Certificate, pX509Chain) != 1)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_Bad);
    }
#else
    X509_STORE_CTX_init(verify_ctx, (X509_STORE*)a_pCertificateStore, pX509Certificate, pX509Chain);
#endif

    if(X509_STORE_CTX_set_app_data(verify_ctx, pCertificateStoreCfg) != 1)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_Bad);
    }

    if((pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_CHECK_REVOCATION_ALL) == OPCUA_P_PKI_OPENSSL_CHECK_REVOCATION_ALL_EXCEPT_SELF_SIGNED
        && !verify_ctx->check_issued(verify_ctx, pX509Certificate, pX509Certificate))
    {
        /* set the flags of the store so that CRLs are consulted */
        X509_STORE_CTX_set_flags(verify_ctx, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
    }

    /* verify the certificate */
    *a_pValidationCode = X509_V_OK;
    if(X509_verify_cert(verify_ctx) <= 0)
    {
        *a_pValidationCode = verify_ctx->error;
        switch(verify_ctx->error)
        {
        case X509_V_ERR_CERT_HAS_EXPIRED:
        case X509_V_ERR_CERT_NOT_YET_VALID:
        case X509_V_ERR_CRL_NOT_YET_VALID:
        case X509_V_ERR_CRL_HAS_EXPIRED:
        case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
        case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
        case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
        case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
            {
                uStatus = OpcUa_BadCertificateTimeInvalid;
                break;
            }
        case X509_V_ERR_CERT_REVOKED:
            {
                uStatus = OpcUa_BadCertificateRevoked;
                break;
            }
        case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
        case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
        case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
            {
                uStatus = OpcUa_BadCertificateUntrusted;
                break;
            }
        case X509_V_ERR_CERT_SIGNATURE_FAILURE:
            {
                uStatus = OpcUa_BadSecurityChecksFailed;
                break;
            }
        default:
            {
                uStatus = OpcUa_BadCertificateInvalid;
            }
        }
        OpcUa_GotoErrorIfBad(uStatus);
    }

    if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_REQUIRE_CHAIN_CERTIFICATE_IN_TRUST_LIST)
    {
        FILE*            pCertificateFile;
        X509*            pTrustCert;
        STACK_OF(X509)*  chain;
        int              trusted, n;

        chain = X509_STORE_CTX_get_chain(verify_ctx);
        trusted = 0;
        if(pCertificateStoreCfg->CertificateTrustListLocation == NULL || pCertificateStoreCfg->CertificateTrustListLocation[0] == '\0')
        {
            uStatus = OpcUa_Bad;
            OpcUa_GotoErrorIfBad(uStatus);
        }

        numCertificates = scandir(pCertificateStoreCfg->CertificateTrustListLocation, &dirlist, certificate_filter_der, alphasort);
        for (i=0; i<numCertificates; i++)
        {
            uStatus = OpcUa_P_OpenSSL_BuildFullPath(pCertificateStoreCfg->CertificateTrustListLocation, dirlist[i]->d_name, MAX_PATH, CertFile);
            OpcUa_GotoErrorIfBad(uStatus);

            /* read DER certificates */
            pCertificateFile = fopen(CertFile, "r");
            if(pCertificateFile == OpcUa_Null)
            {
                continue; /* ignore access errors */
            }

            pTrustCert = d2i_X509_fp(pCertificateFile, (X509**)OpcUa_Null);
            fclose(pCertificateFile);
            if(pTrustCert == OpcUa_Null)
            {
                continue; /* ignore parse errors */
            }

            for(n = 0; n < sk_X509_num(chain); n++)
            {
                if (X509_cmp(sk_X509_value(chain, n), pTrustCert) == 0)
                    break;
            }

            X509_free(pTrustCert);
            if(n < sk_X509_num(chain))
            {
                trusted = 1;
                break;
            }
        }
        for (i=0; i<numCertificates; i++)
        {
            free(dirlist[i]);
        }
        free(dirlist);
        dirlist = NULL;

        if(!trusted)
        {
            uStatus = OpcUa_BadCertificateUntrusted;
            OpcUa_GotoErrorIfBad(uStatus);
        }
    }

    X509_STORE_CTX_free(verify_ctx);
    X509_free(pX509Certificate);
    if(pX509Chain != OpcUa_Null)
    {
        sk_X509_pop_free(pX509Chain, X509_free);
    }

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    if(dirlist != NULL)
    {
        for (i=0; i<numCertificates; i++)
        {
            free(dirlist[i]);
        }
        free(dirlist);
    }

    if(verify_ctx != OpcUa_Null)
    {
        X509_STORE_CTX_free(verify_ctx);
    }

    if(pX509Certificate != OpcUa_Null)
    {
        X509_free(pX509Certificate);
    }

    if(pX509Chain != OpcUa_Null)
    {
        sk_X509_pop_free(pX509Chain, X509_free);
    }

OpcUa_FinishErrorHandling;
}
Пример #12
0
static int ldap_mapper_match_user(X509 *x509, const char *login, void *context) {
	int match_found = 0;
	int i=0;

	if ( 1 != ldap_get_certificate(login)){
		DBG("ldap_get_certificate() failed");
		match_found = 0;
	} else {
		/* TODO: maybe compare public keys instead of hashes */
		while( i<certcnt && !match_found ) {
#ifdef HAVE_NSS
			if ( x509 == ldap_x509[i]) {
#else
			if ( 0 == X509_cmp(x509, ldap_x509[i])) {
#endif
				DBG1("Certificate %d is matching", i);
				match_found = 1;
			} else {
				DBG1("Certificate %d is NOT matching", i);
			}
			i++;
		}
		if (certcnt)
		{
#ifdef HAVE_NSS
			int rv;

			for (rv=0; rv<certcnt; rv++)
				if (ldap_x509[rv])
					CERT_DestroyCertificate(ldap_x509[rv]);
#endif
			free(ldap_x509);
		}
		certcnt=0;
	}
	return match_found;
}

static char * ldap_mapper_find_user(X509 *x509, void *context, int *match) {
	struct passwd *pw = NULL;
	char *found=NULL;
	setpwent();
	while( (pw=getpwent()) !=NULL) {
	    int res;
	    DBG1("Trying to match certificate with user: '******'",pw->pw_name);
	    res= ldap_mapper_match_user(x509,pw->pw_name,context);
	    if (res) {
		DBG1("Certificate maps to user '%s'",pw->pw_name);
		found= clone_str(pw->pw_name);
		*match = 1;
		break;
	    } else {
		DBG1("Certificate map to user '%s' failed",pw->pw_name);
	    }
	}
	endpwent();

#ifdef false
	int res;
	res= ldap_mapper_match_user(x509,"wefel",context);
	if (res) {
			DBG("Certificate maps to user wefel");
			found= clone_str("wefel");
	} else {
			DBG("Certificate map to user wefel failed");
	}
#endif

	return found;
}

static mapper_module * init_mapper_st(scconf_block *blk, const char *name) {
	mapper_module *pt= malloc(sizeof(mapper_module));
	if (!pt) return NULL;
	pt->name = name;
	pt->block = blk;
	pt->context = NULL;
	pt->entries = ldap_mapper_find_entries;
	pt->finder = ldap_mapper_find_user;
	pt->matcher = ldap_mapper_match_user;
	pt->deinit = mapper_module_end;

	return pt;
}
Пример #13
0
/*
 * -1 if authentication failed
 *  1 if authentication succeeded
 *  2 if authentication succeeded, using parameter
 * -2 if authentication is delayed, don't error
 * No AuthStruct = everyone allowed
*/
int	Auth_Check(aClient *cptr, anAuthStruct *as, char *para)
{
#ifdef	AUTHENABLE_UNIXCRYPT
	extern	char *crypt();
#endif

#ifdef AUTHENABLE_SSL_CLIENTCERT
	X509 *x509_clientcert = NULL;
	X509 *x509_filecert = NULL;
	FILE *x509_f = NULL;
#endif

	if (!as)
		return 1;
		
	switch (as->type)
	{
		case AUTHTYPE_PLAINTEXT:
			if (!para)
				return -1;
			/* plain text compare */
			if (!strcmp(para, as->data))
				return 2;
			else
				return -1;
			break;
#ifdef AUTHENABLE_UNIXCRYPT
		case AUTHTYPE_UNIXCRYPT:
			if (!para)
				return -1;
			/* If our data is like 1 or none, we just let em through .. */
			if (!(as->data[0] && as->data[1]))
				return 1;
			if (!strcmp(crypt(para, as->data), as->data))
				return 2;
			else
				return -1;
			break;
#endif
		case AUTHTYPE_MD5:
			return authcheck_md5(cptr, as, para);
			break;
#ifdef AUTHENABLE_SHA1
		case AUTHTYPE_SHA1:
			return authcheck_sha1(cptr, as, para);
			break;
#endif
#ifdef AUTHENABLE_RIPEMD160
		case AUTHTYPE_RIPEMD160:
			return authcheck_ripemd160(cptr, as, para);
#endif
#ifdef AUTHENABLE_SSL_CLIENTCERT
		case AUTHTYPE_SSL_CLIENTCERT:
			if (!para)
				return -1;
			if (!cptr->ssl)
				return -1;
			x509_clientcert = SSL_get_peer_certificate((SSL *)cptr->ssl);
			if (!x509_clientcert)
				return -1;
			if (!(x509_f = fopen(as->data, "r")))
			{
				X509_free(x509_clientcert);
				return -1;
			}
			x509_filecert = PEM_read_X509(x509_f, NULL, NULL, NULL);
			fclose(x509_f);
			if (!x509_filecert)
			{
				X509_free(x509_clientcert);
				return -1;
			}
			if (X509_cmp(x509_filecert, x509_clientcert) != 0)
			{
				X509_free(x509_clientcert);
				X509_free(x509_filecert);
				break;
			}
			X509_free(x509_clientcert);
			X509_free(x509_filecert);
			return 2;	
#endif
	}
	return -1;
}
Пример #14
0
bool operator==(const Certificate& c1, const Certificate& c2)
{
	return (X509_cmp(c1.x, c2.x) == 0 && c1.subject == c2.subject && /* c1.validity == c2.validity && */ c1.issuer == c2.issuer);
}
Пример #15
0
static int test_cert_reparse(const uint8_t *der_bytes, size_t der_len) {
  CBS pkcs7;
  CBB cbb;
  STACK_OF(X509) *certs = sk_X509_new_null();
  STACK_OF(X509) *certs2 = sk_X509_new_null();
  uint8_t *result_data, *result2_data;
  size_t result_len, result2_len, i;

  CBS_init(&pkcs7, der_bytes, der_len);
  if (!PKCS7_get_certificates(certs, &pkcs7)) {
    fprintf(stderr, "PKCS7_get_certificates failed.\n");
    return 0;
  }

  CBB_init(&cbb, der_len);
  if (!PKCS7_bundle_certificates(&cbb, certs) ||
      !CBB_finish(&cbb, &result_data, &result_len)) {
    fprintf(stderr, "PKCS7_bundle_certificates failed.\n");
    return 0;
  }

  CBS_init(&pkcs7, result_data, result_len);
  if (!PKCS7_get_certificates(certs2, &pkcs7)) {
    fprintf(stderr, "PKCS7_get_certificates reparse failed.\n");
    return 0;
  }

  if (sk_X509_num(certs) != sk_X509_num(certs2)) {
    fprintf(stderr, "Number of certs in results differ.\n");
    return 0;
  }

  for (i = 0; i < sk_X509_num(certs); i++) {
    X509 *a = sk_X509_value(certs, i);
    X509 *b = sk_X509_value(certs2, i);

    if (X509_cmp(a, b) != 0) {
      fprintf(stderr, "Certificate %u differs.\n", (unsigned) i);
      return 0;
    }
  }

  CBB_init(&cbb, der_len);
  if (!PKCS7_bundle_certificates(&cbb, certs2) ||
      !CBB_finish(&cbb, &result2_data, &result2_len)) {
    fprintf(stderr,
            "PKCS7_bundle_certificates failed the second time.\n");
    return 0;
  }

  if (result_len != result2_len ||
      memcmp(result_data, result2_data, result_len) != 0) {
    fprintf(stderr, "Serialisation is not stable.\n");
    return 0;
  }

  OPENSSL_free(result_data);
  OPENSSL_free(result2_data);
  sk_X509_pop_free(certs, X509_free);
  sk_X509_pop_free(certs2, X509_free);

  return 1;
}
Пример #16
0
/* This function is called on a socket file descriptor once the connection has been
 * established and we're ready to negotiate SSL.  If the SSL handshake fails for some
 * reason (such as the host on the other end not using SSL), it will return 0 for
 * failure.  Success returns 1.
 */
static int FinishConnection(TCLinkCon *c, int sd)
{
	int ssl_connected, is_error, errcode, res;
	X509 *server_cert;
	time_t start, remaining;
	fd_set in, out, err;
	struct timeval tv;

	/* check if socket has connected successfully */
	int val;
	int /*socklen_t*/ size = 4;
	getsockopt(sd, SOL_SOCKET, SO_ERROR, (char*)&val, &size);
	if (val != 0)
		return 0;

	c->ssl = SSL_new(c->ctx);
	if (!c->ssl)
		return 0;

	FD_ZERO(&in); FD_SET((unsigned)sd, &in);
	FD_ZERO(&out); FD_SET((unsigned)sd, &out);
	FD_ZERO(&err); FD_SET((unsigned)sd, &err);

	SSL_set_fd(c->ssl, sd);

	ssl_connected = 0;
	is_error = 0;
	start = time(0);

	while (!ssl_connected && !is_error)
	{
		remaining = 5 - (time(0) - start);
		if (remaining <= 0) {
			is_error = 1;
			break;
		}

		res = SSL_connect(c->ssl);

		ssl_connected = ((res == 1) && SSL_is_init_finished(c->ssl));

		if (!ssl_connected)
		{
			errcode = SSL_get_error(c->ssl, res);
			switch (errcode)
			{
				case SSL_ERROR_NONE:
					/* no error, we should have a connection, check again */
					break;

				case SSL_ERROR_WANT_READ:
				case SSL_ERROR_WANT_WRITE:
					/* no error, just wait for more data */
					tv.tv_sec = remaining; tv.tv_usec = 0;
					if (select(sd+1, &in, &out, &err, &tv) < 0)
						is_error = 1;
					break;

				case SSL_ERROR_ZERO_RETURN: /* peer closed the connection */
				case SSL_ERROR_SSL:         /* error in SSL handshake */
				default:
					is_error = 1;
			}
		}
	}

	if (is_error) {
		SSL_free(c->ssl);
		return 0;
	}
   
	   
#ifdef WIN32
	u_long param = 0;
	ioctlsocket(sd, FIONBIO, &param);           // make the socket blocking again 
#else
	fcntl(sd, F_SETFL, 0);           /* make the socket blocking again */
#endif
	
	/* verify that server certificate is authentic */
	server_cert = SSL_get_peer_certificate(c->ssl);
	if (!server_cert || (X509_cmp(server_cert, c->tc_cert) != 0)) {
		SSL_free(c->ssl);
		return 0;
	}

	X509_free(server_cert);

	return 1;
}
Пример #17
0
/*
 * -1 if authentication failed
 *  1 if authentication succeeded
 *  2 if authentication succeeded, using parameter
 * -2 if authentication is delayed, don't error
 * No AuthStruct = everyone allowed
*/
int	Auth_Check(aClient *cptr, anAuthStruct *as, char *para)
{
#ifdef	AUTHENABLE_UNIXCRYPT
	extern	char *crypt();
#endif

#if defined(AUTHENABLE_SSL_CLIENTCERT) || defined(AUTHENABLE_SSL_CLIENTCERTFP)
	X509 *x509_clientcert = NULL;
#endif
#ifdef AUTHENABLE_SSL_CLIENTCERT
	X509 *x509_filecert = NULL;
	FILE *x509_f = NULL;
#endif
#ifdef AUTHENABLE_SSL_CLIENTCERTFP
	unsigned int n;
	unsigned int i;
	unsigned int j;
	unsigned int k;
	unsigned char md[EVP_MAX_MD_SIZE];
	char hex[EVP_MAX_MD_SIZE * 2 + 1];
	char hexc[EVP_MAX_MD_SIZE * 3 + 1];
	char hexchars[16] = "0123456789abcdef";
	const EVP_MD *digest = EVP_sha256();
#endif

	if (!as)
		return 1;
		
	switch (as->type)
	{
		case AUTHTYPE_PLAINTEXT:
			if (!para)
				return -1;
			/* plain text compare */
			if (!strcmp(para, as->data))
				return 2;
			else
				return -1;
			break;
#ifdef AUTHENABLE_UNIXCRYPT
		case AUTHTYPE_UNIXCRYPT:
			if (!para)
				return -1;
			/* If our data is like 1 or none, we just let em through .. */
			if (!(as->data[0] && as->data[1]))
				return 1;
			if (!strcmp(crypt(para, as->data), as->data))
				return 2;
			else
				return -1;
			break;
#endif
		case AUTHTYPE_MD5:
			return authcheck_md5(cptr, as, para);
			break;
#ifdef AUTHENABLE_SHA1
		case AUTHTYPE_SHA1:
			return authcheck_sha1(cptr, as, para);
			break;
#endif
#ifdef AUTHENABLE_RIPEMD160
		case AUTHTYPE_RIPEMD160:
			return authcheck_ripemd160(cptr, as, para);
#endif
#ifdef AUTHENABLE_SSL_CLIENTCERT
		case AUTHTYPE_SSL_CLIENTCERT:
			if (!para)
				return -1;
			if (!cptr->ssl)
				return -1;
			x509_clientcert = SSL_get_peer_certificate((SSL *)cptr->ssl);
			if (!x509_clientcert)
				return -1;
			if (!(x509_f = fopen(as->data, "r")))
			{
				X509_free(x509_clientcert);
				return -1;
			}
			x509_filecert = PEM_read_X509(x509_f, NULL, NULL, NULL);
			fclose(x509_f);
			if (!x509_filecert)
			{
				X509_free(x509_clientcert);
				return -1;
			}
			if (X509_cmp(x509_filecert, x509_clientcert) != 0)
			{
				X509_free(x509_clientcert);
				X509_free(x509_filecert);
				break;
			}
			X509_free(x509_clientcert);
			X509_free(x509_filecert);
			return 2;	
#endif
#ifdef AUTHENABLE_SSL_CLIENTCERTFP
		case AUTHTYPE_SSL_CLIENTCERTFP:
			if (!para)
				return -1;
			if (!cptr->ssl)
				return -1;
			x509_clientcert = SSL_get_peer_certificate((SSL *)cptr->ssl);
			if (!x509_clientcert)
				return -1;
			if (!X509_digest(x509_clientcert, digest, md, &n)) {
				X509_free(x509_clientcert);
				return -1;
			}
			j = 0;
			k = 0;
			for (i=0; i<n; i++) {
				hex[j++] = hexchars[(md[i] >> 4) & 0xF];
				hex[j++] = hexchars[md[i] & 0xF];
				hexc[k++] = hexchars[(md[i] >> 4) & 0xF];
				hexc[k++] = hexchars[md[i] & 0xF];
				hexc[k++] = ':';
			}
			hex[j] = '\0';
			hexc[--k] = '\0';
			if (strcasecmp(as->data, hex) && strcasecmp(as->data, hexc)) {
				X509_free(x509_clientcert);
				return -1;
			}
			X509_free(x509_clientcert);
			return 2;
#endif
	}
	return -1;
}