コード例 #1
0
ファイル: csr.c プロジェクト: houzhenggang/luajit-android
static LUA_FUNCTION(openssl_csr_read)
{
  BIO * in = load_bio_object(L, 1);
  int fmt = luaL_checkoption(L, 2, "auto", format);
  X509_REQ * csr = NULL;

  if (fmt == FORMAT_AUTO)
  {
    fmt = bio_is_der(in) ? FORMAT_DER : FORMAT_PEM;
  }

  if (fmt == FORMAT_PEM)
  {
    csr = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
    BIO_reset(in);
  }else
  if (fmt == FORMAT_DER)
  {
    csr = d2i_X509_REQ_bio(in, NULL);
    BIO_reset(in);
  }
  BIO_free(in);

  if (csr)
  {
    PUSH_OBJECT(csr, "openssl.x509_req");
    return 1;
  }
  return openssl_pushresult(L, 0);
}
コード例 #2
0
ファイル: test_pkcs10.c プロジェクト: viktorTarasov/has
int main(int argc, char **argv)
{
    X509_REQ  *pkcs10 = NULL;
    BIO       *bio    = NULL;
    has_t     *p10    = NULL;
    char      *json   = NULL; 
    size_t l;

    openssl_init();

    if ((bio = BIO_new(BIO_s_file())) == NULL) {
        return -1;
    }

    if(argc < 2) {
        BIO_set_fp(bio, stdin, BIO_NOCLOSE);
    } else {
        BIO_read_filename(bio, argv[1]);
    }
    
    /* Format DER */
    if((pkcs10 = d2i_X509_REQ_bio(bio, NULL)) == NULL) {
        ERR_clear_error();
        /* Format PEM */
        pkcs10 = PEM_read_bio_X509_REQ(bio, NULL, NULL, NULL);
    }

    if(!pkcs10) {
        fprintf(stderr, "Error loading certificate\n");
        return -1;
    }

    if((p10 = has_pkcs10_new(pkcs10)) == NULL) {
        fprintf(stderr, "Error converting certificate\n");
        return -1;
    } 

    if(has_json_serialize(p10, &json, &l, HAS_JSON_SERIALIZE_PRETTY) == 0) {
        printf("%s\n", json);
        free(json);
    } else {
        fprintf(stderr, "Error serializing certificate\n");
        return -1;        
    }

    has_free(p10);
    X509_REQ_free(pkcs10);
    BIO_free(bio);

    openssl_cleanup();

    return 0;
}
コード例 #3
0
Handle<CertificationRequest> Provider_System::getCSRFromURI(Handle<std::string> uri, Handle<std::string> format){
	LOGGER_FN();

	try{
		BIO *bioFile = NULL;
		X509_REQ *hreq = NULL;

		LOGGER_OPENSSL(BIO_new);
		bioFile = BIO_new(BIO_s_file());
		LOGGER_OPENSSL(BIO_read_filename);
		if (BIO_read_filename(bioFile, uri->c_str()) > 0){
			LOGGER_OPENSSL(BIO_seek);
			BIO_seek(bioFile, 0);

			if (strcmp(format->c_str(), "PEM") == 0){
				LOGGER_OPENSSL(PEM_read_bio_X509_REQ);
				hreq = PEM_read_bio_X509_REQ(bioFile, NULL, NULL, NULL);
			}
			else if (strcmp(format->c_str(), "DER") == 0){
				LOGGER_OPENSSL(d2i_X509_REQ_bio);
				hreq = d2i_X509_REQ_bio(bioFile, NULL);
			}
			else{
				THROW_EXCEPTION(0, Provider_System, NULL, "Unsupported format. Only PEM | DER");
			}
		}

		LOGGER_OPENSSL(BIO_free);
		BIO_free(bioFile);

		if (!hreq){
			THROW_EXCEPTION(0, Provider_System, NULL, "Unable decode csr from PEM/DER");
		}
		else{
			return new CertificationRequest(hreq);
		}
	}
	catch (Handle<Exception> e){
		THROW_EXCEPTION(0, Provider_System, e, "getCSRFromURI");
	}
}
コード例 #4
0
ファイル: scep.c プロジェクト: xman1979/openscep
/*
 * read requestor data
 *
 * for version 2 requests, the requestor and the SCEP client can be different
 * and the request does not need to be a PKCS#10
 */
static int	read_requestorstuff(scep_t *scep, int type, char *filename) {
	BIO		*bio;
	NETSCAPE_SPKI	*spki = NULL;
	X509_REQ	*req = NULL;
	bio = BIO_new(BIO_s_file());
	if (BIO_read_filename(bio, filename) < 0) {
		BIO_printf(bio_err, "%s:%d: cannot read request file '%s'\n",
			__FILE__, __LINE__, filename);
		goto err;
	}
	switch (type) {
	case 0:
		scep->requestorreq = d2i_X509_REQ_bio(bio, &req);
		if (scep->requestorreq == NULL) {
			BIO_printf(bio_err, "%s:%d: cannot decode X509_REQ\n",
				__FILE__, __LINE__);
			goto err;
		}
		scep->requestorpubkey
			= X509_REQ_get_pubkey(scep->requestorreq);
		break;
	case 1:
		scep->requestorspki = d2i_NETSCAPE_SPKI_bio(bio, &spki);
		if (scep->requestorspki == NULL) {
			BIO_printf(bio_err, "%s:%d: cannot decode SPKI\n",
				__FILE__, __LINE__);
			goto err;
		}
		scep->requestorpubkey
			= NETSCAPE_SPKI_get_pubkey(scep->requestorspki);
		break;
	default:
		goto err;
	}
	return 0;
err:
	ERR_print_errors(bio_err);
	return -1;
}
コード例 #5
0
ファイル: estserver.c プロジェクト: StephenWall/libest
/*
 * We use a simple lookup table to simulate manual enrollment
 * of certs by the CA.  This is the case where an operator
 * needs to review each cert request and approve it (e.g.
 * auto-enrollment is off).
 *
 * Return 1 if a match was found and the enrollment operation
 * should proceed.  Return 0 if no match was found, in which
 * case we'll add the public key from the cert request into
 * our lookup table so it can be correlated later.
 *
 * Windows: Rewriting to forgo the use of search.h API
 * lookup table will be implemented as a basic linked list
 */
static int lookup_pkcs10_request(unsigned char *pkcs10, int p10_len)
{
    X509_REQ *req = NULL;
    BIO *in = NULL;
    BIO *out = NULL;
    BIO *b64;
    EVP_PKEY *pkey = NULL;
    BUF_MEM *bptr;
    int rv;
    LOOKUP_ENTRY *l;
    LOOKUP_ENTRY *n;

    /*
     * Decode the request into an X509_REQ structure
     */
    b64 = BIO_new(BIO_f_base64());
    in = BIO_new_mem_buf(pkcs10, p10_len);
    in = BIO_push(b64, in);
    if ((req = d2i_X509_REQ_bio(in, NULL)) == NULL) {
        /* Unable to parse the request, just let this fall through
         * and the enrollment will fail */
        rv = 1;
        goto DONE;
    }

    /*
     * Get the public key from the request, this will be our index into
     * the lookup table.  Frankly, I'm not sure how a real CA
     * would do this lookup.  But this should be good enough for
     * testing the retry-after logic.
     */
    pkey = X509_PUBKEY_get(req->req_info->pubkey);
    if (!pkey) {
        rv = 1;
        goto DONE;
    }
    out = BIO_new(BIO_s_mem());
    PEM_write_bio_PUBKEY(out, pkey);
    BIO_get_mem_ptr(out, &bptr);

    /*
     * see if we can find a match for this public key
     */
    n = malloc(sizeof(LOOKUP_ENTRY));
    n->data = malloc(bptr->length);
    n->length = bptr->length;
    memcpy(n->data, bptr->data, n->length);
    n->next = NULL;
    l = search_list(lookup_root, n);
    if (l) {
        /* We have a match, allow the enrollment */
        rv = 1;
        lookup_root = delete_lookup_entry(lookup_root, n);
        printf("\nRemoving key from lookup table:\n");
        dumpbin((char*)n->data, n->length);
        free(n->data);
        free(n);
    }
    else {
        /* Not a match, add it to the list and return */

        if (lookup_root == NULL) {
            /*
             * Initialize the list
             */
            lookup_root = n;
        }
        else {
            add_entry(lookup_root, n);
        }
        rv = 0;
        printf("\nAdding key to lookup table:\n");
        dumpbin((char*)n->data, n->length);
    }
    DONE:
    if (out)
        BIO_free_all(out);
    if (in)
        BIO_free_all(in);
    if (req)
        X509_REQ_free(req);
    if (pkey)
        EVP_PKEY_free(pkey);

    return (rv);
}
コード例 #6
0
ファイル: sceplist.c プロジェクト: xman1979/openscep
static scepitem_t	*readitem(char *transid) {
	scepitem_t	*si;
	BIO		*bio;
	char		filename[1024];
	char		oneline[1024];
	X509_NAME	*name;

	/* allocate a new structure					*/
	si = (scepitem_t *)malloc(sizeof(scepitem_t));

	/* first create a copy of the transid				*/
	si->transid = strdup(transid);

	/* make sure that it has the right length			*/
	si->transid[32] = '\0';

	/* find the appropriate file: request or certificate		*/
	switch (itemselect) {
	case SELECT_PENDING:
	case SELECT_REJECTED:
		si->type = ITEM_TYPE_REQ;
		break;
	case SELECT_GRANTED:
	case SELECT_REVOKED:
		si->type = ITEM_TYPE_CERT;
		break;
	}

	/* create the filename for the item				*/
	snprintf(filename, sizeof(filename), "%s/%s/%s.der", OPENSCEPDIR,
		selectname[itemselect], si->transid);
	if (debug)
		fprintf(stderr, "%s:%d: trying file '%s'\n", __FILE__, __LINE__,
			filename);

	/* open the file and read the contents				*/
	bio = BIO_new(BIO_s_file());
	if (BIO_read_filename(bio, filename) < 0) {
		fprintf(stderr, "%s:%d: cannot open file %s\n", __FILE__,
			__LINE__, filename);
		return NULL;
	}
	switch (si->type) {
	case ITEM_TYPE_REQ:
		si->data.req = d2i_X509_REQ_bio(bio, NULL);
		break;
	case ITEM_TYPE_CERT:
		si->data.x509 = d2i_X509_bio(bio, NULL);
		break;
	}
	if (si->data.any == NULL) {
		fprintf(stderr, "%s:%d: cannot decode item, trans id %s\n",
			__FILE__, __LINE__, si->transid);
		ERR_print_errors(bio_err);
		return NULL;
	} else {
		if (debug)
			BIO_printf(bio_err, "%s:%d: got new item\n", __FILE__,
				__LINE__);
	}

	/* extract key information from request or certificate		*/
	switch (sortorder) {
	case SORT_TRANSID:
		si->key = strdup(si->transid);
		break;
	case SORT_NAME:
		name = (si->type == ITEM_TYPE_REQ)
			? X509_REQ_get_subject_name(si->data.req)
			: X509_get_subject_name(si->data.x509);
		X509_NAME_oneline(name, oneline, sizeof(oneline));
		si->key = strdup(oneline);
		break;
	case SORT_NOTBEFORE:
		si->key = asn1_time_to_string(X509_get_notBefore(
			si->data.x509));
		break;
	case SORT_NOTAFTER:
		si->key = asn1_time_to_string(X509_get_notAfter(si->data.x509));
		break;
	case SORT_SERIAL:
		si->key = X509_get_serialNumber(si->data.x509);
		break;
	}

	/* return the completely filled in item				*/
	return si;
}
コード例 #7
0
ファイル: ca.c プロジェクト: danharkins/est
static void
sign_req (int fd, void *unused)
{
    char thefile[80], cmd_buf[300], p7[3000];
    int i, num;
    unsigned char *data, *asn1;
    int32_t msglen;
    BIO *bio = NULL;
    FILE *fp;
    struct stat blah;
    X509_REQ *req = NULL;
    EVP_ENCODE_CTX ctx;
    
    if (recv(fd, (char *)&msglen, sizeof(int32_t), MSG_WAITALL) < sizeof(int32_t)) {
        return;
    }
    msglen = ntohl(msglen);
    if (msglen > 3000) {
        return;
    }
    if ((data = (unsigned char *)malloc(msglen)) == NULL) {
        return;
    }
    if ((asn1 = (unsigned char *)malloc(msglen)) == NULL) {
        free(data);
        return;
    }
    if (recv(fd, (char *)data, msglen, MSG_WAITALL) < msglen) {
        free(data);
        return;
    }

    EVP_DecodeInit(&ctx);
    EVP_DecodeUpdate(&ctx, asn1, &i, data, msglen);
    num = i;
    EVP_DecodeFinal(&ctx, &(asn1[i]), &i);
    num += i;
    free(data);

    if ((bio = BIO_new_mem_buf(asn1, num)) == NULL) {
        free(asn1);
        goto no_cert;
    }
    if ((req = d2i_X509_REQ_bio(bio, NULL)) == NULL) {
        free(asn1);
        goto no_cert;
    }
    free(asn1);
    BIO_free(bio); bio = NULL;
    
    unique++;
    memset(thefile, 0, sizeof(thefile));
    snprintf(thefile, sizeof(thefile), "%dreq.pem", unique);
    if ((fp = fopen(thefile, "w+")) == NULL) {
        goto no_cert;
    }
    if ((bio = BIO_new(BIO_s_file())) == NULL) {
        fprintf(stderr, "unable to create bio for CSR\n");
        goto no_cert;
    }
    BIO_set_fp(bio, fp, BIO_NOCLOSE);
    PEM_write_bio_X509_REQ(bio, req);
    (void)BIO_flush(bio);
    BIO_free(bio); bio = NULL;
    fclose(fp);

    snprintf(cmd_buf, sizeof(cmd_buf),
             "openssl ca "
             "-policy policy_anything -batch -notext "
             "-config ./conf/openssl.cnf "
             "-out %dcert.pem -in %dreq.pem", unique, unique);
    system(cmd_buf);
    unlink(thefile);

    snprintf(thefile, sizeof(thefile), "%dcert.pem", unique);
    if ((stat(thefile, &blah) < 0) || (blah.st_size < 1)) {
        goto no_cert;
    }

    snprintf(cmd_buf, sizeof(cmd_buf),
             "openssl crl2pkcs7 "
             "-certfile %dcert.pem -outform DER -out %dder.p7 -nocrl", unique, unique);
    system(cmd_buf);
    unlink(thefile); 

    snprintf(thefile, sizeof(thefile), "%dder.p7", unique);
    if (stat(thefile, &blah) < 0) {
        goto no_cert;
    }
    i = blah.st_size;
    printf("DER-encoded P7 is %d bytes\n", i);
    if ((data = (unsigned char *)malloc(blah.st_size*2)) == NULL) {
        goto no_cert;
    }
    
    if ((fp = fopen(thefile, "r")) == NULL) {
        free(data);
        goto no_cert;
    }
    if (fread(p7, 1, sizeof(p7), fp) < blah.st_size) {
        free(data);
        goto no_cert;
    }
    fclose(fp);
    unlink(thefile);
    
    i = 0;
    EVP_EncodeInit(&ctx);
    EVP_EncodeUpdate(&ctx, data, &i, (unsigned char *)p7, blah.st_size);
    num = i;
    EVP_EncodeFinal(&ctx, (unsigned char *)&(data[i]), &i);
    num += i;
    printf("PEM-encoded P7 is %d bytes\n", num);
    msglen = num;
    msglen = htonl(msglen);
    send(fd, (char *)&msglen, sizeof(int32_t), 0);
    send(fd, (char *)data, num, 0);
    free(data);

no_cert:
    BIO_free(bio);
    srv_rem_input(srvctx, fd);
    close(fd);
    
    return;
}
コード例 #8
0
		inline certificate_request certificate_request::from_der(bio::bio_ptr bio)
		{
			return take_ownership(d2i_X509_REQ_bio(bio.raw(), NULL));
		}
コード例 #9
0
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;
	}
}
コード例 #10
0
ファイル: scep_msg.c プロジェクト: aleibl/openca-tools
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;
}