Пример #1
0
int
ca_validate_cert(struct iked *env, struct iked_static_id *id,
    void *data, size_t len)
{
	struct ca_store	*store = env->sc_priv;
	X509_STORE_CTX	 csc;
	BIO		*rawcert = NULL;
	X509		*cert = NULL;
	int		 ret = -1, result, error;
	size_t		 idlen, idoff;
	const u_int8_t	*idptr;
	X509_NAME	*idname = NULL, *subject;
	const char	*errstr = "failed";

	if (len == 0) {
		/* Data is already an X509 certificate */
		cert = (X509 *)data;
	} else {
		/* Convert data to X509 certificate */
		if ((rawcert = BIO_new_mem_buf(data, len)) == NULL)
			goto done;
		if ((cert = d2i_X509_bio(rawcert, NULL)) == NULL)
			goto done;
	}

	/* Certificate needs a valid subjectName */
	if ((subject = X509_get_subject_name(cert)) == NULL) {
		errstr = "invalid subject";
		goto done;
	}

	if (id != NULL) {
		if ((ret = ca_validate_pubkey(env, id, X509_get_pubkey(cert),
		    0)) == 0) {
			errstr = "public key found, ok";
			goto done;
		}

		switch (id->id_type) {
		case IKEV2_ID_ASN1_DN:
			idoff = id->id_offset;
			if (id->id_length <= idoff) {
				errstr = "invalid ASN1_DN id length";
				goto done;
			}
			idlen = id->id_length - idoff;
			idptr = id->id_data + idoff;

			if ((idname = d2i_X509_NAME(NULL,
			    &idptr, idlen)) == NULL ||
			    X509_NAME_cmp(subject, idname) != 0) {
				errstr = "ASN1_DN identifier mismatch";
				goto done;
			}
			break;
		default:
			if (ca_x509_subjectaltname_cmp(cert, id) != 0) {
				errstr = "invalid subjectAltName extension";
				goto done;
			}
			break;
		}
	}

	bzero(&csc, sizeof(csc));
	X509_STORE_CTX_init(&csc, store->ca_cas, cert, NULL);
	if (store->ca_cas->param->flags & X509_V_FLAG_CRL_CHECK) {
		X509_STORE_CTX_set_flags(&csc, X509_V_FLAG_CRL_CHECK);
		X509_STORE_CTX_set_flags(&csc, X509_V_FLAG_CRL_CHECK_ALL);
	}

	result = X509_verify_cert(&csc);
	error = csc.error;
	X509_STORE_CTX_cleanup(&csc);
	if (error != 0) {
		errstr = X509_verify_cert_error_string(error);
		goto done;
	}

	if (!result) {
		/* XXX should we accept self-signed certificates? */
		errstr = "rejecting self-signed certificate";
		goto done;
	}

	/* Success */
	ret = 0;

 done:
	if (cert != NULL)
		log_debug("%s: %s %.100s", __func__, cert->name,
		    ret == 0 ? "ok" : errstr);

	if (idname != NULL)
		X509_NAME_free(idname);
	if (rawcert != NULL) {
		BIO_free(rawcert);
		if (cert != NULL)
			X509_free(cert);
	}

	return (ret);
}
Пример #2
0
/* based on BSD-style licensed code of mod_ssl */
static int crl_check(CLI *c, X509_STORE_CTX *callback_ctx) {
    X509_STORE_CTX store_ctx;
    X509_OBJECT obj;
    X509_NAME *subject;
    X509_NAME *issuer;
    X509 *cert;
    X509_CRL *crl;
    X509_REVOKED *revoked;
    EVP_PKEY *pubkey;
    long serial;
    int i, n, rc;
    char *cp;
    ASN1_TIME *last_update=NULL, *next_update=NULL;

    /* determine certificate ingredients in advance */
    cert=X509_STORE_CTX_get_current_cert(callback_ctx);
    subject=X509_get_subject_name(cert);
    issuer=X509_get_issuer_name(cert);

    /* try to retrieve a CRL corresponding to the _subject_ of
     * the current certificate in order to verify it's integrity */
    memset((char *)&obj, 0, sizeof obj);
    X509_STORE_CTX_init(&store_ctx, c->opt->revocation_store, NULL, NULL);
    rc=X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, subject, &obj);
    X509_STORE_CTX_cleanup(&store_ctx);
    crl=obj.data.crl;
    if(rc>0 && crl) {
        cp=X509_NAME_oneline(subject, NULL, 0);
        s_log(LOG_INFO, "CRL: issuer: %s", cp);
        OPENSSL_free(cp);
        last_update=X509_CRL_get_lastUpdate(crl);
        next_update=X509_CRL_get_nextUpdate(crl);
        log_time(LOG_INFO, "CRL: last update", last_update);
        log_time(LOG_INFO, "CRL: next update", next_update);

        /* verify the signature on this CRL */
        pubkey=X509_get_pubkey(cert);
        if(X509_CRL_verify(crl, pubkey)<=0) {
            s_log(LOG_WARNING, "CRL: Invalid signature");
            X509_STORE_CTX_set_error(callback_ctx,
                X509_V_ERR_CRL_SIGNATURE_FAILURE);
            X509_OBJECT_free_contents(&obj);
            if(pubkey)
                EVP_PKEY_free(pubkey);
            return 0; /* reject connection */
        }
        if(pubkey)
            EVP_PKEY_free(pubkey);

        /* check date of CRL to make sure it's not expired */
        if(!next_update) {
            s_log(LOG_WARNING, "CRL: Invalid nextUpdate field");
            X509_STORE_CTX_set_error(callback_ctx,
                X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);
            X509_OBJECT_free_contents(&obj);
            return 0; /* reject connection */
        }
        if(X509_cmp_current_time(next_update)<0) {
            s_log(LOG_WARNING, "CRL: CRL Expired - revoking all certificates");
            X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CRL_HAS_EXPIRED);
            X509_OBJECT_free_contents(&obj);
            return 0; /* reject connection */
        }
        X509_OBJECT_free_contents(&obj);
    }

    /* try to retrieve a CRL corresponding to the _issuer_ of
     * the current certificate in order to check for revocation */
    memset((char *)&obj, 0, sizeof obj);
    X509_STORE_CTX_init(&store_ctx, c->opt->revocation_store, NULL, NULL);
    rc=X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, issuer, &obj);
    X509_STORE_CTX_cleanup(&store_ctx);
    crl=obj.data.crl;
    if(rc>0 && crl) {
        /* check if the current certificate is revoked by this CRL */
        n=sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
        for(i=0; i<n; i++) {
            revoked=sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
            if(ASN1_INTEGER_cmp(revoked->serialNumber,
                    X509_get_serialNumber(cert)) == 0) {
                serial=ASN1_INTEGER_get(revoked->serialNumber);
                cp=X509_NAME_oneline(issuer, NULL, 0);
                s_log(LOG_WARNING, "CRL: Certificate with serial %ld (0x%lX) "
                    "revoked per CRL from issuer %s", serial, serial, cp);
                OPENSSL_free(cp);
                X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CERT_REVOKED);
                X509_OBJECT_free_contents(&obj);
                return 0; /* reject connection */
            }
        }
        X509_OBJECT_free_contents(&obj);
    }
    return 1; /* accept connection */
}
Пример #3
0
unsigned long dtls1_output_cert_chain(SSL *s, X509 *x)
	{
	unsigned char *p;
	int n,i;
	unsigned long l= 3 + DTLS1_HM_HEADER_LENGTH;
	BUF_MEM *buf;
	X509_STORE_CTX xs_ctx;
	X509_OBJECT obj;

	/* TLSv1 sends a chain with nothing in it, instead of an alert */
	buf=s->init_buf;
	if (!BUF_MEM_grow_clean(buf,10))
		{
		SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
		return(0);
		}
	if (x != NULL)
		{
		if(!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,NULL,NULL))
			{
			SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
			return(0);
			}

		for (;;)
			{
			n=i2d_X509(x,NULL);
			if (!BUF_MEM_grow_clean(buf,(int)(n+l+3)))
				{
				SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
				return(0);
				}
			p=(unsigned char *)&(buf->data[l]);
			l2n3(n,p);
			i2d_X509(x,&p);
			l+=n+3;
			if (X509_NAME_cmp(X509_get_subject_name(x),
				X509_get_issuer_name(x)) == 0) break;

			i=X509_STORE_get_by_subject(&xs_ctx,X509_LU_X509,
				X509_get_issuer_name(x),&obj);
			if (i <= 0) break;
			x=obj.data.x509;
			/* Count is one too high since the X509_STORE_get uped the
			 * ref count */
			X509_free(x);
			}

		X509_STORE_CTX_cleanup(&xs_ctx);
		}

	/* Thawte special :-) */
	if (s->ctx->extra_certs != NULL)
	for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
		{
		x=sk_X509_value(s->ctx->extra_certs,i);
		n=i2d_X509(x,NULL);
		if (!BUF_MEM_grow_clean(buf,(int)(n+l+3)))
			{
			SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
			return(0);
			}
		p=(unsigned char *)&(buf->data[l]);
		l2n3(n,p);
		i2d_X509(x,&p);
		l+=n+3;
		}

	l-= (3 + DTLS1_HM_HEADER_LENGTH);

	p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]);
	l2n3(l,p);
	l+=3;
	p=(unsigned char *)&(buf->data[0]);
	p = dtls1_set_message_header(s, p, SSL3_MT_CERTIFICATE, l, 0, l);

	l+=DTLS1_HM_HEADER_LENGTH;
	return(l);
	}
Пример #4
0
static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
	     X509 *x, X509 *xca, EVP_PKEY *pkey, char *serialfile, int create,
	     int days, int clrext, CONF *conf, char *section, ASN1_INTEGER *sno)
	{
	int ret=0;
	ASN1_INTEGER *bs=NULL;
	X509_STORE_CTX xsc;
	EVP_PKEY *upkey;

	upkey = X509_get_pubkey(xca);
	EVP_PKEY_copy_parameters(upkey,pkey);
	EVP_PKEY_free(upkey);

	if(!X509_STORE_CTX_init(&xsc,ctx,x,NULL))
		{
		BIO_printf(bio_err,"Error initialising X509 store\n");
		goto end;
		}
	if (sno) bs = sno;
	else if (!(bs = x509_load_serial(CAfile, serialfile, create)))
		goto end;

/*	if (!X509_STORE_add_cert(ctx,x)) goto end;*/

	/* NOTE: this certificate can/should be self signed, unless it was
	 * a certificate request in which case it is not. */
	X509_STORE_CTX_set_cert(&xsc,x);
	X509_STORE_CTX_set_flags(&xsc, X509_V_FLAG_CHECK_SS_SIGNATURE);
	if (!reqfile && X509_verify_cert(&xsc) <= 0)
		goto end;

	if (!X509_check_private_key(xca,pkey))
		{
		BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
		goto end;
		}

	if (!X509_set_issuer_name(x,X509_get_subject_name(xca))) goto end;
	if (!X509_set_serialNumber(x,bs)) goto end;

	if (X509_gmtime_adj(X509_get_notBefore(x),0L) == NULL)
		goto end;

	/* hardwired expired */
	if (X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days) == NULL)
		goto end;

	if (clrext)
		{
		while (X509_get_ext_count(x) > 0) X509_delete_ext(x, 0);
		}

	if (conf)
		{
		X509V3_CTX ctx2;
		X509_set_version(x,2); /* version 3 certificate */
                X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
                X509V3_set_nconf(&ctx2, conf);
                if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x)) goto end;
		}

	if (!X509_sign(x,pkey,digest)) goto end;
	ret=1;
end:
	X509_STORE_CTX_cleanup(&xsc);
	if (!ret)
		ERR_print_errors(bio_err);
	if (!sno) ASN1_INTEGER_free(bs);
	return ret;
	}
unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
	{
	unsigned char *p;
	int i;
	unsigned long l=7;
	BUF_MEM *buf;
	int no_chain;

	if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
		no_chain = 1;
	else
		no_chain = 0;

	/* TLSv1 sends a chain with nothing in it, instead of an alert */
	buf=s->init_buf;
	if (!BUF_MEM_grow_clean(buf,10))
		{
		SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
		return(0);
		}
	if (x != NULL)
		{
		if (no_chain)
			{
			if (ssl3_add_cert_to_buf(buf, &l, x))
				return(0);
			}
		else
			{
			X509_STORE_CTX xs_ctx;

			if (!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,x,NULL))
				{
				SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
				return(0);
				}
			X509_verify_cert(&xs_ctx);
			/* Don't leave errors in the queue */
			ERR_clear_error();
			for (i=0; i < sk_X509_num(xs_ctx.chain); i++)
				{
				x = sk_X509_value(xs_ctx.chain, i);

				if (ssl3_add_cert_to_buf(buf, &l, x))
					{
					X509_STORE_CTX_cleanup(&xs_ctx);
					return 0;
					}
				}
			X509_STORE_CTX_cleanup(&xs_ctx);
			}
		}
	/* Thawte special :-) */
	for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
		{
		x=sk_X509_value(s->ctx->extra_certs,i);
		if (ssl3_add_cert_to_buf(buf, &l, x))
			return(0);
		}

	l-=7;
	p=(unsigned char *)&(buf->data[4]);
	l2n3(l,p);
	l+=3;
	p=(unsigned char *)&(buf->data[0]);
	*(p++)=SSL3_MT_CERTIFICATE;
	l2n3(l,p);
	l+=4;
	return(l);
	}
Пример #6
0
static int pk7_verify(X509_STORE *cert_store, PKCS7 *p7, BIO *detached, char *ebuf, int ebufsize)
{
	PKCS7_SIGNER_INFO *si;
	verify_context vctx;
	BIO *p7bio=NULL;
	char readbuf[1024*4];
	int res = 1;
	int i;
	STACK_OF(PKCS7_SIGNER_INFO) *sk;

	vctx.err = X509_V_OK;
	ebuf[0] = 0;

	OpenSSL_add_all_algorithms();

	EVP_add_digest(EVP_md5());
	EVP_add_digest(EVP_sha1());

	ERR_load_crypto_strings();

	ERR_clear_error();

	X509_VERIFY_PARAM_set_flags(cert_store->param, X509_V_FLAG_CB_ISSUER_CHECK);
	X509_STORE_set_verify_cb_func(cert_store, verify_callback);

	p7bio = PKCS7_dataInit(p7, detached);

	/* We now have to 'read' from p7bio to calculate digests etc. */
	while (BIO_read(p7bio, readbuf, sizeof(readbuf)) > 0)
		;

	/* We can now verify signatures */
	sk = PKCS7_get_signer_info(p7);
	if (sk == NULL)
	{
		/* there are no signatures on this data */
		res = 0;
		fz_strlcpy(ebuf, "No signatures", ebufsize);
		goto exit;
	}

	for (i=0; i<sk_PKCS7_SIGNER_INFO_num(sk); i++)
	{
		int rc;
		si = sk_PKCS7_SIGNER_INFO_value(sk, i);
		rc = PKCS7_dataVerify(cert_store, &vctx.x509_ctx, p7bio,p7, si);
		if (rc <= 0 || vctx.err != X509_V_OK)
		{
			char tbuf[120];

			if (rc <= 0)
			{
				fz_strlcpy(ebuf, ERR_error_string(ERR_get_error(), tbuf), ebufsize);
			}
			else
			{
				/* Error while checking the certificate chain */
				snprintf(ebuf, ebufsize, "%s(%d): %s", X509_verify_cert_error_string(vctx.err), vctx.err, vctx.certdesc);
			}

			res = 0;
			goto exit;
		}
	}

exit:
	X509_STORE_CTX_cleanup(&vctx.x509_ctx);
	ERR_free_strings();

	return res;
}
Пример #7
0
int MAIN(int argc, char **argv)
	{
	unsigned long nmflag = 0;
	X509_CRL *x=NULL;
	char *CAfile = NULL, *CApath = NULL;
	int ret=1,i,num,badops=0;
	BIO *out=NULL;
	int informat,outformat;
	char *infile=NULL,*outfile=NULL;
	int hash=0,issuer=0,lastupdate=0,nextupdate=0,noout=0,text=0;
	int fingerprint = 0, crlnumber = 0;
	const char **pp;
	X509_STORE *store = NULL;
	X509_STORE_CTX ctx;
	X509_LOOKUP *lookup = NULL;
	X509_OBJECT xobj;
	EVP_PKEY *pkey;
	int do_ver = 0;
	const EVP_MD *md_alg,*digest=EVP_sha1();

	apps_startup();

	if (bio_err == NULL)
		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp(bio_err,OPENSSL_TYPE__FILE_STDERR,BIO_NOCLOSE|BIO_FP_TEXT);

	if (!load_config(bio_err, NULL))
		goto end;

	if (bio_out == NULL)
		if ((bio_out=BIO_new(BIO_s_file())) != NULL)
			{
			BIO_set_fp(bio_out,OPENSSL_TYPE__FILE_STDOUT,BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
			{
			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
			bio_out = BIO_push(tmpbio, bio_out);
			}
#endif
			}

	informat=FORMAT_PEM;
	outformat=FORMAT_PEM;

	argc--;
	argv++;
	num=0;
	while (argc >= 1)
		{
#ifdef undef
		if	(TINYCLR_SSL_STRCMP(*argv,"-p") == 0)
			{
			if (--argc < 1) goto bad;
			if (!args_from_file(++argv,Nargc,Nargv)) { goto end; }*/
			}
#endif
		if 	(TINYCLR_SSL_STRCMP(*argv,"-inform") == 0)
			{
			if (--argc < 1) goto bad;
			informat=str2fmt(*(++argv));
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-outform") == 0)
			{
			if (--argc < 1) goto bad;
			outformat=str2fmt(*(++argv));
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-in") == 0)
			{
			if (--argc < 1) goto bad;
			infile= *(++argv);
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-out") == 0)
			{
			if (--argc < 1) goto bad;
			outfile= *(++argv);
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-CApath") == 0)
			{
			if (--argc < 1) goto bad;
			CApath = *(++argv);
			do_ver = 1;
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-CAfile") == 0)
			{
			if (--argc < 1) goto bad;
			CAfile = *(++argv);
			do_ver = 1;
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-verify") == 0)
			do_ver = 1;
		else if (TINYCLR_SSL_STRCMP(*argv,"-text") == 0)
			text = 1;
		else if (TINYCLR_SSL_STRCMP(*argv,"-hash") == 0)
			hash= ++num;
		else if (TINYCLR_SSL_STRCMP(*argv,"-nameopt") == 0)
			{
			if (--argc < 1) goto bad;
			if (!set_name_ex(&nmflag, *(++argv))) goto bad;
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-issuer") == 0)
			issuer= ++num;
		else if (TINYCLR_SSL_STRCMP(*argv,"-lastupdate") == 0)
			lastupdate= ++num;
		else if (TINYCLR_SSL_STRCMP(*argv,"-nextupdate") == 0)
			nextupdate= ++num;
		else if (TINYCLR_SSL_STRCMP(*argv,"-noout") == 0)
			noout= ++num;
		else if (TINYCLR_SSL_STRCMP(*argv,"-fingerprint") == 0)
			fingerprint= ++num;
		else if (TINYCLR_SSL_STRCMP(*argv,"-crlnumber") == 0)
			crlnumber= ++num;
		else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
			{
			/* ok */
			digest=md_alg;
			}
		else
			{
			BIO_printf(bio_err,"unknown option %s\n",*argv);
			badops=1;
			break;
			}
		argc--;
		argv++;
		}

	if (badops)
		{
bad:
		for (pp=crl_usage; (*pp != NULL); pp++)
			BIO_printf(bio_err,"%s",*pp);
		goto end;
		}

	ERR_load_crypto_strings();
	x=load_crl(infile,informat);
	if (x == NULL) { goto end; }

	if(do_ver) {
		store = X509_STORE_new();
		lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file());
		if (lookup == NULL) goto end;
		if (!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM))
			X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
			
		lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir());
		if (lookup == NULL) goto end;
		if (!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM))
			X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
		ERR_clear_error();

		if(!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) {
			BIO_printf(bio_err,
				"Error initialising X509 store\n");
			goto end;
		}

		i = X509_STORE_get_by_subject(&ctx, X509_LU_X509, 
					X509_CRL_get_issuer(x), &xobj);
		if(i <= 0) {
			BIO_printf(bio_err,
				"Error getting CRL issuer certificate\n");
			goto end;
		}
		pkey = X509_get_pubkey(xobj.data.x509);
		X509_OBJECT_free_contents(&xobj);
		if(!pkey) {
			BIO_printf(bio_err,
				"Error getting CRL issuer public key\n");
			goto end;
		}
		i = X509_CRL_verify(x, pkey);
		EVP_PKEY_free(pkey);
		if(i < 0) goto end;
		if(i == 0) BIO_printf(bio_err, "verify failure\n");
		else BIO_printf(bio_err, "verify OK\n");
	}

	if (num)
		{
		for (i=1; i<=num; i++)
			{
			if (issuer == i)
				{
				print_name(bio_out, "issuer=", X509_CRL_get_issuer(x), nmflag);
				}
			if (crlnumber == i)
				{
				ASN1_INTEGER *crlnum;
				crlnum = (ASN1_INTEGER*)X509_CRL_get_ext_d2i(x, NID_crl_number,
							      NULL, NULL);
				BIO_printf(bio_out,"crlNumber=");
				if (crlnum)
					{
					i2a_ASN1_INTEGER(bio_out, crlnum);
					ASN1_INTEGER_free(crlnum);
					}
				else
					BIO_puts(bio_out, "<NONE>");
				BIO_printf(bio_out,"\n");
				}
			if (hash == i)
				{
				BIO_printf(bio_out,"%08lx\n",
					X509_NAME_hash(X509_CRL_get_issuer(x)));
				}
			if (lastupdate == i)
				{
				BIO_printf(bio_out,"lastUpdate=");
				ASN1_TIME_print(bio_out,
						X509_CRL_get_lastUpdate(x));
				BIO_printf(bio_out,"\n");
				}
			if (nextupdate == i)
				{
				BIO_printf(bio_out,"nextUpdate=");
				if (X509_CRL_get_nextUpdate(x)) 
					ASN1_TIME_print(bio_out,
						X509_CRL_get_nextUpdate(x));
				else
					BIO_printf(bio_out,"NONE");
				BIO_printf(bio_out,"\n");
				}
			if (fingerprint == i)
				{
				int j;
				unsigned int n;
				unsigned char md[EVP_MAX_MD_SIZE];

				if (!X509_CRL_digest(x,digest,md,&n))
					{
					BIO_printf(bio_err,"out of memory\n");
					goto end;
					}
				BIO_printf(bio_out,"%s Fingerprint=",
						OBJ_nid2sn(EVP_MD_type(digest)));
				for (j=0; j<(int)n; j++)
					{
					BIO_printf(bio_out,"%02X%c",md[j],
						(j+1 == (int)n)
						?'\n':':');
					}
				}
			}
		}

	out=BIO_new(BIO_s_file());
	if (out == NULL)
		{
		ERR_print_errors(bio_err);
		goto end;
		}

	if (outfile == NULL)
		{
		BIO_set_fp(out,OPENSSL_TYPE__FILE_STDOUT,BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
		{
		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
		out = BIO_push(tmpbio, out);
		}
#endif
		}
	else
		{
		if (BIO_write_filename(out,outfile) <= 0)
			{
			TINYCLR_SSL_PERROR(outfile);
			goto end;
			}
		}

	if (text) X509_CRL_print(out, x);

	if (noout) 
		{
		ret = 0;
		goto end;
		}

	if 	(outformat == FORMAT_ASN1)
		i=(int)i2d_X509_CRL_bio(out,x);
	else if (outformat == FORMAT_PEM)
		i=PEM_write_bio_X509_CRL(out,x);
	else	
		{
		BIO_printf(bio_err,"bad output format specified for outfile\n");
		goto end;
		}
	if (!i) { BIO_printf(bio_err,"unable to write CRL\n"); goto end; }
	ret=0;
end:
	BIO_free_all(out);
	BIO_free_all(bio_out);
	bio_out=NULL;
	X509_CRL_free(x);
	if(store) {
		X509_STORE_CTX_cleanup(&ctx);
		X509_STORE_free(store);
	}
	apps_shutdown();
	OPENSSL_EXIT(ret);
	}
Пример #8
0
int
crl_main(int argc, char **argv)
{
	unsigned long nmflag = 0;
	X509_CRL *x = NULL;
	int ret = 1, i;
	BIO *out = NULL;
	X509_STORE *store = NULL;
	X509_STORE_CTX ctx;
	X509_LOOKUP *lookup = NULL;
	X509_OBJECT xobj;
	EVP_PKEY *pkey;
	const EVP_MD *digest;
	char *digest_name = NULL;

	if (bio_out == NULL) {
		if ((bio_out = BIO_new(BIO_s_file())) != NULL) {
			BIO_set_fp(bio_out, stdout, BIO_NOCLOSE);
		}
	}

	digest = EVP_sha1();

	memset(&crl_config, 0, sizeof(crl_config));
	crl_config.informat = FORMAT_PEM;
	crl_config.outformat = FORMAT_PEM;

	if (options_parse(argc, argv, crl_options, &digest_name, NULL) != 0) {
		crl_usage();
		goto end;
	}

	if (crl_config.cafile != NULL || crl_config.capath != NULL)
		crl_config.verify = 1;

	if (crl_config.nameopt != NULL) {
		if (set_name_ex(&nmflag, crl_config.nameopt) != 1) {
			fprintf(stderr,
			    "Invalid -nameopt argument '%s'\n",
			    crl_config.nameopt);
			goto end;
		}
	}

	if (digest_name != NULL) {
		if ((digest = EVP_get_digestbyname(digest_name)) == NULL) {
			fprintf(stderr,
			    "Unknown message digest algorithm '%s'\n",
			    digest_name);
			goto end;
		}
	}

	x = load_crl(crl_config.infile, crl_config.informat);
	if (x == NULL)
		goto end;

	if (crl_config.verify) {
		store = X509_STORE_new();
		lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
		if (lookup == NULL)
			goto end;
		if (!X509_LOOKUP_load_file(lookup, crl_config.cafile,
		    X509_FILETYPE_PEM))
			X509_LOOKUP_load_file(lookup, NULL,
			    X509_FILETYPE_DEFAULT);

		lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
		if (lookup == NULL)
			goto end;
		if (!X509_LOOKUP_add_dir(lookup, crl_config.capath,
		    X509_FILETYPE_PEM))
			X509_LOOKUP_add_dir(lookup, NULL,
			    X509_FILETYPE_DEFAULT);
		ERR_clear_error();

		if (!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) {
			BIO_printf(bio_err,
			    "Error initialising X509 store\n");
			goto end;
		}
		i = X509_STORE_get_by_subject(&ctx, X509_LU_X509,
		    X509_CRL_get_issuer(x), &xobj);
		if (i <= 0) {
			BIO_printf(bio_err,
			    "Error getting CRL issuer certificate\n");
			goto end;
		}
		pkey = X509_get_pubkey(xobj.data.x509);
		X509_OBJECT_free_contents(&xobj);
		if (!pkey) {
			BIO_printf(bio_err,
			    "Error getting CRL issuer public key\n");
			goto end;
		}
		i = X509_CRL_verify(x, pkey);
		EVP_PKEY_free(pkey);
		if (i < 0)
			goto end;
		if (i == 0)
			BIO_printf(bio_err, "verify failure\n");
		else
			BIO_printf(bio_err, "verify OK\n");
	}

	/* Print requested information the order that the flags were given. */
	for (i = 1; i <= argc; i++) {
		if (crl_config.issuer == i) {
			print_name(bio_out, "issuer=",
			    X509_CRL_get_issuer(x), nmflag);
		}
		if (crl_config.crlnumber == i) {
			ASN1_INTEGER *crlnum;
			crlnum = X509_CRL_get_ext_d2i(x,
			    NID_crl_number, NULL, NULL);
			BIO_printf(bio_out, "crlNumber=");
			if (crlnum) {
				i2a_ASN1_INTEGER(bio_out, crlnum);
				ASN1_INTEGER_free(crlnum);
			} else
				BIO_puts(bio_out, "<NONE>");
			BIO_printf(bio_out, "\n");
		}
		if (crl_config.hash == i) {
			BIO_printf(bio_out, "%08lx\n",
			    X509_NAME_hash(X509_CRL_get_issuer(x)));
		}
#ifndef OPENSSL_NO_MD5
		if (crl_config.hash_old == i) {
			BIO_printf(bio_out, "%08lx\n",
			    X509_NAME_hash_old(X509_CRL_get_issuer(x)));
		}
#endif
		if (crl_config.lastupdate == i) {
			BIO_printf(bio_out, "lastUpdate=");
			ASN1_TIME_print(bio_out,
			    X509_CRL_get_lastUpdate(x));
			BIO_printf(bio_out, "\n");
		}
		if (crl_config.nextupdate == i) {
			BIO_printf(bio_out, "nextUpdate=");
			if (X509_CRL_get_nextUpdate(x))
				ASN1_TIME_print(bio_out,
				    X509_CRL_get_nextUpdate(x));
			else
				BIO_printf(bio_out, "NONE");
			BIO_printf(bio_out, "\n");
		}
		if (crl_config.fingerprint == i) {
			int j;
			unsigned int n;
			unsigned char md[EVP_MAX_MD_SIZE];

			if (!X509_CRL_digest(x, digest, md, &n)) {
				BIO_printf(bio_err, "out of memory\n");
				goto end;
			}
			BIO_printf(bio_out, "%s Fingerprint=",
			    OBJ_nid2sn(EVP_MD_type(digest)));
			for (j = 0; j < (int) n; j++) {
				BIO_printf(bio_out, "%02X%c", md[j],
				    (j + 1 == (int)n) ? '\n' : ':');
			}
		}
	}

	out = BIO_new(BIO_s_file());
	if (out == NULL) {
		ERR_print_errors(bio_err);
		goto end;
	}
	if (crl_config.outfile == NULL) {
		BIO_set_fp(out, stdout, BIO_NOCLOSE);
	} else {
		if (BIO_write_filename(out, crl_config.outfile) <= 0) {
			perror(crl_config.outfile);
			goto end;
		}
	}

	if (crl_config.text)
		X509_CRL_print(out, x);

	if (crl_config.noout) {
		ret = 0;
		goto end;
	}
	if (crl_config.outformat == FORMAT_ASN1)
		i = (int) i2d_X509_CRL_bio(out, x);
	else if (crl_config.outformat == FORMAT_PEM)
		i = PEM_write_bio_X509_CRL(out, x);
	else {
		BIO_printf(bio_err,
		    "bad output format specified for outfile\n");
		goto end;
	}
	if (!i) {
		BIO_printf(bio_err, "unable to write CRL\n");
		goto end;
	}
	ret = 0;

end:
	BIO_free_all(out);
	BIO_free_all(bio_out);
	bio_out = NULL;
	X509_CRL_free(x);
	if (store) {
		X509_STORE_CTX_cleanup(&ctx);
		X509_STORE_free(store);
	}

	return (ret);
}
Пример #9
0
/*
 * This function verifies the validity of the certificate and the matching of the
 * other part's name with the certificate.
 * It also checks the sign validity of a message.
 * It returns -1 on generic error, -3 on mismatching on certificate, 1 on success.
 * It closes the passed file pointer fp (which should have already been opened).
 * The last argument is used to distinguish if we are initializing or accepting
 * a connection and so which is the correct name to verify.
 * After verifying, It leaves the public parameter of DH and the nonce of the
 * other part respectively in **pub_buf (which is allocated) and *nonce.
 */
int verify_name(FILE* fp,unsigned char *hello_buf,unsigned int hello_len,unsigned char *sign_buf,unsigned int sign_len,unsigned char** pub_buf,unsigned int *pubbuf_len,X509_STORE* str,int* nonce,int init){	
	int sheet_len,ret;
	uint32_t tmp;
	char read_mail[DIM_MAIL],temp_mail[DIM_MAIL],*cert_mail = NULL;
	X509_STORE_CTX* cert_ctx = NULL;
	EVP_PKEY* evp = EVP_PKEY_new();
	EVP_MD_CTX* ctx = NULL;
	*pub_buf = NULL;
	if (!fp) {
		ret = -1;
		goto fail;
	}
	//We must come back to the start of fp
	rewind(fp);
	X509* cert = PEM_read_X509(fp,NULL,NULL,NULL);
	*pub_buf = NULL;
	//the following function is needed to correctly verify the certificate
	OpenSSL_add_all_algorithms();
	if((cert_ctx=X509_STORE_CTX_new())==NULL){
		ret = -1;
		goto fail;
	}
	if(X509_STORE_CTX_init(cert_ctx,str,cert,NULL)<=0){
		ret = -1;
		goto fail;
	}
	if(X509_verify_cert(cert_ctx)==0){
		//fprintf(stderr, "Error verifying certificate: %s\n", X509_verify_cert_error_string(X509_STORE_CTX_get_error(cert_ctx)));
		ret = -3;
		goto fail;	
	}
	X509_STORE_CTX_cleanup(cert_ctx);
	X509_STORE_CTX_free(cert_ctx);
	cert_ctx = NULL;
	ctx  = (EVP_MD_CTX*)calloc(1,sizeof(EVP_MD_CTX));
	EVP_MD_CTX_init(ctx);
	evp = X509_get_pubkey(cert);
	if(EVP_VerifyInit(ctx,EVP_sha512())==0){
		ret = -1;
		goto fail;
	}
	if(EVP_VerifyUpdate(ctx,hello_buf,hello_len)==0){
		ret = -1;
		goto fail;
	}
	ret=EVP_VerifyFinal(ctx,sign_buf,sign_len,evp);
	if(ret == 0){
		ret = -3;
		goto fail;
	}
	if (ret == -1) {
		goto fail;
	}
	rewind(fp);
	cert_mail = read_common_name(fp);//set it free later
	if(init == 1){
		sscanf((char *)hello_buf,"%s%s",temp_mail,read_mail);
	} else{
		sscanf((char *)hello_buf,"%s%s",read_mail,temp_mail);
	}
	sheet_len = strlen(temp_mail)+strlen(read_mail)+2;
	*pubbuf_len = hello_len - sheet_len;
	tmp = *((uint32_t *)(hello_buf+sheet_len));
	*nonce = ntohl(tmp);
	sheet_len+=sizeof(tmp);
	*pub_buf = (unsigned char*)calloc(1,*pubbuf_len);
	memcpy(*pub_buf,hello_buf+sheet_len,*pubbuf_len);
	if(strlen(cert_mail)!=strlen(read_mail)){
		ret = -3;
		goto fail;
	}
	if(strncmp(cert_mail,read_mail,strlen(cert_mail))!=0){
		ret = -3;
		goto fail;
	}
	free(ctx);
	fclose(fp);
	EVP_PKEY_free(evp);
	free(cert_mail);
	return 1;
	fail:
		fclose(fp);
		if(cert_mail!=NULL){
			free(cert_mail);
		}
		if(cert_ctx!=NULL){
			X509_STORE_CTX_cleanup(cert_ctx);
			X509_STORE_CTX_free(cert_ctx);
		}
		if(ctx!=NULL){
			free(ctx);
		}	
		if(*pub_buf!=NULL){
			free(*pub_buf);
		}
		EVP_PKEY_free(evp);
		return ret;
}
Пример #10
0
/**
 * xmlSecOpenSSLX509StoreVerify:
 * @store:              the pointer to X509 key data store klass.
 * @certs:              the untrusted certificates stack.
 * @crls:               the crls stack.
 * @keyInfoCtx:         the pointer to <dsig:KeyInfo/> element processing context.
 *
 * Verifies @certs list.
 *
 * Returns: pointer to the first verified certificate from @certs.
 */
X509*
xmlSecOpenSSLX509StoreVerify(xmlSecKeyDataStorePtr store, XMLSEC_STACK_OF_X509* certs,
                             XMLSEC_STACK_OF_X509_CRL* crls, xmlSecKeyInfoCtx* keyInfoCtx) {
    xmlSecOpenSSLX509StoreCtxPtr ctx;
    STACK_OF(X509)* certs2 = NULL;
    STACK_OF(X509_CRL)* crls2 = NULL;
    X509 * res = NULL;
    X509 * cert;
    X509 * err_cert = NULL;
    char buf[256];
    int err = 0, depth;
    int i;
    int ret;

    xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecOpenSSLX509StoreId), NULL);
    xmlSecAssert2(certs != NULL, NULL);
    xmlSecAssert2(keyInfoCtx != NULL, NULL);

    ctx = xmlSecOpenSSLX509StoreGetCtx(store);
    xmlSecAssert2(ctx != NULL, NULL);
    xmlSecAssert2(ctx->xst != NULL, NULL);

    /* dup certs */
    certs2 = sk_X509_dup(certs);
    if(certs2 == NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
                    "sk_X509_dup",
                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
                    XMLSEC_ERRORS_NO_MESSAGE);
        goto done;
    }

    /* add untrusted certs from the store */
    if(ctx->untrusted != NULL) {
        for(i = 0; i < sk_X509_num(ctx->untrusted); ++i) {
            ret = sk_X509_push(certs2, sk_X509_value(ctx->untrusted, i));
            if(ret < 1) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
                            "sk_X509_push",
                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
                            XMLSEC_ERRORS_NO_MESSAGE);
                goto done;
            }
        }
    }

    /* dup crls but remove all non-verified */
    if(crls != NULL) {
        crls2 = sk_X509_CRL_dup(crls);
        if(crls2 == NULL) {
            xmlSecError(XMLSEC_ERRORS_HERE,
                        xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
                        "sk_X509_CRL_dup",
                        XMLSEC_ERRORS_R_CRYPTO_FAILED,
                        XMLSEC_ERRORS_NO_MESSAGE);
            goto done;
        }

        for(i = 0; i < sk_X509_CRL_num(crls2); ) {
            ret = xmlSecOpenSSLX509VerifyCRL(ctx->xst, sk_X509_CRL_value(crls2, i));
            if(ret == 1) {
                ++i;
            } else if(ret == 0) {
                (void)sk_X509_CRL_delete(crls2, i);
            } else {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
                            "xmlSecOpenSSLX509VerifyCRL",
                            XMLSEC_ERRORS_R_XMLSEC_FAILED,
                            XMLSEC_ERRORS_NO_MESSAGE);
                goto done;
            }
        }
    }

    /* remove all revoked certs */
    for(i = 0; i < sk_X509_num(certs2);) {
        cert = sk_X509_value(certs2, i);

        if(crls2 != NULL) {
            ret = xmlSecOpenSSLX509VerifyCertAgainstCrls(crls2, cert);
            if(ret == 0) {
                (void)sk_X509_delete(certs2, i);
                continue;
            } else if(ret != 1) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
                            "xmlSecOpenSSLX509VerifyCertAgainstCrls",
                            XMLSEC_ERRORS_R_XMLSEC_FAILED,
                            XMLSEC_ERRORS_NO_MESSAGE);
                goto done;
            }
        }

        if(ctx->crls != NULL) {
            ret = xmlSecOpenSSLX509VerifyCertAgainstCrls(ctx->crls, cert);
            if(ret == 0) {
                (void)sk_X509_delete(certs2, i);
                continue;
            } else if(ret != 1) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
                            "xmlSecOpenSSLX509VerifyCertAgainstCrls",
                            XMLSEC_ERRORS_R_XMLSEC_FAILED,
                            XMLSEC_ERRORS_NO_MESSAGE);
                goto done;
            }
        }
        ++i;
    }

    /* get one cert after another and try to verify */
    for(i = 0; i < sk_X509_num(certs2); ++i) {
        cert = sk_X509_value(certs2, i);
        if(xmlSecOpenSSLX509FindNextChainCert(certs2, cert) == NULL) {
            X509_STORE_CTX xsc;

#if !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097)
            X509_VERIFY_PARAM * vpm = NULL;
            unsigned long vpm_flags = 0;

            vpm = X509_VERIFY_PARAM_new();
            if(vpm == NULL) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
                            "X509_VERIFY_PARAM_new",
                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
                            XMLSEC_ERRORS_NO_MESSAGE);
                goto done;
            }
            vpm_flags = vpm->flags;
/*
            vpm_flags &= (~X509_V_FLAG_X509_STRICT);
*/
            vpm_flags &= (~X509_V_FLAG_CRL_CHECK);

            X509_VERIFY_PARAM_set_depth(vpm, 9);
            X509_VERIFY_PARAM_set_flags(vpm, vpm_flags);
#endif /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */


            X509_STORE_CTX_init (&xsc, ctx->xst, cert, certs2);

            if(keyInfoCtx->certsVerificationTime > 0) {
#if !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097)
                vpm_flags |= X509_V_FLAG_USE_CHECK_TIME;
                X509_VERIFY_PARAM_set_time(vpm, keyInfoCtx->certsVerificationTime);
#endif /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */
                X509_STORE_CTX_set_time(&xsc, 0, keyInfoCtx->certsVerificationTime);
            }

#if !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097)
            X509_STORE_CTX_set0_param(&xsc, vpm);
#endif /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */


            ret         = X509_verify_cert(&xsc);
            err_cert    = X509_STORE_CTX_get_current_cert(&xsc);
            err         = X509_STORE_CTX_get_error(&xsc);
            depth       = X509_STORE_CTX_get_error_depth(&xsc);

            X509_STORE_CTX_cleanup (&xsc);

            if(ret == 1) {
                res = cert;
                goto done;
            } else if(ret < 0) {
                const char* err_msg;

                buf[0] = '\0';
                X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof buf);
                err_msg = X509_verify_cert_error_string(err);
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
                            "X509_verify_cert",
                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
                            "subj=%s;err=%d;msg=%s",
                            xmlSecErrorsSafeString(buf),
                            err,
                            xmlSecErrorsSafeString(err_msg));
                goto done;
            } else if(ret == 0) {
                const char* err_msg;

                buf[0] = '\0';
                X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof buf);
                err_msg = X509_verify_cert_error_string(err);
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
                            "X509_verify_cert",
                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
                            "subj=%s;err=%d;msg=%s",
                            xmlSecErrorsSafeString(buf),
                            err,
                            xmlSecErrorsSafeString(err_msg));
            }
        }
    }

    /* if we came here then we found nothing. do we have any error? */
    if((err != 0) && (err_cert != NULL)) {
        const char* err_msg;

        err_msg = X509_verify_cert_error_string(err);
        switch (err) {
        case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
            X509_NAME_oneline(X509_get_issuer_name(err_cert), buf, sizeof buf);
            xmlSecError(XMLSEC_ERRORS_HERE,
                        xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
                        NULL,
                        XMLSEC_ERRORS_R_CERT_ISSUER_FAILED,
                        "err=%d;msg=%s;issuer=%s",
                        err,
                        xmlSecErrorsSafeString(err_msg),
                        xmlSecErrorsSafeString(buf));
            break;
        case X509_V_ERR_CERT_NOT_YET_VALID:
        case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
            xmlSecError(XMLSEC_ERRORS_HERE,
                        xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
                        NULL,
                        XMLSEC_ERRORS_R_CERT_NOT_YET_VALID,
                        "err=%d;msg=%s", err,
                        xmlSecErrorsSafeString(err_msg));
            break;
        case X509_V_ERR_CERT_HAS_EXPIRED:
        case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
            xmlSecError(XMLSEC_ERRORS_HERE,
                        xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
                        NULL,
                        XMLSEC_ERRORS_R_CERT_HAS_EXPIRED,
                        "err=%d;msg=%s", err,
                        xmlSecErrorsSafeString(err_msg));
            break;
        default:
            xmlSecError(XMLSEC_ERRORS_HERE,
                        xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
                        NULL,
                        XMLSEC_ERRORS_R_CERT_VERIFY_FAILED,
                        "err=%d;msg=%s", err,
                        xmlSecErrorsSafeString(err_msg));
        }
    }

done:
    if(certs2 != NULL) {
        sk_X509_free(certs2);
    }
    if(crls2 != NULL) {
        sk_X509_CRL_free(crls2);
    }
    return(res);
}