Beispiel #1
0
int crl2pkcs7_main(int argc, char **argv)
{
    BIO *in = NULL, *out = NULL;
    PKCS7 *p7 = NULL;
    PKCS7_SIGNED *p7s = NULL;
    STACK_OF(OPENSSL_STRING) *certflst = NULL;
    STACK_OF(X509) *cert_stack = NULL;
    STACK_OF(X509_CRL) *crl_stack = NULL;
    X509_CRL *crl = NULL;
    char *infile = NULL, *outfile = NULL, *prog, *certfile;
    int i = 0, informat = FORMAT_PEM, outformat = FORMAT_PEM, ret = 1, nocrl =
        0;
    OPTION_CHOICE o;

    prog = opt_init(argc, argv, crl2pkcs7_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(crl2pkcs7_options);
            ret = 0;
            goto end;
        case OPT_INFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
                goto opthelp;
            break;
        case OPT_OUTFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
                goto opthelp;
            break;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_NOCRL:
            nocrl = 1;
            break;
        case OPT_CERTFILE:
            if ((certflst == NULL)
                && (certflst = sk_OPENSSL_STRING_new_null()) == NULL)
                goto end;
            if (!sk_OPENSSL_STRING_push(certflst, *(++argv))) {
                sk_OPENSSL_STRING_free(certflst);
                goto end;
            }
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();

    if (!nocrl) {
        in = bio_open_default(infile, 'r', informat);
        if (in == NULL)
            goto end;

        if (informat == FORMAT_ASN1)
            crl = d2i_X509_CRL_bio(in, NULL);
        else if (informat == FORMAT_PEM)
            crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
        if (crl == NULL) {
            BIO_printf(bio_err, "unable to load CRL\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if ((p7 = PKCS7_new()) == NULL)
        goto end;
    if ((p7s = PKCS7_SIGNED_new()) == NULL)
        goto end;
    p7->type = OBJ_nid2obj(NID_pkcs7_signed);
    p7->d.sign = p7s;
    p7s->contents->type = OBJ_nid2obj(NID_pkcs7_data);

    if (!ASN1_INTEGER_set(p7s->version, 1))
        goto end;
    if ((crl_stack = sk_X509_CRL_new_null()) == NULL)
        goto end;
    p7s->crl = crl_stack;
    if (crl != NULL) {
        sk_X509_CRL_push(crl_stack, crl);
        crl = NULL;             /* now part of p7 for OPENSSL_freeing */
    }

    if ((cert_stack = sk_X509_new_null()) == NULL)
        goto end;
    p7s->cert = cert_stack;

    if (certflst)
        for (i = 0; i < sk_OPENSSL_STRING_num(certflst); i++) {
            certfile = sk_OPENSSL_STRING_value(certflst, i);
            if (add_certs_from_file(cert_stack, certfile) < 0) {
                BIO_printf(bio_err, "error loading certificates\n");
                ERR_print_errors(bio_err);
                goto end;
            }
        }

    sk_OPENSSL_STRING_free(certflst);

    out = bio_open_default(outfile, 'w', outformat);
    if (out == NULL)
        goto end;

    if (outformat == FORMAT_ASN1)
        i = i2d_PKCS7_bio(out, p7);
    else if (outformat == FORMAT_PEM)
        i = PEM_write_bio_PKCS7(out, p7);
    if (!i) {
        BIO_printf(bio_err, "unable to write pkcs7 object\n");
        ERR_print_errors(bio_err);
        goto end;
    }
    ret = 0;
 end:
    BIO_free(in);
    BIO_free_all(out);
    PKCS7_free(p7);
    X509_CRL_free(crl);

    return (ret);
}
Beispiel #2
0
int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
{
    int ret=0;
    BIO *in=NULL;
    int i,count=0;
    X509_CRL *x=NULL;

    if (file == NULL) return(1);
    in=BIO_new(BIO_s_file_internal());

    if ((in == NULL) || (BIO_read_filename(in,file) <= 0))
    {
        X509err(X509_F_X509_LOAD_CRL_FILE,ERR_R_SYS_LIB);
        goto err;
    }

    if (type == X509_FILETYPE_PEM)
    {
        for (;;)
        {
            x=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
            if (x == NULL)
            {
                if ((ERR_GET_REASON(ERR_peek_last_error()) ==
                        PEM_R_NO_START_LINE) && (count > 0))
                {
                    ERR_clear_error();
                    break;
                }
                else
                {
                    X509err(X509_F_X509_LOAD_CRL_FILE,
                            ERR_R_PEM_LIB);
                    goto err;
                }
            }
            i=X509_STORE_add_crl(ctx->store_ctx,x);
            if (!i) goto err;
            count++;
            X509_CRL_free(x);
            x=NULL;
        }
        ret=count;
    }
    else if (type == X509_FILETYPE_ASN1)
    {
        x=d2i_X509_CRL_bio(in,NULL);
        if (x == NULL)
        {
            X509err(X509_F_X509_LOAD_CRL_FILE,ERR_R_ASN1_LIB);
            goto err;
        }
        i=X509_STORE_add_crl(ctx->store_ctx,x);
        if (!i) goto err;
        ret=i;
    }
    else
    {
        X509err(X509_F_X509_LOAD_CRL_FILE,X509_R_BAD_X509_FILETYPE);
        goto err;
    }
err:
    if (x != NULL) X509_CRL_free(x);
    if (in != NULL) BIO_free(in);
    return(ret);
}
/**
*失効リストチェック関数
* @author University of Tsukuba
* @param *pInData 証明書データ 
* @param lInLen 証明書データ長
* @param *data CRLファイルデータ
* @param len CRLファイルデータレングス
* @return   long  0:未失効 1:失効中 -1:異常 
* @since 2008.02
* @version 1.0
*/
long IDMan_CmCheckCRL(void *pInData, long lInLen, void * data,unsigned long int len )
{
	long 			lRet=-1L;
	/*FILE 			*fp;*/
	X509 			*x509=0x00;
	X509_CRL 		*x509crl=0x00;
	X509_NAME 		*x509crlissuer = 0x00;
	int				iRet=0;
	int				idx;
	X509_REVOKED	rtmp;
	char			*p,*p2;
	char 			szErrBuff[1024];
	BIO 			* BIOptr;

	ERR_load_crypto_strings();

	IDMan_StMemset(szErrBuff, 0x00, sizeof(szErrBuff));

	/** 証明書データパラメータチェックを行う。 */
	/** エラー発生した場合、 */
	if (pInData == 0x00) 
	{
		/** −処理を中断する。 */
		return lRet;
	}
	/** 証明書長データパラメータチェックを行う。 */
	/** エラー発生した場合、 */
	if (lInLen == 0)
	{
		/** −処理を中断する。 */
		return lRet;
	}

	/** 失効データパラメータチェックを行う。 */
	/** 失効データが存在しない場合、 */
	if (data==0x00 || len == 0)
	{
		/** −正常終了する。 */
		lRet =0;
		return lRet;
	}

	
	/** X509構造体の初期化を行う。 */
	/** エラー発生した場合、 */
	if((x509 = X509_new())== 0x00) 
	{
		/** −処理を中断する。 */
		ERR_error_string(ERR_get_error(), szErrBuff);
		return lRet;
	}

	/** DERファイルから、X509構造体にデータを読み込む。 */
	/** BIO構造の作成を行う。 */
	BIOptr = BIO_new(BIO_s_mem());

	/** BIO構造のリセットを行う。 */
	iRet = BIO_reset(BIOptr);
	/** エラー発生した場合、 */
	if(iRet != 1)
	{
		/** −処理を中断する。 */
		ERR_error_string(ERR_get_error(), szErrBuff);
		BIO_free(BIOptr);
		return lRet;
	}

	/** BIO構造へ公開鍵証明書データの設定を行う。 */
	iRet = BIO_write(BIOptr,pInData,lInLen);
	/** エラー発生した場合、 */
	if( iRet != lInLen )
	{
		/** −処理を中断する。 */
		ERR_error_string(ERR_get_error(), szErrBuff);
		BIO_free(BIOptr);
		return lRet;
	}

	/** X509構造体の作成を行う。 */
	x509 =(X509 *) d2i_X509_bio(BIOptr,0x00);
	/** エラー発生した場合、 */
	if((x509 == 0x00))
	{
		/** −処理を中断する。 */
		ERR_error_string(ERR_get_error(), szErrBuff);
		if(x509 !=0x00)	X509_free(x509);
		BIO_free(BIOptr);
		return lRet;
	}

	/** BIO構造の解放を行う。 */
	BIO_free(BIOptr);

	/** issuerDNの取得を行う。 */
	X509_NAME *x509issuer = X509_get_issuer_name(x509);
	p = X509_NAME_oneline(x509issuer, 0, 0);	
	/** CRL情報の取得を行う。 */
	x509crl = X509_CRL_new();

	/** BIO構造の作成を行う。 */
	BIOptr = BIO_new(BIO_s_mem());

	/** BIO構造のリセットを行う。 */
	iRet = BIO_reset(BIOptr);
	/** エラー発生した場合、 */
	if(iRet != 1)
	{
		/** −処理を中断する。 */
		ERR_error_string(ERR_get_error(), szErrBuff);
		BIO_free(BIOptr);
		return lRet;
	}

	/** BIO構造へ失効リストデータの設定を行う。 */
	iRet = BIO_write(BIOptr,data,len);
	/** エラー発生した場合、 */
	if( iRet != (int)len )
	{
		/** −処理を中断する。 */
		ERR_error_string(ERR_get_error(), szErrBuff);
		BIO_free(BIOptr);
		return lRet;
	}
	/** x509crl構造へ失効リストデータの設定を行う。 */
	x509crl = (X509_CRL *) d2i_X509_CRL_bio(BIOptr,0x00);
	/** エラー発生した場合、 */
	if(x509crl==0x00) 
	{
		/** −処理を中断する。 */
		ERR_error_string(ERR_get_error(), szErrBuff);
		if(x509 !=0x00)	X509_free(x509);
		if(x509crl !=0x00)	X509_CRL_free(x509crl);
		BIO_free(BIOptr);
		return lRet;
	}

	/** BIO構造の解放を行う。 */
	BIO_free(BIOptr);

	/** シリアル番号の取得を行う。 */
	rtmp.serialNumber = X509_get_serialNumber(x509);

	/** CRLのissuerDNの取得を行う。 */
	/** エラー発生した場合、 */
	x509crlissuer = X509_CRL_get_issuer(x509crl);
	if ( x509crlissuer == 0x00 )
	{
		/** −処理を中断する。 */
		ERR_error_string(ERR_get_error(), szErrBuff);
		if(x509 !=0x00)	X509_free(x509);
		if(x509crl !=0x00)	X509_CRL_free(x509crl);
		return lRet;
	}

	/** 証明書とCRLのissuerDNの比較を行う。 */
	p2 = X509_NAME_oneline(x509crlissuer, 0, 0);
	/** エラー発生した場合、 */
	if( strcmp(p, p2) != 0)
	{
		/** −処理を中断する。 */
		ERR_error_string(ERR_get_error(), szErrBuff);
		if(x509 !=0x00)	X509_free(x509);
		if(x509crl !=0x00)	X509_CRL_free(x509crl);
		return lRet;
	}

	/** CRLのシリアル番号をソートする。 */
	if (!sk_is_sorted(x509crl->crl->revoked)) 
	{
		sk_sort(x509crl->crl->revoked);
	}
	/** CRLのシリアル番号を検索する。 */
	idx = sk_X509_REVOKED_find(x509crl->crl->revoked, &rtmp);
	/** 該当シリアル番号が存在する場合、 */
	if (idx >= 0) 
	{
		/** −戻り値に1を設定する。 */
		lRet =1;
	}
	/** 該当シリアル番号が存在しない場合、 */
	else
	{
		/** −戻り値に0を設定する。 */
		lRet =0;
	}

	/** X509の開放を行う。 */
	if(x509 !=0x00)	X509_free(x509);

	/** X509CRLの開放を行う。 */
	if(x509crl !=0x00)	X509_CRL_free(x509crl);

	return lRet;
}
Handle<PkiItem> Provider_System::objectToPKIItem(Handle<std::string> uri){
	LOGGER_FN();

	Handle<PkiItem> item;

	Handle<Bio> in =  new Bio(BIO_TYPE_FILE, uri->c_str(), "rb");

	try{
		item = new PkiItem();

		X509_REQ *xreq = NULL;
		X509 *xcert = NULL;
		X509_CRL *xcrl = NULL;

		Handle<Certificate> hcert = NULL;
		Handle<CRL> hcrl = NULL;

		std::string listCertStore[] = {
			"MY",
			"OTHERS",
			"TRUST",
			"CRL"
		};

		std::string strTrust = (uri->substr(0, (uri->find_last_of(CROSSPLATFORM_SLASH))));
		strTrust = strTrust.substr(strTrust.find_last_of(CROSSPLATFORM_SLASH) + 1, strTrust.length());

		bool trueTrust = false;
		for (int i = 0, c = sizeof(listCertStore) / sizeof(*listCertStore); i < c; i++){
			if (strcmp(listCertStore[i].c_str(), strTrust.c_str()) == 0){
				trueTrust = true;
				break;
			}
		}
		if (!trueTrust){
			THROW_EXCEPTION(0, Provider_System, NULL, "Category of object is uncorrect");
		}

		int enc;
		if (itPrivateKey(uri, &enc)){
			item->type = new std::string("KEY");
			item->uri = uri;
			item->provider = new std::string("SYSTEM");
			item->category = new std::string(strTrust);
			item->keyEncrypted = enc;
			item->format = new std::string("PEM");

			Handle<std::string> keyHash = new std::string(uri->c_str());
			const size_t last_slash_idx = keyHash->find_last_of(CROSSPLATFORM_SLASH);
			if (std::string::npos != last_slash_idx){
				keyHash->erase(0, last_slash_idx + 1);
			}
			const size_t period_idx = keyHash->rfind('.');
			if (std::string::npos != period_idx){
				keyHash->erase(period_idx);
			}
			if (keyHash->length() == 40){
				item->hash = keyHash;
			}
			else{
				THROW_EXCEPTION(0, Provider_System, NULL, "Error length hash (need 40 for sha1). Hash is privatekey filename");
			}

			return item;			
		}

		in->seek(0);

		LOGGER_OPENSSL(PEM_read_bio_X509);
		xcert = PEM_read_bio_X509(in->internal(), NULL, NULL, NULL);
		if (xcert){
			hcert = new Certificate(xcert);
			item->format = new std::string("PEM");		
		}
		else{
			in->seek(0);

			LOGGER_OPENSSL(d2i_X509_bio);
			xcert = d2i_X509_bio(in->internal(), NULL);
			if (xcert){
				hcert = new Certificate(xcert);
				item->format = new std::string("DER");
			}
		}

		if (!hcert.isEmpty()){
			item->type = new std::string("CERTIFICATE");
			item->uri = uri;
			item->provider = new std::string("SYSTEM");
			item->category = new std::string(strTrust);

			char * hexHash;
			Handle<std::string> hhash = hcert->getThumbprint();
			PkiStore::bin_to_strhex((unsigned char *)hhash->c_str(), hhash->length(), &hexHash);
			item->hash = new std::string(hexHash);

			item->certSubjectName = hcert->getSubjectName();
			item->certSubjectFriendlyName = hcert->getSubjectFriendlyName();
			item->certIssuerName = hcert->getIssuerName();
			item->certIssuerFriendlyName = hcert->getIssuerFriendlyName();
			item->certSerial = hcert->getSerialNumber();
			item->certOrganizationName = hcert->getOrganizationName();
			item->certSignatureAlgorithm = hcert->getSignatureAlgorithm();

			item->certNotBefore = hcert->getNotBefore();
			item->certNotAfter = hcert->getNotAfter();
			
			item->certKey = getKey(uri);
		
			return item;
		}

		in->seek(0);

		LOGGER_OPENSSL(PEM_read_bio_X509_REQ);
		xreq = PEM_read_bio_X509_REQ(in->internal(), NULL, NULL, NULL);
		if (xreq){
			item->format = new std::string("PEM");
		}
		else{
			in->seek(0);

			LOGGER_OPENSSL(d2i_X509_REQ_bio);
			xreq = d2i_X509_REQ_bio(in->internal(), NULL);
			if (xreq){
				item->format = new std::string("DER");
			}
		}

		if (xreq){
			item->type = new std::string("REQUEST");
			item->uri = uri;
			item->provider = new std::string("SYSTEM");
			item->category = new std::string(strTrust);

			/* SHA-1 hash */
			unsigned char hash[EVP_MAX_MD_SIZE] = { 0 };
			unsigned int hashlen = 0;
			LOGGER_OPENSSL(X509_digest);
			if (!X509_REQ_digest(xreq, EVP_sha1(), hash, &hashlen)) {
				THROW_OPENSSL_EXCEPTION(0, Provider_System, NULL, "X509_REQ_digest");
			}
			Handle<std::string> hhash = new std::string((char *)hash, hashlen);

			char * hexHash;
			PkiStore::bin_to_strhex((unsigned char *)hhash->c_str(), hhash->length(), &hexHash);
			item->hash = new std::string(hexHash);

			/* Request subject name */
			LOGGER_OPENSSL(X509_REQ_get_subject_name);
			X509_NAME *name = X509_REQ_get_subject_name(xreq);
			if (!name){
				THROW_EXCEPTION(0, Provider_System, NULL, "X509_NAME is NULL");
			}				
			LOGGER_OPENSSL(X509_NAME_oneline_ex);
			std::string str_name = X509_NAME_oneline_ex(name);
			Handle<std::string> nameRes = new std::string(str_name.c_str(), str_name.length());
			item->csrSubjectName = nameRes;

			/* Request subject friendly name */
			Handle<std::string> friendlyName = new std::string("");
			int nid = NID_commonName;
			LOGGER_OPENSSL(X509_NAME_get_index_by_NID);
			int index = X509_NAME_get_index_by_NID(name, nid, -1);
			if (index >= 0) {
				LOGGER_OPENSSL(X509_NAME_get_entry);
				X509_NAME_ENTRY *issuerNameCommonName = X509_NAME_get_entry(name, index);

				if (issuerNameCommonName) {
					LOGGER_OPENSSL(X509_NAME_ENTRY_get_data);
					ASN1_STRING *issuerCNASN1 = X509_NAME_ENTRY_get_data(issuerNameCommonName);

					if (issuerCNASN1 != NULL) {
						unsigned char *utf = NULL;
						LOGGER_OPENSSL(ASN1_STRING_to_UTF8);
						ASN1_STRING_to_UTF8(&utf, issuerCNASN1);
						friendlyName = new std::string((char *)utf);
						OPENSSL_free(utf);
					}
				}
			}
			else {
				friendlyName = new std::string("No common name");
			}
			item->csrSubjectFriendlyName = friendlyName;
			item->csrKey = getKey(uri);

			return item;
		}

		in->seek(0);

		LOGGER_OPENSSL(PEM_read_bio_X509_CRL);
		xcrl = PEM_read_bio_X509_CRL(in->internal(), NULL, NULL, NULL);
		if (xcrl){
			hcrl = new CRL(xcrl);
			item->format = new std::string("PEM");
		}
		else{
			in->seek(0);

			LOGGER_OPENSSL(d2i_X509_CRL_bio);
			xcrl = d2i_X509_CRL_bio(in->internal(), NULL);
			if (xcrl){
				hcrl = new CRL(xcrl);
				item->format = new std::string("DER");
			}
		}

		if (!hcrl.isEmpty()){
			item->type = new std::string("CRL");
			item->uri = uri;
			item->provider = new std::string("SYSTEM");			
			item->category = new std::string(strTrust);
			
			char * hexHash;
			Handle<std::string> hhash = hcrl->getThumbprint();
			PkiStore::bin_to_strhex((unsigned char *)hhash->c_str(), hhash->length(), &hexHash);
			item->hash = new std::string(hexHash);

			item->crlIssuerName = hcrl->issuerName();
			item->crlIssuerFriendlyName = hcrl->issuerFriendlyName();
			item->crlLastUpdate = hcrl->getThisUpdate();
			item->crlNextUpdate = hcrl->getNextUpdate();

			return item;
		}
	}
	catch (Handle<Exception> e){
		THROW_EXCEPTION(0, Provider_System, e, "Object type not supported");
	}

	if (item->type->length() == 0){
		return NULL;
	}
}
Beispiel #5
0
int MAIN(int argc, char **argv)
	{
	int i,badops=0;
	BIO *in=NULL,*out=NULL;
	int informat,outformat;
	char *infile,*outfile,*prog,*certfile;
	PKCS7 *p7 = NULL;
	PKCS7_SIGNED *p7s = NULL;
	X509_CRL *crl=NULL;
	STACK_OF(OPENSSL_STRING) *certflst=NULL;
	STACK_OF(X509_CRL) *crl_stack=NULL;
	STACK_OF(X509) *cert_stack=NULL;
	int ret=1,nocrl=0;

	apps_startup();

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

	infile=NULL;
	outfile=NULL;
	informat=FORMAT_PEM;
	outformat=FORMAT_PEM;

	prog=argv[0];
	argc--;
	argv++;
	while (argc >= 1)
		{
		if 	(strcmp(*argv,"-inform") == 0)
			{
			if (--argc < 1) goto bad;
			informat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-outform") == 0)
			{
			if (--argc < 1) goto bad;
			outformat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-in") == 0)
			{
			if (--argc < 1) goto bad;
			infile= *(++argv);
			}
		else if (strcmp(*argv,"-nocrl") == 0)
			{
			nocrl=1;
			}
		else if (strcmp(*argv,"-out") == 0)
			{
			if (--argc < 1) goto bad;
			outfile= *(++argv);
			}
		else if (strcmp(*argv,"-certfile") == 0)
			{
			if (--argc < 1) goto bad;
			if(!certflst) certflst = sk_OPENSSL_STRING_new_null();
			sk_OPENSSL_STRING_push(certflst,*(++argv));
			}
		else
			{
			BIO_printf(bio_err,"unknown option %s\n",*argv);
			badops=1;
			break;
			}
		argc--;
		argv++;
		}

	if (badops)
		{
bad:
		BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
		BIO_printf(bio_err,"where options are\n");
		BIO_printf(bio_err," -inform arg    input format - DER or PEM\n");
		BIO_printf(bio_err," -outform arg   output format - DER or PEM\n");
		BIO_printf(bio_err," -in arg        input file\n");
		BIO_printf(bio_err," -out arg       output file\n");
		BIO_printf(bio_err," -certfile arg  certificates file of chain to a trusted CA\n");
		BIO_printf(bio_err,"                (can be used more than once)\n");
		BIO_printf(bio_err," -nocrl         no crl to load, just certs from '-certfile'\n");
		ret = 1;
		goto end;
		}

	ERR_load_crypto_strings();

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

	if (!nocrl)
		{
		if (infile == NULL)
			BIO_set_fp(in,stdin,BIO_NOCLOSE);
		else
			{
			if (BIO_read_filename(in,infile) <= 0)
				{
				perror(infile);
				goto end;
				}
			}

		if 	(informat == FORMAT_ASN1)
			crl=d2i_X509_CRL_bio(in,NULL);
		else if (informat == FORMAT_PEM)
			crl=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
		else	{
			BIO_printf(bio_err,"bad input format specified for input crl\n");
			goto end;
			}
		if (crl == NULL)
			{
			BIO_printf(bio_err,"unable to load CRL\n");
			ERR_print_errors(bio_err);
			goto end;
			}
		}
	
	if ((p7=PKCS7_new()) == NULL) goto end;
	if ((p7s=PKCS7_SIGNED_new()) == NULL) goto end;
	p7->type=OBJ_nid2obj(NID_pkcs7_signed);
	p7->d.sign=p7s;
	p7s->contents->type=OBJ_nid2obj(NID_pkcs7_data);

	if (!ASN1_INTEGER_set(p7s->version,1)) goto end;
	if ((crl_stack=sk_X509_CRL_new_null()) == NULL) goto end;
	p7s->crl=crl_stack;
	if (crl != NULL)
		{
		sk_X509_CRL_push(crl_stack,crl);
		crl=NULL; /* now part of p7 for OPENSSL_freeing */
		}

	if ((cert_stack=sk_X509_new_null()) == NULL) goto end;
	p7s->cert=cert_stack;

	if(certflst) for(i = 0; i < sk_OPENSSL_STRING_num(certflst); i++) {
		certfile = sk_OPENSSL_STRING_value(certflst, i);
		if (add_certs_from_file(cert_stack,certfile) < 0)
			{
			BIO_printf(bio_err, "error loading certificates\n");
			ERR_print_errors(bio_err);
			goto end;
			}
	}

	sk_OPENSSL_STRING_free(certflst);

	if (outfile == NULL)
		{
		BIO_set_fp(out,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)
			{
			perror(outfile);
			goto end;
			}
		}

	if 	(outformat == FORMAT_ASN1)
		i=i2d_PKCS7_bio(out,p7);
	else if (outformat == FORMAT_PEM)
		i=PEM_write_bio_PKCS7(out,p7);
	else	{
		BIO_printf(bio_err,"bad output format specified for outfile\n");
		goto end;
		}
	if (!i)
		{
		BIO_printf(bio_err,"unable to write pkcs7 object\n");
		ERR_print_errors(bio_err);
		goto end;
		}
	ret=0;
end:
	if (in != NULL) BIO_free(in);
	if (out != NULL) BIO_free_all(out);
	if (p7 != NULL) PKCS7_free(p7);
	if (crl != NULL) X509_CRL_free(crl);

	apps_shutdown();
	OPENSSL_EXIT(ret);
	}
Beispiel #6
0
unsigned char *SCEP_MSG_decrypt( SCEP_MSG *msg, EVP_PKEY *ppkey, 
		X509 *cert, long *len ) {

	char *ret = NULL;
	char *data = NULL;

	BIO *bio = NULL;
	BIO *bio_err = NULL;
	BIO *bio_dup = NULL;

	X509 *foo_cert = NULL;
	EVP_PKEY *pkey = NULL;

	SCEP_RECIP_INFO *rinfo;

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

	/* Get the recipient information to build the fake
	 * certificate needed into the PKCS7_decrypt function */
	rinfo = &(msg->env_data.recip_info);

	/* We need a private key */
	if( ppkey )
		pkey = ppkey;
	else
		pkey = msg->signer_pkey;

	if( !pkey ) return (NULL);

	if( cert ) {
		foo_cert = cert;
	} else {
		if( (foo_cert = X509_new()) == NULL ) {
			BIO_printf(bio_err, "%s:%d: foo_cert not alloc\n", __FILE__,
				__LINE__);

			goto err;
		};

		X509_set_issuer_name(foo_cert,rinfo->ias->issuer);
		X509_set_subject_name(foo_cert,rinfo->ias->issuer);
		X509_set_serialNumber(foo_cert,rinfo->ias->serial);
		X509_set_pubkey(foo_cert, pkey);
	}

	bio = BIO_new(BIO_s_mem());
	if (PKCS7_decrypt( msg->env_data.p7env, pkey, foo_cert, bio, 0) == 0) {
		// printf("%s:%d: decryption failed\n", __FILE__,
		// 	__LINE__);
		goto err;
	}
	BIO_flush(bio);
	if( len ) *len = BIO_get_mem_data(bio, &data);

	switch ( msg->messageType ) {
	   case MSG_CERTREP:
		if( msg->env_data.crl = d2i_X509_CRL_bio(bio,NULL) ) {
			/* There is a CRL */
			ret = (char *) msg->env_data.crl;
		}
		// p7 = d2i_PKCS7_bio(bio, NULL);
		break;
	   case MSG_PKCSREQ:
		msg->env_data.content.req = d2i_X509_REQ_bio(bio, NULL);
		ret = (char *) msg->env_data.content.req;
		break;
	   case MSG_GETCERTINITIAL:
		// req->rd.is = d2i_issuer_and_subject_bio(bio, NULL);
		break;
	   case MSG_GETCERT:
	   case MSG_GETCRL:
		msg->env_data.content.ias = d2i_PKCS7_ias_bio(NULL, bio);
		ret = (char *) msg->env_data.content.ias;
		break;
	case MSG_V2PROXY: // unsupported
	case MSG_V2REQUEST: // unsupported
	default:
		// BIO_printf(bio_err, "%s:%d: unknown message type: %s\n",
		// 	__FILE__, __LINE__, msg->messageType);
		break;
	}

err:
	if( foo_cert && !cert ) X509_free( foo_cert );
	if( bio ) BIO_free(bio);

	ERR_clear_error();

	return ret;
}