예제 #1
1
파일: ssl.c 프로젝트: adrianimboden/burp
// This function taken from openvpn-2.2.1 and tidied up a bit.
static int setenv_x509(X509_NAME *x509, const char *type)
{
	int i, n;
	int fn_nid;
	ASN1_OBJECT *fn;
	ASN1_STRING *val;
	X509_NAME_ENTRY *ent;
	const char *objbuf;
	uint8_t *buf;
	char *name_expand;
	size_t name_expand_size;

	n=X509_NAME_entry_count (x509);
	for(i=0; i<n; ++i)
	{
		if(!(ent=X509_NAME_get_entry (x509, i))
		  || !(fn=X509_NAME_ENTRY_get_object(ent))
		  || !(val=X509_NAME_ENTRY_get_data(ent))
		  || (fn_nid=OBJ_obj2nid(fn))==NID_undef
		  || !(objbuf=OBJ_nid2sn(fn_nid)))
			continue;
		buf=(uint8_t *)1; /* bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 requires this workaround */
		if(ASN1_STRING_to_UTF8(&buf, val)<=0) continue;
		name_expand_size=64+strlen(objbuf);
		if(!(name_expand=(char *)malloc_w(name_expand_size, __func__)))
			return -1;
		snprintf(name_expand, name_expand_size,
			"X509_%s_%s", type, objbuf);
		sanitise(name_expand);
		sanitise((char*)buf);
		setenv(name_expand, (char*)buf, 1);
		free (name_expand);
		OPENSSL_free (buf);
	}
	return 0;
}
예제 #2
0
static PyObject *
get_subject (certificate_x509 *self, PyObject *args)
{
	if (!PyArg_ParseTuple (args, "")) {
		return NULL;
	}

	X509_NAME *name = X509_get_subject_name (self->x509);
	int entries = X509_NAME_entry_count (name);
	int i;

	PyObject *dict = PyDict_New ();
	for (i = 0; i < entries; i++) {
		X509_NAME_ENTRY *entry = X509_NAME_get_entry (name, i);
		ASN1_OBJECT *obj = X509_NAME_ENTRY_get_object (entry);
		ASN1_STRING *data = X509_NAME_ENTRY_get_data (entry);

		PyObject *key =
			PyString_FromString (OBJ_nid2sn (OBJ_obj2nid (obj)));
		PyObject *value = PyString_FromString ((const char *)
						       ASN1_STRING_data (data));
		PyDict_SetItem (dict, key, value);

		Py_DECREF (key);
		Py_DECREF (value);
	}

	return dict;
}
예제 #3
0
static char *lookup_ssl_cert_dn(X509_NAME *xsname, int dnidx)
{
    char *result;
    X509_NAME_ENTRY *xsne;
    int i, j, n, idx = 0;

    result = NULL;

    for (i = 0; info_cert_dn_rec[i].fid != 0; i++) {
        if (info_cert_dn_rec[i].fid == dnidx) {
            for (j = 0; j < sk_X509_NAME_ENTRY_num((STACK_OF(X509_NAME_ENTRY) *)
                                                   (xsname->entries)); j++) {
                xsne = sk_X509_NAME_ENTRY_value((STACK_OF(X509_NAME_ENTRY) *)
                                                (xsname->entries), j);

                n =OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xsne));
                if (n == info_cert_dn_rec[i].nid && idx-- == 0) {
                    result = malloc(xsne->value->length + 1);
                    memcpy(result, xsne->value->data,
                                   xsne->value->length);
                    result[xsne->value->length] = '\0';

#if APR_CHARSET_EBCDIC
                    ap_xlate_proto_from_ascii(result, xsne->value->length);
#endif /* APR_CHARSET_EBCDIC */
                    break;
                }
            }
            break;
        }
    }
    return result;
}
예제 #4
0
/*
 * Given a X509_NAME object and a name identifier, set the corresponding
 * attribute to the given string. Used by the setattr function.
 *
 * Arguments: name  - The X509_NAME object
 *            nid   - The name identifier
 *            value - The string to set
 * Returns:   0 for success, -1 on failure
 */
static int
set_name_by_nid(X509_NAME *name, int nid, char *utf8string)
{
    X509_NAME_ENTRY *ne;
    int i, entry_count, temp_nid;

    /* If there's an old entry for this NID, remove it */
    entry_count = X509_NAME_entry_count(name);
    for (i = 0; i < entry_count; i++)
    {
        ne = X509_NAME_get_entry(name, i);
        temp_nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(ne));
        if (temp_nid == nid)
        {
            ne = X509_NAME_delete_entry(name, i);
            X509_NAME_ENTRY_free(ne);
            break;
        }
    }

    /* Add the new entry */
    if (!X509_NAME_add_entry_by_NID(name, nid, MBSTRING_UTF8, 
				    (unsigned char *)utf8string,
				    -1, -1, 0))
    {
        exception_from_error_queue(crypto_Error);
        return -1;
    }
    return 0;
}
예제 #5
0
static int openssl_push_xname_entry(lua_State* L, X509_NAME_ENTRY* ne)
{
  ASN1_OBJECT* object = X509_NAME_ENTRY_get_object(ne);
  lua_newtable(L);
  openssl_push_asn1object(L, object);
  PUSH_ASN1_STRING(L, X509_NAME_ENTRY_get_data(ne));
  lua_settable(L, -3);
  return 1;
}
예제 #6
0
파일: sslinfo.c 프로젝트: Aslai/postgres
/*
 * Equivalent of X509_NAME_oneline that respects encoding
 *
 * This function converts X509_NAME structure to the text variable
 * converting all textual data into current database encoding.
 *
 * Parameter: X509_NAME *name X509_NAME structure to be converted
 *
 * Returns: text datum which contains string representation of
 * X509_NAME
 */
static Datum
X509_NAME_to_text(X509_NAME *name)
{
	BIO		   *membuf = BIO_new(BIO_s_mem());
	int			i,
				nid,
				count = X509_NAME_entry_count(name);
	X509_NAME_ENTRY *e;
	ASN1_STRING *v;
	const char *field_name;
	size_t		size;
	char		nullterm;
	char	   *sp;
	char	   *dp;
	text	   *result;

	if (membuf == NULL)
		ereport(ERROR,
				(errcode(ERRCODE_OUT_OF_MEMORY),
				 errmsg("could not create OpenSSL BIO structure")));

	(void) BIO_set_close(membuf, BIO_CLOSE);
	for (i = 0; i < count; i++)
	{
		e = X509_NAME_get_entry(name, i);
		nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
		if (nid == NID_undef)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("could not get NID for ASN1_OBJECT object")));
		v = X509_NAME_ENTRY_get_data(e);
		field_name = OBJ_nid2sn(nid);
		if (field_name == NULL)
			field_name = OBJ_nid2ln(nid);
		if (field_name == NULL)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("could not convert NID %d to an ASN1_OBJECT structure", nid)));
		BIO_printf(membuf, "/%s=", field_name);
		ASN1_STRING_print_ex(membuf, v,
							 ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
							  | ASN1_STRFLGS_UTF8_CONVERT));
	}

	/* ensure null termination of the BIO's content */
	nullterm = '\0';
	BIO_write(membuf, &nullterm, 1);
	size = BIO_get_mem_data(membuf, &sp);
	dp = pg_any_to_server(sp, size - 1, PG_UTF8);
	result = cstring_to_text(dp);
	if (dp != sp)
		pfree(dp);
	if (BIO_free(membuf) != 1)
		elog(ERROR, "could not free OpenSSL BIO structure");

	PG_RETURN_TEXT_P(result);
}
예제 #7
0
/*
 * Equivalent of X509_NAME_oneline that respects encoding
 *
 * This function converts X509_NAME structure to the text variable
 * converting all textual data into current database encoding.
 *
 * Parameter: X509_NAME *name X509_NAME structure to be converted
 *
 * Returns: text datum which contains string representation of
 * X509_NAME
 */
Datum
X509_NAME_to_text(X509_NAME *name)
{
	BIO		   *membuf = BIO_new(BIO_s_mem());
	int			i,
				nid,
				count = X509_NAME_entry_count(name);
	X509_NAME_ENTRY *e;
	ASN1_STRING *v;

	const char *field_name;
	size_t		size,
				outlen;
	char	   *sp;
	char	   *dp;
	text	   *result;

	(void) BIO_set_close(membuf, BIO_CLOSE);
	for (i = 0; i < count; i++)
	{
		e = X509_NAME_get_entry(name, i);
		nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
		v = X509_NAME_ENTRY_get_data(e);
		field_name = OBJ_nid2sn(nid);
		if (!field_name)
			field_name = OBJ_nid2ln(nid);
		BIO_printf(membuf, "/%s=", field_name);
		ASN1_STRING_print_ex(membuf, v,
							 ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
							  | ASN1_STRFLGS_UTF8_CONVERT));
	}

	i = 0;
	BIO_write(membuf, &i, 1);
	size = BIO_get_mem_data(membuf, &sp);

	dp = (char *) pg_do_encoding_conversion((unsigned char *) sp,
											size - 1,
											PG_UTF8,
											GetDatabaseEncoding());
	BIO_free(membuf);
	outlen = strlen(dp);
	result = palloc(VARHDRSZ + outlen);
	memcpy(VARDATA(result), dp, outlen);

	/*
	 * pg_do_encoding_conversion has annoying habit of returning source
	 * pointer
	 */
	if (dp != sp)
		pfree(dp);
	VARATT_SIZEP(result) = outlen + VARHDRSZ;
	PG_RETURN_TEXT_P(result);
}
예제 #8
0
파일: IoCertificate.c 프로젝트: anthem/io
IoObject *IoCertificate_nameToObject(IoObject *self, X509_NAME *xname)
{
	IoObject *map = IoObject_new(IoObject_state(self));
	int i;
	for(i = 0; i < X509_NAME_entry_count(xname); i++)
	{
		X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
		const char *key = (const char *)OBJ_nid2ln(OBJ_obj2nid(X509_NAME_ENTRY_get_object(entry)));
		const char *value = (const char *)ASN1_STRING_data(X509_NAME_ENTRY_get_data(entry));
		IoObject_setSlot_to_(map, IOSYMBOL(key), IoSeq_newWithCString_(IoObject_state(self), value));
	}
	return map;
}
예제 #9
0
/*
 * Save X509 fields to environment, using the naming convention:
 *
 *  X509_{cert_depth}_{name}={value}
 */
void
x509_setenv (struct env_set *es, int cert_depth, openvpn_x509_cert_t *peer_cert)
{
  int i, n;
  int fn_nid;
  ASN1_OBJECT *fn;
  ASN1_STRING *val;
  X509_NAME_ENTRY *ent;
  const char *objbuf;
  unsigned char *buf;
  char *name_expand;
  size_t name_expand_size;
  X509_NAME *x509 = X509_get_subject_name (peer_cert);

  n = X509_NAME_entry_count (x509);
  for (i = 0; i < n; ++i)
    {
      ent = X509_NAME_get_entry (x509, i);
      if (!ent)
	continue;
      fn = X509_NAME_ENTRY_get_object (ent);
      if (!fn)
	continue;
      val = X509_NAME_ENTRY_get_data (ent);
      if (!val)
	continue;
      fn_nid = OBJ_obj2nid (fn);
      if (fn_nid == NID_undef)
	continue;
      objbuf = OBJ_nid2sn (fn_nid);
      if (!objbuf)
	continue;
      buf = (unsigned char *)1; /* bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 requires this workaround */
      if (ASN1_STRING_to_UTF8 (&buf, val) <= 0)
	continue;
      name_expand_size = 64 + strlen (objbuf);
      name_expand = (char *) malloc (name_expand_size);
      check_malloc_return (name_expand);
      openvpn_snprintf (name_expand, name_expand_size, "X509_%d_%s", cert_depth,
	  objbuf);
      string_mod (name_expand, CC_PRINT, CC_CRLF, '_');
      string_mod ((char*)buf, CC_PRINT, CC_CRLF, '_');
      setenv_str (es, name_expand, (char*)buf);
      free (name_expand);
      OPENSSL_free (buf);
    }
}
예제 #10
0
파일: sslinfo.c 프로젝트: colinet/sqlix
/*
 * Equivalent of X509_NAME_oneline that respects encoding
 *
 * This function converts X509_NAME structure to the text variable
 * converting all textual data into current database encoding.
 *
 * Parameter: X509_NAME *name X509_NAME structure to be converted
 *
 * Returns: text datum which contains string representation of
 * X509_NAME
 */
datum_t
X509_NAME_to_text(X509_NAME *name)
{
	BIO		   *membuf = BIO_new(BIO_s_mem());
	int			i,
				nid,
				count = X509_NAME_entry_count(name);
	X509_NAME_ENTRY *e;
	ASN1_STRING *v;
	const char *field_name;
	size_t		size;
	char		nullterm;
	char	   *sp;
	char	   *dp;
	text	   *result;

	(void) BIO_set_close(membuf, BIO_CLOSE);
	for (i = 0; i < count; i++)
	{
		e = X509_NAME_get_entry(name, i);
		nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
		v = X509_NAME_ENTRY_get_data(e);
		field_name = OBJ_nid2sn(nid);
		if (!field_name)
			field_name = OBJ_nid2ln(nid);
		BIO_printf(membuf, "/%s=", field_name);
		ASN1_STRING_print_ex(membuf, v,
							 ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
							  | ASN1_STRFLGS_UTF8_CONVERT));
	}

	/* ensure null termination of the BIO's content */
	nullterm = '\0';
	BIO_write(membuf, &nullterm, 1);
	size = BIO_get_mem_data(membuf, &sp);
	dp = (char *) pg_do_encoding_conversion((unsigned char *) sp,
											size - 1,
											PG_UTF8,
											get_db_encoding());
	result = cstring_to_text(dp);
	if (dp != sp)
		pfree(dp);
	BIO_free(membuf);

	RET_TEXT_P(result);
}
예제 #11
0
파일: xname.c 프로젝트: zhaozg/lua-openssl
/***
get index by give asn1_object or nid

@function delete_entry
@tparam integer location which name entry to delete
@treturn[1] asn1_object object that delete name entry
@treturn[1] asn1_string value that delete name entry
@treturn[2] nil delete nothing
*/
static int openssl_xname_delete_entry(lua_State*L)
{
  X509_NAME* xn = CHECK_OBJECT(1, X509_NAME, "openssl.x509_name");
  int loc = luaL_checkint(L, 2);

  X509_NAME_ENTRY *xe = X509_NAME_delete_entry(xn, loc);
  if (xe)
  {
    openssl_push_asn1object(L, X509_NAME_ENTRY_get_object(xe));
    PUSH_ASN1_STRING(L, X509_NAME_ENTRY_get_data(xe));
    X509_NAME_ENTRY_free(xe);
    return 2;
  }
  else
    lua_pushnil(L);

  return 1;
};
예제 #12
0
파일: xname.c 프로젝트: zhaozg/lua-openssl
static int openssl_push_xname_entry(lua_State* L, X509_NAME_ENTRY* ne, int obj)
{
  ASN1_OBJECT* object = X509_NAME_ENTRY_get_object(ne);
  ASN1_STRING* value = X509_NAME_ENTRY_get_data(ne);
  lua_newtable(L);
  if(obj)
  {
    openssl_push_asn1object(L, object);
    PUSH_ASN1_STRING(L, value);
  }
  else
  {
    lua_pushstring(L, OBJ_nid2sn(OBJ_obj2nid(object)));
    lua_pushlstring(L, (const char*)ASN1_STRING_get0_data(value), ASN1_STRING_length(value));
  }
  lua_settable(L, -3);
  return 1;
}
예제 #13
0
/*
 * Convert an X509 subject name to a cstring.
 *
 */
static char *
X509_NAME_to_cstring(X509_NAME *name)
{
	BIO		   *membuf = BIO_new(BIO_s_mem());
	int			i,
				nid,
				count = X509_NAME_entry_count(name);
	X509_NAME_ENTRY *e;
	ASN1_STRING *v;
	const char *field_name;
	size_t		size;
	char		nullterm;
	char	   *sp;
	char	   *dp;
	char	   *result;

	(void) BIO_set_close(membuf, BIO_CLOSE);
	for (i = 0; i < count; i++)
	{
		e = X509_NAME_get_entry(name, i);
		nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
		v = X509_NAME_ENTRY_get_data(e);
		field_name = OBJ_nid2sn(nid);
		if (!field_name)
			field_name = OBJ_nid2ln(nid);
		BIO_printf(membuf, "/%s=", field_name);
		ASN1_STRING_print_ex(membuf, v,
							 ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
							  | ASN1_STRFLGS_UTF8_CONVERT));
	}

	/* ensure null termination of the BIO's content */
	nullterm = '\0';
	BIO_write(membuf, &nullterm, 1);
	size = BIO_get_mem_data(membuf, &sp);
	dp = pg_any_to_server(sp, size - 1, PG_UTF8);

	result = pstrdup(dp);
	if (dp != sp)
		pfree(dp);
	BIO_free(membuf);

	return result;
}
예제 #14
0
static char *ssl_var_lookup_ssl_cert_dn(apr_pool_t *p, X509_NAME *xsname,
                                        const char *var)
{
    const char *ptr;
    char *result;
    X509_NAME_ENTRY *xsne;
    int i, j, n, idx = 0, raw = 0;
    apr_size_t varlen;

    ptr = ap_strrchr_c(var, '_');
    if (ptr && ptr > var && strcmp(ptr + 1, "RAW") == 0) {
        var = apr_pstrmemdup(p, var, ptr - var);
        raw = 1;
    }
    
    /* if an _N suffix is used, find the Nth attribute of given name */
    ptr = ap_strchr_c(var, '_');
    if (ptr != NULL && strspn(ptr + 1, "0123456789") == strlen(ptr + 1)) {
        idx = atoi(ptr + 1);
        varlen = ptr - var;
    } else {
        varlen = strlen(var);
    }

    result = NULL;

    for (i = 0; ssl_var_lookup_ssl_cert_dn_rec[i].name != NULL; i++) {
        if (strEQn(var, ssl_var_lookup_ssl_cert_dn_rec[i].name, varlen)
            && strlen(ssl_var_lookup_ssl_cert_dn_rec[i].name) == varlen) {
            for (j = 0; j < X509_NAME_entry_count(xsname); j++) {
                xsne = X509_NAME_get_entry(xsname, j);

                n =OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xsne));

                if (n == ssl_var_lookup_ssl_cert_dn_rec[i].nid && idx-- == 0) {
                    result = modssl_X509_NAME_ENTRY_to_string(p, xsne, raw);
                    break;
                }
            }
            break;
        }
    }
    return result;
}
예제 #15
0
static PyObject* nassl_X509_NAME_ENTRY_get_data(nassl_X509_NAME_ENTRY_Object *self)
{
    unsigned int nameDataSize = 0, objectDataSize = 0, nameUtf8Size = 0;
    ASN1_STRING *nameData = NULL;
    ASN1_OBJECT *objectData = NULL;
    unsigned char *nameDataTxt = NULL;
    unsigned char *objectDataTxt = NULL;
    PyObject* res = NULL;

    nameData = X509_NAME_ENTRY_get_data(self->x509NameEntry);
    nameDataSize = ASN1_STRING_length(nameData);


    // Extract the text representation of the field's name
    objectData = X509_NAME_ENTRY_get_object(self->x509NameEntry);
    objectDataSize = OBJ_obj2txt(NULL, 0, objectData, 0) + 1;

    objectDataTxt = PyMem_Malloc(objectDataSize);
    if (objectDataTxt == NULL)
    {
        return PyErr_NoMemory();
    }

    OBJ_obj2txt((char *)objectDataTxt, objectDataSize, objectData, 0);
    nameUtf8Size = ASN1_STRING_to_UTF8(&nameDataTxt, nameData);


    // Are we extracting the Common Name ?
    if (strncmp((char *)objectDataTxt, "commonName", strlen("commonName")) == 0)
    {
        if (nameDataSize != nameUtf8Size)
        {
            // TODO: Unit test for that
            // Embedded null character in the Common Name ? Get out
            PyMem_Free(objectDataTxt);
            PyErr_SetString(PyExc_NotImplementedError, "ASN1 string length does not match C string length. Embedded null character ?");
            return NULL;
        }
    }
    PyMem_Free(objectDataTxt);
    res = PyString_FromStringAndSize((const char*) nameDataTxt, nameDataSize);
    return res;
}
예제 #16
0
MONO_API int
mono_btls_x509_name_get_entry_oid (MonoBtlsX509Name *name, int index, char *buffer, int size)
{
	X509_NAME_ENTRY *entry;
	ASN1_OBJECT *obj;

	if (index >= X509_NAME_entry_count (name->name))
		return 0;

	entry = X509_NAME_get_entry (name->name, index);
	if (!entry)
		return 0;

	obj = X509_NAME_ENTRY_get_object (entry);
	if (!obj)
		return 0;

	return OBJ_obj2txt (buffer, size, obj, 1);
}
예제 #17
0
static PyObject *
crypto_X509Name_get_components(crypto_X509NameObj *self, PyObject *args)
{
    int n, i;
    X509_NAME *name = self->x509_name;
    PyObject *list;

    if (!PyArg_ParseTuple(args, ":get_components"))
	return NULL;

    n = X509_NAME_entry_count(name);
    list = PyList_New(n);
    for (i = 0; i < n; i++)
    {
	X509_NAME_ENTRY *ent;
	ASN1_OBJECT *fname;
	ASN1_STRING *fval;
	int nid;
	int l;
	unsigned char *str;
	PyObject *tuple;

	ent = X509_NAME_get_entry(name, i);

	fname = X509_NAME_ENTRY_get_object(ent);
	fval = X509_NAME_ENTRY_get_data(ent);

	l = ASN1_STRING_length(fval);
	str = ASN1_STRING_data(fval);

	nid = OBJ_obj2nid(fname);

	/* printf("fname is %s len=%d str=%s\n", OBJ_nid2sn(nid), l, str); */

	tuple = PyTuple_New(2);
	PyTuple_SetItem(tuple, 0, PyBytes_FromString(OBJ_nid2sn(nid)));
	PyTuple_SetItem(tuple, 1, PyBytes_FromStringAndSize((char *)str, l));

	PyList_SetItem(list, i, tuple);
    }

    return list;
}
예제 #18
0
MONO_API MonoBtlsX509NameEntryType
mono_btls_x509_name_get_entry_type (MonoBtlsX509Name *name, int index)
{
	X509_NAME_ENTRY *entry;
	ASN1_OBJECT *obj;

	if (index >= X509_NAME_entry_count (name->name))
		return -1;

	entry = X509_NAME_get_entry (name->name, index);
	if (!entry)
		return -1;

	obj = X509_NAME_ENTRY_get_object (entry);
	if (!obj)
		return -1;

	return nid2mono (OBJ_obj2nid (obj));
}
예제 #19
0
파일: apn_ssl.c 프로젝트: edwiincao/libcapn
static char *__apn_ssl_cert_entry_string(X509_NAME *name) {
    char subject_entry_buffer[__APN_X509_ENTRY_BUF_SIZE] = {0};
    int entry_count = X509_NAME_entry_count(name);
    for (int i = 0; i < entry_count; i++) {
        X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, i);

        ASN1_OBJECT *entry_object = X509_NAME_ENTRY_get_object(entry);
        const char *entry_name = OBJ_nid2sn(OBJ_obj2nid(entry_object));
        const unsigned char *entry_value = ASN1_STRING_data(X509_NAME_ENTRY_get_data(entry));

        apn_strcat(subject_entry_buffer, entry_name, __APN_X509_ENTRY_BUF_SIZE, strlen(entry_name));
        apn_strcat(subject_entry_buffer, "=", __APN_X509_ENTRY_BUF_SIZE, 1);
        apn_strcat(subject_entry_buffer, (const char *)entry_value, __APN_X509_ENTRY_BUF_SIZE, strlen((const char *)entry_value));
        if(i + 1 < entry_count) {
            apn_strcat(subject_entry_buffer, ", ", __APN_X509_ENTRY_BUF_SIZE, 2);
        }
    }
    return apn_strndup(subject_entry_buffer, strlen(subject_entry_buffer));
}
예제 #20
0
static void openssl_setenv_X509_add_entries(liVRequest *vr, X509 *x509, const gchar *prefix, guint prefix_len) {
	guint i, j;
	GString *k = vr->wrk->tmp_str;

	X509_NAME *xn = X509_get_subject_name(x509);
	X509_NAME_ENTRY *xe;
	const char * xobjsn;

	g_string_truncate(k, 0);
	g_string_append_len(k, prefix, prefix_len);

	for (i = 0, j = X509_NAME_entry_count(xn); i < j; ++i) {
		if (!(xe = X509_NAME_get_entry(xn, i))
			|| !(xobjsn = OBJ_nid2sn(OBJ_obj2nid((ASN1_OBJECT*)X509_NAME_ENTRY_get_object(xe)))))
			continue;
		g_string_truncate(k, prefix_len);
		g_string_append(k, xobjsn);
		li_environment_set(&vr->env, GSTR_LEN(k), (const gchar *)xe->value->data, xe->value->length);
	}
}
예제 #21
0
// generate an LLSD from a certificate name (issuer or subject name).  
// the name will be strings indexed by the 'long form'
LLSD cert_name_from_X509_NAME(X509_NAME* name)
{
	LLSD result = LLSD::emptyMap();
	int name_entries = X509_NAME_entry_count(name);
	for (int entry_index=0; entry_index < name_entries; entry_index++) 
	{
		char buffer[32];
		X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, entry_index);
		
		std::string name_value = std::string((const char*)M_ASN1_STRING_data(X509_NAME_ENTRY_get_data(entry)), 
											 M_ASN1_STRING_length(X509_NAME_ENTRY_get_data(entry)));

		ASN1_OBJECT* name_obj = X509_NAME_ENTRY_get_object(entry);		
		OBJ_obj2txt(buffer, sizeof(buffer), name_obj, 0);
		std::string obj_buffer_str = std::string(buffer);
		result[obj_buffer_str] = name_value;
	}
	
	return result;
}
예제 #22
0
MONO_API int
mono_btls_x509_name_get_entry_oid_data (MonoBtlsX509Name *name, int index, const void **data)
{
	X509_NAME_ENTRY *entry;
	ASN1_OBJECT *obj;

	if (index >= X509_NAME_entry_count (name->name))
		return -1;

	entry = X509_NAME_get_entry (name->name, index);
	if (!entry)
		return -1;

	obj = X509_NAME_ENTRY_get_object (entry);
	if (!obj)
		return -1;

	*data = obj->data;
	return obj->length;
}
예제 #23
0
static void
x509_print_info (X509 *x509crt)
{
  int i, n;
  int fn_nid;
  ASN1_OBJECT *fn;
  ASN1_STRING *val;
  X509_NAME *x509_name;
  X509_NAME_ENTRY *ent;
  const char *objbuf;
  unsigned char *buf;

  x509_name = X509_get_subject_name (x509crt);
  n = X509_NAME_entry_count (x509_name);
  for (i = 0; i < n; ++i)
    {
      ent = X509_NAME_get_entry (x509_name, i);
      if (!ent)
	continue;
      fn = X509_NAME_ENTRY_get_object (ent);
      if (!fn)
	continue;
      val = X509_NAME_ENTRY_get_data (ent);
      if (!val)
	continue;
      fn_nid = OBJ_obj2nid (fn);
      if (fn_nid == NID_undef)
	continue;
      objbuf = OBJ_nid2sn (fn_nid);
      if (!objbuf)
	continue;
      buf = (unsigned char *)1; /* bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 requires this workaround */
      if (ASN1_STRING_to_UTF8 (&buf, val) <= 0)
	continue;

      printf("X509 %s: %s\n", objbuf, (char *)buf);
      OPENSSL_free (buf);
    }
}
예제 #24
0
파일: x509.c 프로젝트: horazont/luasec
/**
 * Retrive the general names from the object.
 */
static int push_x509_name(lua_State* L, X509_NAME *name)
{
  int i;
  int n_entries;
  ASN1_OBJECT *object;
  X509_NAME_ENTRY *entry;
  lua_newtable(L);
  n_entries = X509_NAME_entry_count(name);
  for (i = 0; i < n_entries; i++) {
    entry = X509_NAME_get_entry(name, i);
    object = X509_NAME_ENTRY_get_object(entry);
    lua_newtable(L);
    push_asn1_objname(L, object, 1);
    lua_setfield(L, -2, "oid");
    push_asn1_objname(L, object, 0);
    lua_setfield(L, -2, "name");
    push_asn1_string(L, X509_NAME_ENTRY_get_data(entry));
    lua_setfield(L, -2, "value");
    lua_rawseti(L, -2, i+1);
  }
  return 1;
}
예제 #25
0
static PyObject* nassl_X509_NAME_ENTRY_get_object(nassl_X509_NAME_ENTRY_Object *self)
{
    unsigned int objectDataSize = 0;
    ASN1_OBJECT *objectData = NULL;
    char *objectDataTxt = NULL;
    PyObject* res = NULL;

    objectData = X509_NAME_ENTRY_get_object(self->x509NameEntry);
    objectDataSize = OBJ_obj2txt(NULL, 0, objectData, 0) + 1;

    objectDataTxt = (char *) PyMem_Malloc(objectDataSize);
    if (objectDataTxt == NULL)
    {
        return PyErr_NoMemory();
    }

    // Extract the text representation
    OBJ_obj2txt(objectDataTxt, objectDataSize, objectData, 0);
    res = PyString_FromStringAndSize(objectDataTxt, objectDataSize - 1);
    PyMem_Free(objectDataTxt);
    return res;
}
예제 #26
0
파일: a_strex.c 프로젝트: endlessm/shim
static int do_name_ex(char_io *io_ch, void *arg, X509_NAME *n,
                      int indent, unsigned long flags)
{
    int i, prev = -1, orflags, cnt;
    int fn_opt, fn_nid;
    ASN1_OBJECT *fn;
    ASN1_STRING *val;
    X509_NAME_ENTRY *ent;
    char objtmp[80];
    const char *objbuf;
    int outlen, len;
    char *sep_dn, *sep_mv, *sep_eq;
    int sep_dn_len, sep_mv_len, sep_eq_len;
    if (indent < 0)
        indent = 0;
    outlen = indent;
    if (!do_indent(io_ch, arg, indent))
        return -1;
    switch (flags & XN_FLAG_SEP_MASK) {
    case XN_FLAG_SEP_MULTILINE:
        sep_dn = "\n";
        sep_dn_len = 1;
        sep_mv = " + ";
        sep_mv_len = 3;
        break;

    case XN_FLAG_SEP_COMMA_PLUS:
        sep_dn = ",";
        sep_dn_len = 1;
        sep_mv = "+";
        sep_mv_len = 1;
        indent = 0;
        break;

    case XN_FLAG_SEP_CPLUS_SPC:
        sep_dn = ", ";
        sep_dn_len = 2;
        sep_mv = " + ";
        sep_mv_len = 3;
        indent = 0;
        break;

    case XN_FLAG_SEP_SPLUS_SPC:
        sep_dn = "; ";
        sep_dn_len = 2;
        sep_mv = " + ";
        sep_mv_len = 3;
        indent = 0;
        break;

    default:
        return -1;
    }

    if (flags & XN_FLAG_SPC_EQ) {
        sep_eq = " = ";
        sep_eq_len = 3;
    } else {
        sep_eq = "=";
        sep_eq_len = 1;
    }

    fn_opt = flags & XN_FLAG_FN_MASK;

    cnt = X509_NAME_entry_count(n);
    for (i = 0; i < cnt; i++) {
        if (flags & XN_FLAG_DN_REV)
            ent = X509_NAME_get_entry(n, cnt - i - 1);
        else
            ent = X509_NAME_get_entry(n, i);
        if (prev != -1) {
            if (prev == ent->set) {
                if (!io_ch(arg, sep_mv, sep_mv_len))
                    return -1;
                outlen += sep_mv_len;
            } else {
                if (!io_ch(arg, sep_dn, sep_dn_len))
                    return -1;
                outlen += sep_dn_len;
                if (!do_indent(io_ch, arg, indent))
                    return -1;
                outlen += indent;
            }
        }
        prev = ent->set;
        fn = X509_NAME_ENTRY_get_object(ent);
        val = X509_NAME_ENTRY_get_data(ent);
        fn_nid = OBJ_obj2nid(fn);
        if (fn_opt != XN_FLAG_FN_NONE) {
            int objlen, fld_len;
            if ((fn_opt == XN_FLAG_FN_OID) || (fn_nid == NID_undef)) {
                OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1);
                fld_len = 0;    /* XXX: what should this be? */
                objbuf = objtmp;
            } else {
                if (fn_opt == XN_FLAG_FN_SN) {
                    fld_len = FN_WIDTH_SN;
                    objbuf = OBJ_nid2sn(fn_nid);
                } else if (fn_opt == XN_FLAG_FN_LN) {
                    fld_len = FN_WIDTH_LN;
                    objbuf = OBJ_nid2ln(fn_nid);
                } else {
                    fld_len = 0; /* XXX: what should this be? */
                    objbuf = "";
                }
            }
            objlen = strlen(objbuf);
            if (!io_ch(arg, objbuf, objlen))
                return -1;
            if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) {
                if (!do_indent(io_ch, arg, fld_len - objlen))
                    return -1;
                outlen += fld_len - objlen;
            }
            if (!io_ch(arg, sep_eq, sep_eq_len))
                return -1;
            outlen += objlen + sep_eq_len;
        }
        /*
         * If the field name is unknown then fix up the DER dump flag. We
         * might want to limit this further so it will DER dump on anything
         * other than a few 'standard' fields.
         */
        if ((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS))
            orflags = ASN1_STRFLGS_DUMP_ALL;
        else
            orflags = 0;

        len = do_print_ex(io_ch, arg, flags | orflags, val);
        if (len < 0)
            return -1;
        outlen += len;
    }
    return outlen;
}
예제 #27
0
static void https_add_ssl_entries(connection *con) {
	X509 *xs;
	X509_NAME *xn;
	X509_NAME_ENTRY *xe;
	int i, nentries;

	if (
		SSL_get_verify_result(con->ssl) != X509_V_OK
		|| !(xs = SSL_get_peer_certificate(con->ssl))
	) {
		return;
	}

	xn = X509_get_subject_name(xs);
	for (i = 0, nentries = X509_NAME_entry_count(xn); i < nentries; ++i) {
		int xobjnid;
		const char * xobjsn;
		data_string *envds;

		if (!(xe = X509_NAME_get_entry(xn, i))) {
			continue;
		}
		xobjnid = OBJ_obj2nid((ASN1_OBJECT*)X509_NAME_ENTRY_get_object(xe));
		xobjsn = OBJ_nid2sn(xobjnid);
		if (!xobjsn) {
			continue;
		}

		if (NULL == (envds = (data_string *)array_get_unused_element(con->environment, TYPE_STRING))) {
			envds = data_string_init();
		}
		buffer_copy_string_len(envds->key, CONST_STR_LEN("SSL_CLIENT_S_DN_"));
		buffer_append_string(envds->key, xobjsn);
		buffer_copy_string_len(
			envds->value,
			(const char *)xe->value->data, xe->value->length
		);
		/* pick one of the exported values as "authed user", for example
		 * ssl.verifyclient.username   = "******" or "SSL_CLIENT_S_DN_emailAddress"
		 */
		if (buffer_is_equal(con->conf.ssl_verifyclient_username, envds->key)) {
			buffer_copy_string_buffer(con->authed_user, envds->value);
		}
		array_insert_unique(con->environment, (data_unset *)envds);
	}
	if (con->conf.ssl_verifyclient_export_cert) {
		BIO *bio;
		if (NULL != (bio = BIO_new(BIO_s_mem()))) {
			data_string *envds;
			int n;

			PEM_write_bio_X509(bio, xs);
			n = BIO_pending(bio);

			if (NULL == (envds = (data_string *)array_get_unused_element(con->environment, TYPE_STRING))) {
				envds = data_string_init();
			}

			buffer_copy_string_len(envds->key, CONST_STR_LEN("SSL_CLIENT_CERT"));
			buffer_prepare_copy(envds->value, n+1);
			BIO_read(bio, envds->value->ptr, n);
			BIO_free(bio);
			envds->value->ptr[n] = '\0';
			envds->value->used = n+1;
			array_insert_unique(con->environment, (data_unset *)envds);
		}
	}
	X509_free(xs);
}
예제 #28
0
파일: openssl.c 프로젝트: jmhardison/corefx
/*
Function:
GetX509NameInfo

Used by System.Security.Cryptography.X509Certificates' OpenSslX509CertificateReader as the entire
implementation of X509Certificate2.GetNameInfo.

Return values:
NULL if the certificate is invalid or no name information could be found, otherwise a pointer to a
memory-backed BIO structure which contains the answer to the GetNameInfo query
*/
BIO*
GetX509NameInfo(
    X509* x509,
    int nameType,
    int forIssuer)
{
    static const char szOidUpn[] = "1.3.6.1.4.1.311.20.2.3";

    if (!x509 || !x509->cert_info || nameType < NAME_TYPE_SIMPLE || nameType > NAME_TYPE_URL)
    {
        return NULL;
    }

    // Algorithm behaviors (pseudocode).  When forIssuer is true, replace "Subject" with "Issuer" and
    // SAN (Subject Alternative Names) with IAN (Issuer Alternative Names).
    //
    // SimpleName: Subject[CN] ?? Subject[OU] ?? Subject[O] ?? Subject[E] ?? Subject.Rdns.FirstOrDefault() ?? SAN.Entries.FirstOrDefault(type == GEN_EMAIL);
    // EmailName: SAN.Entries.FirstOrDefault(type == GEN_EMAIL) ?? Subject[E];
    // UpnName: SAN.Entries.FirsOrDefaultt(type == GEN_OTHER && entry.AsOther().OID == szOidUpn).AsOther().Value;
    // DnsName: SAN.Entries.FirstOrDefault(type == GEN_DNS) ?? Subject[CN];
    // DnsFromAlternativeName: SAN.Entries.FirstOrDefault(type == GEN_DNS);
    // UrlName: SAN.Entries.FirstOrDefault(type == GEN_URI);
    if (nameType == NAME_TYPE_SIMPLE)
    {
        X509_NAME* name = forIssuer ? x509->cert_info->issuer : x509->cert_info->subject;

        if (name)
        {
            ASN1_STRING* cn = NULL;
            ASN1_STRING* ou = NULL;
            ASN1_STRING* o = NULL;
            ASN1_STRING* e = NULL;
            ASN1_STRING* firstRdn = NULL;

            // Walk the list backwards because it is stored in stack order
            for (int i = X509_NAME_entry_count(name) - 1; i >= 0; --i)
            {
                X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, i);

                if (!entry)
                {
                    continue;
                }

                ASN1_OBJECT* oid = X509_NAME_ENTRY_get_object(entry);
                ASN1_STRING* str = X509_NAME_ENTRY_get_data(entry);

                if (!oid || !str)
                {
                    continue;
                }

                int nid = OBJ_obj2nid(oid);

                if (nid == NID_commonName)
                {
                    // CN wins, so no need to keep looking.
                    cn = str;
                    break;
                }
                else if (nid == NID_organizationalUnitName)
                {
                    ou = str;
                }
                else if (nid == NID_organizationName)
                {
                    o = str;
                }
                else if (nid == NID_pkcs9_emailAddress)
                {
                    e = str;
                }
                else if (!firstRdn)
                {
                    firstRdn = str;
                }
            }

            ASN1_STRING* answer = cn;

            // If there was no CN, but there was something, then perform fallbacks.
            if (!answer && firstRdn)
            {
                answer = ou;

                if (!answer)
                {
                    answer = o;
                }

                if (!answer)
                {
                    answer = e;
                }

                if (!answer)
                {
                    answer = firstRdn;
                }
            }

            if (answer)
            {
                BIO* b = BIO_new(BIO_s_mem());
                ASN1_STRING_print_ex(b, answer, 0);
                return b;
            }
        }
    }

    if (nameType == NAME_TYPE_SIMPLE ||
        nameType == NAME_TYPE_DNS ||
        nameType == NAME_TYPE_DNSALT ||
        nameType == NAME_TYPE_EMAIL ||
        nameType == NAME_TYPE_UPN ||
        nameType == NAME_TYPE_URL)
    {
        int expectedType = -1;

        switch (nameType)
        {
            case NAME_TYPE_DNS:
            case NAME_TYPE_DNSALT:
                expectedType = GEN_DNS;
                break;
            case NAME_TYPE_SIMPLE:
            case NAME_TYPE_EMAIL:
                expectedType = GEN_EMAIL;
                break;
            case NAME_TYPE_UPN:
                expectedType = GEN_OTHERNAME;
                break;
            case NAME_TYPE_URL:
                expectedType = GEN_URI;
                break;
        }

        STACK_OF(GENERAL_NAME)* altNames =
            X509_get_ext_d2i(x509, forIssuer ? NID_issuer_alt_name : NID_subject_alt_name, NULL, NULL);

        if (altNames)
        {
            int i;

            for (i = 0; i < sk_GENERAL_NAME_num(altNames); ++i)
            {
                GENERAL_NAME* altName = sk_GENERAL_NAME_value(altNames, i);

                if (altName && altName->type == expectedType)
                {
                    ASN1_STRING* str = NULL;

                    switch (nameType)
                    {
                        case NAME_TYPE_DNS:
                        case NAME_TYPE_DNSALT:
                            str = altName->d.dNSName;
                            break;
                        case NAME_TYPE_SIMPLE:
                        case NAME_TYPE_EMAIL:
                            str = altName->d.rfc822Name;
                            break;
                        case NAME_TYPE_URL:
                            str = altName->d.uniformResourceIdentifier;
                            break;
                        case NAME_TYPE_UPN:
                        {
                            OTHERNAME* value = altName->d.otherName;

                            if (value)
                            {
                                // Enough more padding than szOidUpn that a \0 won't accidentally align
                                char localOid[sizeof(szOidUpn) + 3];
                                int cchLocalOid = 1 + OBJ_obj2txt(localOid, sizeof(localOid), value->type_id, 1);

                                if (sizeof(szOidUpn) == cchLocalOid &&
                                    0 == strncmp(localOid, szOidUpn, sizeof(szOidUpn)))
                                {
                                    //OTHERNAME->ASN1_TYPE->union.field
                                    str = value->value->value.asn1_string;
                                }
                            }

                            break;
                        }
                    }

                    if (str)
                    {
                        BIO* b = BIO_new(BIO_s_mem());
                        ASN1_STRING_print_ex(b, str, 0);
                        sk_GENERAL_NAME_free(altNames);
                        return b;
                    }
                }
            }

            sk_GENERAL_NAME_free(altNames);
        }
    }

    if (nameType == NAME_TYPE_EMAIL ||
        nameType == NAME_TYPE_DNS)
    {
        X509_NAME* name = forIssuer ? x509->cert_info->issuer : x509->cert_info->subject;
        int expectedNid = NID_undef;

        switch (nameType)
        {
            case NAME_TYPE_EMAIL:
                expectedNid = NID_pkcs9_emailAddress;
                break;
            case NAME_TYPE_DNS:
                expectedNid = NID_commonName;
                break;
        }

        if (name)
        {
            // Walk the list backwards because it is stored in stack order
            for (int i = X509_NAME_entry_count(name) - 1; i >= 0; --i)
            {
                X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, i);

                if (!entry)
                {
                    continue;
                }

                ASN1_OBJECT* oid = X509_NAME_ENTRY_get_object(entry);
                ASN1_STRING* str = X509_NAME_ENTRY_get_data(entry);

                if (!oid || !str)
                {
                    continue;
                }

                int nid = OBJ_obj2nid(oid);

                if (nid == expectedNid)
                {
                    BIO* b = BIO_new(BIO_s_mem());
                    ASN1_STRING_print_ex(b, str, 0);
                    return b;
                }
            }
        }
    }

    return NULL;
}
예제 #29
0
static int verifypeer(const struct tls_info *info, SSL *ssl)
{
	X509 *x=NULL;
	X509_NAME *subj=NULL;
	int nentries, j;
	char domain[256];
	char *p;
	char errmsg[1000];

	if (!info->peer_verify_domain)
		return (1);

	if (info->isserver)
	{
		x=SSL_get_peer_certificate(ssl);

		if (x)
			subj=X509_get_subject_name(x);
	}
	else
	{
		STACK_OF(X509) *peer_cert_chain=SSL_get_peer_cert_chain(ssl);

		if (peer_cert_chain && peer_cert_chain->stack.num > 0)
		{
			X509 *xx=(X509 *)peer_cert_chain->stack.data[0];

			if (xx)
				subj=X509_get_subject_name(xx);
		}
	}

	
	nentries=0;
	if (subj)
		nentries=X509_NAME_entry_count(subj);

	domain[0]=0;
	for (j=0; j<nentries; j++)
	{
		const char *obj_name;
		X509_NAME_ENTRY *e;
		ASN1_OBJECT *o;
		ASN1_STRING *d;

		int dlen;
		unsigned char *ddata;

		e=X509_NAME_get_entry(subj, j);
		if (!e)
			continue;

		o=X509_NAME_ENTRY_get_object(e);
		d=X509_NAME_ENTRY_get_data(e);

		if (!o || !d)
			continue;

		obj_name=OBJ_nid2sn(OBJ_obj2nid(o));

		dlen=ASN1_STRING_length(d);
		ddata=ASN1_STRING_data(d);

		if (strcasecmp(obj_name, "CN") == 0)
		{
			if (dlen >= sizeof(domain)-1)
				dlen=sizeof(domain)-1;

			memcpy(domain, ddata, dlen);
			domain[dlen]=0;
		}
	}

	if (x)
		X509_free(x);
	p=domain;

	if (*p == '*')
	{
		int	pl, l;

		pl=strlen(++p);
		l=strlen(info->peer_verify_domain);

		if (*p == '.' && pl <= l &&
		    strcasecmp(info->peer_verify_domain+l-pl, p) == 0)
			return (1);
	}
	else if (strcasecmp(info->peer_verify_domain, p) == 0)
		return (1);

	strcpy(errmsg, "couriertls: Mismatched SSL certificate: CN=");
	strcat(errmsg, domain);
	strcat(errmsg, " (expected ");
	strncat(errmsg, info->peer_verify_domain, 256);
	strcat(errmsg, ")");
	(*info->tls_err_msg)(errmsg, info->app_data);
	return (0);
}
예제 #30
0
파일: misc.c 프로젝트: LuaDist/lua-openssl
void add_assoc_name_entry(lua_State*L, char * key, X509_NAME * name, int shortname) /* {{{ */
{
	int i, j = -1, last = -1, obj_cnt = 0;
	char *sname;
	int nid;
	X509_NAME_ENTRY * ne;
	ASN1_STRING * str = NULL;
	ASN1_OBJECT * obj;
	char* p;

	lua_newtable(L);
	
	p=X509_NAME_oneline(name,NULL,0);
	lua_pushstring(L, p);
	lua_rawseti(L, -2, 0);
	OPENSSL_free(p);

	for (i = 0; i < X509_NAME_entry_count(name); i++) {
		unsigned char *to_add;
		int to_add_len;
		int tindex = 0;
		//int utf8 = 0;

		ne  = X509_NAME_get_entry(name, i);
		obj = X509_NAME_ENTRY_get_object(ne);
		nid = OBJ_obj2nid(obj);
		obj_cnt = 0;

		if (shortname) {
			sname = (char *) OBJ_nid2sn(nid);
		} else {
			sname = (char *) OBJ_nid2ln(nid);
		}

		lua_newtable(L);

		last = -1;
		for (;;) {
			j = X509_NAME_get_index_by_OBJ(name, obj, last);
			if (j < 0) {
				if (last != -1) break;
			} else {
				obj_cnt++;
				ne  = X509_NAME_get_entry(name, j);
				str = X509_NAME_ENTRY_get_data(ne);

				/* Some Certificate not stardand
				if (ASN1_STRING_type(str) != V_ASN1_UTF8STRING) {
					to_add_len = ASN1_STRING_to_UTF8(&to_add, str);
				}
				*/

				to_add = ASN1_STRING_data(str);
				to_add_len = ASN1_STRING_length(str);
				tindex++;
				lua_pushlstring(L,(char *)to_add, to_add_len);
				lua_rawseti(L,-2,tindex);
			}
			last = j;
		}
		i = last;
		
		if (obj_cnt > 1) {
			lua_setfield(L,-2,sname);
		} else {
			lua_pop(L,1);
			if (obj_cnt && str && to_add_len > -1) {
				lua_pushlstring(L,(char *)to_add, to_add_len);
				lua_setfield(L,-2, sname);
			}
		}
	}

	if (key != NULL) {
		lua_setfield(L,-2,key);
	}
}